如何在iOS 9中通过幻灯片和拆分视图使用AVCaptureSession?
我的团队正在开发一套用于条码扫描 , ID扫描和OCR的SDK。 我们使用设备的相机,特别是AVCaptureSession
,来获取我们进行处理的video帧。
我们正在探索新的iOS 9多任务function幻灯片和拆分视图。
苹果build议select以相机为中心的应用程序的这些function,使用整个屏幕快速预览和捕捉片刻是一个主要function( 参考 )。 这是在他们的示例应用程序AVCam中使用的方法。
但是,我们的客户可能有不属于这个类别的应用程序(例如手机银行应用程序),所以我们不能强迫他们退出,而是需要处理SDK中的新function。 我们正在探索什么是最好的方法,因为目前的文档并没有告诉我们该怎么做。
我们使用我们简单的Camera示例应用程序来分析用例。 示例应用程序在Github上可用,它是从iOS 9 Beta 5开发的。
从示例应用程序中,可以清楚地看到使用“幻灯片放映”时以及使用“分割视图”时发生了哪些系统事件。
- 当我们的应用程序是主要的,并使用幻灯片,我们得到了
UIApplicationWillResignActiveNotification
和AVCaptureSessionDidStopRunningNotification
- 当使用幻灯片播放,我们的应用程序是次要的,我们得到
UIApplicationWillEnterForegroundNotification
和AVCaptureSessionDidStopRunningNotification
后立即 - 当使用拆分视图时,在每个分隔符拖动,我们的应用程序获取
UIApplicationWillResignActiveNotification
。 - 但是,如果在分割视图中启动相机,则立即获取
AVCaptureSessionDidStopRunningNotification
所以,凭经验来看,当使用“幻灯片”或“分割视图”时, AVCaptureSession
会立即停止。
令人困惑的是我们的示例应用程序也支持的UIImagePickerController
performance出完全不同的行为。
当应用程序进入幻灯片放映/分割视图时, 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