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

Cer*_*vec 26 camera multitasking ios avcapturesession ios9

我的团队正在开发一套用于条形码扫描,ID扫描OCR的SDK .我们使用设备的相机AVCaptureSession来获取我们执行处理的视频帧.

我们正在探索新的iOS 9多任务处理功能Slide Over和Split View.


Apple建议选择退出这些功能,以相机为中心的应用程序,其中使用整个屏幕进行预览和快速捕捉片刻是一个主要功能(参考).这是他们的示例应用程序AVCam中使用的方法.

但是,我们的客户可能拥有不属于此类别的应用程序(例如移动银行应用程序),因此我们无法强制他们选择退出,而是需要处理SDK中的新功能.我们正在探索最好的方法,因为目前的文档并没有真正告诉我们该做什么.


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

从示例应用程序中,可以清楚地看到使用"幻灯片放映"时以及使用"拆分视图"时发生的系统事件.

  • 当我们的应用程序是主要的,并使用幻灯片放映时,我们得到UIApplicationWillResignActiveNotificationAVCaptureSessionDidStopRunningNotification
  • 当滑过时,和我们的应用程序是次要的,我们得到UIApplicationWillEnterForegroundNotificationAVCaptureSessionDidStopRunningNotification之后立即
  • 使用拆分视图时,在每个分隔符拖动时,我们的应用程序都会获得UIApplicationWillResignActiveNotification.
  • 但是,如果在分割视图中启动摄像头,它会立即启动 AVCaptureSessionDidStopRunningNotification

因此,根据经验,AVCaptureSession当使用"幻灯片放大"或"拆分视图"时,它会立即停止.

令人困惑的是UIImagePickerController,我们的示例应用程序也支持它,表现出完全不同的行为.

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


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

  • 如果AVCaptureSession在使用"幻灯片放大"和"拆分视图"时立即暂停,是否最好监控AVCaptureSessionDidStopRunningNotification并向用户显示"Camera Paused"消息,以便他清楚地知道应用程序没有执行扫描?

  • 为什么行为UIImagePickerController不同AVCaptureSession

  • 我们可以期待Apple比未来beta版本的AVCaptureSession变化行为更符合UIImagePickerController吗?

Jos*_*oss 14

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

如果在使用"幻灯片放大"和"拆分视图"时立即暂停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)
}
Run Code Online (Sandbox Code Playgroud)

您还可以通过观察AVCaptureSessionInterruptionEndedNotification来了解中断何时结束

基于以下两个链接的答案:

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