SFSpeechRecognizer — что это, API и интеграция в iOS

Автор: IT Sectr Опубликовано: 2026-07-19 Время чтения: 10 мин

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 — основной ASR API Apple для iOS (iOS 10+)
  • On-device — распознавание без интернета с iOS 17, WER 12–14% на русском
  • Streaming — частичные результаты в реальном времени (partial results)
  • 60+ языков — русский, английский, китайский, арабский и другие
  • Swift Native — полная интеграция с AVFoundation, Combine, Swift Concurrency

Что такое SFSpeechRecognizer: обзор возможностей

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 recognitionOffline ASRiOS 17+
Combined RecognitionГибрид on-device + cloudiOS 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

Разрешения пользователя: 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/Диктовку в настройках). Доступность зависит от региона: китайский — только в Китае, арабский — в ОАЭ.

swift
// 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 — для сохранения.

swift
// 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+).

swift
// 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 против Cloud: сравнение режимов

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.60.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-приложениях

Голосовой ввод в кастомной клавиатуре — 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 (кастомные команды).

swift
// 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.

Часто задаваемые вопросы

С какой версии iOS поддерживается SFSpeechRecognizer?

SFSpeechRecognizer доступен с iOS 10, macOS 10.15, watchOS 6 и tvOS 17. On-device режим — с iOS 17 (requiresOnDeviceRecognition). На iOS 10–16 SFSpeechRecognizer работает только через облачные серверы Apple (требуется интернет). На всех версиях требуется явное разрешение пользователя (NSMicrophoneUsageDescription + NSSpeechRecognitionUsageDescription). SFSpeechRecognizer.supportedLocales — динамический список, зависит от региона и модели устройства.

Можно ли использовать SFSpeechRecognizer для непрерывного распознавания?

Да, через создание новых 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-.

Как получить confidence каждого слова в SFSpeechRecognizer?

Используйте 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 без ручного парсинга.

Почему SFSpeechRecognizer возвращает ошибку 203?

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 отличается от Whisper Core ML?

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 транскрибации длинных аудио.

Итоги

  • SFSpeechRecognizer — встроенный ASR API Apple, iOS 10+, 60+ языков
  • On-device режим — iOS 17+, без интернета, WER 12–14% на русском
  • Live микрофон — AVAudioEngine + request.append(buffer) + partial results
  • Аудиофайлы — SFSpeechURLRecognitionRequest, .m4a/.wav, до 1–2 минут
  • Segments — per-word timestamps + confidence (0..1) для каждого слова
  • Бесплатно — без ограничений, без оплаты Apple, без сторонних SDK
  • Применение — голосовой ввод, транскрибация, команды, accessibility, диктовка

Мы разработаем мобильное приложение под ключ

IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.

Обсудить проект

Читайте также