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, SFSpeechRecognizer використовується в більш ніж 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 з часовими мітками, впевненістю, substringRange, alternativeSubstrings). Впевненість для кожного сегмента (0..1) — дозволяє фільтрувати ненадійні фрагменти. Segments — ключова фіча Speech.framework: дає покадрову розмітку кожного слова з впевненістю.

Архітектура SFSpeechRecognizer: AVFoundation (захоплення аудіо) → Audio 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 може захоплювати буфер будь-якого формату, запит конвертує автоматично. Мінімальна довжина: 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
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 недоступний. Увімкніть Siri та Диктування в Налаштуваннях")
    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 від мікрофона до буфера). SFSpeechRecognitionDelegate: didHypothesizeTranscription (кожні 200–500 ms — частковий текст), didFinishRecognition (фінальний результат). Task.isFinishing — можна скасовувати, коли розпізнавання завершено. Для continuous recognition (нескінченна диктовка) — створюйте новий task після isFinal.

SFSpeechRecognitionTaskDelegate: необов’язкові методи. speechRecognitionDidDetectSpeech (початок мовлення) — для UI-індикації. didHypothesizeTranscription (проміжний текст) — для відображення в міру вимовляння. didFinishRecognition (фінальний результат) — для фіксації тексту. didFinishSuccessfully (успіх/помилка) — для завершення. didProcessAudio (аудіобуфер оброблено) — для метра RMS. Рекомендується реалізувати didHypothesizeTranscription — користувач бачить текст відразу, без затримки. Final transcription — для збереження.

swift
// Потокове розпізнавання мовлення
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
// Транскрибація аудіофайлу
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?.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 (+мережа)
Макс. довжина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 + SFSpeechRecognizer + Shortcuts — кастомні голосові команди без написання UI. Для accessibility: Voice Control (вбудований) + SFSpeechRecognizer (кастомні команди).

swift
// Голосові команди з контекстними рядками
let request = SFSpeechAudioBufferRecognitionRequest()
request.requiresOnDeviceRecognition = true
request.shouldReportPartialResults = true
request.contextualStrings = ["open contacts", "send message",
                             "show notifications", "увімкнути ліхтарик"]

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-device 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 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.

Обговорити проект

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