从dataTask completeHandler引发错误

Way*_*eio 5 swift nsurlsessiondatatask

如何迅速在这样的完成处理程序中引发错误:

    let task = URLSession.shared.dataTask(with: request as URLRequest, completionHandler: {
        (data, response, error) in
        do {
            //something
            completion(result)
        } catch let jsonError {
            throw CustomError.myerror //THIS DOESN'T WORK
        }
    })
    task.resume()
Run Code Online (Sandbox Code Playgroud)

因为错误是

从类型为((_,_,_)的throwing函数将->()无效转换为非抛出函数类型为'(Data ?, URLResponse ?, Error?)-> Void'

vad*_*ian 13

简单地说:你不能throwdataTask完成关闭

您可以在完成处理程序中返回两个值

...completion: @escaping (ResultType?, Error?)->Void
Run Code Online (Sandbox Code Playgroud)

然后返回

completion(result, nil)
completion(nil, CustomError.myerror)
Run Code Online (Sandbox Code Playgroud)

或更方便地使用具有关联类型的枚举

enum Result {
    case success(ResultType), failure(Error)
}

...completion: @escaping (Result)->Void
Run Code Online (Sandbox Code Playgroud)

然后返回

completion(.success(result))
completion(.failure(CustomError.myerror))
Run Code Online (Sandbox Code Playgroud)

您可以处理结果

foo() { result in
    switch result {
    case .success(let resultType): // do something with the result
    case .failure(let error): // Handle the error
    }
}
Run Code Online (Sandbox Code Playgroud)

更新:

在使用新的内置Result类型的Swift 5中,它更加舒适,因为它Result可以捕获throwing表达式的结果

...completion: @escaping (Result<MyType,Error>)->Void

let task = URLSession.shared.dataTask(with: request as URLRequest, completionHandler: {
    (data, response, error) in

    completion(Result { try something()})
})
task.resume()
Run Code Online (Sandbox Code Playgroud)