【问题标题】:Swift 3 URLSession.shared() Ambiguous reference to member 'dataTask(with:completionHandler:) error (bug)Swift 3 URLSession.shared() 对成员 'dataTask(with:completionHandler:) 错误(错误)的模糊引用
【发布时间】:2016-10-15 04:51:06
【问题描述】:

您好,我有用于 swift2.2 的 json 解析代码,但是当我将它用于 Swift 3.0 时,出现了该错误

ViewController.swift:132:31:对成员“dataTask(with:completionHandler:)”的模糊引用

我的代码在这里

   let listUrlString =  "http://bla.com?batchSize=" + String(batchSize) + "&fromIndex=" + String(fromIndex)
    let myUrl = URL(string: listUrlString);
    let request = NSMutableURLRequest(url:myUrl!);
    request.httpMethod = "GET";

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

        if error != nil {
            print(error!.localizedDescription)
            DispatchQueue.main.sync(execute: {
                AWLoader.hide()
            })

            return
        }

        do {

            let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSArray

            if let parseJSON = json {

                var items = self.categoryList

                items.append(contentsOf: parseJSON as! [String])

                if self.fromIndex < items.count {

                    self.categoryList = items
                    self.fromIndex = items.count

                    DispatchQueue.main.async(execute: {

                        self.categoriesTableView.reloadData()

                        AWLoader.hide()

                    })
                }else if( self.fromIndex == items.count){


                    DispatchQueue.main.async(execute: {

                        AWLoader.hide()

                    })

                }



            }

        } catch {
            AWLoader.hide()
            print(error)

        }
    }

    task.resume()

感谢您的想法。

【问题讨论】:

  • 我遇到了同样的错误,因为我正在将一个字符串传递给dataTask(with:,例如我有url = "www.yahoo.com,我直接将它传递给函数没有将它转换为URL

标签: ios json swift3


【解决方案1】:

编译器被函数签名弄糊涂了。你可以这样修复它:

let task = URLSession.shared.dataTask(with: request as URLRequest) {

但是,请注意,我们不必在此签名中将“请求”转换为 URLRequest如果它之前声明为 URLRequest 而不是 NSMutableURLRequest

var request = URLRequest(url:myUrl!)

这是NSMutableURLRequest 和新的URLRequest 之间的自动转换失败,迫使我们在这里进行此转换。

【讨论】:

  • var request = URLRequest(url:myUrl!)
  • SE-0072 说,移除隐式桥接。当“swifty function name”变成“de facto override method”时,我们无法反向查找Objective-C SEL,所以我们必须使用或强制转换为Foundation struct。
  • 非常有帮助的答案。我只想补充一点,最好避免使用 myUrl!通过这样做强制展开:guard let myUrl = URL(string:listUrlString) else { return } 然后可以在没有 ! 的情况下调用请求var request = URLRequest(url:myUrl)
  • URL(string:) 构造函数会失败吗?
  • 必须投票,但我仍然有问题,它输出“字符 0 周围的无效值”有人会吗?
【解决方案2】:

你已经将myRequest 初始化为NSMutableURLRequest,你需要这个:

var URLRequest

Swift 正在抛弃 NSMutable... 的东西。只需将var 用于新类即可。

【讨论】:

    【解决方案3】:

    Xcode 8 和 Swift 3.0

    使用 URLSession:

     let url = URL(string:"Download URL")!
     let req = NSMutableURLRequest(url:url)
     let config = URLSessionConfiguration.default
     let session = URLSession(configuration: config, delegate: self, delegateQueue: OperationQueue.main)
    
     let task : URLSessionDownloadTask = session.downloadTask(with: req as URLRequest)
    task.resume()
    

    URLSession 委托调用:

    func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
    
    }
    
    
    func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, 
    didWriteData bytesWritten: Int64, totalBytesWritten writ: Int64, totalBytesExpectedToWrite exp: Int64) {
                       print("downloaded \(100*writ/exp)" as AnyObject)
    
    }
    
    func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL){
    
    }
    

    使用块 GET/POST/PUT/DELETE:

     let request = NSMutableURLRequest(url: URL(string: "Your API URL here" ,param: param))!,
            cachePolicy: .useProtocolCachePolicy,
            timeoutInterval:"Your request timeout time in Seconds")
        request.httpMethod = "GET"
        request.allHTTPHeaderFields = headers as? [String : String] 
    
        let session = URLSession.shared
    
        let dataTask = session.dataTask(with: request as URLRequest) {data,response,error in
            let httpResponse = response as? HTTPURLResponse
    
            if (error != nil) {
             print(error)
             } else {
             print(httpResponse)
             }
    
            DispatchQueue.main.async {
               //Update your UI here
            }
    
        }
        dataTask.resume()
    

    对我来说工作得很好.. 试试吧 100% 结果保证

    【讨论】:

      【解决方案4】:

      这个问题是由于 URLSession 有两个 dataTask 方法造成的

      open func dataTask(with request: URLRequest, completionHandler: @escaping (Data?, URLResponse?, Error?) -> Swift.Void) -> URLSessionDataTask
      open func dataTask(with url: URL, completionHandler: @escaping (Data?, URLResponse?, Error?) -> Swift.Void) -> URLSessionDataTask
      

      第一个有URLRequest作为参数,第二个有URL作为参数,所以我们需要指定调用哪个类型,比如我要调用第二个方法

      let task = URLSession.shared.dataTask(with: url! as URL) {
          data, response, error in
          // Handler
      }
      

      【讨论】:

      • 确实有道理。谢谢
      【解决方案5】:

      在我的情况下,错误出现在 NSURL

      let url = NSURL(string: urlString)
      

      在 Swift 3 中你必须只写 URL

      let url = URL(string: urlString)
      

      【讨论】:

        【解决方案6】:

        经过测试的 xcode 8 稳定版; 需要将 var request 变量与 URLRequest() 一起使用,这样您就可以轻松修复该问题(bug

        var request = URLRequest(url:myUrl!)

        let task = URLSession.shared().dataTask(with: request as URLRequest) { }
        

        工作得很好!谢谢大家,我想帮助很多人。 !

        【讨论】:

        • 从 URLRequest 转换为 URLRequest 没有意义
        • var request = URLRequest(url: url); let task = URLSession.shared().dataTask(with: request) { ... }
        • shared 在 Swift 3 中是一个属性而不是一个函数(没有括号)。
        • @vadian 在我发表评论时没有
        【解决方案7】:

        对于 Swift 3 和 Xcode 8:

              var dataTask: URLSessionDataTask?
        
              if  let url = URL(string: urlString) {
                    self.dataTask = URLSession.shared.dataTask(with: url, completionHandler: { (data, response, error) in
        
                        if let error = error {
                            print(error.localizedDescription)
                        } else if let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200 {
                             // You can use data received.
                            self.process(data: data as Data?)
                        }
                    })
                }
             }
        

        //注意:您可以随时使用调试器检查错误

        【讨论】:

          【解决方案8】:

          在 swift 3 中,编译器被函数签名弄糊涂了。指定它将清除错误。还将 url 字符串转换为类型 URL。以下代码对我有用。

             let urlString = "http://bla.com?batchSize="
             let pathURL = URL(string: urlString)!
             var urlRequest = URLRequest(url:pathURL)
          
              let session = URLSession.shared
              let dataTask = session.dataTask(with: urlRequest as URLRequest) { (data,response,error) in
          

          【讨论】:

            【解决方案9】:

            Swift 3 的简短回答:

            guard let requestUrl = URL(string: yourURL) else { return }
            
            let request = URLRequest(url:requestUrl)
            URLSession.shared.dataTask(with: request) {
                (data, response, error) in
                ...
            
            }.resume()
            

            【讨论】:

              【解决方案10】:
               // prepare json data
                      let mapDict = [ "1":"First", "2":"Second"]
              
                      let json = [ "title":"ABC" , "dict": mapDict ] as [String : Any]
                      let jsonData : NSData = NSKeyedArchiver.archivedData(withRootObject: json) as NSData
              
                      // create post request
                      let url = NSURL(string: "http://httpbin.org/post")!
                      let request = NSMutableURLRequest(url: url as URL)
                      request.httpMethod = "POST"
              
                      // insert json data to the request
                      request.httpBody = jsonData as Data
              
              
                      let task = URLSession.shared.dataTask(with: request as URLRequest){ data,response,error in
                          if error != nil{
                              return
                          }
                          do {
                              let result = try JSONSerialization.jsonObject(with: data!, options: []) as? [String:AnyObject]
              
                              print("Result",result!)
              
                          } catch {
                              print("Error -> \(error)")
                          }
                      }
              
                      task.resume()
              

              【讨论】:

                【解决方案11】:

                要通过 GET 请求加载数据,您不需要任何 URLRequest(也不需要分号)

                let listUrlString =  "http://bla.com?batchSize=" + String(batchSize) + "&fromIndex=" + String(fromIndex)
                let myUrl = URL(string: listUrlString)!
                let task = URLSession.shared.dataTask(with: myUrl) { ...
                

                【讨论】:

                  【解决方案12】:
                  let task = URLSession.shared.dataTask(with: request as URLRequest, completionHandler: { data,response,error in
                          if error != nil{
                              print(error!.localizedDescription)
                              return
                          }
                          if let responseJSON = (try? JSONSerialization.jsonObject(with: data!, options: [])) as? [String:AnyObject]{
                              if let response_token:String = responseJSON["token"] as? String {
                                  print("Singleton Firebase Token : \(response_token)")
                                  completion(response_token)
                              }
                          }
                      })
                      task.resume()
                  

                  【讨论】:

                    【解决方案13】:

                    Xcode 10.1 斯威夫特 4

                    这对我有用:

                    let task: URLSessionDataTask = session.dataTask(with: request as URLRequest) { (data, response, error) -> Void in
                    ...
                    

                    关键是在URLSessionDataTask 类型声明中添加。

                    【讨论】:

                      【解决方案14】:

                      我这样做是为了找到,

                      let url = URL(string: urlString)
                      URLSession.shared.dataTask(with: url!) { (data, response, error) in ...}
                      

                      无法使用

                      "let url = NSURL(string: urlString)
                      

                      【讨论】:

                        猜你喜欢
                        • 2023-03-04
                        • 2018-04-02
                        • 2023-03-25
                        • 1970-01-01
                        • 2020-02-22
                        • 2019-11-17
                        • 1970-01-01
                        • 2016-05-01
                        相关资源
                        最近更新 更多