まず、このエラーはiOSの最新の12.4リリースでのみ発生します。この問題はシミュレータでは発生せず、デバイスで実行する必要があります。問題は、アプリがバックグラウンドになると、AVAudioRecorderに録音する呼び出しが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に録音する呼び出しがtrueを返すことを期待しています
私はAppleこれについて(audioRecorder.record()がバックグラウンドでfalseを返す)にフィードバックを提出しましたが、それは新しいプライバシー保護制限である、つまり修正されないという回答を得ました。
「記載されている動作は変更ですが、今後の正しい動作であり、以前に録音されていなかった(その後、通話またはSiriによって中断された)バックグラウンドでオーディオ録音を開始しようとしても機能しません(基本的に、背景はランダムに機能しなくなります)。これは、12.4で導入されたプライバシー保護の新しい制限です。」