【问题标题】:try-catch inside closure -> Invalid conversion from throwing to non-throwing function type闭包内的 try-catch -> 从抛出到非抛出函数类型的无效转换
【发布时间】:2017-12-04 01:31:51
【问题描述】:

我已经用 throws 标记了我的函数,为什么 swift 强制我使用 do-try-catch 块?

我想处理我在下面调用此函数时引发的任何类型的错误。

static func getPosts() throws {

    let url = URL(string: "https://jsonplaceholder.typicode.com/posts/1")
    let request = URLRequest(url: url!)

    let session = URLSession.shared
    session.dataTask(with: request) { (data, response, error) in

        let json = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableLeaves) as! [String: Any]  

    }.resume()        
}

下面是我遇到的错误的屏幕截图。

【问题讨论】:

标签: ios swift error-handling try-catch


【解决方案1】:

你的throws 是说你的getPosts() 函数本身会抛出。但是,它在调用闭包之前就完成了,这意味着即使json解析抛出异常,你已经过了可以捕获和处理异常的时间。

闭包中的错误必须在闭包中处理。您正在寻找类似

static func getPosts(completion: @escaping (_ error: String) -> Void) {

    let url = URL(string: "https://jsonplaceholder.typicode.com/posts/1")
    let request = URLRequest(url: url!)

    let session = URLSession.shared
    session.dataTask(with: request) { (data, response, error) in
        do {
            let json = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableLeaves) as! [String: Any]
            completion("ok")
        }catch let error {
            print(error)
            completion("error")
        }

    }.resume()        
}

【讨论】:

    【解决方案2】:

    不可能从闭包中捕获错误。

    一个合适的解决方案是一个枚举和一个完成处理程序

    enum PostResult {
        case success([String:Any]), failure(Error)
    }
    
    func getPosts(completion:@escaping (PostResult)->() ) {
    
        let url = URL(string: "https://jsonplaceholder.typicode.com/posts/1")!
        // no URLRequest needed !
        let session = URLSession.shared
        session.dataTask(with: url) { (data, response, error) in
            if let error = error { 
                completion(.failure(error)) 
                return
            }
            do {
                let json = try JSONSerialization.jsonObject(with: data!) as! [String: Any]
                completion(.success(json))
            } catch {
                completion(.failure(error))
            }
    
        }.resume()
    }
    

    并使用它

    getPosts { result in
        switch result {
        case .success(let json): print(json)
             // process json 
        case .failure(let error): print(error)
             // handle error
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多