我打开了一个包含mailto链接(mailto:test@test.com)
的网页的webview我能够获得url=mailto:test@test.com
但不能获得与常规网址不同的部分。我想在撰写邮件时从mailto url中提取电子邮件以进行预填充。有没有一种优雅的方法从Swift iOS中的mailto url中提取test@test.com?
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
let request: URLRequest = navigationAction.request
if let url = request.url,
url.scheme == "mailto" {
decisionHandler(.cancel)
let urlString = "scheme://myapp/open/compose?\(url.absoluteString.replacingOccurrences(of: ":", with: "="))
UIApplication.shared.open(URL(string: urlString)!)
return
}
}
答案 0 :(得分:6)
您可以获取您的网址路径组件:
let url = URL(string: "mailto:test@test.com")!
if url.scheme == "mailto",
let components = URLComponents(url: url, resolvingAgainstBaseURL: false) {
let email = components.path
print(email) // "test@test.com\n"
}
您还可以按以下方式扩展网址:
extension URL {
var email: String? {
return scheme == "mailto" ? URLComponents(url: self, resolvingAgainstBaseURL: false)?.path : nil
}
}
if let email = url.email {
print("email:", email) // "email: test@test.com\n"
}
答案 1 :(得分:1)
为了完成@Leo Dabus的回答,我写了一篇详尽的struct
,该文档处理了RFC2368中指定的所有情况:
struct EmailParameters {
/// Guaranteed to be non-empty
let toEmails: [String]
let ccEmails: [String]
let bccEmails: [String]
let subject: String?
let body: String?
/// Defaults validation is just verifying that the email is not empty.
static func defaultValidateEmail(_ email: String) -> Bool {
return !email.isEmpty
}
/// Returns `nil` if `toEmails` contains at least one email address validated by `validateEmail`
/// A "blank" email address is defined as an address that doesn't only contain whitespace and new lines characters, as defined by CharacterSet.whitespacesAndNewlines
/// `validateEmail`'s default implementation is `defaultValidateEmail`.
init?(
toEmails: [String],
ccEmails: [String],
bccEmails: [String],
subject: String?,
body: String?,
validateEmail: (String) -> Bool = defaultValidateEmail
) {
func parseEmails(_ emails: [String]) -> [String] {
return emails.map { $0.trimmingCharacters(in: .whitespacesAndNewlines) }.filter(validateEmail)
}
let toEmails = parseEmails(toEmails)
let ccEmails = parseEmails(ccEmails)
let bccEmails = parseEmails(bccEmails)
if toEmails.isEmpty {
return nil
}
self.toEmails = toEmails
self.ccEmails = ccEmails
self.bccEmails = bccEmails
self.subject = subject
self.body = body
}
/// Returns `nil` if `scheme` is not `mailto`, or if it couldn't find any `to` email addresses
/// `validateEmail`'s default implementation is `defaultValidateEmail`.
/// Reference: https://tools.ietf.org/html/rfc2368
init?(url: URL, validateEmail: (String) -> Bool = defaultValidateEmail) {
guard let urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: false) else {
return nil
}
let queryItems = urlComponents.queryItems ?? []
func splitEmail(_ email: String) -> [String] {
return email.split(separator: ",").map(String.init)
}
let initialParameters = (toEmails: urlComponents.path.isEmpty ? [] : splitEmail(urlComponents.path), subject: String?(nil), body: String?(nil), ccEmails: [String](), bccEmails: [String]())
let emailParameters = queryItems.reduce(into: initialParameters) { emailParameters, queryItem in
guard let value = queryItem.value else {
return
}
switch queryItem.name {
case "to":
emailParameters.toEmails += splitEmail(value)
case "cc":
emailParameters.ccEmails += splitEmail(value)
case "bcc":
emailParameters.bccEmails += splitEmail(value)
case "subject" where emailParameters.subject == nil:
emailParameters.subject = value
case "body" where emailParameters.body == nil:
emailParameters.body = value
default:
break
}
}
self.init(
toEmails: emailParameters.toEmails,
ccEmails: emailParameters.ccEmails,
bccEmails: emailParameters.bccEmails,
subject: emailParameters.subject,
body: emailParameters.body,
validateEmail: validateEmail
)
}
}
一旦包含在您的应用中,解析mailto
链接就变得非常简单:
let mailToURL: URL(string: "mailto:test@example.com")!
if let emailParameters = EmailParameters(url: url) {
// You can then access each of `emailParameters`'s fields
// emailParameters.toEmails is guaranteed to have a non-empty email address (i.e accessing `emailParameters.toEmails[0]` will never crash)
// Note it doesn't perform email validation by default, but you can specify
// a custom `validateEmail` closure if need be in the `EmailParameters` initializer above
}
我还创建了一个要点,以提供更多here可用功能(主要用于很好地支持嵌入式HTML和Markdown内容中的链接)。