Tout d'abord, cette erreur ne se produit que dans la dernière version 12.4 sur iOS. Le problème ne se produit PAS dans le simulateur et doit être exécuté sur un appareil. Le problème est que l'appel à enregistrer sur l'AVAudioRecorder retourne faux une fois que l'application passe en arrière-plan. Dans toutes les versions précédentes d'iOS, cela ne se produirait pas. Le fichier info.plist est mis à jour avec la balise NSMicrophoneUsageDescription, et les capacités de l'application incluent le mode d'arrière-plan audio.
J'ai écrit un petit ViewController qui montre le problème. Étapes pour recréer:
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
}
}
Étant donné que la capacité de l'application à enregistrer en arrière-plan a été définie, je m'attends à ce que l'appel à enregistrer sur AVAudioRecorder renvoie true
J'ai envoyé un commentaire à Apple à ce sujet (audioRecorder.record () renvoie false en arrière-plan) et j'ai obtenu la réponse qu'il s'agit d'une nouvelle restriction de protection de la vie privée, c'est-à-dire qu'ils ne le corrigeront pas.
"Le comportement mentionné est un changement mais est le comportement correct à l'avenir, tenter de démarrer l'enregistrement audio en arrière-plan qui n'avait pas été enregistré précédemment (puis interrompu par un appel ou Siri) ne fonctionnera pas (essentiellement essayer de démarrer l'enregistrement à partir de la arrière-plan ne fonctionnera plus). Il s'agit d'une nouvelle restriction de protection de la vie privée introduite en 12.4. "