SFSpeechRecognizer — qué es, API e integración en iOS

Autor: IT Sectr Publicado: 2026-07-19 Tiempo de lectura: 10 min

SFSpeechRecognizer es la API principal de Apple para reconocimiento de voz en el ecosistema iOS. El framework proporciona acceso al motor ASR del dispositivo a través de Speech.framework, soportando transcripción por streaming en tiempo real y reconocimiento único de archivos de audio. SFSpeechRecognizer está disponible en iOS 10+, macOS 10.15+, watchOS 6+ y tvOS 17+. Con iOS 17, Apple añadió un modo on-device completo que permite el reconocimiento de voz sin conexión a internet. Según Apple Speech Documentation, 2025, SFSpeechRecognizer se utiliza en más de 200 000 aplicaciones de App Store y procesa millones de solicitudes al día con un WER del 7% en inglés.

Puntos clave

  • SFSpeechRecognizer — la API ASR principal de Apple para iOS (iOS 10+)
  • On-device — reconocimiento sin internet desde iOS 17, WER 12–14% en ruso
  • Streaming — resultados parciales en tiempo real
  • 60+ idiomas — ruso, inglés, chino, árabe y más
  • Swift Native — integración completa con AVFoundation, Combine, Swift Concurrency

Qué es SFSpeechRecognizer: descripción general

SFSpeechRecognizer es una clase de Speech.framework que representa un reconocedor de voz para un idioma específico. Se inicializa con un Locale (ru_RU, en_US, zh_CN). SFSpeechRecognizer gestiona una solicitud de reconocimiento (SFSpeechRecognitionRequest) y devuelve un resultado (SFSpeechRecognitionResult) con transcripciones y metadatos. Soporta dos tipos de solicitudes: SFSpeechAudioBufferRecognitionRequest (flujo de audio en vivo) y SFSpeechURLRecognitionRequest (archivo de audio). Ambos devuelven SFTranscription — un array de hipótesis alternativas de reconocimiento.

SFSpeechRecognitionResult contiene: bestTranscription (mejor hipótesis, SFTranscription), transcriptions (todas las alternativas), isFinal (final/intermedio). SFTranscription contiene: formattedString (texto), segments (array de SFTranscriptionSegment con marcas de tiempo, confianza, substringRange, alternativeSubstrings). La confianza para cada segmento (0..1) — permite filtrar fragmentos no fiables. Los segments son una característica clave de Speech.framework: proporcionan un marcado palabra por palabra con puntuaciones de confianza.

Arquitectura de SFSpeechRecognizer: AVFoundation (captura de audio) → Audio Buffer → SFSpeechAudioBufferRecognitionRequest → SFSpeechRecognizer (motor ASR) → SFSpeechRecognitionResult → SFSpeechRecognitionTask (control: cancel, finish, pause). El motor ASR de Apple utiliza una arquitectura híbrida: Conformer (encoder) + RNNT (decoder) para on-device, Transducer para cloud. Los modelos están optimizados para Apple Neural Engine (ANE). En A17 Pro, el ASR on-device funciona con RTF 0.3–0.6 (más rápido que el tiempo real).

ComponentePropósitoVersión iOS
SFSpeechRecognizerClase principal de reconocimientoiOS 10+
SFSpeechAudioBufferRecognitionRequestFlujo de audio en vivoiOS 10+
SFSpeechURLRecognitionRequestArchivo de audio (.wav, .m4a)iOS 10+
SFSpeechRecognitionTaskGestión de solicitud (cancel, finish)iOS 10+
On-device recognitionASR sin conexióniOS 17+
Combined RecognitionHíbrido on-device + cloudiOS 17+

Requisitos de audio: SFSpeechRecognizer acepta LPCM (16 kHz, 16 bit, mono) u Opus (iOS 17+). AVFoundation puede capturar buffers de cualquier formato, la solicitud convierte automáticamente. Longitud mínima: 0.5 segundos (detección de silencio). Máxima: 1 minuto (cloud) / 2 minutos (on-device) por solicitud. Para transcripciones largas, divida el audio en fragmentos de 30–60 segundos con superposición de 2–5 segundos.

Configuración y permisos de SFSpeechRecognizer

Permisos del usuario: SFSpeechRecognizer requiere dos permisos explícitos. NSMicrophoneUsageDescription (Privacy — Microphone Usage Description) — para acceso al micrófono. NSSpeechRecognitionUsageDescription (Privacy — Speech Recognition Usage Description) — para acceso al reconocimiento de voz. Ambos son cadenas que explican el motivo al usuario. SFSpeechRecognizer.requestAuthorization — muestra el diálogo de permisos. Estados: notDetermined, denied, restricted, authorized. Sin el estado authorized, llamar al recognizer devuelve el error 216 (Speech framework error).

Verificación de disponibilidad: SFSpeechRecognizer.isAvailable — comprueba si ASR está disponible para el idioma actual. En iOS 16-, isAvailable = false sin internet. En iOS 17+, isAvailable = true para idiomas on-device incluso sin conexión. SFSpeechRecognizer.supportedLocales — método estático para obtener la lista de idiomas compatibles con el dispositivo. Se recomienda verificar isAvailable antes de cada inicio (el usuario puede desactivar Siri/Dictado en ajustes). La disponibilidad depende de la región: chino — solo en China, árabe — en EAU.

swift
// Configuración de 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 no disponible. Active Siri y Dictado en Ajustes")
    return
}

let request = SFSpeechAudioBufferRecognitionRequest()
request.requiresOnDeviceRecognition = true

Manejo de errores: SFSpeechRecognizer se llama con un completion handler que puede devolver un Error. Errores principales: 203 — sin internet (cloud, iOS 16-); 216 — no autorizado (sin permiso); 301 — error de audio (problema con micrófono/formato); 401 — servicio no disponible (servicio sobrecargado); 601 — idioma no disponible (idioma no compatible en el dispositivo). Para on-device iOS 17+, errores principales: 301 (audio), 601 (idioma). Siempre maneje el completion handler — los errores pueden ocurrir en cualquier momento durante la grabación.

Reconocimiento de voz en vivo desde el micrófono

Pipeline ASR en vivo: AVAudioEngine (captura de micrófono) → installTap (buffer de audio) → request.append(buffer) → SFSpeechRecognizer → recognitionTask → delegate/resultHandler. AVAudioEngine proporciona baja latencia (5–10 ms del mic al buffer). SFSpeechRecognitionDelegate: didHypothesizeTranscription (cada 200–500 ms — texto parcial), didFinishRecognition (resultado final). Task.isFinishing — se puede cancelar cuando el reconocimiento está completo. Para reconocimiento continuo (dictado infinito), cree una nueva tarea después de isFinal.

SFSpeechRecognitionTaskDelegate: métodos opcionales. speechRecognitionDidDetectSpeech (inicio de voz) — para indicación en UI. didHypothesizeTranscription (texto intermedio) — para mostrar mientras se habla. didFinishRecognition (resultado final) — para fijar el texto. didFinishSuccessfully (éxito/error) — para finalización. didProcessAudio (buffer de audio procesado) — para medidor RMS. Se recomienda implementar didHypothesizeTranscription — el usuario ve el texto de inmediato sin demora. La transcripción final es para guardar.

swift
// Reconocimiento de voz en vivo
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()

Reconocimiento continuo: para el modo de “escucha siempre” (entrada de voz, asistente), es necesario reiniciar la tarea después de isFinal. Cree un bucle: finishTask → request = SFSpeechAudioBufferRecognitionRequest() → recognitionTask = recognizer.recognitionTask(with: request). Para evitar pausas, superponga el final de una tarea con el inicio de la siguiente (inicie una nueva solicitud 1–2 segundos antes de que termine la anterior). AVFoundation AVAudioSession — configure .playAndRecord para reproducción y grabación simultáneas. En iOS 17+, el ASR continuo con on-device consume 2–5% de batería por hora (A15+).

Reconocimiento de archivos de audio y grabaciones

SFSpeechURLRecognitionRequest — una solicitud para reconocer un archivo de audio por URL. Soporta formatos: .wav (16 kHz, 16 bit, mono), .m4a (AAC), .mp4, .mov. Longitud máxima: ~1 minuto para cloud, ~2 minutos para on-device. Para archivos más largos, divida en fragmentos (AVAssetExportSession + trim). SFSpeechURLRecognitionRequest no soporta streaming (sin resultados parciales) — solo el resultado final. Para resultados parciales con un archivo, convierta a una solicitud de Audio Buffer.

Obtención de transcripción de archivo de audio: SFSpeechRecognizer.recognitionTask(with: request) resultHandler. Extraiga bestTranscription.formattedString. Para marcas de tiempo a nivel de palabra — segments de bestTranscription.segments (segment.duration, segment.timestamp, segment.substring). Confianza por segmento — confianza ASR para cada palabra (úsela para filtrar). Hipótesis alternativas — alternativas de transcriptionFormatter para palabras con baja confianza. Para archivos con varios hablantes, SFSpeechRecognitionRequest puede devolver múltiples solicitudes (una por hablante, iOS 17+).

swift
// Transcripción de archivo de 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("Error: \(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)
    }
}

División de archivos de audio largos: para archivos > 1 minuto, divida en fragmentos de 30–60 segundos con superposición de 2–3 segundos (empalme). AVAssetExportSession + CMTimeRange — exportar fragmentos. Alternativa: UISelectionView (el usuario selecciona un segmento). Empalme de transcripciones: concatenar textos, empalmar por superposición (las últimas 2–3 palabras del fragmento anterior se comparan con las primeras 2–3 del siguiente — eliminar duplicados). Vosk y Whisper soportan audio largo de forma nativa, SFSpeechRecognizer no. Para transcripciones largas, recomiendo Whisper (Core ML) — sin límite de longitud.

On-device vs Cloud: comparación de modos

Modo On-device (iOS 17+): request.requiresOnDeviceRecognition = true. ASR se ejecuta localmente en Apple Neural Engine (ANE). Ventajas: sin necesidad de internet, privacidad (el audio nunca sale del dispositivo), costo cero (gratuito), baja latencia (RTF 0.3–0.6). Desventajas: menor precisión (WER 12–14% vs 7–12%), límite de 2 minutos por solicitud, conjunto de idiomas limitado (no todos los 60 idiomas disponibles on-device). El modelo on-device ocupa ~50–100 MB en el dispositivo y se descarga en la primera solicitud.

Cloud (iOS 16-): request.requiresOnDeviceRecognition = false (o parámetro ausente). ASR en servidores de Apple — más preciso (WER 7% EN, 12% RU), más idiomas, hasta 1 minuto por solicitud. Requiere internet (WiFi o cellular). Apple no cobra a los desarrolladores por cloud ASR (gratuito). Límites: 1 solicitud por minuto por aplicación (no especificado), pero Apple puede limitar a escala de producción. Cloud ASR proporciona calidad de mejor esfuerzo sin SLA. Para aplicaciones empresariales, use Google Cloud ASR o Whisper (Core ML).

ParámetroOn-device (iOS 17+)Cloud (iOS 10+)
Requiere internetNo
WER (EN)10–12%7%
WER (RU)12–14%12%
Latencia (RTF)0.3–0.60.3–0.8 (+red)
Longitud máxima2 minutos1 minuto
PrivacidadCompletaEl audio sale del dispositivo
Gratuito

Reconocimiento Combinado (iOS 17+): request.requiresOnDeviceRecognition = false con internet (cloud), = true sin conexión (fallback). Apple selecciona automáticamente el modo. Para aplicaciones críticas en precisión: verifique NetworkMonitor (NWPathMonitor) — use cloud con internet, on-device sin. Para aplicaciones críticas en privacidad: siempre on-device. Para transcripción: cloud (más preciso). Para entrada de voz: on-device (más rápido). Se recomienda Combinado: 80% cloud, 20% on-device fallback.

Uso de SFSpeechRecognizer en aplicaciones iOS

Entrada de voz en teclado personalizado — SFSpeechRecognizer integrado en extensiones de teclado (iOS 10+). El usuario pulsa el botón del micrófono, ASR transcribe la voz a texto y lo inserta en el campo de texto. Requisitos: resultados parciales (ver el texto en tiempo real), on-device (el teclado debe funcionar sin internet). SFSpeechRecognizer + AVSpeechSynthesizer — entrada de voz + salida de voz. Para teclados personalizados en iOS 17+, use on-device. Limitaciones de la extensión de teclado: AVAudioEngine está disponible pero con restricciones de tiempo (ejecución en segundo plano limitada).

Transcripción de reuniones y conferencias — aplicaciones para grabar y transcribir audio (Otter.ai, Rev, Apple Voice Memos). SFSpeechURLRecognitionRequest procesa archivos .m4a. Para grabaciones largas (30–60 minutos) — Whisper Core ML (sin límite de longitud). Los segments de SFSpeechRecognizer con marcas de tiempo — para sincronizar texto con audio (resaltado de texto durante la reproducción). Confianza por segmento — para mostrar fragmentos no fiables (resaltado en amarillo). Para diarización de hablantes (quién habló) — Apple no proporciona API, use pyannote-audio + Whisper en el servidor.

Comandos de voz en aplicaciones iOS — SFSpeechRecognizer + framework VGS (Voice Grammar Services) para ejecutar comandos: “abrir configuración”, “enviar mensaje”, “encender la luz”. Reconocimiento basado en gramática: SFSpeechRecognitionRequest contextualStrings = array de comandos. Esto mejora la precisión del reconocimiento de comandos hasta 95% (vs 85% de formato libre). SFSpeechRecognitionTask.cancel — para interrumpir después de ejecutar el comando. VGS + SFSpeechRecognizer + Shortcuts — comandos de voz personalizados sin escribir UI. Para accesibilidad: Voice Control (integrado) + SFSpeechRecognizer (comandos personalizados).

swift
// Comandos de voz con cadenas contextuales
let request = SFSpeechAudioBufferRecognitionRequest()
request.requiresOnDeviceRecognition = true
request.shouldReportPartialResults = true
request.contextualStrings = ["open contacts", "send message",
                             "show notifications", "encender linterna"]

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

Dictado en aplicaciones médicas y legales — SFSpeechRecognizer para crear documentos estructurados por voz. Adaptación de dominio: contextualStrings con términos médicos/legales (500+ frases). SFSpeechRecognitionRequest.customLmProbability — impacto de contextualStrings (0.1–1.0). Para dictado médico, use on-device (privacidad de datos del paciente). Whisper ajustado con datos médicos — alternativa con WER 5% en lugar de 12% del SFSpeechRecognizer base. Cumplimiento HIPAA: modo on-device (los datos nunca salen del dispositivo). Para transcripción de citas — SFSpeechURLRecognitionRequest + segments con marcas de tiempo de hablante.

Preguntas frecuentes

¿Desde qué versión de iOS es compatible SFSpeechRecognizer?

SFSpeechRecognizer está disponible desde iOS 10, macOS 10.15, watchOS 6 y tvOS 17. El modo on-device desde iOS 17 (requiresOnDeviceRecognition). En iOS 10–16, SFSpeechRecognizer funciona solo a través de los servidores cloud de Apple (requiere internet). Todas las versiones requieren permiso explícito del usuario (NSMicrophoneUsageDescription + NSSpeechRecognitionUsageDescription). SFSpeechRecognizer.supportedLocales — lista dinámica, depende de la región y el modelo del dispositivo.

¿Se puede usar SFSpeechRecognizer para reconocimiento continuo?

Sí, creando nuevos recognitionTask después de isFinal. Reinicie la tarea después de que la anterior finalice para reconocimiento continuo. En iOS 17, el ASR continuo on-device consume 2–5% de batería por hora (A15+). En iOS 16-, el ASR continuo requiere internet (tráfico ~1 MB/minuto). Para reconocimiento verdaderamente continuo (siempre escuchando), use Vosk (offline) o Whisper Core ML. SFSpeechRecognizer no soporta el modo siempre activo en iOS 16-.

¿Cómo obtener la confianza de cada palabra en SFSpeechRecognizer?

Use result.bestTranscription.segments — cada SFTranscriptionSegment contiene confidence (Float 0..1) para la palabra. segments[i].substring — texto de la palabra. segments[i].confidence — confianza ASR para esa palabra. Las palabras con confidence < 0.5 no son fiables — resáltelas en la UI. segments[i].timestamp — tiempo de inicio (TimeInterval). segments[i].duration — duración. segments[i].alternativeSubstrings — hipótesis alternativas de reconocimiento para la palabra. Para archivos largos, iterar sobre segments proporciona confianza por palabra sin análisis manual.

¿Por qué SFSpeechRecognizer devuelve el error 203?

203 es SFSpeechError.ErrorCode.opportunistic (sin internet para cloud ASR). Ocurre en iOS 16- o cuando request.requiresOnDeviceRecognition = false sin internet. Solución: establezca requiresOnDeviceRecognition = true (iOS 17+) para funcionamiento sin conexión. En iOS 16-, use NWPathMonitor — cuando no haya internet, muestre un mensaje diciendo “el reconocimiento de voz requiere conexión a internet”. Alternativa: Vosk (offline, iOS 12+) como fallback cuando no hay red disponible.

¿En qué se diferencia SFSpeechRecognizer de Whisper Core ML?

SFSpeechRecognizer — API integrada de Apple, gratuita, fácil de integrar, pero con límites de longitud (1–2 minutos), precisión WER 7–14% y solo para el ecosistema iOS. Whisper Core ML — open-source (MIT), soporta 99 idiomas, WER 6–10%, sin límite de longitud, pero requiere integración manual, modelos Core ML (39M–769M parámetros), RTF 0.5–6 (más lento que SFSpeechRecognizer). SFSpeechRecognizer — para entrada de voz estándar. Whisper — para transcripción de alta precisión de audio largo.

Resumen

  • SFSpeechRecognizer — API ASR integrada de Apple, iOS 10+, 60+ idiomas
  • Modo on-device — iOS 17+, sin internet, WER 12–14% en ruso
  • Micrófono en vivo — AVAudioEngine + request.append(buffer) + resultados parciales
  • Archivos de audio — SFSpeechURLRecognitionRequest, .m4a/.wav, hasta 1–2 minutos
  • Segments — marcas de tiempo por palabra + confianza (0..1) para cada palabra
  • Gratuito — sin límites, sin cargos de Apple, sin SDK de terceros
  • Uso — entrada de voz, transcripción, comandos, accesibilidad, dictado

Desarrollaremos una aplicación móvil llave en mano

IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.

Discutir el proyecto

Lea también