SFSpeechRecognizer — основният API на Apple за разпознаване на реч в екосистемата на iOS. Framework предоставя достъп до 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 — клас от 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 → 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, моно) или Opus (iOS 17+). AVFoundation може да улавя буфер във всякакъв формат, заявката конвертира автоматично. Минимална дължина: 0.5 секунди (откриване на тишина). Максимална: 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 езици дори офлайн. SFSpeechRecognizer.supportedLocales — статичен метод за получаване на списък с поддържаните езици на устройството. Препоръчва се проверка на isAvailable преди всяко стартиране (потребителят може да изключи Siri/Диктовка в настройките). Наличността зависи от региона: китайски — само в Китай, арабски — в ОАЕ.
// 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 осигурява ниска латентност (5–10 ms от микрофон до буфер). SFSpeechRecognitionDelegate: didHypothesizeTranscription (на всеки 200–500 ms — частичен текст), didFinishRecognition (окончателен резултат). Task.isFinishing — може да бъде отменен, когато разпознаването приключи. За непрекъснато разпознаване (безкрайна диктовка) — създайте нов task след isFinal.
SFSpeechRecognitionTaskDelegate: опционални методи. speechRecognitionDidDetectSpeech (начало на реч) — за UI индикация. didHypothesizeTranscription (временен текст) — за показване при говорене. didFinishRecognition (окончателен резултат) — за фиксиране на текст. didFinishSuccessfully (успех/грешка) — за завършване. didProcessAudio (аудио буферът е обработен) — за RMS метър. Препоръчва се имплементиране на didHypothesizeTranscription — потребителят вижда текста веднага, без забавяне. Крайна транскрипция — за запазване.
// Живо разпознаване на реч
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()
Непрекъснато разпознаване: за режим “слушай винаги” (гласов вход, асистент) се изисква рестартиране на задачата след isFinal. Създайте цикъл: finishTask → request = SFSpeechAudioBufferRecognitionRequest() → recognitionTask = recognizer.recognitionTask(with: request). За да избегнете паузи, припокрийте края на една задача с началото на следващата (стартирайте нова заявка 1–2 секунди преди завършването на предишната). AVFoundation AVAudioSession — конфигурация .playAndRecord за едновременно възпроизвеждане и запис. На iOS 17+ непрекъснатото ASR с on-device консумира 2–5% батерия на час (A15+).
SFSpeechURLRecognitionRequest — заявка за разпознаване на аудио файл чрез URL. Поддържа формати: .wav (16 kHz, 16 bit, моно), .m4a (AAC), .mp4, .mov. Максимална дължина: ~1 минута за cloud, ~2 минути за on-device. За по-дълги файлове — разделете на части (AVAssetExportSession + trim). SFSpeechURLRecognitionRequest не поддържа поточно предаване (няма частични резултати) — само окончателен резултат. За частични резултати с файл — конвертирайте в Audio Buffer Request.
Получаване на транскрипция на аудио файл: SFSpeechRecognizer.recognitionTask(with: request) resultHandler. Извлечете bestTranscription.formattedString. За времеви маркери на ниво дума — segments от bestTranscription.segments (segment.duration, segment.timestamp, segment.substring). Confidence на сегмент — увереността на ASR във всяка дума (използвайте за филтриране). Алтернативни варианти — алтернативи на transcriptionFormatter за думи с ниско confidence. За файлове с множество говорещи — SFSpeechRecognitionRequest може да върне множество заявки (по една на говорещ, iOS 17+).
// Транскрипция на аудио файл
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 (потребителят избира сегмент). Съединяване на транскрипции: конкатенация на текстове, съединяване чрез припокриване (последните 2–3 думи от предишната част се сравняват с първите 2–3 думи на следващата — премахнете дубликатите). Vosk и Whisper поддържат дълго аудио естествено, SFSpeechRecognizer — не. За дълга транскрипция препоръчвам Whisper (Core ML) — без ограничение на дължината.
On-device режим (iOS 17+): request.requiresOnDeviceRecognition = true. ASR се изпълнява локално на Apple Neural Engine (ANE). Предимства: без интернет, поверителност (аудиото не напуска устройството), нулева цена (безплатно), ниска латентност (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 или мобилен). Apple не таксува разработчика за cloud ASR (безплатно). Ограничения: 1 заявка на минута на приложение (неуточнено), но за производствен мащаб 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% |
| Латентност (RTF) | 0.3–0.6 | 0.3–0.8 (+мрежа) |
| Макс. дължина | 2 минути | 1 минута |
| Поверителност | Пълна | Аудиото отива на сървър |
| Безплатно | Да | Да |
Combined Recognition (iOS 17+): request.requiresOnDeviceRecognition = false с интернет (cloud), = true при офлайн (fallback). Apple автоматично избира режим. За приложения, критични за точност: проверявайте NetworkMonitor (NWPathMonitor) — с интернет cloud, без него on-device. За приложения, критични за поверителност: винаги on-device. За транскрипция: cloud (по-точен). За гласов вход: on-device (по-бърз). Препоръчителен Combined: 80% cloud, 20% on-device fallback.
Гласов вход в персонализирана клавиатура — SFSpeechRecognizer е вграден в разширенията на клавиатурата (iOS 10+). Потребителят натиска бутона на микрофона — ASR транскрибира речта в текст и го вмъква в текстовото поле. Изисквания: частични резултати (виждане на текст в реално време), 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 с времеви маркери — за синхронизиране на текст с аудио (подсветка на текст при възпроизвеждане). Confidence на сегмент — за показване на ненадеждни фрагменти (жълта подсветка). За диаризация на говорещи (кой е говорил) — Apple не предоставя API, използвайте pyannote-audio + Whisper на сървър.
Гласови команди в iOS приложения — SFSpeechRecognizer + VGS framework (Voice Grammar Services) за изпълнение на команди: “отвори настройки”, “изпрати съобщение”, “включи фенерчето”. Разпознаване, базирано на граматика: SFSpeechRecognitionRequest contextualStrings = масив от команди. Това повишава точността на разпознаване на команди до 95% (срещу 85% free-form). SFSpeechRecognitionTask.cancel — за прекъсване след изпълнение на команда. VGS + SFSpeechRecognizer + Shortcuts — персонализирани гласови команди без писане на интерфейс. За достъпност: Voice Control (вграден) + SFSpeechRecognizer (персонализирани команди).
// Гласови команди с контекстни низове
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 фино настроен върху медицински данни — алтернатива с WER 5% вместо 12% на базовия SFSpeechRecognizer. Съответствие с HIPAA: on-device режим (данните не напускат устройството). За транскрипция на консултации — SFSpeechURLRecognitionRequest + segments с времеви маркери на говорещия.
Често задавани въпроси
SFSpeechRecognizer е достъпен от iOS 10, macOS 10.15, watchOS 6 и tvOS 17. On-device режим — от iOS 17 (requiresOnDeviceRecognition). На iOS 10–16 SFSpeechRecognizer работи само чрез cloud сървърите на Apple (изисква интернет). На всички версии се изисква изрично разрешение от потребителя (NSMicrophoneUsageDescription + NSSpeechRecognitionUsageDescription). SFSpeechRecognizer.supportedLocales — динамичен списък, зависи от региона и модела на устройството.
Да, чрез създаване на нови recognitionTask след isFinal. Рестартирайте задачата след финализиране на предишната за непрекъснато разпознаване. На iOS 17 непрекъснатото on-device ASR консумира 2–5% батерия на час (A15+). На iOS 16- непрекъснатото ASR изисква интернет (консумация на данни ~1 MB/минута). За наистина непрекъснато разпознаване (винаги слуша) използвайте Vosk (офлайн) или Whisper Core ML. SFSpeechRecognizer не поддържа винаги включен режим на iOS 16-.
Използвайте result.bestTranscription.segments — всеки SFTranscriptionSegment съдържа confidence (Float 0..1) за думата. segments[i].substring — текст на думата. segments[i].confidence — увереност на ASR в тази дума. Думи с confidence < 0.5 — ненадеждни, подчертайте ги в интерфейса. segments[i].timestamp — начално време (TimeInterval). segments[i].duration — продължителност. segments[i].alternativeSubstrings — алтернативни варианти за разпознаване на думата. За дълги файлове преминаването през segments дава per-word confidence без ръчно парсване.
203 — SFSpeechError.ErrorCode.opportunistic (няма интернет за cloud ASR). Появява се на iOS 16- или при request.requiresOnDeviceRecognition = false без интернет. Решение: задайте requiresOnDeviceRecognition = true (iOS 17+) за офлайн работа. На iOS 16- използвайте NWPathMonitor — при липса на интернет покажете съобщение “за разпознаване на реч е необходим интернет”. Алтернатива: Vosk (офлайн, iOS 12+) като fallback при липса на мрежа.
SFSpeechRecognizer — вграден Apple API, безплатен, лесен за интеграция, но с ограничение на дължината (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 — за транскрипция на дълго аудио с висока точност.
Резюме
Ще разработим мобилно приложение под ключ
IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също