Как использовать AVCaptureSession со слайдом и разделенным представлением в iOS 9?
Моя команда разрабатывает набор SDK для сканирования штрих-кодов, сканирование идентификаторов и OCR. Мы используем камеру устройства, в частности AVCaptureSession
, для получения видеокадров, на которых мы выполняем нашу обработку.
Мы изучаем новые функции многозадачности iOS 9. Слайд и разделение.
Apple предлагает отказаться от этих функций для приложений, ориентированных на камеры, где основной экран для предварительного просмотра и быстрого захвата - основная функция (ссылка). Это подход к использованию в своем примере приложения AVCam.
Однако у наших клиентов могут быть приложения, которые не попадают в эту категорию (например, приложения для мобильного банкинга), поэтому мы не можем заставить их отказаться, вместо этого нам нужно обрабатывать новые функции в SDK. Мы изучаем, как лучше всего это сделать, поскольку в настоящий момент документы не говорят нам, что делать.
Мы использовали наше простое приложение для примера камеры, чтобы проанализировать прецедент. Пример приложения можно найти на Github, и он был разработан с версии IOS 9 Beta 5.
Из примера приложения ясно видно, какие системные события происходят при использовании режима "Слайд", и когда используется Split View.
- Когда наше приложение является первичным, и используется функция "Слайд", мы получаем
UIApplicationWillResignActiveNotification
и AVCaptureSessionDidStopRunningNotification
- Когда используется функция Slide Over, а наше приложение является вторичным, мы получаем
UIApplicationWillEnterForegroundNotification
и AVCaptureSessionDidStopRunningNotification
сразу после этого
- Когда используется Split View, при каждом перетаскивании разделителя наше приложение получает
UIApplicationWillResignActiveNotification
.
- Однако, если камера запускается в режиме Split View, она сразу получает
AVCaptureSessionDidStopRunningNotification
Итак, эмпирически, похоже, что AVCaptureSession
сразу же останавливается при использовании режима Слайд или Сплит.
Что сбивает с толку то, что UIImagePickerController
, которое также поддерживает наше примерное приложение, демонстрирует совершенно другое поведение.
UIImagePickerController
не останавливается, когда приложение переходит в режим "Слайд Over/Split", вместо этого он функционирует нормально. Обычно можно сфотографировать в режиме Split View. Фактически, два приложения, оба из которых присутствуют UIImagePickerController
, могут работать бок о бок, при активном активном приложении UIImagePickerController
. (Вы можете попробовать это, запустив наше примерное приложение и приложение "Контакты" → "Новый контакт → Добавить фотографию" )
Учитывая все это, наши вопросы таковы:
-
Если AVCaptureSession
немедленно приостанавливается при использовании режима "Слайд-вспять" и "Сплит-просмотр", рекомендуется ли отслеживать AVCaptureSessionDidStopRunningNotification
и представлять пользователю сообщение "Camera Paused", чтобы он четко знал что приложение не выполняет сканирование?
-
Почему поведение UIImagePickerController
отличается от AVCaptureSession
?
-
Можно ли ожидать от Apple, чем в будущих версиях бета-версий изменений AVCaptureSession
в соответствии с UIImagePickerController
?
Ответы
Ответ 1
Если вы еще не обнаружили. После некоторого расследования я теперь могу ответить на ваш первый вопрос:
Если AVCaptureSession сразу приостанавливается при переполнении и сплите Просмотр используется, рекомендуется ли отслеживать AVCaptureSessionDidStopRunningNotification и представить сообщение "Камера приостановлена" пользователю, так что он ясно знает, что приложение не выполняет сканирование?
Уведомление, которое вы действительно хотите наблюдать, это следующее: 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