SFSpeechRecognizer — główne API Apple do rozpoznawania mowy w ekosystemie iOS. Framework zapewnia dostęp do silnika ASR urządzenia przez Speech.framework, obsługując strumieniową transkrypcję w czasie rzeczywistym i jednorazowe rozpoznawanie plików audio. SFSpeechRecognizer jest dostępny na iOS 10+, macOS 10.15+, watchOS 6+ i tvOS 17+. Od iOS 17 Apple dodało w pełni funkcjonalny tryb on-device, umożliwiający rozpoznawanie mowy bez połączenia z internetem. Według danych Apple Speech Documentation, 2025, SFSpeechRecognizer jest używany w ponad 200 000 aplikacji w App Store i przetwarza miliony zapytań dziennie z WER 7% dla języka angielskiego.
Najważniejsze
SFSpeechRecognizer — klasa z Speech.framework, reprezentująca rozpoznawacz mowy dla konkretnego języka. Inicjalizuje się z Locale (ru_RU, en_US, zh_CN). SFSpeechRecognizer zarządza żądaniem rozpoznawania (SFSpeechRecognitionRequest) i zwraca wynik (SFSpeechRecognitionResult) z transkrypcjami i metadanymi. Obsługuje dwa typy żądań: SFSpeechAudioBufferRecognitionRequest (żywy strumień audio) i SFSpeechURLRecognitionRequest (plik audio). Oba zwracają SFTranscription — tablicę alternatywnych wariantów rozpoznawania.
SFSpeechRecognitionResult zawiera: bestTranscription (najlepszy wariant, SFTranscription), transcriptions (wszystkie alternatywy), isFinal (końcowy/częściowy). SFTranscription zawiera: formattedString (tekst), segments (tablica SFTranscriptionSegment z znacznikami czasowymi, confidence, substringRange, alternativeSubstrings). Confidence dla każdego segmentu (0..1) — pozwala filtrować zawodne fragmenty. segments — kluczowa funkcja Speech.framework: zapewnia adnotację każdego słowa z pewnością.
Architektura SFSpeechRecognizer: AVFoundation (przechwytywanie audio) → Audio Buffer → SFSpeechAudioBufferRecognitionRequest → SFSpeechRecognizer (silnik ASR) → SFSpeechRecognitionResult → SFSpeechRecognitionTask (kontrola: cancel, finish, pause). Silnik ASR Apple używa hybrydowej architektury: Conformer (enkoder) + RNNT (dekoder) dla on-device, Transducer dla chmury. Modele są zoptymalizowane pod Apple Neural Engine (ANE). Na A17 Pro on-device ASR działa z RTF 0.3–0.6 (szybciej niż w czasie rzeczywistym).
| Komponent | Przeznaczenie | Wersja iOS |
|---|---|---|
| SFSpeechRecognizer | Główna klasa rozpoznawania | iOS 10+ |
| SFSpeechAudioBufferRecognitionRequest | Żywy strumień audio | iOS 10+ |
| SFSpeechURLRecognitionRequest | Plik audio (.wav, .m4a) | iOS 10+ |
| SFSpeechRecognitionTask | Zarządzanie żądaniem (cancel, finish) | iOS 10+ |
| On-device recognition | Offline ASR | iOS 17+ |
| Combined Recognition | Hybryda on-device + cloud | iOS 17+ |
Wymagania audio: SFSpeechRecognizer przyjmuje LPCM (16 kHz, 16 bit, mono) lub Opus (iOS 17+). AVFoundation może przechwytywać bufor w dowolnym formacie, żądanie konwertuje automatycznie. Minimalna długość: 0.5 sekundy (wykrywanie ciszy). Maksymalna: 1 minuta (cloud) / 2 minuty (on-device) na jedno żądanie. Do długiej transkrypcji dziel audio na fragmenty po 30–60 sekund z nakładaniem 2–5 sekund.
Uprawnienia użytkownika: SFSpeechRecognizer wymaga dwóch wyraźnych uprawnień. NSMicrophoneUsageDescription (Privacy — Microphone Usage Description) — do dostępu do mikrofonu. NSSpeechRecognitionUsageDescription (Privacy — Speech Recognition Usage Description) — do dostępu do rozpoznawania mowy. Oba to ciągi wyjaśniające użytkownikowi dlaczego. SFSpeechRecognizer.requestAuthorization — wywołanie okna dialogowego uprawnień. Statusy: notDetermined, denied, restricted, authorized. Bez authorized wywołanie recognizer zwraca błąd 216 (Speech framework error).
Sprawdzanie dostępności: SFSpeechRecognizer.isAvailable — sprawdza, czy ASR jest dostępny dla bieżącego języka. Na iOS 16- isAvailable = false bez internetu. Na iOS 17+ isAvailable = true dla języków on-device nawet offline. SFSpeechRecognizer.supportedLocales — statyczna metoda do uzyskania listy obsługiwanych języków urządzenia. Zaleca się sprawdzanie isAvailable przed każdym uruchomieniem (użytkownik może wyłączyć Siri/Dyktowanie w ustawieniach). Dostępność zależy od regionu: chiński — tylko w Chinach, arabski — w ZEA.
// Konfiguracja 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 niedostępne. Włącz Siri i dyktowanie w Ustawieniach")
return
}
let request = SFSpeechAudioBufferRecognitionRequest()
request.requiresOnDeviceRecognition = true
Obsługa błędów: SFSpeechRecognizer wywoływany jest z completion handler, który może zwrócić Error. Główne błędy: 203 — no internet (cloud, iOS 16-); 216 — not authorized (brak uprawnień); 301 — audio error (problem z mikrofonem/formatem); 401 — service unavailable (usługa przeciążona); 601 — language unavailable (język nie jest obsługiwany na urządzeniu). Dla on-device iOS 17+ główne błędy: 301 (audio), 601 (language). Zawsze obsługuj completion handler — błędy mogą wystąpić w dowolnym momencie nagrywania.
Live ASR pipeline: AVAudioEngine (przechwytywanie z mikrofonu) → installTap (bufor audio) → request.append(buffer) → SFSpeechRecognizer → recognitionTask → delegate/resultHandler. AVAudioEngine zapewnia niskie opóźnienie (5–10 ms od mikrofonu do bufora). SFSpeechRecognitionDelegate: didHypothesizeTranscription (co 200–500 ms — częściowy tekst), didFinishRecognition (wynik końcowy). Task.isFinishing — można anulować, gdy rozpoznawanie jest zakończone. Do ciągłego rozpoznawania (niekończąca się dyktanda) — utwórz nowy task po isFinal.
SFSpeechRecognitionTaskDelegate: opcjonalne metody. speechRecognitionDidDetectSpeech (początek mowy) — do wskazania w interfejsie. didHypothesizeTranscription (tekst częściowy) — do wyświetlania w miarę wypowiadania. didFinishRecognition (wynik końcowy) — do zatwierdzenia tekstu. didFinishSuccessfully (sukces/błąd) — do zakończenia. didProcessAudio (bufor audio przetworzony) — do miernika RMS. Zaleca się implementację didHypothesizeTranscription — użytkownik widzi tekst natychmiast, bez opóźnienia. Końcowa transkrypcja — do zapisania.
// Rozpoznawanie mowy na żywo
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()
Ciągłe rozpoznawanie: w trybie „słuchaj zawsze” (wprowadzanie głosowe, asystent) wymagane jest ponowne uruchomienie zadania po isFinal. Utwórz pętlę: finishTask → request = SFSpeechAudioBufferRecognitionRequest() → recognitionTask = recognizer.recognitionTask(with: request). Aby uniknąć pauz, nakładaj koniec jednego zadania z początkiem następnego (uruchom nowe żądanie 1–2 sekundy przed zakończeniem poprzedniego). AVFoundation AVAudioSession — konfiguracja .playAndRecord do jednoczesnego odtwarzania i nagrywania. Na iOS 17+ ciągłe ASR z on-device zużywa 2–5% baterii na godzinę (A15+).
SFSpeechURLRecognitionRequest — żądanie do rozpoznawania pliku audio po URL. Obsługuje formaty: .wav (16 kHz, 16 bit, mono), .m4a (AAC), .mp4, .mov. Maksymalna długość: ~1 minuta dla chmury, ~2 minuty dla on-device. W przypadku dłuższych plików — dziel na fragmenty (AVAssetExportSession + trim). SFSpeechURLRecognitionRequest nie obsługuje strumieniowania (brak częściowych wyników) — tylko wynik końcowy. Dla częściowych wyników z plikiem — konwertuj na Audio Buffer Request.
Uzyskiwanie transkrypcji pliku audio: SFSpeechRecognizer.recognitionTask(with: request) resultHandler. Wyodrębnij bestTranscription.formattedString. Dla znaczników czasowych na poziomie słów — segments z bestTranscription.segments (segment.duration, segment.timestamp, segment.substring). Confidence na segment — pewność ASR w każdym słowie (użyj do filtrowania). Alternatywne warianty — alternatywy transcriptionFormatter dla słów z niskim confidence. Dla plików z wieloma mówcami — SFSpeechRecognitionRequest może zwracać wiele żądań (po jednym na mówcę, iOS 17+).
// Transkrypcja plików audio
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("Błąd: \(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)
}
}
Dzielenie długich plików audio: dla plików > 1 minuty tnij na fragmenty po 30–60 sekund z nakładaniem 2–3 sekund (łączenie). AVAssetExportSession + CMTimeRange — eksport fragmentów. Alternatywa: UISelectionView (użytkownik wybiera segment). Łączenie transkrypcji: konkatenacja tekstów, łączenie po nakładaniu (ostatnie 2–3 słowa poprzedniego fragmentu porównywane z pierwszymi 2–3 słowami następnego — usuń duplikaty). Vosk i Whisper obsługują długie audio natywnie, SFSpeechRecognizer — nie. Do długiej transkrypcji polecam Whisper (Core ML) — bez ograniczenia długości.
Tryb on-device (iOS 17+): request.requiresOnDeviceRecognition = true. ASR wykonuje się lokalnie na Apple Neural Engine (ANE). Zalety: bez internetu, prywatność (audio nie opuszcza urządzenia), zerowy koszt (bezpłatny), niskie opóźnienie (RTF 0.3–0.6). Wady: niższa dokładność (WER 12–14% vs 7–12%), ograniczenie 2 minuty na żądanie, ograniczony zestaw języków (nie wszystkie 60 dostępne on-device). Model on-device zajmuje ~50–100 MB na urządzeniu, ładowany przy pierwszym żądaniu.
Cloud (iOS 16-): request.requiresOnDeviceRecognition = false (lub brak parametru). ASR na serwerach Apple — dokładniejszy (WER 7% EN, 12% RU), więcej języków, do 1 minuty na żądanie. Wymaga internetu (WiFi lub komórkowy). Apple nie pobiera opłat od programisty za cloud ASR (bezpłatnie). Limity: 1 żądanie na minutę na aplikację (nieokreślone), ale dla skali produkcyjnej Apple może ograniczać. cloud ASR — jakość best-effort, bez SLA. Dla aplikacji korporacyjnych używaj Google Cloud ASR lub Whisper (Core ML).
| Parametr | On-device (iOS 17+) | Cloud (iOS 10+) |
|---|---|---|
| Wymaga internetu | Nie | Tak |
| WER (EN) | 10–12% | 7% |
| WER (RU) | 12–14% | 12% |
| Opóźnienie (RTF) | 0.3–0.6 | 0.3–0.8 (+sieć) |
| Maks. długość | 2 minuty | 1 minuta |
| Prywatność | Pełna | Audio trafia na serwer |
| Bezpłatne | Tak | Tak |
Combined Recognition (iOS 17+): request.requiresOnDeviceRecognition = false przy internecie (cloud), = true przy offline (fallback). Apple automatycznie wybiera tryb. Dla aplikacji krytycznych pod względem dokładności: sprawdzaj NetworkMonitor (NWPathMonitor) — przy internecie cloud, przy jego braku on-device. Dla aplikacji krytycznych pod względem prywatności: zawsze on-device. Do transkrypcji: cloud (dokładniejszy). Do wprowadzania głosowego: on-device (szybszy). Zalecany Combined: 80% cloud, 20% on-device fallback.
Wprowadzanie głosowe w niestandardowej klawiaturze — SFSpeechRecognizer jest wbudowany w rozszerzenia klawiatury (iOS 10+). Użytkownik naciska przycisk mikrofonu — ASR transkrybuje mowę na tekst i wstawia go do pola tekstowego. Wymagania: częściowe wyniki (widzieć tekst w czasie rzeczywistym), on-device (klawiatura musi działać bez internetu). SFSpeechRecognizer + AVSpeechSynthesizer — wprowadzanie głosowe + wyjście głosowe. Dla niestandardowej klawiatury na iOS 17+ używaj on-device. Ograniczenia rozszerzenia klawiatury: AVAudioEngine jest dostępny, ale z ograniczeniami czasowymi (background execution limited).
Transkrypcja spotkań i wykładów — aplikacje do nagrywania i transkrypcji audio (Otter.ai, Rev, Apple Voice Memos). SFSpeechURLRecognitionRequest przetwarza plik .m4a. Dla długich nagrań (30–60 minut) — Whisper Core ML (bez ograniczenia długości). Segmenty SFSpeechRecognizer z znacznikami czasowymi — do synchronizacji tekstu z audio (podświetlanie tekstu podczas odtwarzania). Confidence na segment — do wyświetlania zawodnych fragmentów (podświetlenie na żółto). Do diarizacji mówców (kto mówił) — Apple nie udostępnia API, używaj pyannote-audio + Whisper na serwerze.
Polecenia głosowe w aplikacjach iOS — SFSpeechRecognizer + VGS framework (Voice Grammar Services) do wykonywania poleceń: „otwórz ustawienia”, „wyślij wiadomość”, „włącz światło”. Rozpoznawanie oparte na gramatyce: SFSpeechRecognitionRequest contextualStrings = tablica poleceń. Zwiększa to dokładność rozpoznawania poleceń do 95% (vs 85% free-form). SFSpeechRecognitionTask.cancel — do przerywania po wykonaniu polecenia. VGS + SFSpeechRecognizer + Shortcuts — niestandardowe polecenia głosowe bez pisania interfejsu. Dla dostępności: Voice Control (wbudowany) + SFSpeechRecognizer (niestandardowe polecenia).
// Polecenia głosowe z kontekstowymi ciągami
let request = SFSpeechAudioBufferRecognitionRequest()
request.requiresOnDeviceRecognition = true
request.shouldReportPartialResults = true
request.contextualStrings = ["open contacts", "send message",
"show notifications", "włącz latarkę"]
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()
}
}
Dyktowanie w aplikacjach medycznych i prawniczych — SFSpeechRecognizer do tworzenia strukturalnych dokumentów głosem. Domain Adaptation: contextualStrings z terminami medycznymi/prawniczymi (500+ fraz). SFSpeechRecognitionRequest.customLmProbability — wpływ contextualStrings (0.1–1.0). Do medycznego dyktowania używaj on-device (prywatność danych pacjenta). Whisper fine-tuned na danych medycznych — alternatywa z WER 5% zamiast 12% bazowego SFSpeechRecognizer. HIPAA compliance: tryb on-device (dane nie opuszczają urządzenia). Do transkrypcji wizyt — SFSpeechURLRecognitionRequest + segments z znacznikami czasowymi mówcy.
Często zadawane pytania
SFSpeechRecognizer jest dostępny od iOS 10, macOS 10.15, watchOS 6 i tvOS 17. Tryb on-device — od iOS 17 (requiresOnDeviceRecognition). Na iOS 10–16 SFSpeechRecognizer działa tylko przez chmurowe serwery Apple (wymaga internetu). We wszystkich wersjach wymagana jest wyraźna zgoda użytkownika (NSMicrophoneUsageDescription + NSSpeechRecognitionUsageDescription). SFSpeechRecognizer.supportedLocales — dynamiczna lista, zależy od regionu i modelu urządzenia.
Tak, poprzez tworzenie nowych recognitionTask po isFinal. Ponownie uruchamiaj zadanie po finalizacji poprzedniego dla ciągłego rozpoznawania. Na iOS 17 ciągłe ASR on-device zużywa 2–5% baterii na godzinę (A15+). Na iOS 16- ciągłe ASR wymaga internetu (zużycie danych ~1 MB/minutę). Do rzeczywiście ciągłego rozpoznawania (zawsze słucha) używaj Vosk (offline) lub Whisper Core ML. SFSpeechRecognizer nie obsługuje trybu zawsze włączonego na iOS 16-.
Użyj result.bestTranscription.segments — każdy SFTranscriptionSegment zawiera confidence (Float 0..1) dla słowa. segments[i].substring — tekst słowa. segments[i].confidence — pewność ASR w tym słowie. Słowa z confidence < 0.5 — zawodne, podświetlaj je w interfejsie. segments[i].timestamp — czas rozpoczęcia (TimeInterval). segments[i].duration — czas trwania. segments[i].alternativeSubstrings — alternatywne warianty rozpoznawania słowa. Dla długich plików przejście po segments daje per-word confidence bez ręcznego parsowania.
203 — to SFSpeechError.ErrorCode.opportunistic (brak internetu dla cloud ASR). Występuje na iOS 16- lub przy request.requiresOnDeviceRecognition = false bez internetu. Rozwiązanie: ustaw requiresOnDeviceRecognition = true (iOS 17+) do pracy offline. Na iOS 16- używaj NWPathMonitor — przy braku internetu wyświetlaj komunikat „do rozpoznawania mowy wymagany jest internet”. Alternatywa: Vosk (offline, iOS 12+) jako fallback przy braku sieci.
SFSpeechRecognizer — wbudowane API Apple, bezpłatne, proste w integracji, ale z ograniczeniem długości (1–2 minuty), dokładnością WER 7–14% i tylko dla ekosystemu iOS. Whisper Core ML — open-source (MIT), obsługuje 99 języków, WER 6–10%, bez ograniczenia długości, ale wymaga ręcznej integracji, modele Core ML (39M–769M parametrów), RTF 0.5–6 (wolniejszy niż SFSpeechRecognizer). SFSpeechRecognizer — do standardowego wprowadzania głosowego. Whisper — do transkrypcji długiego audio z wysoką dokładnością.
Podsumowanie
Opracujemy aplikację mobilną pod klucz
IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.
Przeczytaj również