【问题标题】:Swift - Simplifying or refactoring an escaping closure? Can a closure be reusable?Swift - 简化或重构转义闭包?闭包可以重复使用吗?
【发布时间】:2020-09-09 00:18:23
【问题描述】:

我很好奇是否有办法简化/使闭包可重用?我在这里问了一个更深入的问题: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 是一个类的实例,它在self.viewController 上呈现一个MFMailComposeViewControllerresultMFMailComposeResult。这是闭包中的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
        }
    }
}

【问题讨论】:

  • 你不能把switch语句提取到一个函数中并调用那个函数吗?或者你想这样做,但不知道怎么做?
  • 我想这样做,但不知道怎么做。

标签: ios swift closures mfmailcomposeviewcontroller


【解决方案1】:

是的,您可以通过创建与闭包具有相同参数的函数来实现。 调用下面的函数。而不是在发送中编写闭包,只需键入不带括号的 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)

【讨论】:

  • 谢谢!这给了我一些工作!如果您不介意,我在我现在使用的代码中进行了编辑。它工作正常,但我很好奇上面是否有任何可疑之处?
  • 你不觉得简单的邮件功能代码太多了吗?您可以做的是创建共享实例类。创建 sendEmail 方法以发送电子邮件并以相同的方法获取邮件发送状态。
  • 看看我创建的这个简单的类。 ibb.co/61Yr4hs
  • 我确实认为这是很多代码。但它的代码比以前少了! - 我已经搞砸了这个代码大约一个月了。虽然这仍然是一项工作和进步,但我必须说我从中学到了很多东西。 - 尤其是闭包,感谢您的帮助。 - 我现在正在看你做的课程,所以一旦我有机会尝试一下,我会回来的!
  • 谢谢!我想我已经成功了!我用更新的代码重新编辑了最初的帖子。这是我所拥有的和你建议的混合!
猜你喜欢
  • 2018-05-05
  • 2015-03-04
  • 2017-01-29
  • 2019-02-13
  • 1970-01-01
  • 2015-08-07
  • 2018-03-16
  • 2021-12-20
  • 2017-01-23
相关资源
最近更新 更多