diff --git a/App/Browser View/BrowserViewController.swift b/App/Browser View/BrowserViewController.swift index 656ca20..b27501c 100644 --- a/App/Browser View/BrowserViewController.swift +++ b/App/Browser View/BrowserViewController.swift @@ -51,6 +51,12 @@ class BrowserViewController: UIViewController } } + internal enum PreferredEmailSharingRecipient: String, CaseIterable { + case readLater = "Read Later" + case bookmark = "Bookmark" + case other = "Other…" + } + override var preferredStatusBarStyle: UIStatusBarStyle { .lightContent } internal var changingFocusToAutocompleteController = false @@ -270,7 +276,7 @@ class BrowserViewController: UIViewController // Email documentControls.emailView.addAction(UIAction { [unowned self] _ in - composeEmailForCurrentURL(fromViewController: documentControls) + queryPreferredEmailSharingRecipientForCurrentURL(fromViewController: documentControls) }, for: .touchUpInside) // Settings @@ -324,7 +330,24 @@ class BrowserViewController: UIViewController self.present(activityController, animated: true, completion: nil) } - internal func composeEmailForCurrentURL(fromViewController: UIViewController?) { + internal func queryPreferredEmailSharingRecipientForCurrentURL(fromViewController: UIViewController?) { + if let fromViewController = fromViewController { + fromViewController.dismiss(animated: false, completion: nil) + } + + let actionSheet = UIAlertController(title: "Select Preferred Recipient", message: nil, preferredStyle: .actionSheet) + for preferredRecipient in PreferredEmailSharingRecipient.allCases { + actionSheet.addAction(UIAlertAction(title: preferredRecipient.rawValue, style: .default, handler: { [unowned self] action in + actionSheet.dismiss(animated: true, completion: { [unowned self] in + composeEmailForCurrentURL(preferredRecipientSelection: preferredRecipient) + }) + })) + } + + present(actionSheet, animated: true, completion: nil) + } + + internal func composeEmailForCurrentURL(preferredRecipientSelection: PreferredEmailSharingRecipient) { guard let url = self.webView.url else { return } let composeController = MFMailComposeViewController() @@ -332,10 +355,22 @@ class BrowserViewController: UIViewController composeController.setMessageBody(url.absoluteString, isHTML: false) composeController.mailComposeDelegate = self - if let fromViewController = fromViewController { - fromViewController.dismiss(animated: false, completion: nil) + let preferredRecipient: String? = { preferredRecipientSelection in + switch preferredRecipientSelection { + case .readLater: + return "read@buzzert.net" + case .bookmark: + return "bookmarks@buzzert.net" + case .other: + return nil + } + }(preferredRecipientSelection) + + if let preferredRecipient = preferredRecipient { + composeController.setToRecipients([ preferredRecipient ]) } + present(composeController, animated: true, completion: nil) } diff --git a/App/Hacks/MFMailComposeViewControllerFix.m b/App/Hacks/MFMailComposeViewControllerFix.m new file mode 100644 index 0000000..35283dc --- /dev/null +++ b/App/Hacks/MFMailComposeViewControllerFix.m @@ -0,0 +1,33 @@ +// +// MFMailComposeViewControllerFix.c +// App +// +// Created by James Magahern on 5/25/21. +// + +#import +#import +#import + +@interface MFMailComposeViewController (InternalMethods) ++ (BOOL)canSendMailSourceAccountManagement:(NSInteger)sourceAccountManagement; +@end + +static void swizzleClassMethod(Class targetClass, SEL originalSelector, IMP replacementIMP) +{ + Method originalMethod = class_getClassMethod(targetClass, originalSelector); + method_setImplementation(originalMethod, replacementIMP); +} + +__attribute__((constructor)) +static void swizzleMFMailComposeViewController() +{ + // Hacks to work around the fact that MFMailComposeViewController is broken in iOS 14+ + swizzleClassMethod(MFMailComposeViewController.class, @selector(canSendMail), imp_implementationWithBlock(^BOOL(void) { + return YES; + })); + + swizzleClassMethod(MFMailComposeViewController.class, @selector(canSendMailSourceAccountManagement:), imp_implementationWithBlock(^BOOL(NSInteger sam) { + return YES; + })); +} diff --git a/SBrowser.xcodeproj/project.pbxproj b/SBrowser.xcodeproj/project.pbxproj index 212b881..fb180b8 100644 --- a/SBrowser.xcodeproj/project.pbxproj +++ b/SBrowser.xcodeproj/project.pbxproj @@ -47,6 +47,7 @@ CD7A8915251975B70075991E /* AutocompleteViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD7A8914251975B70075991E /* AutocompleteViewController.swift */; }; CD7A89172519872D0075991E /* KeyboardShortcuts.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD7A89162519872D0075991E /* KeyboardShortcuts.swift */; }; CD7A8919251989C90075991E /* UIKeyCommand+ConvInit.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD7A8918251989C90075991E /* UIKeyCommand+ConvInit.swift */; }; + CD7F2135265DAD010001D042 /* MFMailComposeViewControllerFix.m in Sources */ = {isa = PBXBuildFile; fileRef = CD7F2134265DAD010001D042 /* MFMailComposeViewControllerFix.m */; }; CD853BCE24E7763900D2BDCC /* BrowserHistory.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD853BCD24E7763900D2BDCC /* BrowserHistory.swift */; }; CD853BD124E778B800D2BDCC /* History.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = CD853BCF24E778B800D2BDCC /* History.xcdatamodeld */; }; CD853BD424E77BF900D2BDCC /* HistoryItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD853BD324E77BF900D2BDCC /* HistoryItem.swift */; }; @@ -141,6 +142,7 @@ CD7A8914251975B70075991E /* AutocompleteViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutocompleteViewController.swift; sourceTree = ""; }; CD7A89162519872D0075991E /* KeyboardShortcuts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyboardShortcuts.swift; sourceTree = ""; }; CD7A8918251989C90075991E /* UIKeyCommand+ConvInit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIKeyCommand+ConvInit.swift"; sourceTree = ""; }; + CD7F2134265DAD010001D042 /* MFMailComposeViewControllerFix.m */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; path = MFMailComposeViewControllerFix.m; sourceTree = ""; }; CD853BCD24E7763900D2BDCC /* BrowserHistory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrowserHistory.swift; sourceTree = ""; }; CD853BD024E778B800D2BDCC /* History.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = History.xcdatamodel; sourceTree = ""; }; CD853BD324E77BF900D2BDCC /* HistoryItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HistoryItem.swift; sourceTree = ""; }; @@ -266,6 +268,7 @@ 1A03810E24E71CCA00826501 /* Common UI */, CDCE2662251AA7FC007FE92A /* Document Controls UI */, 1AD3104125254FA300A4A952 /* Find on Page */, + CD7F2133265DACEE0001D042 /* Hacks */, CDC5DA3C25DB7A5500BA8D99 /* Reader View */, 1ADFF4CE24CBBCBD006DC7AE /* Script Policy UI */, CDE6A30225F023A000E912A4 /* Settings */, @@ -372,6 +375,14 @@ path = Autocomplete; sourceTree = ""; }; + CD7F2133265DACEE0001D042 /* Hacks */ = { + isa = PBXGroup; + children = ( + CD7F2134265DAD010001D042 /* MFMailComposeViewControllerFix.m */, + ); + path = Hacks; + sourceTree = ""; + }; CD853BD224E77BEF00D2BDCC /* History */ = { isa = PBXGroup; children = ( @@ -561,6 +572,7 @@ CDE6A30625F023EA00E912A4 /* SettingsView.swift in Sources */, 1AB88EFD24D3BA560006F850 /* TabController.swift in Sources */, 1ADFF4C324CA6AF6006DC7AE /* Geometry.swift in Sources */, + CD7F2135265DAD010001D042 /* MFMailComposeViewControllerFix.m in Sources */, CDAD9CE8263A2DF200FF7199 /* DocumentControlsView.swift in Sources */, 1ADFF4C924CA793E006DC7AE /* ToolbarViewController.swift in Sources */, CD7A89172519872D0075991E /* KeyboardShortcuts.swift in Sources */,