---
title: iOS 26 SpeechAnalyzer をライブマイクに繋ぐ最小実装 — ドキュメントが書かない落とし穴
tags:  #ios26 #speechanalyzer #swift #swiftui  
author: [Obsidian連携シンプルメモ](https://docswell.com/user/SimpleMemo)
site: [Docswell](https://www.docswell.com/)
thumbnail: https://bcdn.docswell.com/page/4JMYL25QJW.jpg?width=480
description: iOS 26 は SFSpeechRecognizer を SpeechAnalyzer + 合成可能モジュールに置き換えました。本資料は SpeechTranscriber をライブの AVAudioEngine マイクに繋ぐ最小実装（SwiftUI・オンデバイス）と、ドキュメントが書かない落とし穴をまとめたものです：オーディオバッファの形式変換が必須／言語モデルは初回利用時にダウンロード（システム共有アセット）／volatile と final の扱い分け／カスタム語彙は無い／SpeechAnalyzer は watchOS 非対応（system dictation にフォールバック）。warm start の初 volatile 結果までの実測は ~0.3–0.5s（iPhone 16e / iOS 26.5 / time-to-first-volatile-result、first-party 計測であり対照ベンチではありません）。  サンプルコード(MIT): https://github.com/simplememofast/ios26-speechanalyzer-live-mic 詳しい解説(原典): https://simplememofast.com/en/blog/ios26-speechanalyzer-live-mic この実装が動いている例: https://simplememofast.com/voice-input/  — 株式会社ユリカ
published: June 23, 26
canonical: https://docswell.com/s/SimpleMemo/K9NN8Y-2026-06-23-165552
---
# Page. 1

![Page Image](https://bcdn.docswell.com/page/4JMYL25QJW.jpg)

SOLO iOS GROWTH DIA RY
·
VOL. 7
iOS 26 の SpeechAnalyzer を
ライブマイクに繋ぐ
ドキュメントが書かない落とし穴
最小SwiftUIサンプル · オンデバイス · 出荷版iOS 26実機でビルド&amp;実行（Xcode 26, Swift 6）
株式会社ユリカ / Simple Memo team


# Page. 2

![Page Image](https://bcdn.docswell.com/page/PJR9KM3K79.jpg)

TL ;D R
1つのオブジェクトから、オーケストレータ + モジュールへ
•
iOS 26 は SFSpeechRecognizer を SpeechAnalyzer + 合成可能モジュールに置き換え。
•
本資料: SpeechTranscriber を ライブの AVAudioEngine マイクに繋ぐ（SwiftUI・オンデバイス）。
•
ドキュメントが飛ばす5つの罠: バッファ変換 / 初回モデルDL / volatile と final / カスタム語彙なし /
watchOS非対応。
•
完全なサンプルは GitHub（MIT）。出荷版 iOS 26 実機でビルド&amp;実行。
Solo iOS Growth Diary — Vol. 7
株式会社ユリカ · 1


# Page. 3

![Page Image](https://bcdn.docswell.com/page/PEXQLV45JX.jpg)

対象
想定読者
•
SFSpeechRecognizer から移行する開発者。
•
WWDCサンプルを試して「ビルドは通るが文字が出ない」状態になった人。
「ビルドは通るのに無音」で午後を溶かした人へ — その答えはバッファ変換のスライド。
Solo iOS Growth Diary — Vol. 7
株式会社ユリカ · 2


# Page. 4

![Page Image](https://bcdn.docswell.com/page/3EK9LQZRED.jpg)

なぜ
なぜ SpeechAnalyzer が SFSpeechRecognizer を置き換えるのか
•
旧: 1つのオブジェクトが セッション + 言語 + 認識 を抱えていた。
•
新: モジュールを attach する オーケストレータ。必要なものだけ合成する。
•
長め・会話的な音声に最適化。
•
対応ロケールでは完全オンデバイス。
•
設定で「音声入力 / Siri を有効化」する手順が不要。
Solo iOS Growth Diary — Vol. 7
株式会社ユリカ · 3


# Page. 5

![Page Image](https://bcdn.docswell.com/page/L73W3PDG75.jpg)

メンタル モデル
Analyzer + モジュール
mic --&gt; AVAudioEngine.installTap --&gt; AVAudioConverter --&gt; AnalyzerInput
|
SpeechAnalyzer([ SpeechTranscriber ])
|
for try await result in transcriber.results
result.text (AttributedString) / result.isFinal
SpeechTranscriber＝文字起こし。 SpeechDetector＝音声区間検出。 DictationTranscriber＝短文ディクテーション。
Solo iOS Growth Diary — Vol. 7
株式会社ユリカ · 4


# Page. 6

![Page Image](https://bcdn.docswell.com/page/87DK4LPNJG.jpg)

最小実装 · 1 / 3
権限 + transcriber と analyzer を組む
// Info.plist: NSMicrophoneUsageDescription / NSSpeechRecognitionUsageDescription
guard let locale = await SpeechTranscriber
.supportedLocale(equivalentTo: .current) else {
throw Failure.localeNotSupported
}
let transcriber = SpeechTranscriber(
locale: locale,
transcriptionOptions: [],
reportingOptions: [.volatileResults],
// 発話中の暫定結果
attributeOptions: [])
// + .audioTimeRange で語単位タイミング
let analyzer = SpeechAnalyzer(modules: [transcriber])
let analyzerFormat = await SpeechAnalyzer
.bestAvailableAudioFormat(compatibleWith: [transcriber])
Solo iOS Growth Diary — Vol. 7
株式会社ユリカ · 5


# Page. 7

![Page Image](https://bcdn.docswell.com/page/VJPKM2NNE8.jpg)

最小実装 · 2 / 3
結果ループ → analyzer を開始
resultsTask = Task {
for try await result in transcriber.results {
let piece = String(result.text.characters)
// AttributedString
if result.isFinal { finalizedText += piece; volatileText = &quot;&quot; }
else
{ volatileText = piece }
}
}
let (sequence, builder) = AsyncStream&lt;AnalyzerInput&gt;.makeStream()
self.inputBuilder = builder
try await analyzer.start(inputSequence: sequence)
Solo iOS Growth Diary — Vol. 7
株式会社ユリカ · 6


# Page. 8

![Page Image](https://bcdn.docswell.com/page/2EVV9DKYEQ.jpg)

最小実装 · 3 / 3
マイクの tap
let converter = AudioBufferConverter()
// ローカルだけをキャプチャ
let input = audioEngine.inputNode
let micFormat = input.outputFormat(forBus: 0)
input.installTap(onBus: 0, bufferSize: 4096,
format: micFormat) { buffer, _ in
// SpeechAnalyzer が要求する形式に変換してから yield
guard let c = try? converter.convert(buffer,
to: analyzerFormat) else { return }
builder.yield(AnalyzerInput(buffer: c))
}
audioEngine.prepare(); try audioEngine.start()
完全な SpeechSession / AudioBufferConverter / SwiftUIビューはリポジトリに。
Solo iOS Growth Diary — Vol. 7
株式会社ユリカ · 7


# Page. 9

![Page Image](https://bcdn.docswell.com/page/57GLZYQWEL.jpg)

落とし穴 01
オーディオバッファの変換は必須
•
入力ノードの形式（多くは48kHz・ハード依存）は
SpeechAnalyzer.bestAvailableAudioFormat(compatibleWith:) と一致しないことが多い。
•
不一致 → ビルドは成功、文字起こしはゼロ。
•
「ビルドは通るが何も起きない」の最頻出原因。
•
対策: 全バッファをまず AVAudioConverter に通す。
Solo iOS Growth Diary — Vol. 7
株式会社ユリカ · 8


# Page. 10

![Page Image](https://bcdn.docswell.com/page/4EQYLMKQJP.jpg)

落とし穴 02
モデルは初回利用時にDL — オフラインを処理
let installed = await Set(
SpeechTranscriber.installedLocales.map { $0.identifier(.bcp47) })
if !installed.contains(locale.identifier(.bcp47)) {
if let request = try await AssetInventory
.assetInstallationRequest(supporting: [transcriber]) {
try await request.downloadAndInstall()
// request.progress でUI表示
}
}
•
言語モデル＝システム共有アセット（アプリ容量に算入されない）。
•
初回かつ無ネットワークではDL不可 → .assetUnavailable を明示処理し、無音で失敗させない。
Solo iOS Growth Diary — Vol. 7
株式会社ユリカ · 9


# Page. 11

![Page Image](https://bcdn.docswell.com/page/KJ4WDVPY71.jpg)

UXの要
volatile と finalized の結果
•
reportingOptions: [.volatileResults] → 発話中の高速な暫定結果。
•
result.isFinal → 確定テキスト。
•
定番UI: volatile は淡色表示、final が来たら置換。永続化は final のみ。
•
result.text は AttributedString → attributeOptions: [.audioTimeRange] で語単位タイミング（ハイライト /
シーク）。
Solo iOS Growth Diary — Vol. 7
株式会社ユリカ · 10


# Page. 12

![Page Image](https://bcdn.docswell.com/page/LE1YZ39N7G.jpg)

出荷版 iOS 26 で計測
レイテンシ — 条件とセットで提示する
ベータ期の報告
出荷版 iOS 26.5
14s+
~0.3–0.5s
初結果 · iPhone 16 Pro · iOS 26.0 beta · Xcode beta 5（
allocate / preheat 後も）
初 volatile 結果 · iPhone 16e（非Pro A18）· warm start（モデ
ル導入済・locale allocated）
first-party 計測（time-to-first-volatile-result）であり対照ベンチではない。初回起動はモデルDLを1度だけ含む — 別枠でプログレス表示。
Neural Engine は A18 ファミリ共通の16コア。
Solo iOS Growth Diary — Vol. 7
株式会社ユリカ · 11


# Page. 13

![Page Image](https://bcdn.docswell.com/page/GEWG9PNMJ2.jpg)

落とし穴 03
カスタム語彙は無い
•
SFSpeechRecognizer には既知語へ寄せる contextualStrings があった。
•
SpeechAnalyzer は iOS 26.0 時点で相当機能なし。
•
固有名詞・専門用語が多い領域は、このギャップを今から見込む。
Solo iOS Growth Diary — Vol. 7
株式会社ユリカ · 12


# Page. 14

![Page Image](https://bcdn.docswell.com/page/47ZL9K3MJ3.jpg)

落とし穴 04
watchOS — SpeechAnalyzer は無い、でも音声入力はある
•
SpeechAnalyzer: iOS / iPadOS / macOS / visionOS / tvOS 26 — watchOS には無い。
•
フォールバック: watchOS の system dictation → 確定テキストを返す（volatile / タイムレンジ / 独自tap は失うが、
音声入力は機能）。
// watchOS — system がディクテーションを処理しテキストを返す:
TextFieldLink(prompt: Text(&quot;Speak or type&quot;)) {
Image(systemName: &quot;mic.fill&quot;)
} onSubmit: { text in send(text) }
実際に出荷している分割: iPhone＝SpeechAnalyzer、Watch＝TextFieldLink。
Solo iOS Growth Diary — Vol. 7
株式会社ユリカ · 13


# Page. 15

![Page Image](https://bcdn.docswell.com/page/YJ6WKQX5JV.jpg)

落とし穴 05
Swift 6 並行性 + 可用性ゲート
•
マイクtapのクロージャは実時間オーディオスレッドで動く。
•
ローカルだけをキャプチャ（AsyncStream.Continuation・target AVAudioFormat・直前生成のconverter）。
tap内で @MainActor を触らない。
•
complete strict concurrency でビルド可。@unchecked Sendable は不要。
•
iOS 26 未満も対応するなら @available(iOS 26.0, *) + if #available(iOS 26.0, *)。
Solo iOS Growth Diary — Vol. 7
株式会社ユリカ · 14


# Page. 16

![Page Image](https://bcdn.docswell.com/page/GJ5MPRXGJ4.jpg)

移行
SFSpeechRecognizer → SpeechAnalyzer (iOS 26)
SFSpeechRecognizer（旧）
SpeechAnalyzer（iOS 26）
1オブジェクト: セッション + 認識
SpeechAnalyzer + 合成可能モジュール
append(_:) でバッファ追加
AnalyzerInput(buffer:) を AsyncStream に
partialResults フラグ
reportingOptions: [.volatileResults]
delegate / result handler
for try await result in transcriber.results
bestTranscription.formattedString
String(result.text.characters)
contextualStrings（カスタム語彙）
相当機能なし
設定でディクテーション有効化が必要
不要
watchOS で動作
watchOS 非対応（system dictation）
Solo iOS Growth Diary — Vol. 7
株式会社ユリカ · 15


# Page. 17

![Page Image](https://bcdn.docswell.com/page/9E296DXD7R.jpg)

リポジト リと採用箇所
サンプルを入手、解説を読む
サンプル（MIT）
github.com/simplememofast/ios26-speechanalyzer-live-mic
SpeechSession + AudioBufferConverter + SwiftUIビュー。出荷版iOS 26でビルド（Xcode 26, Swift 6）。
詳しい解説（原典）
simplememofast.com/en/blog/ios26-speechanalyzer-live-mic
採用箇所
このパイプライン（メール送信部を除く）は Simple Memo のオンデバイス音声入力に採用:
simplememofast.com/voice-input/
© 2026 株式会社ユリカ · サンプルは MIT · 修正は PR 歓迎
Solo iOS Growth Diary — Vol. 7
株式会社ユリカ · 16


