我调用了一个函数来访问用户的联系信息。但是,我需要此功能来提示用户警告,如果 authorizationStatus 被拒绝,可以将他们重定向到他们的设置页面。
到目前为止,我的代码可以成功提示用户输入他们的联系信息。但是,如果案例最终被拒绝,我想运行 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 类,但我不希望在我的模板 View 中包含此逻辑。
最佳答案
我之前在使用camera usage的时候也做过类似的实现。
我认为您可以使用 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)
}
}))
}
}
}
关于如果 authorizationStatus 被拒绝,SwiftUI 将用户定向到他们的设置页面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62561308/