Native Swift bindings for cooklang-import via UniFFI.
Xcode UI: File → Add Package Dependencies → Enter URL:
https://github.com/cooklang/cooklang-import
Package.swift:
dependencies: [
.package(url: "https://github.com/cooklang/cooklang-import.git", from: "0.8.6")
]Add to your target:
.target(
name: "YourApp",
dependencies: [
.product(name: "CooklangImport", package: "cooklang-import")
]
)- Download
CooklangImport-ios.zipfrom the latest release - Extract and add
CooklangImportFFI.xcframeworkto your Xcode project - Add the Swift bindings file from
swift/to your project
Uses default LLM provider from environment variables (e.g., OPENAI_API_KEY).
import CooklangImport
func importRecipe() async throws {
let cooklang = try await simpleImport(url: "https://example.com/recipe")
print(cooklang)
}func importWithLlm() async throws {
let config = FfiImportConfig(
provider: .anthropic,
apiKey: "your-api-key",
model: nil, // Uses default model
timeoutSeconds: 30,
extractOnly: false
)
let result = try await importFromUrl(
url: "https://example.com/recipe",
config: config
)
print(result)
}func extractOnly() async throws {
let config = FfiImportConfig(
provider: nil,
apiKey: nil,
model: nil,
timeoutSeconds: 30,
extractOnly: true
)
let result = try await importFromUrl(
url: "https://example.com/recipe",
config: config
)
// Returns structured recipe data without Cooklang conversion
}func convertText() async throws {
let config = FfiImportConfig(
provider: .openai,
apiKey: "your-api-key",
model: "gpt-4.1-mini",
timeoutSeconds: 30,
extractOnly: false
)
let text = "Take 2 eggs and 1 cup flour. Mix and bake at 350F for 30 min."
let cooklang = try await importFromText(text: text, config: config)
print(cooklang)
}import SwiftUI
import CooklangImport
struct RecipeImportView: View {
@State private var url = ""
@State private var result = ""
@State private var isLoading = false
@State private var error: String?
var body: some View {
VStack(spacing: 16) {
TextField("Recipe URL", text: $url)
.textFieldStyle(.roundedBorder)
Button("Import Recipe") {
Task {
await importRecipe()
}
}
.disabled(isLoading || url.isEmpty)
if isLoading {
ProgressView()
}
if let error = error {
Text(error)
.foregroundColor(.red)
}
ScrollView {
Text(result)
.font(.system(.body, design: .monospaced))
}
}
.padding()
}
func importRecipe() async {
isLoading = true
error = nil
do {
result = try await simpleImport(url: url)
} catch {
self.error = error.localizedDescription
}
isLoading = false
}
}enum FfiLlmProvider {
case openai // Requires OPENAI_API_KEY or apiKey parameter
case anthropic // Requires ANTHROPIC_API_KEY or apiKey parameter
case google // Requires GOOGLE_API_KEY or apiKey parameter
case azureOpenai // Requires additional Azure configuration
case ollama // Local models via Ollama
}do {
let result = try await simpleImport(url: url)
} catch {
print("Import failed: \(error)")
}./scripts/build-ios.shOutput in target/ios/:
CooklangImportFFI.xcframework- XCFramework for all iOS targetsCooklangImport/- Swift Package ready to useswift/- Swift binding files
- arm64 (devices)
- arm64 (simulator, Apple Silicon Macs)
- x86_64 (simulator, Intel Macs)