Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift 3 URLSession.shared() Ambiguous reference to member 'dataTask(with:completionHandler:) error (bug)

Tags:

json

ios

swift3

Hello I have working json parsing code for swift2.2 but when i use it for Swift 3.0 gives me that error

ViewController.swift:132:31: Ambiguous reference to member 'dataTask(with:completionHandler:)'

My codes here

   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()

Thanks for ideas.

like image 601
SwiftDeveloper Avatar asked Jun 14 '16 12:06

SwiftDeveloper


5 Answers

The compiler is confused by the function signature. You can fix it like this:

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

But, note that we don't have to cast "request" as URLRequest in this signature if it was declared earlier as URLRequest instead of NSMutableURLRequest:

var request = URLRequest(url:myUrl!)

This is the automatic casting between NSMutableURLRequest and the new URLRequest that is failing and which forced us to do this casting here.

like image 165
Eric Aya Avatar answered Nov 04 '22 03:11

Eric Aya


You have init'd myRequest as NSMutableURLRequest, you need this:

var URLRequest

Swift is ditching both the NSMutable... thing. Just use var for the new classes.

like image 32
HenryRootTwo Avatar answered Nov 04 '22 04:11

HenryRootTwo


Xcode 8 and Swift 3.0

Using 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 Delegate call:

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){

}

Using Block 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()

Working fine for me.. try it 100% result guarantee

like image 17
Saumil Shah Avatar answered Nov 04 '22 04:11

Saumil Shah


This problem is caused by URLSession has two dataTask methods

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

The first one has URLRequest as parameter, and the second one has URL as parameter, so we need to specify which type to call, for example, I want to call the second method

let task = URLSession.shared.dataTask(with: url! as URL) {
    data, response, error in
    // Handler
}
like image 15
liwp_Stephen Avatar answered Nov 04 '22 04:11

liwp_Stephen


In my case error was in NSURL

let url = NSURL(string: urlString)

In Swift 3 you must write just URL:

let url = URL(string: urlString)
like image 10
Zhanserik Avatar answered Nov 04 '22 04:11

Zhanserik