简体   繁体   English

在 iOS 中请求相机权限对话框启动(Prime Permissions)

[英]Request Camera Permission Dialog Priming (Prime Permissions) in iOS

What is the most effective way to prompt a User to provide access to the Camera (or other feature), while ensuring the best experience?在确保最佳体验的同时,提示用户提供对相机(或其他功能)的访问权限的最有效方法是什么?

When accessing the Camera, iOS must ask the Customer permission to allow access.访问相机时,iOS 必须征得客户的许可以允许访问。 As we all know, if the Customer says "No" but then changes their mind, there is no way to reverse this decision from within your App.众所周知,如果客户说“不”但后来改变了主意,则无法从您的应用程序中撤消此决定。 They must go to Settings and follow a number of steps to re-enable access, namely:他们必须转到“设置”并按照一些步骤重新启用访问,即:

Settings -> Privacy -> Camera -> [Your App] -> turn switch on

Permission Priming is an effective way to avoid a situation where your Customer might deny access to a key feature of your app. 权限启动是避免客户可能拒绝访问应用程序关键功能的有效方法。

On iOS an App is only allowed to trigger the default system permission once per feature. 在iOS上,每个功能只允许应用程序触发一次默认系统权限。 Permission priming is when an app "primes" the Customer with an alert that mimics a system permission. 权限启动是指应用程序使用模仿系统权限的警报“填充”客户。

The benefit to doing this is so that if the Customer opts-out (selects Cancel), the App is still able to ask again in future, until they say yes — at which time the actual system permission is displayed and the Customer is statistically less likely to then change their mind and enter into the negative work flow. 这样做的好处是,如果客户选择退出(选择取消),应用程序仍然可以在将来再次询问,直到他们说是 - 此时显示实际的系统权限并且客户在统计上更少可能会改变主意并进入负面工作流程。

Furthermore, since cameraSelected() performs this workflow, if the user declines, but then at some future point does change their settings, the App will immediately reflect the new permissions without further input (ie. the User could switch to Settings, change permissions, and then switch back to the App). 此外,由于cameraSelected()执行此工作流程,如果用户拒绝,但在某个未来点确实更改其设置,应用程序将立即反映新权限而无需进一步输入(即,用户可以切换到设置,更改权限,然后切换回App)。

Here is some Swift 3 code to implement this feature: 以下是一些实现此功能的Swift 3代码:

[UPDATE: Included is a solution to open a deep-link to Settings where the User can enable camera access, if they have previously denied it.] [更新:包含一个解决方案,打开设置的深层链接,用户可以启用相机访问,如果他们以前拒绝了它。]

[UPDATE 2: Added sample lines for Analytics implementation.] [更新2:为分析实施添加了示例行。]

func cameraSelected() {
    // First we check if the device has a camera (otherwise will crash in Simulator - also, some iPod touch models do not have a camera).
    if let deviceHasCamera = UIImagePickerController.isSourceTypeAvailable(.camera) {
        let authStatus = AVCaptureDevice.authorizationStatus(forMediaType: AVMediaTypeVideo)
        switch authStatus {
            case .authorized:
                showCameraPicker()
            case .denied:
                alertPromptToAllowCameraAccessViaSettings()
            case .notDetermined:
                permissionPrimeCameraAccess()
            default:
                permissionPrimeCameraAccess()
        }
    } else {
        let alertController = UIAlertController(title: "Error", message: "Device has no camera", preferredStyle: .alert)
        let defaultAction = UIAlertAction(title: "OK", style: .default, handler: { (alert) in
            Analytics.track(event: .permissionsPrimeCameraNoCamera)
        })
        alertController.addAction(defaultAction)
        present(alertController, animated: true, completion: nil)
    }
}


func alertPromptToAllowCameraAccessViaSettings() {
    let alert = UIAlertController(title: "\"<Your App>\" Would Like To Access the Camera", message: "Please grant permission to use the Camera so that you can  <customer benefit>.", preferredStyle: .alert )
    alert.addAction(UIAlertAction(title: "Open Settings", style: .cancel) { alert in
        Analytics.track(event: .permissionsPrimeCameraOpenSettings)
        if let appSettingsURL = NSURL(string: UIApplicationOpenSettingsURLString) {
          UIApplication.shared.openURL(appSettingsURL)
        }
    })
    present(alert, animated: true, completion: nil)
}


func permissionPrimeCameraAccess() {
    let alert = UIAlertController( title: "\"<Your App>\" Would Like To Access the Camera", message: "<Your App> would like to access your Camera so that you can <customer benefit>.", preferredStyle: .alert )
    let allowAction = UIAlertAction(title: "Allow", style: .default, handler: { (alert) -> Void in
        Analytics.track(event: .permissionsPrimeCameraAccepted)
        if AVCaptureDevice.devices(withMediaType: AVMediaTypeVideo).count > 0 {
            AVCaptureDevice.requestAccess(forMediaType: AVMediaTypeVideo, completionHandler: { [weak self] granted in
                DispatchQueue.main.async {
                    self?.cameraSelected() // try again
                }
            })
        }
    })
    alert.addAction(allowAction)
    let declineAction = UIAlertAction(title: "Not Now", style: .cancel) { (alert) in
        Analytics.track(event: .permissionsPrimeCameraCancelled)
    }
    alert.addAction(declineAction)
    present(alert, animated: true, completion: nil)
}


func showCameraPicker() {
    let picker = UIImagePickerController()
    picker.delegate = self
    picker.modalPresentationStyle = UIModalPresentationStyle.currentContext
    picker.allowsEditing = false
    picker.sourceType = UIImagePickerControllerSourceType.camera
    present(picker, animated: true, completion: nil)
}

Suppose we have two buttons (one for picking picture from library another from camera) with tags 1,2 that are linked to action:假设我们有两个按钮(一个用于从库中选择图片,另一个用于从相机中选择),带有与动作相关联的标签 1,2:

import UIKit
import AVFoundation

    @IBAction func changeImage(sender: UIButton) {
        let picker = UIImagePickerController()
        if sender.tag == 2 { // tag = 2 for camera button. tag = 1 for image picker
            guard UIImagePickerController.isSourceTypeAvailable(.camera) else { return }
            let cameraAuthorizationStatus = AVCaptureDevice.authorizationStatus(for: .video)
            
            switch cameraAuthorizationStatus {
            case .notDetermined:
                requestCameraPermission()
                return
            case .authorized:
                break
            case .restricted, .denied:
                alertCameraAccessNeeded()
                return
            @unknown default:
                return
            }
            picker.sourceType = .camera
        }
        
        picker.allowsEditing = true
        picker.delegate = self
        present(picker, animated: true)
    }

    private func requestCameraPermission() {
        AVCaptureDevice.requestAccess(for: .video) { [weak self] accessGranted in
            if !accessGranted {
                DispatchQueue.main.async {
                    self?.alertCameraAccessNeeded()
                }
            }
        }
    }
    
    private  func alertCameraAccessNeeded() {
        guard let settingsAppURL = URL(string: UIApplication.openSettingsURLString),
              UIApplication.shared.canOpenURL(settingsAppURL) else { return } // This should never happen
        let alert = UIAlertController(
            title: "Need Camera Access",
            message: "Camera access is required to take pictures of item.",
            preferredStyle: .alert
        )
        alert.addAction(UIAlertAction(title: "Cancel", style: .default))
        alert.addAction(UIAlertAction(title: "Allow Camera", style: .cancel) { _ in
            UIApplication.shared.open(settingsAppURL, options: [:])
        })
        present(alert, animated: true)
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 iOS 相机权限,本机 iOS 权限警报未在第一次请求时触发 - iOS camera permissions, native iOS permission alert not firing on first request iOS 12:“摄像机访问请求”对话框显示默认权限 - iOS 12 : Camera access request dialog box shows default permission 在 iOS 8 中显示相机权限对话框 - Presenting camera permission dialog in iOS 8 如何在运行时请求iOS权限(相机和位置)? - How to request iOS permissions (camera and location) on runtime? 在iOS上的设置中拒绝权限后如何显示相机的权限对话框 - How to display permission dialog for Camera after permission was denied in settings on iOS 在运行时在 Unity 中的 iOS 上请求相机权限 - Request Camera Permission on iOS in Unity at Runtime 在 iOS 15 上 React Native Webview (camera, getUserMedia) 双重请求权限 - React Native Webview (camera, getUserMedia) double request of permissions on iOS 15 在 iOS 10 中请求相机和库的权限 - Info.plist - Request Permission for Camera and Library in iOS 10 - Info.plist iOS 请求权限对话框未显示在屏幕录制或快速视频上 - iOS Request permission dialog not showing on screen recording or quicktime video 在iOS中检测相机的权限 - Detect permission of camera in iOS
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM