SFSpeechRecognizer — основной API Apple для распознавания речи в экосистеме iOS. Фреймворк предоставляет доступ к ASR-движку устройства через Speech.framework, поддерживая потоковую транскрибацию в реальном времени и однократное распознавание аудиофайлов. SFSpeechRecognizer доступен на iOS 10+, macOS 10.15+, watchOS 6+ и tvOS 17+. С iOS 17 Apple добавила полноценный on-device режим, позволяющий распознавать речь без интернет-соединения. По данным Apple Speech Documentation, 2025, SFSpeechRecogniser используется в более чем 200,000 приложений App Store и обрабатывает миллионы запросов в день с WER 7% на английском языке.
Главное
SFSpeechRecognizer — класс из Speech.framework, представляющий распознаватель речи для конкретного языка. Он инициализируется с Locale (ru_RU, en_US, zh_CN). SFSpeechRecognizer управляет запросом на распознавание (SFSpeechRecognitionRequest) и возвращает результат (SFSpeechRecognitionResult) с транскрипциями и метаданными. Поддерживает два типа запросов: SFSpeechAudioBufferRecognitionRequest (живой аудиопоток) и SFSpeechURLRecognitionRequest (аудиофайл). Оба возвращают SFTranscription — массив альтернативных вариантов распознавания.
SFSpeechRecognitionResult содержит: bestTranscription (лучший вариант, SFTranscription), transcriptions (все альтернативы), isFinal (финальный/промежуточный). SFTranscription содержит: formattedString (текст), segments (массив SFTranscriptionSegment с временными метками, confidence, substringRange, alternativeSubstrings). Confidence для каждого сегмента (0..1) — позволяет фильтровать ненадёжные фрагменты. segments — ключевая фича Speech.framework: даёт покадровую разметку каждого слова с уверенностью.
Архитектура SFSpeechRecognizer: AVFoundation (захват аудио) → Audio Buffer Buffer → SFSpeechAudioBufferRecognitionRequest → SFSpeechRecognizer (ASR движок) → SFSpeechRecognitionResult → SFSpeechRecognitionTask (контроль: cancel, finish, pause). ASR движок Apple использует гибридную архитектуру: Conformer (энкодер) + RNNT (декодер) для on-device, Transducer для cloud. Модели оптимизированы под Apple Neural Engine (ANE). На A17 Pro on-device ASR работает с RTF 0.3–0.6 (быстрее реального времени).
| Компонент | Назначение | iOS Версия |
|---|---|---|
| SFSpeechRecognizer | Основной класс распознавания | iOS 10+ |
| SFSpeechAudioBufferRecognitionRequest | Живой аудиопоток | iOS 10+ |
| SFSpeechURLRecognitionRequest | Аудиофайл (.wav, .m4a) | iOS 10+ |
| SFSpeechRecognitionTask | Управление запросом (cancel, finish) | iOS 10+ |
| On-device recognition | Offline ASR | iOS 17+ |
| Combined Recognition | Гибрид on-device + cloud | iOS 17+ |
Требования к аудио: SFSpeechRecognizer принимает LPCM (16 kHz, 16 bit, mono) или Opus (iOS 17+). AVFoundation может захватывать буфер любого формата, request конвертирует автоматически. Минимальная длина: 0.5 секунды (silence detection). Максимальная: 1 минута (cloud) / 2 минуты (on-device) за один запрос. Для длинной транскрибации разбивайте аудио на чанки по 30–60 секунд с перекрытием 2–5 секунд.
Разрешения пользователя: SFSpeechRecognizer требует два явных разрешения. NSMicrophoneUsageDescription (Privacy — Microphone Usage Description) — для доступа к микрофону. NSSpeechRecognitionUsageDescription (Privacy — Speech Recognition Usage Description) — для доступа к распознаванию речи. Оба — строки, объясняющие пользователю зачем. SFSpeechRecognizer.requestAuthorization — вызов диалога разрешений. Статусы: notDetermined, denied, restricted, authorized. Без authorized вызов recognizer выдаёт ошибку 216 (Speech framework error).
Проверка доступности: SFSpeechRecognizer.isAvailable — проверяет, доступен ли ASR для текущего языка. На iOS 16- isAvailable = false без интернета. На iOS 17+ isAvailable = true для on-device языков даже offline. SFSpeechRecognizer.supportedLocales — статический метод для получения списка поддерживаемых языков устройством. Рекомендуется проверять isAvailable перед каждым запуском (пользователь может отключить Siri/Диктовку в настройках). Доступность зависит от региона: китайский — только в Китае, арабский — в ОАЭ.
// SFSpeechRecognizer setup
import Speech
SFSpeechRecognizer.requestAuthorization { status in
guard status == .authorized else { return }
}
let recognizer = SFSpeechRecognizer(locale: Locale(identifier: "ru_RU"))!
guard recognizer.isAvailable else {
print("ASR not available. Enable Siri & Dictation in Settings")
return
}
let request = SFSpeechAudioBufferRecognitionRequest()
request.requiresOnDeviceRecognition = true
Обработка ошибок: SFSpeechRecognizer вызывается с completion handler, который может вернуть Error. Основные ошибки: 203 — no internet (cloud, iOS 16-); 216 — not authorized (нет разрешения); 301 — audio error (проблема с микрофоном/форматом); 401 — service unavailable (сервис перегружен); 601 — language unavailable (язык не поддерживается на устройстве). Для on-device iOS 17+ основные ошибки: 301 (audio), 601 (language). Всегда обрабатывайте completion handler — ошибки могут возникнуть в любой момент записи.
Live ASR pipeline: AVAudioEngine (захват с микрофона) → installTap (буфер аудио) → request.append(buffer) → SFSpeechRecognizer → recognitionTask → delegate/resultHandler. AVAudioEngine обеспечивает низкую latency (5–10 ms from mic to buffer). SFSpeechRecognitionDelegate: didHypothesizeTranscription (каждые 200–500 ms — частичный текст), didFinishRecognition (финальный результат). Task.isFinishing — можно отменять, когда распознавание завершено. Для continuous recognition (бесконечная диктовка) — создавайте новый task после isFinal.
SFSpeechRecognitionTaskDelegate: необязательные методы. speechRecognitionDidDetectSpeech (начало речи) — для UI-индикации. didHypothesizeTranscription (промежуточный текст) — для отображения по мере произнесения. didFinishRecognition (финальный результат) — для фиксации текста. didFinishSuccessfully (успех/ошибка) — для завершения. didProcessAudio (аудиобуфер обработан) — для метра RMS. Рекомендуется реализовать didHypothesizeTranscription — пользователь видит текст сразу, без задержки. Final transcription — для сохранения.
// Live speech recognition
let audioEngine = AVAudioEngine()
let request = SFSpeechAudioBufferRecognitionRequest()
request.shouldReportPartialResults = true
recognitionTask = recognizer.recognitionTask(with: request) { result, error in
if let result = result {
textView.text = result.bestTranscription.formattedString
}
if error != nil || result?.isFinal == true {
audioEngine.stop()
request.endAudio()
}
}
let inputNode = audioEngine.inputNode
let recordingFormat = inputNode.outputFormat(forBus: 0)
inputNode.installTap(onBus: 0, bufferSize: 1024,
format: recordingFormat) { buffer, _ in
request.append(buffer)
}
audioEngine.prepare()
try audioEngine.start()
Continuous recognition: для режима «слушай всегда» (голосовой ввод, ассистент) требуется перезапуск задачи после isFinal. Создайте цикл: finishTask → request = SFSpeechAudioBufferRecognitionRequest() → recognitionTask = recognizer.recognitionTask(with: request). Для избежания пауз перекрывайте конец одной задачи с началом следующей (start new request за 1–2 секунды до окончания предыдущего). AVFoundation AVAudioSession — настройка .playAndRecord для одновременного воспроизведения и записи. На iOS 17+ Continuous ASR с on-device потребляет 2–5% батареи в час (A15+).
SFSpeechURLRecognitionRequest — запрос для распознавания аудиофайла по URL. Поддерживает форматы: .wav (16 kHz, 16 bit, mono), .m4a (AAC), .mp4, .mov. Максимальная длина: ~1 минута для cloud, ~2 минуты для on-device. Для файлов длиннее — разбивайте на чанки (AVAssetExportSession + trim). SFSpeechURLRecognitionRequest не поддерживает streaming (нет partial results) — только финальный результат. Для частичных результатов с файлом — конвертируйте в Audio Buffer Request.
Получение транскрипции аудиофайла: SFSpeechRecognizer.recognitionTask(with: request) resultHandler. Извлекайте bestTranscription.formattedString. Для word-level timestamps — segments из bestTranscription.segments (segment.duration, segment.timestamp, segment.substring). Confidence per segment — уверенность ASR в каждом слове (используйте для фильтрации). Альтернативные варианты — transcriptionFormatter альтернативы для слов с низким confidence. Для файлов с несколькими спикерами — SFSpeechRecognitionRequest может возвращать multiple requests (по одному на спикера, iOS 17+).
// Audio file transcription
let audioURL = Bundle.main.url(forResource: "recording", withExtension: "m4a")!
let request = SFSpeechURLRecognitionRequest(url: audioURL)
request.requiresOnDeviceRecognition = true
recognizer.recognitionTask(with: request) { result, error in
guard let result = result, error == nil else {
print("Error: \(error?.localizedDescription ?? "unknown")")
return
}
let transcription = result.bestTranscription
let text = transcription.formattedString
let words = transcription.segments.map { segment in
Word(text: segment.substring,
start: segment.timestamp,
duration: segment.duration,
confidence: segment.confidence)
}
}
Разбивка длинных аудиофайлов: для файлов > 1 минуты нарезайте на чанки по 30–60 секунд с перекрытием 2–3 секунды (стыковка). AVAssetExportSession + CMTimeRange — экспорт чанков. Альтернатива: UISelectionView (пользователь выбирает сегмент). Сшивка транскрипций: concat текстов, stitching по перекрытию (last 2–3 words предыдущего чанка сравниваются с first 2–3 words следующего — remove duplicate). Vosk и Whisper поддерживают длинные аудио нативно, SFSpeechRecognizer — нет. Для длинной транскрибации рекомендую Whisper (Core ML) — нет ограничения длины.
On-device режим (iOS 17+): request.requiresOnDeviceRecognition = true. ASR выполняется локально на Apple Neural Engine (ANE). Преимущества: без интернета, приватность (аудио не покидает устройство), zero cost (бесплатно), низкая latency (RTF 0.3–0.6). Недостатки: точность ниже (WER 12–14% vs 7–12%), ограничение 2 минуты на запрос, ограниченный набор языков (не все 60 доступны on-device). On-device модель занимает ~50–100 MB на устройстве, загружается при первом запросе.
Cloud (iOS 16-): request.requiresOnDeviceRecognition = false (или отсутствует параметр). ASR на серверах Apple — точнее (WER 7% EN, 12% RU), больше языков, до 1 минуты на запрос. Требует интернет (WiFi или cellular). Apple не взимает плату с разработчика за cloud ASR (бесплатно). Лимиты: 1 запрос в минуту на приложение (unspecified), но для production масштабов Apple может ограничивать. cloud ASR — best-effort качество, без SLA. Для корпоративных приложений используйте Google Cloud ASR или Whisper (Core ML).
| Параметр | On-device (iOS 17+) | Cloud (iOS 10+) |
|---|---|---|
| Требует интернет | Нет | Да |
| WER (EN) | 10–12% | 7% |
| WER (RU) | 12–14% | 12% |
| Latency (RTF) | 0.3–0.6 | 0.3–0.8 (+network) |
| Макс. длина | 2 минуты | 1 минута |
| Приватность | Полная | Аудио уходит на сервер |
| Бесплатно | Да | Да |
Combined Recognition (iOS 17+): request.requiresOnDeviceRecognition = false при интернете (cloud), = true при offline (fallback). Apple автоматически выбирает режим. Для приложений, критичных к точности: проверяйте NetworkMonitor (NWPathMonitor) — при интернете cloud, при его отсутствии on-device. Для приложений, критичных к приватности: всегда on-device. Для транскрибации: cloud (точнее). Для голосового ввода: on-device (быстрее). Рекомендуется Combined: 80% cloud, 20% on-device fallback.
Голосовой ввод в кастомной клавиатуре — SFSpeechRecognizer встраивается в клавиатурные расширения (iOS 10+). Пользователь нажимает кнопку микрофона — ASR транскрибирует речь в текст и вставляет в текстовое поле. Требования: partial results (видеть текст в реальном времени), on-device (клавиатура должна работать без интернета). SFSpeechRecognizer + AVSpeechSynthesizer — голосовой ввод + голосовой вывод. Для кастомной клавиатуры на iOS 17+ используйте on-device. Ограничения клавиатурного расширения: AVAudioEngine доступен, но с ограничениями по времени (background execution limited).
Транскрибация встреч и лекций — приложения для записи и транскрибации аудио (Otter.ai, Rev, Apple Voice Memos). SFSpeechURLRecognitionRequest обрабатывает файл .m4a. Для длинных записей (30–60 минут) — Whisper Core ML (без ограничения длины). SFSpeechRecognizer segments с временными метками — для синхронизации текста с аудио (highlight текста при воспроизведении). Confidence per segment — для отображения ненадёжных фрагментов (подсветка жёлтым). Для speaker diarization (кто говорил) — Apple не предоставляет API, используйте pyannote-audio + Whisper на сервере.
Голосовые команды в iOS-приложениях — SFSpeechRecognizer + VGS framework (Voice Grammar Services) для выполнения команд: «открой настройки», «отправь сообщение», «включи свет». Grammar-based recognition: SFSpeechRecognitionRequest contextualStrings = массив команд. Это повышает точность распознавания команд до 95% (vs 85% free-form). SFSpeechRecognitionTask.cancel — для прерывания после выполнения команды. VGS + SFSpeechRecogniser + Shortcuts — кастомные голосовые команды без написания UI. Для accessibility: Voice Control (встроенный) + SFSpeechRecogniser (кастомные команды).
// Voice commands with contextual strings
let request = SFSpeechAudioBufferRecognitionRequest()
request.requiresOnDeviceRecognition = true
request.shouldReportPartialResults = true
request.contextualStrings = ["open contacts", "send message",
"show notifications", "turn on flashlight"]
recognitionTask = recognizer.recognitionTask(with: request) { result, _ in
guard let text = result?.bestTranscription.formattedString.lowercased() else { return }
voiceCommands.first { text.contains($0) }.map { command in
DispatchQueue.main.async { self.executeCommand(command) }
recognitionTask?.cancel()
}
}
Диктовка в медицинских и юридических приложениях — SFSpeechRecognizer для создания структурированных документов голосом. Domain Adaptation: contextualStrings с медицинскими/юридическими терминами (500+ фраз). SFSpeechRecognitionRequest.customLmProbability — влияние contextualStrings (0.1–1.0). Для медицинской диктовки используйте on-device (приватность данных пациента). Whisper fine-tuned на медицинских данных — альтернатива с WER 5% вместо 12% базового SFSpeechRecognizer. HIPAA compliance: on-device режим (данные не покидают устройство). Для транскрибации приёмов — SFSpeechURLRecognitionRequest + segments с speaker timestamps.
Часто задаваемые вопросы
SFSpeechRecognizer доступен с iOS 10, macOS 10.15, watchOS 6 и tvOS 17. On-device режим — с iOS 17 (requiresOnDeviceRecognition). На iOS 10–16 SFSpeechRecognizer работает только через облачные серверы Apple (требуется интернет). На всех версиях требуется явное разрешение пользователя (NSMicrophoneUsageDescription + NSSpeechRecognitionUsageDescription). SFSpeechRecognizer.supportedLocales — динамический список, зависит от региона и модели устройства.
Да, через создание новых recognitionTask после isFinal. Перезапускайте задачу после финализации предыдущей для непрерывного распознавания. На iOS 17 on-devide continuous ASR потребляет 2–5% батареи в час (A15+). На iOS 16- continuous ASR требует интернет (расход трафика ~1 MB/минута). Для реально непрерывного распознавания (всегда слушает) используйте Vosk (offline) или Whisper Core ML. SFSpeechRecognizer не поддерживает всегда-включённый режим на iOS 16-.
Используйте result.bestTranscription.segments — каждый SFTranscriptionSegment содержит confidence (Float 0..1) для слова. segments[i].substring — текст слова. segments[i].confidence — уверенность ASR в этом слове. Слова с confidence < 0.5 — ненадёжные, подсвечивайте их в UI. segments[i].timestamp — время начала (TimeInterval). segments[i].duration — длительность. segments[i].alternativeSubstrings — альтернативные варианты распознавания слова. Для длинных файлов проход по segments даёт per-word confidence без ручного парсинга.
203 — это SFSpeechError.ErrorCode.opportunistic (no internet for cloud ASR). Происходит на iOS 16- или при request.requiresOnDeviceRecognition = false без интернета. Решение: установите requiresOnDeviceRecognition = true (iOS 17+) для работы offline. На iOS 16- используйте NWPathMonitor — при отсутствии интернета отображайте сообщение «для распознавания речи требуется интернет». Альтернатива: Vosk (offline, iOS 12+) как fallback при отсутствии сети.
SFSpeechRecognizer — встроенный API Apple, бесплатный, простой в интеграции, но с ограничением длины (1–2 минуты), точностью WER 7–14% и только для iOS-экосистемы. Whisper Core ML — open-source (MIT), поддерживает 99 языков, WER 6–10%, без ограничения длины, но требует ручной интеграции, Core ML модели (39M–769M параметров), RTF 0.5–6 (медленнее SFSpeechRecognizer). SFSpeechRecognizer — для стандартного голосового ввода. Whisper — для high-accuracy транскрибации длинных аудио.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также