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 上呈现 MFMailComposeViewControllerresultMFMailComposeResult。即闭包中的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)