Как использовать AVCaptureSession с слайдером и разделенным видом в iOS 9?
Моя команда разрабатывает набор SDK для сканирования штрих-кодов, сканирования идентификаторов и распознавания текста. Мы используем камеру устройства, в частности, AVCaptureSession
, чтобы получить видеокадры, на которых мы выполняем нашу обработку.
Мы исследуем новые функции многозадачности iOS 9 Slide Over и Split View.
Apple предлагает отказаться от этих функций для приложений, ориентированных на камеры, где использование всего экрана для предварительного просмотра и быстрого захвата изображения является основной функцией ( ссылка). Этот подход используется в их примере приложения AVCam.
Однако у наших клиентов могут быть приложения, которые не попадают в эту категорию (например, приложения для мобильного банкинга), поэтому мы не можем заставить их отказаться, вместо этого нам нужно обрабатывать новые функции в SDK. Мы изучаем, как лучше всего это сделать, поскольку документы на данный момент не говорят нам, что делать.
Мы использовали наш простой пример приложения Camera для анализа варианта использования. Пример приложения доступен на Github и разработан для iOS 9 Beta 5.
Из примера приложения можно ясно увидеть, какие системные события происходят, когда используется слайдер, и когда используется разделенный вид.
- Когда наше приложение является основным и используется Slide Over, мы получаем
UIApplicationWillResignActiveNotification
а такжеAVCaptureSessionDidStopRunningNotification
- Когда используется Slide Over, а наше приложение вторично, мы получаем
UIApplicationWillEnterForegroundNotification
а такжеAVCaptureSessionDidStopRunningNotification
сразу после этого - При использовании Split View при каждом перетаскивании разделителя наше приложение получает
UIApplicationWillResignActiveNotification
, - Однако, если камера запускается в режиме разделенного просмотра, она сразу же получает
AVCaptureSessionDidStopRunningNotification
Итак, эмпирически это выглядит AVCaptureSession
немедленно останавливается, когда используются режим слайд-шоу или разделенный вид.
Что смущает то, что UIImagePickerController
, которое также поддерживает наше приложение, демонстрирует совершенно другое поведение.
UIImagePickerController
не останавливается, когда приложение переходит в режим "Слайд-овер / сплит-просмотр", а работает полностью нормально. Обычно можно сделать фотографию в режиме Split View. На самом деле, два приложения, оба из которых представляют UIImagePickerController
, может работать рядом, с UIImagePickerController
активного приложения, являющегося активным. (Вы можете попробовать это, запустив наше приложение-образец и приложение Контакты -> Новый контакт -> Добавить фото)
Учитывая все это, мы задаем следующие вопросы:
Если
AVCaptureSession
немедленно приостанавливается при использовании режима "Слайд-овер" и "Разделенный вид". Рекомендуется ли отслеживатьAVCaptureSessionDidStopRunningNotification
и представить пользователю сообщение "Камера приостановлена", чтобы он четко знал, что приложение не выполняет сканирование?Почему поведение
UIImagePickerController
отличающийся отAVCaptureSession
?Можем ли мы ожидать от Apple, чем в будущих бета-версиях поведение
AVCaptureSession
изменения, чтобы соответствоватьUIImagePickerController
?
2 ответа
В случае, если вы еще не узнали. После еще одного расследования я теперь могу ответить на ваш первый вопрос:
Если AVCaptureSession немедленно приостанавливается при использовании Slide Over и Split View, рекомендуется ли отслеживать 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
Начиная с iOS 16.0+ можно использоватьisMultitaskingCameraAccessEnabled
флаг. Ссылка
Начиная с iOS 13.5+ и iPadOS 13.5+ можно использовать праваcom.apple.developer.avfoundation.multitasking-camera-access
, позволяя приложению продолжать использовать камеру, работая вместе с другим приложением переднего плана. Ссылка
Подробнее о доступе к камере в режиме многозадачности здесь