SFSpeechRecognizer — co to jest, API i integracja w iOS

Autor: IT Sectr Opublikowano: 2026-07-19 Czas czytania: 10 min

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 — główne API ASR Apple dla iOS (iOS 10+)
  • On-device — rozpoznawanie bez internetu od iOS 17, WER 12–14% dla rosyjskiego
  • Streaming — częściowe wyniki w czasie rzeczywistym (partial results)
  • 60+ języków — rosyjski, angielski, chiński, arabski i inne
  • Swift Native — pełna integracja z AVFoundation, Combine, Swift Concurrency

Czym jest SFSpeechRecognizer: przegląd możliwości

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).

KomponentPrzeznaczenieWersja iOS
SFSpeechRecognizerGłówna klasa rozpoznawaniaiOS 10+
SFSpeechAudioBufferRecognitionRequestŻywy strumień audioiOS 10+
SFSpeechURLRecognitionRequestPlik audio (.wav, .m4a)iOS 10+
SFSpeechRecognitionTaskZarządzanie żądaniem (cancel, finish)iOS 10+
On-device recognitionOffline ASRiOS 17+
Combined RecognitionHybryda on-device + cloudiOS 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.

Konfiguracja i uprawnienia SFSpeechRecognizer

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.

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

Strumieniowe rozpoznawanie mowy z mikrofonu

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.

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

Rozpoznawanie plików audio i nagrań

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

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

On-device a Cloud: porównanie trybów

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).

ParametrOn-device (iOS 17+)Cloud (iOS 10+)
Wymaga internetuNieTak
WER (EN)10–12%7%
WER (RU)12–14%12%
Opóźnienie (RTF)0.3–0.60.3–0.8 (+sieć)
Maks. długość2 minuty1 minuta
PrywatnośćPełnaAudio trafia na serwer
BezpłatneTakTak

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.

Zastosowanie SFSpeechRecognizer w aplikacjach iOS

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).

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

Od jakiej wersji iOS obsługiwany jest SFSpeechRecognizer?

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.

Czy można używać SFSpeechRecognizer do ciągłego rozpoznawania?

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

Jak uzyskać confidence każdego słowa w SFSpeechRecognizer?

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.

Dlaczego SFSpeechRecognizer zwraca błąd 203?

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.

Czym SFSpeechRecognizer różni się od Whisper Core ML?

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

  • SFSpeechRecognizer — wbudowane API ASR Apple, iOS 10+, 60+ języków
  • Tryb on-device — iOS 17+, bez internetu, WER 12–14% dla rosyjskiego
  • Live mikrofon — AVAudioEngine + request.append(buffer) + częściowe wyniki
  • Pliki audio — SFSpeechURLRecognitionRequest, .m4a/.wav, do 1–2 minut
  • Segments — znaczniki czasowe per-word + confidence (0..1) dla każdego słowa
  • Bezpłatnie — bez ograniczeń, bez opłat dla Apple, bez zewnętrznych SDK
  • Zastosowanie — wprowadzanie głosowe, transkrypcja, polecenia, dostępność, dyktowanie

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.

Omów projekt

Przeczytaj również