SFSpeechRecognizer — cos’è, API e integrazione iOS

Autore: IT Sectr Pubblicato: 2026-07-19 Tempo di lettura: 10 min

SFSpeechRecognizer è la principale API di riconoscimento vocale di Apple nell’ecosistema iOS. Il framework fornisce l’accesso al motore ASR del dispositivo attraverso Speech.framework, supportando la trascrizione in streaming in tempo reale e il riconoscimento una tantum di file audio. SFSpeechRecognizer è disponibile su iOS 10+, macOS 10.15+, watchOS 6+ e tvOS 17+. Con iOS 17, Apple ha aggiunto una modalità on-device completa che consente il riconoscimento vocale senza connessione Internet. Secondo Apple Speech Documentation, 2025, SFSpeechRecognizer è utilizzato in oltre 200.000 applicazioni App Store e processa milioni di richieste al giorno con un WER del 7% in inglese.

Punti chiave

  • SFSpeechRecognizer — la principale API ASR di Apple per iOS (iOS 10+)
  • On-device — riconoscimento senza Internet da iOS 17, WER 12–14% in russo
  • Streaming — risultati parziali in tempo reale
  • 60+ lingue — russo, inglese, cinese, arabo e altre
  • Swift Native — integrazione completa con AVFoundation, Combine, Swift Concurrency

Cos’è SFSpeechRecognizer: panoramica delle funzionalità

SFSpeechRecognizer è una classe di Speech.framework che rappresenta un riconoscitore vocale per una lingua specifica. Viene inizializzata con un Locale (ru_RU, en_US, zh_CN). SFSpeechRecognizer gestisce una richiesta di riconoscimento (SFSpeechRecognitionRequest) e restituisce un risultato (SFSpeechRecognitionResult) con trascrizioni e metadati. Supporta due tipi di richieste: SFSpeechAudioBufferRecognitionRequest (flusso audio in diretta) e SFSpeechURLRecognitionRequest (file audio). Entrambi restituiscono SFTranscription — un array di ipotesi alternative di riconoscimento.

SFSpeechRecognitionResult contiene: bestTranscription (migliore ipotesi, SFTranscription), transcriptions (tutte le alternative), isFinal (finale/intermedio). SFTranscription contiene: formattedString (testo), segments (array di SFTranscriptionSegment con timestamp, confidenza, substringRange, alternativeSubstrings). La confidenza per ogni segmento (0..1) — consente di filtrare i frammenti inaffidabili. I segments sono una caratteristica chiave di Speech.framework: forniscono un markup parola per parola con punteggi di confidenza.

Architettura di SFSpeechRecognizer: AVFoundation (cattura audio) → Audio Buffer → SFSpeechAudioBufferRecognitionRequest → SFSpeechRecognizer (motore ASR) → SFSpeechRecognitionResult → SFSpeechRecognitionTask (controllo: cancel, finish, pause). Il motore ASR di Apple utilizza un’architettura ibrida: Conformer (encoder) + RNNT (decoder) per on-device, Transducer per il cloud. I modelli sono ottimizzati per Apple Neural Engine (ANE). Su A17 Pro, l’ASR on-device funziona con RTF 0.3–0.6 (più veloce del tempo reale).

ComponenteScopoVersione iOS
SFSpeechRecognizerClasse principale di riconoscimentoiOS 10+
SFSpeechAudioBufferRecognitionRequestFlusso audio in direttaiOS 10+
SFSpeechURLRecognitionRequestFile audio (.wav, .m4a)iOS 10+
SFSpeechRecognitionTaskGestione richieste (cancel, finish)iOS 10+
Riconoscimento on-deviceASR offlineiOS 17+
Riconoscimento combinatoIbrido on-device + cloudiOS 17+

Requisiti audio: SFSpeechRecognizer accetta LPCM (16 kHz, 16 bit, mono) o Opus (iOS 17+). AVFoundation può catturare buffer di qualsiasi formato, la richiesta converte automaticamente. Lunghezza minima: 0.5 secondi (rilevamento silenzio). Massima: 1 minuto (cloud) / 2 minuti (on-device) per richiesta. Per trascrizioni lunghe, suddividere l’audio in chunk da 30–60 secondi con sovrapposizione di 2–5 secondi.

Configurazione e autorizzazioni di SFSpeechRecognizer

Autorizzazioni utente: SFSpeechRecognizer richiede due autorizzazioni esplicite. NSMicrophoneUsageDescription (Privacy — Microphone Usage Description) — per l’accesso al microfono. NSSpeechRecognitionUsageDescription (Privacy — Speech Recognition Usage Description) — per l’accesso al riconoscimento vocale. Entrambe sono stringhe che spiegano il motivo all’utente. SFSpeechRecognizer.requestAuthorization — mostra il dialogo delle autorizzazioni. Stati: notDetermined, denied, restricted, authorized. Senza lo stato authorized, chiamare il recognizer restituisce l’errore 216 (Speech framework error).

Verifica disponibilità: SFSpeechRecognizer.isAvailable — verifica se ASR è disponibile per la lingua corrente. Su iOS 16-, isAvailable = false senza Internet. Su iOS 17+, isAvailable = true per le lingue on-device anche offline. SFSpeechRecognizer.supportedLocales — metodo statico per ottenere l’elenco delle lingue supportate dal dispositivo. Si consiglia di verificare isAvailable prima di ogni avvio (l’utente potrebbe disabilitare Siri/Dettatura nelle impostazioni). La disponibilità dipende dalla regione: cinese — solo in Cina, arabo — negli EAU.

swift
// Configurazione di 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 non disponibile. Abilita Siri e Dettatura nelle Impostazioni")
    return
}

let request = SFSpeechAudioBufferRecognitionRequest()
request.requiresOnDeviceRecognition = true

Gestione degli errori: SFSpeechRecognizer viene chiamato con un completion handler che può restituire un Error. Errori principali: 203 — nessun Internet (cloud, iOS 16-); 216 — non autorizzato (nessun permesso); 301 — errore audio (problema microfono/formato); 401 — servizio non disponibile (servizio sovraccarico); 601 — lingua non disponibile (lingua non supportata sul dispositivo). Per on-device iOS 17+, errori principali: 301 (audio), 601 (lingua). Gestire sempre il completion handler — gli errori possono verificarsi in qualsiasi momento durante la registrazione.

Riconoscimento vocale in diretta dal microfono

Pipeline ASR in diretta: AVAudioEngine (cattura microfono) → installTap (buffer audio) → request.append(buffer) → SFSpeechRecognizer → recognitionTask → delegate/resultHandler. AVAudioEngine offre bassa latenza (5–10 ms dal microfono al buffer). SFSpeechRecognitionDelegate: didHypothesizeTranscription (ogni 200–500 ms — testo parziale), didFinishRecognition (risultato finale). Task.isFinishing — può annullare quando il riconoscimento è completo. Per il riconoscimento continuo (dettatura infinita), creare una nuova attività dopo isFinal.

SFSpeechRecognitionTaskDelegate: metodi opzionali. speechRecognitionDidDetectSpeech (inizio discorso) — per indicazione nell’interfaccia utente. didHypothesizeTranscription (testo intermedio) — per visualizzazione mentre si parla. didFinishRecognition (risultato finale) — per finalizzare il testo. didFinishSuccessfully (successo/errore) — per completamento. didProcessAudio (buffer audio elaborato) — per misuratore RMS. Si consiglia di implementare didHypothesizeTranscription — l’utente vede il testo immediatamente senza ritardo. La trascrizione finale è per il salvataggio.

swift
// Riconoscimento vocale in diretta
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()

Riconoscimento continuo: per la modalità “ascolta sempre” (input vocale, assistente), è necessario riavviare l’attività dopo isFinal. Creare un ciclo: finishTask → request = SFSpeechAudioBufferRecognitionRequest() → recognitionTask = recognizer.recognitionTask(with: request). Per evitare pause, sovrapporre la fine di un’attività con l’inizio della successiva (avviare una nuova richiesta 1–2 secondi prima della fine della precedente). AVFoundation AVAudioSession — configurare .playAndRecord per riproduzione e registrazione simultanee. Su iOS 17+, l’ASR continuo con on-device consuma 2–5% di batteria all’ora (A15+).

Riconoscimento di file audio e registrazioni

SFSpeechURLRecognitionRequest — una richiesta per riconoscere un file audio tramite URL. Supporta i formati: .wav (16 kHz, 16 bit, mono), .m4a (AAC), .mp4, .mov. Lunghezza massima: ~1 minuto per il cloud, ~2 minuti per on-device. Per file più lunghi, suddividere in chunk (AVAssetExportSession + trim). SFSpeechURLRecognitionRequest non supporta lo streaming (nessun risultato parziale) — solo il risultato finale. Per risultati parziali con un file, convertire in una richiesta di buffer audio.

Ottenere la trascrizione di un file audio: SFSpeechRecognizer.recognitionTask(with: request) resultHandler. Estrarre bestTranscription.formattedString. Per timestamp a livello di parola — segments da bestTranscription.segments (segment.duration, segment.timestamp, segment.substring). Confidenza per segmento — confidenza ASR per ogni parola (usare per filtrare). Ipotesi alternative — alternative di transcriptionFormatter per parole con bassa confidenza. Per file con più parlanti, SFSpeechRecognitionRequest può restituire più richieste (una per parlante, iOS 17+).

swift
// Trascrizione file 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("Errore: \(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)
    }
}

Suddivisione di file audio lunghi: per file > 1 minuto, suddividere in chunk da 30–60 secondi con sovrapposizione di 2–3 secondi (cucitura). AVAssetExportSession + CMTimeRange — esportare chunk. Alternativa: UISelectionView (l’utente seleziona un segmento). Cucitura delle trascrizioni: concatenare testi, cucire per sovrapposizione (le ultime 2–3 parole del chunk precedente vengono confrontate con le prime 2–3 del successivo — rimuovere duplicati). Vosk e Whisper supportano l’audio lungo nativamente, SFSpeechRecognizer no. Per trascrizioni lunghe, consiglio Whisper (Core ML) — nessun limite di lunghezza.

On-device vs Cloud: confronto delle modalità

Modalità On-device (iOS 17+): request.requiresOnDeviceRecognition = true. L’ASR viene eseguito localmente su Apple Neural Engine (ANE). Vantaggi: nessun Internet necessario, privacy (l’audio non lascia mai il dispositivo), costo zero (gratuito), bassa latenza (RTF 0.3–0.6). Svantaggi: precisione inferiore (WER 12–14% vs 7–12%), limite di 2 minuti per richiesta, set linguistico limitato (non tutte le 60 lingue sono disponibili on-device). Il modello on-device occupa ~50–100 MB sul dispositivo e viene scaricato alla prima richiesta.

Cloud (iOS 16-): request.requiresOnDeviceRecognition = false (o parametro assente). ASR sui server Apple — più preciso (WER 7% EN, 12% RU), più lingue, fino a 1 minuto per richiesta. Richiede Internet (WiFi o cellulare). Apple non addebita costi agli sviluppatori per l’ASR cloud (gratuito). Limiti: 1 richiesta al minuto per applicazione (non specificato), ma Apple potrebbe limitare a scala di produzione. L’ASR cloud fornisce qualità best-effort senza SLA. Per applicazioni aziendali, utilizzare Google Cloud ASR o Whisper (Core ML).

ParametroOn-device (iOS 17+)Cloud (iOS 10+)
Richiede InternetNo
WER (EN)10–12%7%
WER (RU)12–14%12%
Latenza (RTF)0.3–0.60.3–0.8 (+rete)
Lunghezza max2 minuti1 minuto
PrivacyCompletaL’audio lascia il dispositivo
Gratuito

Riconoscimento combinato (iOS 17+): request.requiresOnDeviceRecognition = false con Internet (cloud), = true in offline (fallback). Apple seleziona automaticamente la modalità. Per app critiche per la precisione: verificare NetworkMonitor (NWPathMonitor) — utilizzare cloud con Internet, on-device senza. Per app critiche per la privacy: sempre on-device. Per trascrizione: cloud (più preciso). Per input vocale: on-device (più veloce). Si consiglia Combinato: 80% cloud, 20% fallback on-device.

Utilizzo di SFSpeechRecognizer nelle app iOS

Input vocale in tastiera personalizzata — SFSpeechRecognizer integrato nelle estensioni tastiera (iOS 10+). L’utente preme il pulsante microfono, ASR trascrive la voce in testo e lo inserisce nel campo di testo. Requisiti: risultati parziali (vedere il testo in tempo reale), on-device (la tastiera deve funzionare senza Internet). SFSpeechRecognizer + AVSpeechSynthesizer — input vocale + output vocale. Per tastiere personalizzate su iOS 17+, utilizzare on-device. Limitazioni dell’estensione tastiera: AVAudioEngine è disponibile ma con restrizioni di tempo (esecuzione in background limitata).

Trascrizione di riunioni e lezioni — app per registrare e trascrivere audio (Otter.ai, Rev, Apple Voice Memos). SFSpeechURLRecognitionRequest elabora file .m4a. Per registrazioni lunghe (30–60 minuti) — Whisper Core ML (nessun limite di lunghezza). I segments di SFSpeechRecognizer con timestamp — per sincronizzare il testo con l’audio (evidenziazione del testo durante la riproduzione). Confidenza per segmento — per visualizzare frammenti inaffidabili (evidenziazione gialla). Per la diarizzazione dei parlanti (chi ha parlato) — Apple non fornisce API, utilizzare pyannote-audio + Whisper sul server.

Comandi vocali nelle app iOS — SFSpeechRecognizer + framework VGS (Voice Grammar Services) per eseguire comandi: “apri impostazioni”, “invia messaggio”, “accendi la luce”. Riconoscimento basato su grammatica: SFSpeechRecognitionRequest contextualStrings = array di comandi. Ciò migliora la precisione del riconoscimento dei comandi al 95% (vs 85% in forma libera). SFSpeechRecognitionTask.cancel — per interrompere dopo l’esecuzione del comando. VGS + SFSpeechRecognizer + Shortcuts — comandi vocali personalizzati senza scrivere interfaccia utente. Per accessibilità: Voice Control (integrato) + SFSpeechRecognizer (comandi personalizzati).

swift
// Comandi vocali con stringhe contestuali
let request = SFSpeechAudioBufferRecognitionRequest()
request.requiresOnDeviceRecognition = true
request.shouldReportPartialResults = true
request.contextualStrings = ["open contacts", "send message",
                             "show notifications", "accendi la torcia"]

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()
    }
}

Dettatura in app mediche e legali — SFSpeechRecognizer per creare documenti strutturati tramite voce. Adattamento di dominio: contextualStrings con termini medici/legali (500+ frasi). SFSpeechRecognitionRequest.customLmProbability — impatto di contextualStrings (0.1–1.0). Per la dettatura medica, utilizzare on-device (privacy dei dati del paziente). Whisper ottimizzato su dati medici — alternativa con WER 5% invece del 12% di SFSpeechRecognizer base. Conformità HIPAA: modalità on-device (i dati non lasciano mai il dispositivo). Per trascrizione appuntamenti — SFSpeechURLRecognitionRequest + segments con timestamp del parlante.

Domande frequenti

Da quale versione di iOS SFSpeechRecognizer è supportato?

SFSpeechRecognizer è disponibile da iOS 10, macOS 10.15, watchOS 6 e tvOS 17. La modalità on-device da iOS 17 (requiresOnDeviceRecognition). Su iOS 10–16, SFSpeechRecognizer funziona solo attraverso i server cloud di Apple (richiede Internet). Tutte le versioni richiedono l’autorizzazione esplicita dell’utente (NSMicrophoneUsageDescription + NSSpeechRecognitionUsageDescription). SFSpeechRecognizer.supportedLocales — elenco dinamico, dipende dalla regione e dal modello del dispositivo.

Si può usare SFSpeechRecognizer per il riconoscimento continuo?

Sì, creando nuovi recognitionTask dopo isFinal. Riavviare l’attività dopo il completamento della precedente per il riconoscimento continuo. Su iOS 17, l’ASR continuo on-device consuma 2–5% di batteria all’ora (A15+). Su iOS 16-, l’ASR continuo richiede Internet (traffico ~1 MB/minuto). Per il riconoscimento veramente continuo (sempre in ascolto), utilizzare Vosk (offline) o Whisper Core ML. SFSpeechRecognizer non supporta la modalità sempre accesa su iOS 16-.

Come ottenere la confidenza di ogni parola in SFSpeechRecognizer?

Utilizzare result.bestTranscription.segments — ogni SFTranscriptionSegment contiene confidence (Float 0..1) per la parola. segments[i].substring — testo della parola. segments[i].confidence — confidenza ASR per quella parola. Le parole con confidence < 0.5 sono inaffidabili — evidenziarle nell’interfaccia utente. segments[i].timestamp — tempo di inizio (TimeInterval). segments[i].duration — durata. segments[i].alternativeSubstrings — ipotesi alternative di riconoscimento per la parola. Per file lunghi, l’iterazione su segments fornisce confidenza per parola senza analisi manuale.

Perché SFSpeechRecognizer restituisce l’errore 203?

203 è SFSpeechError.ErrorCode.opportunistic (nessun Internet per ASR cloud). Si verifica su iOS 16- o quando request.requiresOnDeviceRecognition = false senza Internet. Soluzione: impostare requiresOnDeviceRecognition = true (iOS 17+) per il funzionamento offline. Su iOS 16-, utilizzare NWPathMonitor — quando non c’è Internet, visualizzare un messaggio che dice “il riconoscimento vocale richiede una connessione Internet”. Alternativa: Vosk (offline, iOS 12+) come fallback quando non è disponibile alcuna rete.

In che cosa SFSpeechRecognizer differisce da Whisper Core ML?

SFSpeechRecognizer — API integrata di Apple, gratuita, facile da integrare, ma con limiti di lunghezza (1–2 minuti), precisione WER 7–14% e solo per l’ecosistema iOS. Whisper Core ML — open-source (MIT), supporta 99 lingue, WER 6–10%, nessun limite di lunghezza, ma richiede integrazione manuale, modelli Core ML (39M–769M parametri), RTF 0.5–6 (più lento di SFSpeechRecognizer). SFSpeechRecognizer — per input vocale standard. Whisper — per trascrizione di alta precisione di audio lungo.

Riepilogo

  • SFSpeechRecognizer — API ASR integrata di Apple, iOS 10+, 60+ lingue
  • Modalità on-device — iOS 17+, senza Internet, WER 12–14% in russo
  • Microfono in diretta — AVAudioEngine + request.append(buffer) + risultati parziali
  • File audio — SFSpeechURLRecognitionRequest, .m4a/.wav, fino a 1–2 minuti
  • Segments — timestamp per parola + confidenza (0..1) per ogni parola
  • Gratuito — senza limiti, senza costi Apple, senza SDK di terze parti
  • Utilizzo — input vocale, trascrizione, comandi, accessibilità, dettatura

Svilupperemo un'applicazione mobile chiavi in mano

IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.

Discuti il progetto

Leggi anche