如何在没有撰写视图的情况下打开 iOS 14 上的默认邮件应用程序?

Rap*_*ael 9 ios swift

我想在 iOS 14 上打开用户选择的默认邮件应用程序 - 但不显示撰写视图。注册帐户后,用户应该确认他们的电子邮件地址,因此我想将用户引导到那里。

根据我发现的其他问题,似乎有两种已知的方法:

UIApplication.shared.open(URL(string: "mailto://")!)

UIApplication.shared.open(URL(string: "message://")!)

第一个选项的问题在于,它将在应用程序中打开一个空的撰写邮件视图,要求用户输入新电子邮件。那不是我想要的。这会让用户感到困惑,他们认为必须向我们发送电子邮件。通过 mailto URL 语法的参数输入一些文本,我基本上用一些文本预先填充邮件撰写视图,指示放弃新的电子邮件草稿并要求检查他们的电子邮件,这可以作为一种解决方法,但不是很好。

第二个选项的问题是,即使这不是默认的邮件应用程序,它也会始终打开 Mail.app,并且如果用户从手机中删除 Mail.app,它可能会要求用户安装 Mail.app,因为他们选择了例如Protonmail 作为他们的默认邮件应用程序。对于不主要使用 Mail.app 的人来说,这也不是一个很好的选择。

因此,其他人提出的两种方法都不能很好地解决我的问题。

解决这个问题的最佳方法是什么?

是否有一些应用程序可以查询 iOS 的默认邮件应用程序,以便至少我可以尝试启动该应用程序(如果我知道该应用程序的自定义 URL 方案(例如googlegmail://))?

Rap*_*ael 3

我通过向具有警报视图的用户询问他们的偏好最终解决了一半,因为我没有找到直接查询 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)
}
Run Code Online (Sandbox Code Playgroud)

然后,我像这样响应用户的选择:

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
}
Run Code Online (Sandbox Code Playgroud)

当然,这种方法的一个明显限制是我将用户限制为非常特定的应用程序(在本例中为 Google Mail、iOS“默认”Mail、Microsoft Outlook 和 ProtonMail)。所以这种方法并不能很好地扩展。

但至少,您可以涵盖一些最喜欢的内容,并根据用户的反馈从那里开始。

跳过第一个问题的主要原因是,至少目前,直接从 iOS 获取这些信息似乎是不可能的。我也找不到一个 URL 方案,该方案始终会打开所选的默认邮件应用程序而不显示撰写新电子邮件视图。