AVCaptureDevice.requestAccess使用UINavigationController呈现意外行为 [英] AVCaptureDevice.requestAccess presents unexpected behavior with a UINavigationController

查看:104
本文介绍了AVCaptureDevice.requestAccess使用UINavigationController呈现意外行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用Xcode 10.1和Swift 4.2

我有一个使用 UINavigationController AppDelegate 中实现。

I have a complex app that uses a UINavigationController implemented in the AppDelegate.

navigationController的rootViewController是 DashboardController()类( UIViewController

The rootViewController of the navigationController is a DashboardController() class (subclass of UIViewController)

DashboardController 使用多个ViewControllers(带有 self.addChild(viewController)

The DashboardController implements a left menu drawer using several ViewControllers (with self.addChild(viewController))

一切正常,除非需要推送viewController来显示 BarCodeScannerView()。

Everything works fine, except when I need to push a viewController to present a BarCodeScannerView().

准骨barCodeScannerView可以按下弹出

The barebone barCodeScannerView can be pushed and popped as expected.

当我请求访问相机时(仅是第一次)出现问题。

The problems arises when I request access to the camera (only the first time).


  1. 我出示 Device.requestAccess(for:)如下所示:弹出视图控制器,并显示上一个视图(rootViewController)。 (仍与 App要访问摄像机 AlertView一起使用)

  1. As soon as I present the Device.requestAccess(for:) as follow: the viewController is popped and the previous view (rootViewController) is presented. (Still with the "App would like to access the camera" AlertView)

func requestCameraAccess(){
AVCaptureDevice.requestAccess(for:AVMediaType.video){如果被授予,则以
授予{
self.launchScanner()
}否则{
self.goBack()
}
}
}

func requestCameraAccess() { AVCaptureDevice.requestAccess(for: AVMediaType.video) { granted in if granted { self.launchScanner() } else { self.goBack() } } }

如果我单击确定,系统将注册已授予访问权限,但
applicationDidBecomeActive (在 AppDelegate 中)在大约1秒钟后被调用。我在 applicationDidBecomeActive 中有一些初始化程序,它们都被再次执行。并且在快速延迟之后,一切正常。

If I click "OK" The system will register that the access was granted, but the applicationDidBecomeActive (in the AppDelegate) is called after aprox 1 second. I have some initializers in applicationDidBecomeActive, and they all are executed again. And after a quick delay, everything works fine.

BTW: applicationWillResignActive applicationDidEnterBackground applicationWillEnterForeground 不会被调用。因此很明显,这不是App LifeCycle的一部分。

BTW: applicationWillResignActive, applicationDidEnterBackground and applicationWillEnterForeground are NOT called. So it is clear that this is not part of an App LifeCycle.

任何想法我会在这里发生什么?什么可以使系统在应用程序中调用 applicationDidBecomeActive ?并仍然保持一切正常运行?

Any idea what might me going on here? What can make the system call applicationDidBecomeActive within the app? and still keep everything running?

预先感谢...

更新阅读评论后,我能够按如下所述隔离问题#2:

UPDATE After reading the comments, I was able to isolate the issue #2 as follows:

一个简单的/准系统项目,其中包含 UINavigationController 和一个dashboardViewController作为 rootViewController 。 dashboardViewController将 CameraViewController()推送到 viewDidLoad()中。 cameraViewController请求访问相机。单击确定时,将触发对 applicationDidBecomeActive 的调用。

A simple/barebones project with a UINavigationController with a dashboardViewController as rootViewController. The dashboardViewController pushes a CameraViewController() in viewDidLoad(). The cameraViewController requests access to the camera. When clicking OK, the call to applicationDidBecomeActive is triggered.

已附加整个项目。 (除了.plist中的隐私-相机使用说明键。

The full project is attached. (except the "Privacy - Camera Usage Description" key in the .plist.

import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    var window: UIWindow? = UIWindow()
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        let dashboardViewController = DashboardViewController()
        window?.rootViewController = UINavigationController(rootViewController: dashboardViewController)
        window?.makeKeyAndVisible()
        return true
    }
    func applicationDidBecomeActive(_ application: UIApplication) {
        print("applicationDidBecomeActive")
    }
    func applicationWillResignActive(_ application: UIApplication) {}
    func applicationDidEnterBackground(_ application: UIApplication) {}
    func applicationWillEnterForeground(_ application: UIApplication) {}
    func applicationWillTerminate(_ application: UIApplication) {}
}
class DashboardViewController: UIViewController {
    override func viewDidAppear(_ animated: Bool) {
        let cameraVC = CameraViewController()
        self.navigationController?.pushViewController(cameraVC, animated: true)
    }
}
import AVFoundation
class CameraViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        AVCaptureDevice.requestAccess(for: AVMediaType.video) { granted in
            if granted {
                print("Access granted")
            }
        }
    }   
}


推荐答案

我会说问题出在您的测试过程上。当我在 applicationWillResignActive 中使用 print 语句运行代码时,这就是我看到的:

I'd say the problem is just with your testing procedure. When I run your code with a print statement in applicationWillResignActive, this is what I see:

applicationDidBecomeActive
applicationWillResignActive
Access granted
applicationDidBecomeActive

这似乎完全是正常的。得到一个虚假的 didBecomeActive 会很奇怪,但这不是正在发生的事情。我们辞职活跃,然后再次活跃,这很好。您应该期望您的应用程序可以随时退出并重新激活。正常生命周期中的许多事情都可能导致这种情况,并且诸如授权对话框之类的进程外对话框的表示可以合理地成为其中之一。您应该以应付这种可能性的方式编写代码。

That seems completely in order and normal. It would have been weird to get a spurious didBecomeActive, but that is not what's happening; we resign active and then become active again, which is fine. You should expect that at any time your app can resign active and become active again. Many things in the normal lifecycle can cause that, and the presentation of an out-of-process dialog like the authorization dialog can reasonably be one of them. You should write your code in such a way as to cope with that possibility.

这篇关于AVCaptureDevice.requestAccess使用UINavigationController呈现意外行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆