【问题标题】:Request Camera Permission Dialog Priming (Prime Permissions) in iOSiOS中的请求相机权限对话框启动(Prime Permissions)
【发布时间】:2017-05-09 07:05:12
【问题描述】:

在确保最佳体验的同时,提示用户提供对相机(或其他功能)的访问权限的最有效方法是什么?

访问相机时,iOS 必须请求客户许可才能允许访问。众所周知,如果客户说“不”但随后改变了主意,则无法从您的应用程序中撤销此决定。他们必须转到“设置”并按照多个步骤重新启用访问权限,即:

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

【问题讨论】:

    标签: ios swift permissions camera user-experience


    【解决方案1】:

    假设我们有两个按钮(一个用于从库中选择图片,另一个用于从相机中选择图片),标签为 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)
        }
    

    【讨论】:

      【解决方案2】:

      权限启动是避免客户拒绝访问您应用的关键功能的有效方法。

      在 iOS 上,每个功能仅允许应用触发一次默认系统权限。权限启动是指应用向客户“启动”模拟系统权限的警报。

      这样做的好处是,如果客户选择退出(选择取消),应用程序仍然可以在未来再次询问,直到他们说是 - 此时会显示实际的系统权限并且客户从统计学上讲,他们改变主意并进入负面工作流程的可能性较小。

      此外,由于cameraSelected() 执行此工作流程,如果用户拒绝,但在未来某个时间确实更改了他们的设置,应用程序将立即反映新权限而无需进一步输入(即。用户可以切换到设置,更改权限,然后切换回应用程序)。

      这里有一些 Swift 3 代码来实现这个功能:

      [更新:包括一个解决方案,用于打开指向设置的深层链接,用户可以在其中启用相机访问,如果他们以前拒绝过。]

      [更新 2:为 Analytics 实施添加了示例行。]

      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)
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-11-06
        • 1970-01-01
        • 1970-01-01
        • 2012-11-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-07-31
        相关资源
        最近更新 更多