处理Swift 2中异步关闭错误的最佳方法?

瓦西里

我正在使用大量异步网络请求(顺便说一下,iOS中的任何网络请求都需要通过异步),并且我正在寻找方法来更好地处理AppledataTaskWithRequest不支持的错误throws

我有这样的代码:

func sendRequest(someData: MyCustomClass?, completion: (response: NSData?) -> ()) {
    let request = NSURLRequest(URL: NSURL(string: "http://google.com")!)

    if someData == nil {
        // throw my custom error
    }

    let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
        data, response, error in

        // here I want to handle Apple's error
    }
    task.resume()
}

我需要解析可能的自定义错误,并处理来自的可能的连接错误dataTaskWithRequestSwift 2引入了throws,但是您不能从Apple的关闭中退出,因为它们不支持抛出并且运行异步。

我看到NSError返回添加到完成块的唯一方法,但是据我所知,这NSError是旧式的Objective-C方法。ErrorType只能与throws(afaik)一起使用。

使用Apple网络封包时处理错误的最佳和最现代的方法是什么?据我了解,没有办法在任何异步网络功能中都没有用处吗?

凯西

有很多方法可以解决此问题,但是我建议使用需要Result Enum的完成块这可能是最“快捷”的方式。

结果枚举恰好具有两个状态,成功和错误,这对于通常的两个可选返回值(数据和错误)有很大的好处,这两个返回值会导致4种可能的状态。

enum Result<T> {
    case Success(T)
    case Error(String, Int)
}

在完成块中使用结果枚举可解决难题。

let InvalidURLCode = 999
let NoDataCode = 998
func getFrom(urlString: String, completion:Result<NSData> -> Void) {
    // make sure the URL is valid, if not return custom error
    guard let url = NSURL(string: urlString) else { return completion(.Error("Invalid URL", InvalidURLCode)) }

    let request = NSURLRequest(URL: url)
    NSURLSession.sharedSession().dataTaskWithRequest(request) { data, response, error in
       // if error returned, extract message and code then pass as Result enum
        guard error == nil else { return completion(.Error(error!.localizedDescription, error!.code)) }

        // if no data is returned, return custom error
        guard let data = data else { return completion(.Error("No data returned", NoDataCode)) }

        // return success
        completion(.Success(data))
    }.resume()
}

因为返回值是一个枚举,所以应将其关闭。

getFrom("http://www.google.com") { result in
    switch result {
    case .Success(let data):
        // handle successful data response here
        let responseString = String(data:data, encoding: NSASCIIStringEncoding)
        print("got data: \(responseString)");
    case .Error(let msg, let code):
        // handle error here
        print("Error [\(code)]: \(msg)")
    }
}

另一种解决方案是传递两个完成模块,一个用于成功,一个用于错误。类似于以下内容:

func getFrom(urlString: String, successHandler:NSData -> Void, errorHandler:(String, Int) -> Void)

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章