我最终解决了一半,通过警告视图询问用户他们的偏好,因为我没有找到直接查询 iOS 的方法。
所以首先显示一个像这样的警报视图:
func askUserForTheirPreference(in presentingViewController: UIViewController) {
let alertController = UIAlertController(title: nil, message: "pleaseConfirmWithApp", preferredStyle: .actionSheet)
alertController.addAction(UIAlertAction(title: "Apple Mail", style: .default) { action in
self.open(presentingViewController, .applemail)
})
alertController.addAction(UIAlertAction(title: "Google Mail", style: .default) { action in
self.open(presentingViewController, .googlemail)
})
alertController.addAction(UIAlertAction(title: "Microsoft Outlook", style: .default) { action in
self.open(presentingViewController, .outlook)
})
alertController.addAction(UIAlertAction(title: "Protonmail", style: .default) { action in
self.open(presentingViewController, .protonmail)
})
alertController.addAction(UIAlertAction(title: "Cancel", style: .cancel) { action in
os_log("Cancelling", log: Self.log, type: .debug)
})
presentingViewController.present(alertController, animated: true)
}
然后,我将这样回应用户的选择:
func open(_ presentingViewController: UIViewController, _ appType: AppType) {
switch appType {
case .applemail: UIApplication.shared.open(URL(string: "message:")!, completionHandler: { handleAppOpenCompletion(presentingViewController, $0) })
case .googlemail: UIApplication.shared.open(URL(string: "googlegmail:")!, completionHandler: { handleAppOpenCompletion(presentingViewController, $0) })
case .outlook: UIApplication.shared.open(URL(string: "ms-outlook:")!, completionHandler: { handleAppOpenCompletion(presentingViewController, $0) })
case .protonmail: UIApplication.shared.open(URL(string: "protonmail:")!, completionHandler: { handleAppOpenCompletion(presentingViewController, $0) })
}
}
private func handleAppOpenCompletion(_ presentingViewController: UIViewController, _ isSuccess: Bool) {
guard isSuccess else {
let alertController = UIAlertController(title: nil, message: "thisAppIsNotInstalled", preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "Dismiss", style: .cancel))
presentingViewController.present(alertController, animated: true)
return
}
}
enum AppType {
case applemail, googlemail, outlook, protonmail
}
这种方法的一个明显限制当然是我将用户限制在非常特定的应用程序(在本例中为 Google Mail、iOS“默认”邮件、Microsoft Outlook 和 ProtonMail)。
所以这种方法并不能很好地扩展。
但至少,您可以覆盖一些最喜欢的,然后根据用户的反馈从那里开始。
跳过这些询问第一个问题的主要原因是,至少目前,直接从 iOS 获取这些信息似乎是不可能的。
我也找不到始终打开所选默认邮件应用程序而不显示撰写新电子邮件视图的 URL 方案。