Swift - 简化或重构转义闭包?闭包可以重复使用吗?
Swift - Simplifying or refactoring an escaping closure? Can a closure be reusable?
我很好奇是否有办法简化/使闭包可重用?我在这里问了一个更深入的问题:Swift - Refactoring code. Closure and inout? 及其相同的代码。
我想做的是让这个闭包成为一行:
self.feedbackManager?.send(on: self) { [weak self] result in
switch result {
case .failure(let error):
print("error: ", error.localizedDescription)
case .success(_):
print("Success")
}
self?.feedbackManager = nil
}
feedbackManager
是 class 的实例,它在 self.viewController
上呈现 MFMailComposeViewController
。 result
是 MFMailComposeResult
。即闭包中的result
。
那么理想情况下,它可以这样称呼吗?
self.feedbackManager?.send(on: self) { switchResultClosure }
编辑:结果
实施:
let feedback = Feedback(subject: "subject", body: "body", footer: "footer")
sendEmail(with: feedback, on: self)
Class:
import UIKit
import MessageUI
struct Feedback {
let recipients = [R.App.Contact.email]
let subject: String
let body: String
let footer: String
}
enum SendStatus: Int {
case sent, cancelled, failed, notSupported, saved
}
protocol FeedbackProtocol {
func sendEmail(with feedback: Feedback, on viewController: UIViewController)
}
extension FeedbackProtocol {
func sendEmail(with feedback: Feedback, on viewController: UIViewController) {
print("protocol FeedbackController: sendEmail()")
ShareController.shared.sendMailToRecipients(with: feedback, on: viewController) { (SendStatus) in
print("SendStatus: ", SendStatus)
}
}
}
final class ShareController: NSObject {
static var shared = ShareController()
var completionBlock: ((SendStatus) -> Void)?
private override init() { }
}
extension ShareController: MFMailComposeViewControllerDelegate {
func sendMailToRecipients(with feedback: Feedback, on viewController: UIViewController, block: @escaping (SendStatus) -> Void) {
print("sendMailToRecipients()")
guard MFMailComposeViewController.canSendMail() else {
block(.notSupported)
return
}
var appVersion = ""
if let version = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String {
appVersion = version
}
completionBlock = block
let mailController = MFMailComposeViewController()
mailController.mailComposeDelegate = self
mailController.mailComposeDelegate = self
mailController.setToRecipients(feedback.recipients)
mailController.setSubject(feedback.subject)
mailController.setMessageBody((feedback.body), isHTML: true)
DispatchQueue.main.async {
viewController.present(mailController, animated: true, completion: nil)
}
}
func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
print("mailComposeController(): ShareVC")
controller.dismiss(animated: true)
switch result {
case .sent: completionBlock?(.sent)
case .cancelled: completionBlock?(.cancelled)
case .failed: completionBlock?(.failed)
case .saved: completionBlock?(.saved)
default: break
}
}
}
是的,您可以通过创建与闭包具有相同参数的函数来实现。
调用下面的函数。而不是在发送中编写闭包,只需键入 switchResultClosure 即可。语法可能不准确。
func switchResultClosure(result: ResultDataType) {
// switch code
switch result {
case let .failure(error):
print("error: ", error.localizedDescription)
case .success:
print("Success")
}
self?.feedbackManager = nil
}
feedbackManager?.send(on: self, switchResultClosure)
我很好奇是否有办法简化/使闭包可重用?我在这里问了一个更深入的问题:Swift - Refactoring code. Closure and inout? 及其相同的代码。
我想做的是让这个闭包成为一行:
self.feedbackManager?.send(on: self) { [weak self] result in
switch result {
case .failure(let error):
print("error: ", error.localizedDescription)
case .success(_):
print("Success")
}
self?.feedbackManager = nil
}
feedbackManager
是 class 的实例,它在 self.viewController
上呈现 MFMailComposeViewController
。 result
是 MFMailComposeResult
。即闭包中的result
。
那么理想情况下,它可以这样称呼吗?
self.feedbackManager?.send(on: self) { switchResultClosure }
编辑:结果
实施:
let feedback = Feedback(subject: "subject", body: "body", footer: "footer")
sendEmail(with: feedback, on: self)
Class:
import UIKit
import MessageUI
struct Feedback {
let recipients = [R.App.Contact.email]
let subject: String
let body: String
let footer: String
}
enum SendStatus: Int {
case sent, cancelled, failed, notSupported, saved
}
protocol FeedbackProtocol {
func sendEmail(with feedback: Feedback, on viewController: UIViewController)
}
extension FeedbackProtocol {
func sendEmail(with feedback: Feedback, on viewController: UIViewController) {
print("protocol FeedbackController: sendEmail()")
ShareController.shared.sendMailToRecipients(with: feedback, on: viewController) { (SendStatus) in
print("SendStatus: ", SendStatus)
}
}
}
final class ShareController: NSObject {
static var shared = ShareController()
var completionBlock: ((SendStatus) -> Void)?
private override init() { }
}
extension ShareController: MFMailComposeViewControllerDelegate {
func sendMailToRecipients(with feedback: Feedback, on viewController: UIViewController, block: @escaping (SendStatus) -> Void) {
print("sendMailToRecipients()")
guard MFMailComposeViewController.canSendMail() else {
block(.notSupported)
return
}
var appVersion = ""
if let version = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String {
appVersion = version
}
completionBlock = block
let mailController = MFMailComposeViewController()
mailController.mailComposeDelegate = self
mailController.mailComposeDelegate = self
mailController.setToRecipients(feedback.recipients)
mailController.setSubject(feedback.subject)
mailController.setMessageBody((feedback.body), isHTML: true)
DispatchQueue.main.async {
viewController.present(mailController, animated: true, completion: nil)
}
}
func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
print("mailComposeController(): ShareVC")
controller.dismiss(animated: true)
switch result {
case .sent: completionBlock?(.sent)
case .cancelled: completionBlock?(.cancelled)
case .failed: completionBlock?(.failed)
case .saved: completionBlock?(.saved)
default: break
}
}
}
是的,您可以通过创建与闭包具有相同参数的函数来实现。 调用下面的函数。而不是在发送中编写闭包,只需键入 switchResultClosure 即可。语法可能不准确。
func switchResultClosure(result: ResultDataType) {
// switch code
switch result {
case let .failure(error):
print("error: ", error.localizedDescription)
case .success:
print("Success")
}
self?.feedbackManager = nil
}
feedbackManager?.send(on: self, switchResultClosure)