mailto links now open on iOS

fixes #2036

Extends `URL` with an email address `var` for `mailto` schemes and adds a decisionHandler for `mailto` schemes on `WebViewController`. If the device cannot send mail, an alert is displayed.
This commit is contained in:
Stuart Breckenridge 2020-05-03 21:33:57 +08:00
parent d09541a0c0
commit f901436211
No known key found for this signature in database
GPG Key ID: 977FF9C8CE7AB207
3 changed files with 50 additions and 0 deletions

View File

@ -674,6 +674,9 @@
D5F4EDB720074D6500B9E363 /* WebFeed+Scriptability.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5F4EDB620074D6500B9E363 /* WebFeed+Scriptability.swift */; };
D5F4EDB920074D7C00B9E363 /* Folder+Scriptability.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5F4EDB820074D7C00B9E363 /* Folder+Scriptability.swift */; };
DD82AB0A231003F6002269DF /* SharingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD82AB09231003F6002269DF /* SharingTests.swift */; };
DF41F3AE245EFCD7004EFB01 /* URL-Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF41F3AD245EFCD7004EFB01 /* URL-Extensions.swift */; };
DF41F3C8245EFD45004EFB01 /* URL-Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF41F3AD245EFCD7004EFB01 /* URL-Extensions.swift */; };
DF41F3C9245EFD46004EFB01 /* URL-Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF41F3AD245EFCD7004EFB01 /* URL-Extensions.swift */; };
FF3ABF13232599810074C542 /* ArticleSorterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF3ABF09232599450074C542 /* ArticleSorterTests.swift */; };
FF3ABF1523259DDB0074C542 /* ArticleSorter.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF3ABF1423259DDB0074C542 /* ArticleSorter.swift */; };
FF3ABF162325AF5D0074C542 /* ArticleSorter.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF3ABF1423259DDB0074C542 /* ArticleSorter.swift */; };
@ -1635,6 +1638,7 @@
D5F4EDB620074D6500B9E363 /* WebFeed+Scriptability.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "WebFeed+Scriptability.swift"; sourceTree = "<group>"; };
D5F4EDB820074D7C00B9E363 /* Folder+Scriptability.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Folder+Scriptability.swift"; sourceTree = "<group>"; };
DD82AB09231003F6002269DF /* SharingTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SharingTests.swift; sourceTree = "<group>"; };
DF41F3AD245EFCD7004EFB01 /* URL-Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "URL-Extensions.swift"; sourceTree = "<group>"; };
FF3ABF09232599450074C542 /* ArticleSorterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleSorterTests.swift; sourceTree = "<group>"; };
FF3ABF1423259DDB0074C542 /* ArticleSorter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleSorter.swift; sourceTree = "<group>"; };
FFD43E372340F320009E5CA3 /* MarkAsReadAlertController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MarkAsReadAlertController.swift; sourceTree = "<group>"; };
@ -2405,6 +2409,7 @@
51126DA3225FDE2F00722696 /* RSImage-Extensions.swift */,
516AE9DE2372269A007DEEAA /* IconImage.swift */,
B2B8075D239C49D300F191E0 /* RSImage-AppIcons.swift */,
DF41F3AD245EFCD7004EFB01 /* URL-Extensions.swift */,
);
path = Extensions;
sourceTree = "<group>";
@ -3852,6 +3857,7 @@
65ED401C235DEF6C0081F399 /* FaviconGenerator.swift in Sources */,
65ED401D235DEF6C0081F399 /* RefreshInterval.swift in Sources */,
65ED401E235DEF6C0081F399 /* TimelineCellData.swift in Sources */,
DF41F3C9245EFD46004EFB01 /* URL-Extensions.swift in Sources */,
65ED401F235DEF6C0081F399 /* BuiltinSmartFeedInspectorViewController.swift in Sources */,
65ED4020235DEF6C0081F399 /* AppDelegate+Scriptability.swift in Sources */,
65ED4021235DEF6C0081F399 /* NNW3Document.swift in Sources */,
@ -4038,6 +4044,7 @@
51C4529F22650A1900C03939 /* AuthorAvatarDownloader.swift in Sources */,
5108F6D22375EED2001ABC45 /* TimelineCustomizerViewController.swift in Sources */,
519E743D22C663F900A78E47 /* SceneDelegate.swift in Sources */,
DF41F3C8245EFD45004EFB01 /* URL-Extensions.swift in Sources */,
FFD43E412340F488009E5CA3 /* MarkAsReadAlertController.swift in Sources */,
51C452A322650A1E00C03939 /* HTMLMetadataDownloader.swift in Sources */,
51C4528D2265095F00C03939 /* AddFolderViewController.swift in Sources */,
@ -4156,6 +4163,7 @@
51EF0F922279CA620050506E /* AccountsAddTableCellView.swift in Sources */,
849A97431ED9EAA9007D329B /* AddFolderWindowController.swift in Sources */,
8405DDA522168C62008CE1BF /* TimelineContainerViewController.swift in Sources */,
DF41F3AE245EFCD7004EFB01 /* URL-Extensions.swift in Sources */,
844B5B671FEA18E300C7C76A /* MainWIndowKeyboardHandler.swift in Sources */,
848D578E21543519005FFAD5 /* PasteboardWebFeed.swift in Sources */,
5144EA2F2279FAB600D19003 /* AccountsDetailViewController.swift in Sources */,

View File

@ -0,0 +1,17 @@
//
// URL-Extensions.swift
// NetNewsWire
//
// Created by Stuart Breckenridge on 03/05/2020.
// Copyright © 2020 Ranchero Software. All rights reserved.
//
import Foundation
extension URL {
/// Extracts email address from a `URL` with a `mailto` scheme, otherwise `nil`.
var emailAddress: String? {
scheme == "mailto" ? URLComponents(url: self, resolvingAgainstBaseURL: false)?.path : nil
}
}

View File

@ -12,6 +12,7 @@ import RSCore
import Account
import Articles
import SafariServices
import MessageUI
protocol WebViewControllerDelegate: class {
func webViewController(_: WebViewController, articleExtractorButtonStateDidUpdate: ArticleExtractorButtonState)
@ -310,6 +311,23 @@ extension WebViewController: WKNavigationDelegate {
let vc = SFSafariViewController(url: url)
self.present(vc, animated: true)
}
} else if components?.scheme == "mailto" {
decisionHandler(.cancel)
guard let emailAddress = components?.url?.emailAddress else {
return
}
if MFMailComposeViewController.canSendMail() {
let mailComposeViewController = MFMailComposeViewController()
mailComposeViewController.setToRecipients([emailAddress])
mailComposeViewController.mailComposeDelegate = self
self.present(mailComposeViewController, animated: true, completion: {})
} else {
let alert = UIAlertController(title: "Error", message: "This device cannot send emails.", preferredStyle: .alert)
alert.addAction(.init(title: "Dismiss", style: .cancel, handler: nil))
self.present(alert, animated: true, completion: nil)
}
} else {
decisionHandler(.allow)
}
@ -666,3 +684,10 @@ private extension WebViewController {
}
}
// MARK: MFMailComposeViewControllerDelegate
extension WebViewController: MFMailComposeViewControllerDelegate {
func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
self.dismiss(animated: true, completion: nil)
}
}