【问题标题】:iOS Swift Networking LayeriOS Swift 网络层
【发布时间】:2019-01-16 06:46:46
【问题描述】:

所以我正在关注一个 git repo 来处理网络请求。我已经成功地将它实现到我的应用程序中,followed guide

我在我的SignInController 中调用SignInOperation 如下:SignInOperation(email: email, password: password).start() 所以这个repo 的设置方式主要是处理RequestOperation 中的成功和失败,如下所示:

import Foundation

public class SignInOperation: ServiceOperation {

    private let request: SignInRequest

    public var success: ((SignInItem) -> Void)?
    public var failure: ((NSError) -> Void)?

    public init(email: String, password: String, service: BackendService = MyBackendService(BackendConfiguration.shared)) {
        request = SignInRequest(email: email, password: password)
        super.init(service: service)
    }

    public override func start() {
        super.start()
        service.request(request, success: handleSuccess, failure: handleFailure)
    }

    private func handleSuccess(_ response: Any?) {
        do {
            let item = try SignInResponseMapper.process(response)
            self.success?(item)
            self.finish()
        } catch {
            handleFailure(NSError.cannotParseResponse())
        }
    }

    private func handleFailure(_ error: NSError) {
        self.failure?(error)
        self.finish()
    }
}

主要是我想做的事情是这样的:

SignInOperation(email: email, password: password).start().then(
  // handleResponse
)

甚至不一定是那样。但只是一种我可以在我的控制器而不是网络文件中处理响应的方法。任何建议或想法将不胜感激。如果有人认为有必要,我绝对可以分享更多代码。

PS。我特别尝试遵循这种处理您的Network Requests 的设计,因为我正在构建一个更大规模的社交应用程序。因此,我想要一些可维护、可扩展和可测试的东西。

【问题讨论】:

  • 您可以将回调引用保留在 SignInOperation 中,并在一切完成后调用。我想推荐你使用Alamofire。这将节省您的时间。
  • 我试图远离像Alamofire 这样的东西。我正在使用URLSession 作为回报,我认为它可以为您提供与Alamofire 相同的功能和易于实施,并且不是第三方依赖项。但是,我遵循提供的指南的原因是因为我试图通过一种完全可测试、可扩展和可维护的方式来处理我的Network Layer,我认为你可以通过Alamofire 获得一些东西。
  • 您需要查看PromiseKit。我建议将其包含在您的项目中。即使您不想添加依赖项,仍然值得检查实现,以便您可以采用这个概念并以自己的方式编写它。
  • 我不确定您为什么认为 3rd 方库不可测试、不可扩展和不可维护。但是如果你想自己实现,你只需要在你的类中保留一个回调闭包的引用。

标签: ios swift networking callback closures


【解决方案1】:

操作成功和错误状态被传递给闭包调用闭包来处理。希望下面的代码对你有所帮助。

 class Test : UIViewController{

let mail = "abc@xyz.com"
let password = "******"

var operation : SignInOperation?

override func viewDidLoad() {
    super.viewDidLoad()

    operation = SignInOperation(email: mail, password: password)
    operation?.failure = { error in
        print(error.localizedDescription)
        // handle failure over here
    }

    operation?.success = { item in
        // handle success here
        // you can use data from item which is an Instance of SignInItem over here
    }
  }
}

【讨论】:

  • 我认为这是一个非常好的答案。在接受它作为最终答案之前,我将等待潜在的其他建议或想法。但是实例化类对象然后引用它的回调属性似乎是处理这个问题的正确方法。谢谢你的回答。
猜你喜欢
  • 1970-01-01
  • 2020-05-07
  • 2012-10-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多