Подтвердить что ты не робот

Как использовать 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?

4b9b3361

Ответ 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