English | 日本語
Vokra は iOS 対応の XCFramework を Package.swift
にラップして配布しています。このチュートリアルは git clone から実機で
Vokra 呼び出しを動かすまでを扱います。
- Xcode 14 以上(macOS)
- iOS 15 以上の実機または Simulator(iOS 14 以下はスコープ外)
- 実機配布用の Apple Developer 署名プロファイル
- Vokra リポジトリ、または公開済み
v0.3.0パッケージ。リリース asset はVokra.xcframework.zipです。使用時は consumer 側のPackage.swifttarget に公開 SHA-256 を明示し、未検証の binary に置き換えないでください。
2 通り:
git clone https://github.com/ayutaz/vokra.git
cd vokra
scripts/build-ios.sh
# build/ios/Vokra.xcframework に 2 slice を生成:
# - iOS device (arm64)
# - iOS Simulator (arm64 + x86_64)Slice の検証:
scripts/verify-ios-xcframework.sh build/ios/Vokra.xcframeworkv0.3.0 GitHub Release は Vokra.xcframework.zip と SHA-256 を公開済みです。
公開済み v0.3.0 tag の Package.swift は local の
build/ios/Vokra.xcframework path を使います。現行 main の manifest には
次の固定 URL/checksum target が入っています。tag/local 経路では上の local
build を使い、release asset を使う consumer は自身の manifest にこの target
を明示してください:
.binaryTarget(
name: "Vokra",
url: "https://github.com/ayutaz/vokra/releases/download/v0.3.0/Vokra.xcframework.zip",
checksum: "fe74aeb45cc44c7fc2a1875bdd61af7d88c4ae87d2966851c88cfa4e9dcbc5a5"
)Xcode で:
- File → Add Package Dependencies → Add Local でリポジトリルートを 選ぶ(経路 A)、または URL を貼る(経路 B)
Vokraproduct をアプリターゲットにアタッチ- GGUF(
whisper-base.gguf)と WAV fixture (tests/fixtures/audio/jfk-30s.wav)をアプリのバンドル Resources に 追加。Copy items if needed と Add to target を両方 ON - Signing & Capabilities: Team と一意な Bundle ID を設定
- Build Settings → Enable Bitcode = No に設定(Apple が deprecate 済み。XCFramework は Bitcode 同梱ではない)
import SwiftUI
import Vokra // Clang module がすべての `vokra_*` C シンボルを re-export
import Foundation
import AVFoundation
struct ContentView: View {
@State private var status = "Idle"
var body: some View {
VStack(spacing: 20) {
Text(status).font(.system(.body, design: .monospaced))
Button("Transcribe") { transcribe() }
}.padding()
}
func transcribe() {
guard
let gguf = Bundle.main.path(forResource: "whisper-base", ofType: "gguf"),
let wav = Bundle.main.path(forResource: "jfk-30s", ofType: "wav")
else {
status = "resource missing"; return
}
var session: OpaquePointer?
let rc = vokra_session_create_from_file(gguf, &session)
guard rc.rawValue == VOKRA_OK.rawValue, let s = session else {
status = "session_create err=\(rc.rawValue)"; return
}
defer { vokra_session_destroy(s) }
do {
// WAV parse は C ABI の外。transcribe には mono Float32 PCM、
// sample 数、sample rate を渡す。
let file = try AVAudioFile(forReading: URL(fileURLWithPath: wav))
let format = file.processingFormat
guard format.channelCount == 1, format.sampleRate == 16_000,
let buffer = AVAudioPCMBuffer(
pcmFormat: format,
frameCapacity: AVAudioFrameCount(file.length)
)
else { status = "fixture must be mono 16 kHz"; return }
try file.read(into: buffer)
guard let pcm = buffer.floatChannelData?[0] else {
status = "fixture is not Float32 PCM"; return
}
var out: UnsafeMutablePointer<CChar>?
let arc = vokra_asr_transcribe(
s, pcm, Int(buffer.frameLength), 16_000, &out
)
let text = out.map { String(cString: $0) } ?? "<null>"
if let o = out { vokra_string_free(o) }
status = "rc=\(arc.rawValue): \(text.prefix(120))"
} catch {
status = "WAV read failed: \(error)"
}
}
}vokra_* C シンボルは XCFramework の Headers/vokra.h と完全一致で、
Clang module Vokra がすべて re-export します。
Vokra iOS ビルドはプラットフォームの制約を強制します:
- 静的リンクのみ — iOS の動的ライブラリロード禁止(NFR-RL-03)に対応。
XCFramework は
.aslice で、Unity 側はDllImport("__Internal")、 Swift 側は Clang module 経由で同一シンボルにアクセス。 - JIT 不使用 — iOS の W^X 制約。Vokra はランタイム CPU ディスパッチ のみ(NFR-RL-05)で JIT は同梱しません。
- CUDA は iOS で compile error —
vokra-backend-cudaのcompile_error!(...)により、動かせない CUDA 型シンボルを silent に リンクしてしまうのを防ぎます。 - アクセラレーションは Metal — CPU(Apple Silicon の NEON)は常に
利用可能。Metal は
vokra_session_options_tにVOKRA_BACKEND_METALを設定し、vokra_session_create_from_file_with_optionsへ渡す construction-time 選択です。FR-EX-08 により、Metal unavailable / unsupported は明示 エラーで、silent CPU fallback は行いません。
NFR-PF-03(実機で Whisper base RTF < 0.5 — v0.5 Exit criteria)の計測 は、専用の引き渡し文書を参照してください:
SwiftUI 計測アプリ、記録テンプレート(backend / device / iOS version / elapsed / audio / RTF)、R4「iPhone で Metal probe が失敗した場合」の境 界ケース、そして deliverable checklist が含まれます。
module 'Vokra' not found: SwiftPM が binary target を解決できて いません。build/ios/Vokra.xcframeworkの存在(経路 A)、あるいはPackage.swiftの URL + checksum の一致(経路 B)を確認してください。Undefined symbol: _vokra_...: 古い XCFramework の可能性。該当 コミットでscripts/build-ios.shを再実行してください。- アプリサイズ: リリース XCFramework は
.aベース。App Store slicing で不要 slice のシンボルを最終.ipaから落とせます。それでも 大きい場合はvokra-cli convert --quantize q4_kで K-quant 化した GGUF を検討してください。
- Simulator vs 実機: Simulator の RTF は NFR-PF-03 の判定には使え ません。実機で計測してください。
- Metal 検証: macOS の Metal 経路とペアで動かすと turnaround が速い です。両経路とも同じ Rust runtime + 同じ GGUF を使うため、iPhone で 再現するバグは macOS でも通常再現します。
- 移行:
onnxruntime-swiftや Core ML パイプラインから移行する場 合は Migration Guide を参照。