iOS 12.4 AVAudioRecorder.record 当应用程序处于后台时返回 false

iOS 12.4 AVAudioRecorder.record is returning false when app is in the background

首先,此错误仅出现在 iOS 的最新 12.4 版本中。该问题不会出现在模拟器中,并且必须 运行 在设备上。问题是,一旦应用程序进入后台,对 AVAudioRecorder 的录音调用就会 returning false。在 iOS 之前的所有版本中,都不会发生这种情况。 info.plist 使用 NSMicrophoneUsageDescription 标签更新,应用程序的功能包括音频背景模式。

我写了一个小 ViewController 来说明这个问题。重新创建的步骤:

1) Update the info.plist file with the NSMicrophoneUsageDescription tag so that the app gets permission to use the microphone 2) Update the app capabilities to set Audio background mode 3) Run the application 4) Send the application to the background 5) The current recording will finish, but the call to start a new recording will fail.


class ViewController: UIViewController, AVAudioRecorderDelegate {
   var recordLabel: UILabel!
   var recordingSession: AVAudioSession!
   var audioRecorder: AVAudioRecorder!
   var count: Int = 0

   override func viewDidLoad() {
       super.viewDidLoad()

       recordingSession = AVAudioSession.sharedInstance()

       do {
           try recordingSession.setCategory(.playAndRecord, mode: .default)
           try recordingSession.setActive(true)
           recordingSession.requestRecordPermission() { [unowned self] allowed in
               DispatchQueue.main.async {
                   if allowed {
                       self.loadRecordingUI()
                   } else {
                       print("No permissions!!!")
                   }
               }
           }
       } catch {
           print("Exception in viewDidLoad!!!")
       }
   }

   func loadRecordingUI() {
       super.viewDidLoad()

       recordLabel = UILabel(frame: CGRect(x: 0, y: 0, width: 300, height: 21))
       recordLabel.center = CGPoint(x: 160, y: 285)
       recordLabel.textAlignment = .center
       recordLabel.text = "Waiting...."
       self.view.addSubview(recordLabel)

       setupRecorder()
       startRecording();
   }

   func setupRecorder() {
       let audioFilename = getDocumentsDirectory().appendingPathComponent("recording.m4a")

       let settings = [
           AVFormatIDKey: Int(kAudioFormatMPEG4AAC),
           AVSampleRateKey: 12000,
           AVNumberOfChannelsKey: 1,
           AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue
       ]

       do {
           audioRecorder = try AVAudioRecorder(url: audioFilename, settings: settings)
           audioRecorder.delegate = self
       } catch {
           print("Exception thrown in setupRecorder")
       }
   }

   func startRecording() {
       count += 1

       let ret = audioRecorder.record(forDuration: 10)  //record for 10 seonds

       let txt = "Record returned " + ret.description + " for #\(count)"
       recordLabel.text = txt
       print(txt)
   }

   func getDocumentsDirectory() -> URL {
       let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
       return paths[0]
   }

   func audioRecorderDidFinishRecording(_ recorder: AVAudioRecorder, successfully flag: Bool) {
       startRecording()  //immediately start recording again
   }
}

由于已设置应用程序在后台录制的功能,我希望在 AVAudioRecorder 上录制的调用为 return true

我就此事向 Apple 提交了反馈(audioRecorder.record() returns false while in background),得到的答复是这是一项新的隐私保护限制,即他们不会修复它。

"The behaviour mentioned is a change but is the correct behaviour going forward, attempting to start audio recording in the background which had not been recording previously (and then interrupted by a call or Siri) will not work (essentially trying to start recording from the background randomly will no longer work). This is a new a privacy protection restriction introduced in 12.4."