AVCaptureDevice.requestAccess使用UINavigationController呈现意外行为

时间:2018-11-07 20:13:59

标签: ios swift uinavigationcontroller avcapturedevice

使用Xcode 10.1和Swift 4.2

我有一个复杂的应用,该应用使用在UINavigationController中实现的AppDelegate

navigationController的rootViewController是DashboardController()类(UIViewController的子类)

DashboardController使用几个ViewController(带有self.addChild(viewController))实现了一个左侧菜单抽屉

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

可以按预期按下弹出准系统barCodeScannerView。

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

  1. 当我按如下所示显示Device.requestAccess(for:)时:弹出视图控制器,并显示上一个视图(rootViewController)。 (仍然带有“ App要访问摄像机” AlertView)

    func requestCameraAccess(){     AVCaptureDevice.requestAccess(for:AVMediaType.video){在         如果授予{             self.launchScanner()         }其他{             self.goBack()         }     } }

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

顺便说一句:applicationWillResignActiveapplicationDidEnterBackgroundapplicationWillEnterForeground没有被调用。因此很明显,这不是App LifeCycle的一部分。

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

提前谢谢...

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

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

完整的项目已附加。 (.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")
            }
        }
    }   
}

1 个答案:

答案 0 :(得分:1)

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

applicationDidBecomeActive
applicationWillResignActive
Access granted
applicationDidBecomeActive

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