如何在iOS 9中通过幻灯片和拆分视图使用AVCaptureSession?

我的团队正在开发一套用于条码扫描 , ID扫描和OCR的SDK。 我们使用设备的相机,特别是AVCaptureSession ,来获取我们进行处理的video帧。

我们正在探索新的iOS 9多任务function幻灯片和拆分视图。


苹果build议select以相机为中心的应用程序的这些function,使用整个屏幕快速预览和捕捉片刻是一个主要function( 参考 )。 这是在他们的示例应用程序AVCam中使用的方法。

但是,我们的客户可能有不属于这个类别的应用程序(例如手机银行应用程序),所以我们不能强迫他们退出,而是需要处理SDK中的新function。 我们正在探索什么是最好的方法,因为目前的文档并没有告诉我们该怎么做。


我们使用我们简单的Camera示例应用程序来分析用例。 示例应用程序在Github上可用,它是从iOS 9 Beta 5开发的。

从示例应用程序中,可以清楚地看到使用“幻灯片放映”时以及使用“分割视图”时发生了哪些系统事件。

  • 当我们的应用程序是主要的,并使用幻灯片,我们得到了UIApplicationWillResignActiveNotificationAVCaptureSessionDidStopRunningNotification
  • 当使用幻灯片播放,我们的应用程序是次要的,我们得到UIApplicationWillEnterForegroundNotificationAVCaptureSessionDidStopRunningNotification后立即
  • 当使用拆分视图时,在每个分隔符拖动,我们的应用程序获取UIApplicationWillResignActiveNotification
  • 但是,如果在分割视图中启动相机,则立即获取AVCaptureSessionDidStopRunningNotification

所以,凭经验来看,当使用“幻灯片”或“分割视图”时, AVCaptureSession会立即停止。

令人困惑的是我们的示例应用程序也支持的UIImagePickerControllerperformance出完全不同的行为。

当应用程序进入幻灯片放映/分割视图时, UIImagePickerController不会停止,而是完全正常运行。 通常可以在分割视图中拍照。 实际上,两个呈现UIImagePickerController应用程序可以并行工作,活动应用程序的UIImagePickerController处于活动状态。 (您可以通过运行我们的示例应用程序和联系人应用程序 – >新build联系人 – >添加照片来尝试)


考虑到这一切,我们的问题如下:

  • 如果在使用“幻灯片”和“分割视图”时立即暂停AVCaptureSession ,是否需要监视AVCaptureSessionDidStopRunningNotification ,并向用户显示消息“Camera Paused”,以便他清楚地知道应用程序未执行扫描?

  • 为什么UIImagePickerController行为与AVCaptureSession不同?

  • 我们可以期待从苹果比AVCaptureSession未来testing版本行为更改为匹配UIImagePickerController

如果你还没有发现。 经过更多的调查,我现在可以回答你的第一个问题:

如果在使用“幻灯片”和“分割视图”时立即暂停AVCaptureSession,是否需要监视AVCaptureSessionDidStopRunningNotification,并向用户显示消息“Camera Paused”,以便他清楚地知道应用程序未执行扫描?

您实际上想要观察的通知是这样一个: AVCaptureSessionWasInterruptedNotification

而你想检查在iOS9中新引入的原因: AVCaptureSessionInterruptionReason.VideoDeviceNotAvailableWithMultipleForegroundApps

 override func viewWillAppear(animated: Bool) { super.viewWillAppear(animated) self.addObserverForAVCaptureSessionWasInterrupted() } func addObserverForAVCaptureSessionWasInterrupted() { let mainQueue = NSOperationQueue.mainQueue() NSNotificationCenter.defaultCenter().addObserverForName(AVCaptureSessionWasInterruptedNotification, object: nil, queue: mainQueue) { (notification: NSNotification) -> Void in guard let userInfo = notification.userInfo else { return } // Check if the current system is iOS9+ because AVCaptureSessionInterruptionReasonKey is iOS9+ (relates to Split View / Slide Over) if #available(iOS 9.0, *) { if let interruptionReason = userInfo[AVCaptureSessionInterruptionReasonKey] where Int(interruptionReason as! NSNumber) == AVCaptureSessionInterruptionReason.VideoDeviceNotAvailableWithMultipleForegroundApps.rawValue { // Warn the user they need to get back to Full Screen Mode } } else { // Fallback on earlier versions. From iOS8 and below Split View and Slide Over don't exist, no need to handle anything then. } } } override func viewWillDisappear(animated: Bool) { super.viewWillDisappear(true) NSNotificationCenter.defaultCenter().removeObserver(self) } 

你也可以通过观察AVCaptureSessionInterruptionEndedNotification知道中断何时结束

基于这两个环节回答:

http://asciiwwdc.com/2015/sessions/211 https://developer.apple.com/library/ios/samplecode/AVCam/Introduction/Intro.html