Swift3的许多问题:无法理解完成处理程序的新语法

时间:2016-09-24 12:47:28

标签: swift xcode swift3 ios10 xcode8

昨天我更新了新的Mac OS X Sierra和XCode 8,迫使我更新为Swift 3.0语法。在我的应用程序中,我有许多功能,如下所示:

fileprivate func requestFisheFieldWithHandler(_ url:String, completionHandler: @escaping (_ success: NSDictionary?, _ error: NSError?) -> Void) {

    let configuration = URLSessionConfiguration.default

    let url: URL = URL(string: url)!
    let urlRequest: URLRequest = URLRequest(url: url)

    let session = URLSession(configuration: configuration)

    let task = session.dataTask(with: urlRequest, completionHandler: { (data: Foundation.Data?, response: URLResponse?, error: NSError?) -> Void in

        if (error != nil) {
            //print(error?.code)
            //print(error)
            completionHandler(success: nil, error: error)
        }

        else {
            do {
                let responseJSON = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions()) as! [String: String]
                completionHandler(success: responseJSON, error:nil)
            }
            catch let error as NSError {
                completionHandler(success: nil, error:error)
            }
        }
    } as! (Data?, URLResponse?, Error?) -> Void)

    task.resume()
}

我收到此错误:

  

“无法转换类型的值'(数据?,URLResponse?,错误?) - > Void'到预期的参数类型'(数据?,URLResponse?,错误?) - > Void'”

此外,我还使用了许多关联数组来从下载的JSON文件中收集数据,如下所示:

for comune in response! {
                        self.comuni.append(comune["nome"] as! String)
                        self.comuniWithID[comune["nome"] as! String] = Int(comune["idcomune"] as! String)
}
DispatchQueue.main.async {
    self.myPicker.reloadComponent(1)
}

我得到的另一个错误是:

  

“输入'NSFastEnumerationIterator.Element'(又名'Any')没有下标成员”

拜托,有人会帮我纠正吗?因为我无法理解他们的意思,我的应用程序将于9月30日发布...

2 个答案:

答案 0 :(得分:5)

最重要的变化是在Swift 3中删除了闭包中的所有参数标签。

这是你的代码Swift 3兼容。

与往常一样,不要将Swift集合类型强制转换为Foundation对象。你将丢弃所有类型的信息。

并且不要在完成块返回值中使用注释,编译器可以推断出类型。如果您需要在符号上查找实际类型⌥-单击

fileprivate func requestFisheFieldWithHandler(_ url:String, completionHandler: @escaping ([String: String]?, NSError?) -> Void) {

  let configuration = URLSessionConfiguration.default

  let url: URL = URL(string: url)!
  let urlRequest = URLRequest(url: url)

  let session = URLSession(configuration: configuration)

  let task = session.dataTask(with: urlRequest) { (data, response, error) -> Void in
    if (error != nil) {
      completionHandler(nil, error as NSError?)
    }

    else {
      do {
        let responseJSON = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions()) as! [String: String]
        completionHandler(responseJSON, nil)
      }
      catch let error as NSError {
        completionHandler(nil, error)
      }
    }
  }
  task.resume()
}

关于第二个错误,您必须将response!转换为比Any更有意义的内容,我猜... in response as! [[String:Any]]

答案 1 :(得分:1)

Swift 3中dataTask(with:completionHandler:)的完成处理程序已更改为completionHandler: @escaping (Data?, URLResponse?, Error?) -> Void,因此请使用Error代替NSError

let task = session.dataTask(with: urlRequest, completionHandler: { (data: Data?, response: URLResponse?, error: Error?) -> Void in

有关完成处理程序的更多信息,请检查Apple Documentation

为您的错误

  

键入' NSFastEnumerationIterator.Element' (又名'任何')没有下标成员"

您需要指定对[[String:Any]]的回复类型,然后全部恢复正常。

if let array = response as? [[String: Any]] {
    for comune in array {
        self.comuni.append(comune["nome"] as! String)
        self.comuniWithID[comune["nome"] as! String] = Int(comune["idcomune"] as! String)
    }
}