如何在 iOS 9 中使用带有 Slide Over 和 Split View 的 AVCaptureSession?
How to use AVCaptureSession with Slide Over and Split View in iOS 9?
我的团队正在为 barcode scanning, ID scanning and OCR 开发一组 SDK。我们使用设备的摄像头,具体来说,AVCaptureSession
来获取我们执行处理的视频帧。
我们正在探索新的 iOS 9 项多任务处理功能“滑过”和“拆分视图”。
Apple 建议为以相机为中心的应用选择退出这些功能,其中使用整个屏幕进行预览和快速捕捉瞬间是主要功能 (reference). This is the approach the use in their sample app AVCam.
但是,我们的客户可能拥有不属于此类的应用程序(例如移动银行应用程序),因此我们不能强迫他们选择退出,相反,我们需要处理 SDK 中的新功能。我们正在探索什么是最好的方法来做到这一点,因为目前的文档并没有真正告诉我们该怎么做。
我们使用简单的相机示例应用程序来分析用例。示例应用程序在 Github 上可用,它是从 iOS 9 Beta 5 开始开发的。
从示例应用程序中,可以清楚地看到使用 Slide Over 和使用 Split View 时发生了哪些系统事件。
- 当我们的应用程序是主要的,并且使用 Slide Over 时,我们得到
UIApplicationWillResignActiveNotification
和 AVCaptureSessionDidStopRunningNotification
- 当使用 Slide Over 时,我们的应用程序是次要的,我们在之后立即得到
UIApplicationWillEnterForegroundNotification
和 AVCaptureSessionDidStopRunningNotification
- 使用 Split View 时,在每次拖动分隔线时,我们的应用会得到
UIApplicationWillResignActiveNotification
。
- 但是,如果在拆分视图中启动相机,它会立即获得
AVCaptureSessionDidStopRunningNotification
因此,根据经验,当使用 Slide Over 或 Split View 时,AVCaptureSession
似乎会立即停止。
令人困惑的是 UIImagePickerController
,我们的示例应用程序也支持它,表现出完全不同的行为。
UIImagePickerController
当应用程序进入侧拉/拆分视图时不会停止,相反,它会完全正常运行。人们通常可以在 Split View 中拍摄照片。事实上,两个都存在 UIImagePickerController
的应用程序可以并排工作,活动应用程序的 UIImagePickerController
处于活动状态。 (您可以通过 运行 我们的示例应用程序和联系人应用程序 -> 新建联系人 -> 添加照片来尝试)
考虑到所有这些,我们的问题如下:
如果使用 Slide Over 和 Split View 时 AVCaptureSession
立即暂停,监视 AVCaptureSessionDidStopRunningNotification
并显示消息 "Camera Paused" 是个好主意吗给用户,让他清楚地知道应用程序没有执行扫描?
为什么 UIImagePickerController
的行为与 AVCaptureSession
不同?
我们能否期望 Apple 在未来的 beta 版本中 AVCaptureSession
的行为会发生变化以匹配 UIImagePickerController
?
以防你还没有发现。经过更多调查后,我现在可以回答您的第一个问题:
If AVCaptureSession is immediately paused when Slide Over and Split
View are used, is it a good idea to monitor
AVCaptureSessionDidStopRunningNotification, and present a message
"Camera Paused" to the user, so that he clearly knows that the app
isn't performing scanning?
你真正想要观察的通知是这个: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
我的团队正在为 barcode scanning, ID scanning and OCR 开发一组 SDK。我们使用设备的摄像头,具体来说,AVCaptureSession
来获取我们执行处理的视频帧。
我们正在探索新的 iOS 9 项多任务处理功能“滑过”和“拆分视图”。
Apple 建议为以相机为中心的应用选择退出这些功能,其中使用整个屏幕进行预览和快速捕捉瞬间是主要功能 (reference). This is the approach the use in their sample app AVCam.
但是,我们的客户可能拥有不属于此类的应用程序(例如移动银行应用程序),因此我们不能强迫他们选择退出,相反,我们需要处理 SDK 中的新功能。我们正在探索什么是最好的方法来做到这一点,因为目前的文档并没有真正告诉我们该怎么做。
我们使用简单的相机示例应用程序来分析用例。示例应用程序在 Github 上可用,它是从 iOS 9 Beta 5 开始开发的。
从示例应用程序中,可以清楚地看到使用 Slide Over 和使用 Split View 时发生了哪些系统事件。
- 当我们的应用程序是主要的,并且使用 Slide Over 时,我们得到
UIApplicationWillResignActiveNotification
和AVCaptureSessionDidStopRunningNotification
- 当使用 Slide Over 时,我们的应用程序是次要的,我们在之后立即得到
UIApplicationWillEnterForegroundNotification
和AVCaptureSessionDidStopRunningNotification
- 使用 Split View 时,在每次拖动分隔线时,我们的应用会得到
UIApplicationWillResignActiveNotification
。 - 但是,如果在拆分视图中启动相机,它会立即获得
AVCaptureSessionDidStopRunningNotification
因此,根据经验,当使用 Slide Over 或 Split View 时,AVCaptureSession
似乎会立即停止。
令人困惑的是 UIImagePickerController
,我们的示例应用程序也支持它,表现出完全不同的行为。
UIImagePickerController
当应用程序进入侧拉/拆分视图时不会停止,相反,它会完全正常运行。人们通常可以在 Split View 中拍摄照片。事实上,两个都存在 UIImagePickerController
的应用程序可以并排工作,活动应用程序的 UIImagePickerController
处于活动状态。 (您可以通过 运行 我们的示例应用程序和联系人应用程序 -> 新建联系人 -> 添加照片来尝试)
考虑到所有这些,我们的问题如下:
如果使用 Slide Over 和 Split View 时
AVCaptureSession
立即暂停,监视AVCaptureSessionDidStopRunningNotification
并显示消息 "Camera Paused" 是个好主意吗给用户,让他清楚地知道应用程序没有执行扫描?为什么
UIImagePickerController
的行为与AVCaptureSession
不同?我们能否期望 Apple 在未来的 beta 版本中
AVCaptureSession
的行为会发生变化以匹配UIImagePickerController
?
以防你还没有发现。经过更多调查后,我现在可以回答您的第一个问题:
If AVCaptureSession is immediately paused when Slide Over and Split View are used, is it a good idea to monitor AVCaptureSessionDidStopRunningNotification, and present a message "Camera Paused" to the user, so that he clearly knows that the app isn't performing scanning?
你真正想要观察的通知是这个: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