Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Apple Intelligence x Expoで作る音声メモアプリ
Search
Tenhou
June 24, 2026
9
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Apple Intelligence x Expoで作る音声メモアプリ
Tenhou
June 24, 2026
More Decks by Tenhou
See All by Tenhou
家のネットワークを つよつよにしようとしたら爆散した話
tenhou
0
5
AO入試の同級生と技術力で争おうとして心が折れた話
tenhou
0
8
インターンまでの道のり
tenhou
0
7
エンジニアこそ哲学せよ
tenhou
0
9
AIが実装を担う時代、エンジニアは何をするのか
tenhou
0
9
Featured
See All Featured
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
9
1.6k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
6.1k
Un-Boring Meetings
codingconduct
0
420
The Pragmatic Product Professional
lauravandoore
37
7.4k
Music & Morning Musume
bryan
48
7.4k
Deep Space Network (abreviated)
tonyrice
0
310
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
50
10k
Color Theory Basics | Prateek | Gurzu
gurzu
1
470
Product Roadmaps are Hard
iamctodd
55
13k
Evolving SEO for Evolving Search Engines
ryanjones
0
290
How to Talk to Developers About Accessibility
jct
2
550
How to make the Groovebox
asonas
2
2.4k
Transcript
Apple Intelligence × Expo で作る音声メモアプリ Audinote-mobile 開発記 tenhou / 2026
🎙 ↓ 📝
BACKGROUND そもそも Audinote とは? 🖥 デスクトップ版(Electron) • USB の IC
レコーダーを挿すと自動検出 • Gemini API で文字起こし・要約 • Markdown ファイルとして保存 • Obsidian のボルトに直接吐き出す → 📱 モバイル版(Expo / iOS) • アプリ内で録音 or ファイル選択 • Apple Intelligence でオンデバイス処 理 • 同じ Markdown 出力 • Obsidian アプリと共有 「ICレコーダーがなくてもスマホで同じことしたい」
MOTIVATION なぜ Apple Intelligence を選んだか 🔒 プライバシー 音声がデバイス外に 出ない ⚡
レイテンシ API呼び出し不要 録音後すぐ完了 💸 コスト 課金ゼロになる 🌐 オフライン 機内・地下でも動作 ただし iOS 26 + Apple Intelligence 対応機が必要 → 非対応端末は Gemini にフォールバック
DESIGN Clean Architecture × 自動フォールバック 呼び出し側はバックエンドを意識しない Presentation MainScreen / HistoryScreen
/ SettingsScreen Application ProcessAudioUseCase Domain ITranscriptionService / ISummarizationService / IFilenameGenerationService Infrastructure Apple 実装 or Gemini 実装 ← DI コンテナが自動選択 起動時の自動選択 checkAvailability() ↓ iOS 26+ かつ AI 有効? YES → Apple 系サービス AppleTranscriptionService AppleSummarizationService NO → Gemini 系サービス GeminiTranscriptionService GeminiSummarizationService ↓ 同一インターフェース ProcessAudioUseCase
IMPLEMENTATION ① Expo ローカルモジュールで Swift を呼ぶ modules/apple-intelligence/ に Swift コードを置くだけ
Swift の AsyncFunction を宣言するだけで TypeScript の async 関数として呼べる ① Swift — AsyncFunction で宣言 AsyncFunction("summarize") { (text: String, prompt: String) async throws -> String in let session = LanguageModelSession() let res = try await session.respond(to: prompt) return res.content } Expo Bridge ←→ ② TypeScript — そのまま呼ぶだけ const M = requireNativeModule( 'AppleIntelligence') // 型補完が効く普通の async 関数 const summary = await M.summarize( transcription, userPrompt )
IMPLEMENTATION ② SFSpeechRecognizer — オンデバイス文字起こし 音声ファイル → テキスト変換。データはデバイス外に出ない ✅ iOS
標準、追加ライブラリ不要 ✅ オンデバイス認識でプライバシー保護 ⚠ 無音は空文字が正常終了で返る ⚠ シミュレータでは認識失敗しやすい let rec = SFSpeechRecognizer( locale: Locale(identifier: "ja-JP"))! let req = SFSpeechURLRecognitionRequest( url: audioURL) rec.recognitionTask(with: req) { result, _ in guard let r = result, r.isFinal else { return } let text = r.bestTranscription .formattedString // ⚠ 空文字が返ることがある guard !text.isEmpty else { throw .transcriptionEmpty } }
IMPLEMENTATION ③ Foundation Models — iOS 26 Apple Intelligence のモデルをデバイス上で直接呼び出せる
session.respond(to: prompt) ── これだけで推論完了 🧠 デバイス上で推論 クラウド通信ゼロ 💬 セッション管理 LanguageModelSession 🇯🇵 日本語対応 要約・ファイル名生成に活用 ⚙ Xcode 26 beta 必須 #if canImport で Xcode 16 でもビルド可 // 可用性チェック guard case .available = SystemLanguageModel .default.availability else { throw .unavailable } // セッション作成 & 推論 let session = LanguageModelSession( instructions: "音声要約AI") let res = try await session.respond(to: filledPrompt) return res.content
TROUBLES ハマったこと 3 選 📤 Share Extension の通信 問題: URLスキームでアプリを起動
しようとしたが Extension → アプリ 間 の通信ができない 解決: App Group の共有フォルダに ファイルを置いてポーリング監視 → 解決 ⏱ バックグラウンド処理 問題: 処理中に画面を離れると iOS がアプリを中断してしまう 解決: beginBackgroundTask() で 最大約3分を確保 Sendable 警告は Box クラスで解消 → 解決 🔇 SFSpeech の罠 問題: 無音・短い録音で空文字が 正常終了として返ってくる 解決: formattedString を trimming してから空チェック → カスタムエラーを throw → 解決
SUMMARY まとめ Expo ローカルモジュール TypeScript から Swift のネイティブ API を型付きで呼べ
る。 iOS 専用機能も React Native アプリに自然に組み込める 。 Foundation Models LanguageModelSession にプロンプトを投げるだけ。API は驚くほどシンプル。 ただし Xcode 26 beta 必須という現実的な制約がある。 SFSpeechRecognizer オンデバイス文字起こしはプライバシー・レイテンシ両 面で優れる。 空文字・ロケール・シミュレータ対応が地味にハマりど ころ。 フォールバック設計 インターフェースを統一して DI コンテナで差し替え。 起動時の自動判定で Apple 非対応端末でも Gemini が動く 。 ありがとうございました 🎙 → 📝