AVAudioRecorder - 展开可选时发现 nil

Posted

技术标签:

【中文标题】AVAudioRecorder - 展开可选时发现 nil【英文标题】:AVAudioRecorder - found nil when unwrapping optional 【发布时间】:2016-07-08 13:28:35 【问题描述】:

我目前正在尝试设置 AVAudioRecorder 以从 iPhone 上的麦克风捕获一些用户音频,但我不断收到“打开可选选项时意外发现 nil”错误。

在用户点击按钮并且我确定我绝对拥有麦克风权限之前,我不会尝试开始录制。

我的代码如下,我看不出哪里出错了。recordTapped 是连接到按钮的 IBAction,特别是当我尝试实例化“记录器”对象时,它会崩溃。如果我使用“打印”语句并设置了设置,则会填充 AudioUrl,所以我不确定这里发生了什么。

@IBAction func recordTapped() 
        if recorder == nil 
            startRecording()
         else 
            finishRecording(success: true)
        
    

    func startRecording() 
        view.backgroundColor = UIColor(red: 0.6, green: 0, blue: 0, alpha: 1)

        recordButton.setTitle("Tap to Stop", forState: .Normal)

        let audioURL = ViewController.getAudioURL()
        let settings = [
            AVFormatIDKey: Int(kAudioFileMPEG4Type),
            AVSampleRateKey: 12000.0,
            AVNumberOfChannelsKey: 1 as NSNumber,
            AVEncoderAudioQualityKey: AVAudioQuality.High.rawValue
        ]

        do 
            recorder = try AVAudioRecorder(URL: audioURL, settings: settings)
            recorder.prepareToRecord()

            recorder.delegate = self
            recorder.record()
         catch 
            finishRecording(success: false)
        
    

    class func getDocumentsDirectory() -> NSString 
        let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) as [String]
        let documentsDirectory = paths[0]
        return documentsDirectory
    

    class func getAudioURL() -> NSURL 
        let audioFilename = getDocumentsDirectory().stringByAppendingPathComponent("audio.m4a")
        let audioURL = NSURL(fileURLWithPath: audioFilename)

        return audioURL
    

我发现了这个问题Swift, unwrapping nil runtime error for recording audio,但似乎没有什么真正适用的。

编辑: 当我调试时,它会在录音机上暂停执行 = 尝试 AVAudioRecorder 行,然后转到

libswiftCore.dylib`function signature specialization <Arg[0] = Exploded, Arg[1] = Exploded, Arg[2] = Dead, Arg[3] = Dead> of Swift._fatalErrorMessage (Swift.StaticString, Swift.StaticString, Swift.StaticString, Swift.UInt) -> ():
    0x10027655c <+0>:   stp    x29, x30, [sp, #-16]!
    0x100276560 <+4>:   mov    x29, sp
    0x100276564 <+8>:   sub    sp, sp, #16               ; =16 
    0x100276568 <+12>:  and    w8, w2, #0x1
    0x10027656c <+16>:  tbnz   w8, #0, 0x10027658c       ; <+48>
    0x100276570 <+20>:  tbnz   x1, #63, 0x1002765c8      ; <+108>
    0x100276574 <+24>:  add    x1, x0, x1
    0x100276578 <+28>:  mov    x2, x3
    0x10027657c <+32>:  mov    x3, x4
    0x100276580 <+36>:  mov    x4, x5
    0x100276584 <+40>:  bl     0x1002be5b0               ; function signature specialization <Arg[0] = Exploded, Arg[1] = Exploded> of Swift.(_fatalErrorMessage (Swift.StaticString, Swift.StaticString, Swift.StaticString, Swift.UInt) -> ()).(closure #2)
->  0x100276588 <+44>:  brk    #0x1

'bt'的输出如下:

 * thread #1: tid = 0x71d9f5, 0x000000010036cfc0 libswiftCore.dylib`swift_willThrow, queue = 'com.apple.main-thread', stop reason = breakpoint 2.1
    frame #0: 0x000000010036cfc0 libswiftCore.dylib`swift_willThrow
    frame #1: 0x00000001000ec75c`AVAudioRecorder.__allocating_init(URL : NSURL, settings : [String : AnyObject]) throws -> AVAudioRecorder + 188 at ViewController.swift:0
  * frame #2: 0x00000001000ea480`ViewController.startRecording(self=0x000000015f664ac0) -> () + 1032 at ViewController.swift:112
    frame #3: 0x00000001000ea000`ViewController.recordTapped(self=0x000000015f664ac0) -> () + 164 at ViewController.swift:92
    frame #4: 0x00000001000ea064`@objc ViewController.recordTapped() -> () + 40 at ViewController.swift:0
    frame #5: 0x0000000188868be8 UIKit`-[UIApplication sendAction:to:from:forEvent:] + 100
    frame #6: 0x0000000188868b64 UIKit`-[UIControl sendAction:to:forEvent:] + 80
    frame #7: 0x0000000188850870 UIKit`-[UIControl _sendActionsForEvents:withEvent:] + 436
    frame #8: 0x0000000188868454 UIKit`-[UIControl touchesEnded:withEvent:] + 572
    frame #9: 0x0000000188868084 UIKit`-[UIWindow _sendTouchesForEvent:] + 804
    frame #10: 0x0000000188860c20 UIKit`-[UIWindow sendEvent:] + 784
    frame #11: 0x000000018883104c UIKit`-[UIApplication sendEvent:] + 248
    frame #12: 0x000000018882f628 UIKit`_UIApplicationHandleEventQueue + 6568
    frame #13: 0x000000018368909c CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 24
    frame #14: 0x0000000183688b30 CoreFoundation`__CFRunLoopDoSources0 + 540
    frame #15: 0x0000000183686830 CoreFoundation`__CFRunLoopRun + 724
    frame #16: 0x00000001835b0c50 CoreFoundation`CFRunLoopRunSpecific + 384
    frame #17: 0x0000000184e98088 GraphicsServices`GSEventRunModal + 180
    frame #18: 0x000000018889a088 UIKit`UIApplicationMain + 204
    frame #19: 0x00000001000ed528`main + 144 at AppDelegate.swift:12
    frame #20: 0x000000018314e8b8 libdyld.dylib`start + 4

更新: 所以最初的崩溃是由我没有包含的“stopRecording”方法引起的。这基本上是在调用 recorder.stop() 即使记录器不存在。通过简单的 nil 检查解决了问题。虽然这仍然无法解决以下错误:

  Error Domain=NSOSStatusErrorDomain Code=1718449215 "(null)"

快速的谷歌搜索告诉我我正在使用无效类型进行录制!

对于其他看到这个的人,事实证明我在我的录音机设置中使用的是 KAudioFile... 而不是 kAudioFormat

谢谢

【问题讨论】:

收到错误时堆栈跟踪是什么样的? 我在控制台中得到的只是致命错误:在打开一个可选值时意外发现 nil 并且在录音机上 = 尝试 AVAudioRecorder 行 当它停止时,您应该能够查看 Debug Navigator 窗口或在控制台中键入“bt”以查看堆栈。 您确定您已将recordButton 正确连接到 UIButton 吗?您可能已成功连接@IBAction,但不能保证您已正确连接@IBOutlet。 - 显示更多信息,此评论可能无用。对不起。 @OOper 连接正确,按钮似乎没有给我带来任何问题 【参考方案1】:

对于其他看到这个的人,事实证明我在我的录音机设置中使用的是 KAudioFile... 而不是 kAudioFormat

【讨论】:

以上是关于AVAudioRecorder - 展开可选时发现 nil的主要内容,如果未能解决你的问题,请参考以下文章

重新激活 NSLayoutConstraint 在展开可选时发现 nil

使用 View Controller 作为辅助视图的委托失败,在展开可选时意外发现 nil

尝试将 AlamoFire JSON 响应映射到类并接收“致命错误:在展开可选时意外发现 nil”

HealthKit(打开可选时意外发现 nil)

Xcode NSManagedObject 子类在它们被标记为非可选时包含可选

为啥在 regex char 可选时找不到匹配项