Swift-简化还是重构转义的闭包?封闭可以重用吗?

问题描述

我很好奇是否有一种方法可以简化/使封包可重用?我在这里问了一个更深入的问题: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一个类的实例,它在MFMailComposeViewController显示self.viewControllerresultMFMailComposeResult。闭包中的result

所以理想情况下,可以将其称为这样?

self.FeedbackManager?.send(on: self) { switchResultClosure }

修改:结果

实施:

let Feedback = Feedback(subject: "subject",body: "body",footer: "footer")
sendEmail(with: Feedback,on: self)

班级:

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
        }
    }
}

解决方法

是的,可以通过创建与闭包相同参数的函数来完成。 调用下面的函数。而不是在send中编写闭包,只需键入 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)