【问题标题】:SwiftUI direct a User to their settings page if authorizationStatus is denied如果authorizationStatus 被拒绝,SwiftUI 会将用户引导到他们的设置页面
【发布时间】:2023-03-24 23:25:01
【问题描述】:

我调用了一个函数来访问用户的联系信息。但是,如果授权状态被拒绝,我需要这个功能来提示用户一个警报,可以将他们重定向到他们的设置页面。

到目前为止,我的代码成功提示用户输入他们的联系信息。但是,如果案例最终被拒绝,我想运行show_settings_alert 函数,如下所示:

func requestContactPermissions(completion: @escaping (Bool) -> ()) {
    let store = CNContactStore()
    var authStatus = CNContactStore.authorizationStatus(for: .contacts)
    switch authStatus {
    case .denied:
        show_settings_alert()
}

这是我在一些关于此问题的教程中找到的 show_settings_alert 函数:

func show_settings_alert() {
    let alertController = UIAlertController(title: "TITLE", message: "Please go to Settings and turn on the permissions", preferredStyle: .alert)
    let settingsAction = UIAlertAction(title: "Settings", style: .default) { (_) -> Void in
        guard let settingsUrl = URL(string: UIApplication.openSettingsURLString) else {
            return
        }
        if UIApplication.shared.canOpenURL(settingsUrl) {
            UIApplication.shared.open(settingsUrl, completionHandler: { (success) in })
         }
    }
    let cancelAction = UIAlertAction(title: "Cancel", style: .default, handler: nil)
    alertController.addAction(cancelAction)
    alertController.addAction(settingsAction)
    
    self.present(alertController, animated: true, completion: nil)
}

问题是,我试图在函数中运行self.present,因此我无法访问 self.我也知道这是 UIKit 代码,我不完全确定如何在使用 SwiftUI 时获得相同的功能。

我知道 SwiftUI 附带了一个 Alert 类,但我不想在我的模板视图中包含这个逻辑。

【问题讨论】:

    标签: swift uikit swiftui


    【解决方案1】:

    我之前使用相机时也做过类似的实现。
    我认为你可以通过使用 Combine 和 SwiftUI 来实现它。 当您选择拒绝或限制时,以下实现将显示警报。

    import Combine
    import Contacts
    
    class Contact: ObservableObject {
      var dispose = Set<AnyCancellable>()
      let contactStore = CNContactStore()
      @Published var invalidPermission: Bool = false
      
      var authorizationStatus: AnyPublisher<CNAuthorizationStatus, Never> {
        Future<CNAuthorizationStatus, Never> { promise in
          self.contactStore.requestAccess(for: .contacts) { (_, _) in
            let status = CNContactStore.authorizationStatus(for: .contacts)
            promise(.success(status))
          }
        }
        .eraseToAnyPublisher()
      }
      
      func requestAccess() {
        self.authorizationStatus
          .receive(on: RunLoop.main)
          .map { $0 == .denied || $0 == .restricted }
          .assign(to: \.invalidPermission, on: self)
          .store(in: &dispose)
      }
    }
    

    ContactView 通过 Contact 类的invalidPermission 状态显示警报。

    在此代码中,您按下一个按钮来向联系人请求使用它的权限。如果被拒绝,则显示前往设置的警报。如果已授权,则不会显示警报。

    struct ContactView: View {
      @ObservedObject var contact = Contact()
      
      var body: some View {
        VStack {
          Button(action: {
            // if pressed button, request contact permissions
            self.contact.requestAccess()
          }) {
            Text("Request access to Contacts")
          }
        }
        .alert(isPresented: self.$contact.invalidPermission) {
          Alert(
            title: Text("TITLE"),
            message: Text("Please go to Settings and turn on the permissions"),
            primaryButton: .cancel(Text("Cancel")),
            secondaryButton: .default(Text("Settings"), action: {
              if let url = URL(string: UIApplication.openSettingsURLString), UIApplication.shared.canOpenURL(url) {
                UIApplication.shared.open(url, options: [:], completionHandler: nil)
              }
            }))
        }
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-11
      • 1970-01-01
      • 1970-01-01
      • 2023-03-15
      • 1970-01-01
      相关资源
      最近更新 更多