From 7d17d851556e638a2b43aa2087aaa4ab22ca569c Mon Sep 17 00:00:00 2001 From: Alex Ivashko Date: Fri, 5 Jun 2020 00:13:16 +0300 Subject: [PATCH 1/2] Create MFMailComposeViewController Initial commit of MFMailComposeViewController --- Xcode/Closures.xcodeproj/project.pbxproj | 4 + .../Source/MFMailComposeViewController.swift | 76 +++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 Xcode/Closures/Source/MFMailComposeViewController.swift diff --git a/Xcode/Closures.xcodeproj/project.pbxproj b/Xcode/Closures.xcodeproj/project.pbxproj index f173d25..d30fa9e 100644 --- a/Xcode/Closures.xcodeproj/project.pbxproj +++ b/Xcode/Closures.xcodeproj/project.pbxproj @@ -27,6 +27,7 @@ 3FB77F311EE4DB5200C60F5C /* UITableViewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FB77F301EE4DB5200C60F5C /* UITableViewTests.swift */; }; 3FD393C61F9E583900DA155D /* UIBarButtonItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FD393C51F9E583900DA155D /* UIBarButtonItem.swift */; }; 3FD393C81F9E61A900DA155D /* UIBarButtonItemTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FD393C71F9E61A900DA155D /* UIBarButtonItemTests.swift */; }; + CC095542241EA9C0000125E1 /* MFMailComposeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC095541241EA9C0000125E1 /* MFMailComposeViewController.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -63,6 +64,7 @@ 3FB77F301EE4DB5200C60F5C /* UITableViewTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UITableViewTests.swift; sourceTree = ""; }; 3FD393C51F9E583900DA155D /* UIBarButtonItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIBarButtonItem.swift; sourceTree = ""; }; 3FD393C71F9E61A900DA155D /* UIBarButtonItemTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIBarButtonItemTests.swift; sourceTree = ""; }; + CC095541241EA9C0000125E1 /* MFMailComposeViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MFMailComposeViewController.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -89,6 +91,7 @@ children = ( 3F59C5681F1C32AA00945666 /* Core.swift */, 3F59C5691F1C32AA00945666 /* KVO.swift */, + CC095541241EA9C0000125E1 /* MFMailComposeViewController.swift */, 3F59C56A1F1C32AA00945666 /* UICollectionView.swift */, 3F59C56B1F1C32AA00945666 /* UIControl.swift */, 3F59C56C1F1C32AA00945666 /* UIGestureRecognizer.swift */, @@ -258,6 +261,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + CC095542241EA9C0000125E1 /* MFMailComposeViewController.swift in Sources */, 3F59C5731F1C32BF00945666 /* UICollectionView.swift in Sources */, 3F59C5741F1C32BF00945666 /* UIControl.swift in Sources */, 3F59C5721F1C32BF00945666 /* KVO.swift in Sources */, diff --git a/Xcode/Closures/Source/MFMailComposeViewController.swift b/Xcode/Closures/Source/MFMailComposeViewController.swift new file mode 100644 index 0000000..70b6c18 --- /dev/null +++ b/Xcode/Closures/Source/MFMailComposeViewController.swift @@ -0,0 +1,76 @@ +// +// File.swift +// +// +// Created by Alex Ivashko on 15.03.2020. +// + +import MessageUI + +@available(iOS 9.0, *) +class MailComposeDelegate: NSObject, MFMailComposeViewControllerDelegate, DelegateProtocol { + fileprivate static var delegates = Set>() + + fileprivate var didFinishWith: ((_ result: MFMailComposeResult, _ error: Error?) -> Void)? + func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) { + didFinishWith?(result, error) + } + + override func responds(to aSelector: Selector!) -> Bool { + switch aSelector { + case #selector(MailComposeDelegate.mailComposeController(_:didFinishWith:error:)): + return didFinishWith != nil + default: + return super.responds(to: aSelector) + } + } +} + +extension MFMailComposeViewController { + + public convenience init(subject: String, + toRecipients: [String]?, + ccRecipients: [String]?, + bccRecipients: [String]?, + body: (body: String, isHTML: Bool), + attachment: (data: Data, mimeType: String, fileName: String)) { + self.init() + setSubject(subject) + setToRecipients(toRecipients) + setCcRecipients(ccRecipients) + setBccRecipients(bccRecipients) + setMessageBody(body.body, isHTML: body.isHTML) + addAttachmentData(attachment.data, mimeType: attachment.mimeType, fileName: attachment.fileName) + } + + @available(iOS 9.0, *) + @discardableResult + public func didFinish(handler: @escaping (_ result: MFMailComposeResult, _ error: Error?) -> Void) -> Self { + update { $0.didFinishWith = handler } + } + +} + +@available(iOS 9.0, *) +extension MFMailComposeViewController: DelegatorProtocol { + @discardableResult + @objc func update(handler: (_ delegate: MailComposeDelegate) -> Void) -> Self { + DelegateWrapper.update(self, + delegate: MailComposeDelegate(), + delegates: &MailComposeDelegate.delegates, + bind: MFMailComposeViewController.bind) { + handler($0.delegate) + } + return self + } + + public func clearClosureDelegates() { + DelegateWrapper.remove(delegator: self, from: &MailComposeDelegate.delegates) + MFMailComposeViewController.bind(self, nil) + } + + fileprivate static func bind(_ delegator: MFMailComposeViewController, _ delegate: MailComposeDelegate?) { + delegator.mailComposeDelegate = nil + delegator.mailComposeDelegate = delegate + } +} From dedb334080746cbea15e742a706ed07f992a657f Mon Sep 17 00:00:00 2001 From: Alex Ivashko Date: Tue, 9 Jun 2020 22:33:28 +0300 Subject: [PATCH 2/2] Refactor init MFMailComposeViewController Fixed unit test --- .../Source/MFMailComposeViewController.swift | 45 ++++++++++++------- Xcode/ClosuresTests/UITableViewTests.swift | 2 +- 2 files changed, 29 insertions(+), 18 deletions(-) diff --git a/Xcode/Closures/Source/MFMailComposeViewController.swift b/Xcode/Closures/Source/MFMailComposeViewController.swift index 70b6c18..84160c4 100644 --- a/Xcode/Closures/Source/MFMailComposeViewController.swift +++ b/Xcode/Closures/Source/MFMailComposeViewController.swift @@ -1,5 +1,5 @@ // -// File.swift +// MFMailComposeViewController.swift // // // Created by Alex Ivashko on 15.03.2020. @@ -26,39 +26,50 @@ class MailComposeDelegate: NSObject, MFMailComposeViewControllerDelegate, Delega } } +@available(iOS 9.0, *) extension MFMailComposeViewController { - - public convenience init(subject: String, - toRecipients: [String]?, - ccRecipients: [String]?, - bccRecipients: [String]?, - body: (body: String, isHTML: Bool), - attachment: (data: Data, mimeType: String, fileName: String)) { + public convenience init?(subject: String? = nil, + toRecipients: [String]? = nil, + ccRecipients: [String]? = nil, + bccRecipients: [String]? = nil, + body: (body: String, isHTML: Bool)? = nil, + attachment: (data: Data, mimeType: String, fileName: String)? = nil, + handler: @escaping ((_ result: MFMailComposeResult, _ error: Error?) -> Void)) { + guard MFMailComposeViewController.canSendMail() else { + return nil + } self.init() - setSubject(subject) + if let subject = subject { + setSubject(subject) + } setToRecipients(toRecipients) setCcRecipients(ccRecipients) setBccRecipients(bccRecipients) - setMessageBody(body.body, isHTML: body.isHTML) - addAttachmentData(attachment.data, mimeType: attachment.mimeType, fileName: attachment.fileName) + if let body = body { + setMessageBody(body.body, isHTML: body.isHTML) + } + if let attachment = attachment { + addAttachmentData(attachment.data, mimeType: attachment.mimeType, fileName: attachment.fileName) + } + didFinish(handler: handler) } - @available(iOS 9.0, *) @discardableResult public func didFinish(handler: @escaping (_ result: MFMailComposeResult, _ error: Error?) -> Void) -> Self { update { $0.didFinishWith = handler } } - } @available(iOS 9.0, *) extension MFMailComposeViewController: DelegatorProtocol { @discardableResult @objc func update(handler: (_ delegate: MailComposeDelegate) -> Void) -> Self { - DelegateWrapper.update(self, - delegate: MailComposeDelegate(), - delegates: &MailComposeDelegate.delegates, - bind: MFMailComposeViewController.bind) { + DelegateWrapper.update( + self, + delegate: MailComposeDelegate(), + delegates: &MailComposeDelegate.delegates, + bind: MFMailComposeViewController.bind + ) { handler($0.delegate) } return self diff --git a/Xcode/ClosuresTests/UITableViewTests.swift b/Xcode/ClosuresTests/UITableViewTests.swift index fc40463..263893a 100644 --- a/Xcode/ClosuresTests/UITableViewTests.swift +++ b/Xcode/ClosuresTests/UITableViewTests.swift @@ -305,7 +305,7 @@ class UITableViewTests: XCTestCase { func testTableViewMethodExpectations() { let lastKnownDelegateCount: Int if #available(iOS 13, *) { - lastKnownDelegateCount = 49 + lastKnownDelegateCount = 48 } else { lastKnownDelegateCount = 41 }