You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS项目中SFSpeechRecognizer运行数分钟后失效问题求助

解决SFSpeechRecognizer运行1-2分钟后失效的问题

Hey Jerry, let's tackle this frustrating issue you're facing with SFSpeechRecognizer. Based on what you described—initial success then sudden failure after 1-2 minutes, plus you're storing recognized words in an array for analysis—here are the most likely fixes to check:

1. 检查识别请求与任务的生命周期管理

This is the #1 culprit when modifying Apple's sample code for continuous recognition. If you're not properly cleaning up old tasks or reusing requests incorrectly, the recognizer can get stuck or stop receiving input.

  • Use class-level variables for recognitionRequest and recognitionTask (avoid local variables that get deallocated mid-session).
  • Cancel and reset old tasks before starting a new session to avoid conflicts.
  • Handle final results/errors properly—don't leave hanging tasks that block new input.

Here's a cleaned-up snippet of how to manage this:

import Speech
import AVFoundation

class SpeechManager: NSObject {
    private let speechRecognizer = SFSpeechRecognizer(locale: Locale(identifier: "en-US"))!
    private var recognitionRequest: SFSpeechAudioBufferRecognitionRequest?
    private var recognitionTask: SFSpeechRecognitionTask?
    private let audioEngine = AVAudioEngine()
    var recognizedWords: [String] = [] // Your word storage array
    
    func startContinuousRecognition() {
        // Step 1: Clean up existing tasks/requests
        if let recognitionTask = recognitionTask {
            recognitionTask.cancel()
            self.recognitionTask = nil
        }
        recognitionRequest = nil
        
        // Step 2: Initialize new recognition request
        recognitionRequest = SFSpeechAudioBufferRecognitionRequest()
        guard let recognitionRequest = recognitionRequest else {
            fatalError("Failed to create recognition request")
        }
        recognitionRequest.shouldReportPartialResults = true // Critical for continuous updates
        
        // Step 3: Start recognition task
        recognitionTask = speechRecognizer.recognitionTask(with: recognitionRequest) { [weak self] result, error in
            guard let self = self else { return }
            
            // Handle recognized results
            if let result = result {
                let transcript = result.bestTranscription
                // Extract words and add to your array
                for segment in transcript.segments {
                    let wordRange = transcript.formattedString.range(from: segment.range)!
                    let word = String(transcript.formattedString[wordRange])
                    if !self.recognizedWords.contains(word) { // Avoid duplicates if needed
                        self.recognizedWords.append(word)
                    }
                }
            }
            
            // Handle errors or final results
            if error != nil || result?.isFinal == true {
                print("Recognition ended with error: \(error?.localizedDescription ?? "No error")")
                // Restart engine to keep continuous recognition
                self.audioEngine.stop()
                self.audioEngine.inputNode.removeTap(onBus: 0)
                self.startContinuousRecognition()
            }
        }
        
        // Step 4: Configure audio engine input
        let inputNode = audioEngine.inputNode
        let recordingFormat = inputNode.outputFormat(forBus: 0)
        
        inputNode.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat) { buffer, time in
            self.recognitionRequest?.append(buffer)
        }
        
        audioEngine.prepare()
        do {
            try audioEngine.start()
        } catch {
            print("Audio engine failed to start: \(error)")
        }
    }
    
    func stopRecognition() {
        audioEngine.stop()
        recognitionRequest?.endAudio()
        recognitionTask?.cancel()
        recognitionRequest = nil
        recognitionTask = nil
    }
}

2. 排查音频引擎的运行状态

If the AVAudioEngine stops running (due to system interruptions, audio route changes, or unhandled errors), the recognizer will stop receiving audio input entirely. Add checks to confirm the engine is still active when recognition fails:

  • Print audioEngine.isRunning in your error handler to see if it's stopped.
  • Listen for audio session notifications (like AVAudioSession.interruptionNotification) to handle interruptions gracefully and restart the engine when needed.

3. 清理你的单词存储数组

While this won't directly break recognition, a continuously growing array can lead to memory bloat over time. If your app hits a memory warning, iOS might terminate the recognition process to free up resources. Add logic to prune the array periodically:

// Example: Keep only the last 100 words to prevent memory overload
if recognizedWords.count > 100 {
    recognizedWords.removeFirst(recognizedWords.count - 100)
}

4. 检查识别错误日志

Always log the error returned in the recognitionTask completion handler—this will tell you exactly why recognition stopped. Common issues include:

  • SFSpeechRecognitionError.network: No internet access (needed for cloud-based recognition).
  • SFSpeechRecognitionError.busy: The recognizer is already in use.
  • SFSpeechRecognitionError.audioSession: Issues with the audio session configuration.

Add this to your completion block to get detailed error info:

if let error = error as? SFSpeechRecognitionError {
    print("Speech recognition error code: \(error.code.rawValue)")
    print("Error message: \(error.localizedDescription)")
}

Start with checking the error logs first—they'll give you the clearest clue about what's going wrong. Then verify your task/request lifecycle and audio engine state. That should get your continuous recognition running smoothly again!

内容的提问来源于stack exchange,提问作者Jerry Chang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:21:34