Honey Honey - 1 month ago 15
Swift Question

Where is dataTaskWithRequest method used?

public func dataTaskWithRequest(request: NSURLRequest, completionHandler: (NSData?, NSURLResponse?, NSError?) -> Void) -> NSURLSessionDataTask


I know the usage method of above.

public func dataTaskWithRequest(request: NSURLRequest) -> NSURLSessionDataTask


But what is the usage of this method? I'm confused about how it is used.All examples I see are using the first method. The method returns no data, no error to handle, nor any response? Or is that you somehow envelope this as a task and later run in a queue?

Rob Rob
Answer

You use this latter method if you've specified a delegate for a custom NSURLSession. The data is not returned to the closure, but rather the session calls your delegate's didReceiveData, which you have to implement separately.

It takes more work to implement the delegate methods, though, so you generally only do that where you absolutely have to (e.g. you want to process data as it comes in rather than waiting for all of the data to come in; you need delegate methods for custom handling of redirects and challenges; you are doing background NSURLSession with download or upload tasks rather than data tasks; etc.).


For example, to issue a simple GET request, expecting JSON response, you might define your class to conform to NSURLSessionDelegate and NSURLSessionDataDelegate and then do something like the following in Swift 3:

var responseData: Data?

func performRequest() {
    let url = URL(string: "http://ip.jsontest.com/")!
    var request = URLRequest(url: url)
    request.setValue("application/json", forHTTPHeaderField: "Accept")
    let configuration = URLSessionConfiguration.default
    let session = URLSession(configuration: configuration, delegate: self, delegateQueue: nil)
    responseData = Data()
    let task = session.dataTask(with: request)
    task.resume()
}

func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
    responseData!.append(data)
}

func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
    guard error == nil else {
        print(error!)
        return
    }

    do {
        guard let jsonObject = try JSONSerialization.jsonObject(with: responseData!) as? [String: AnyObject] else {
            print("response was not JSON dictionary")
            print("responseString: \(String(data: responseData!, encoding: .utf8))")
            return
        }

        print(jsonObject)
    } catch let parseError {
        print("JSON Error: \(parseError)")
    }
}

Or, in Swift 2:

var responseData: NSMutableData?

func performRequest() {
    let url = NSURL(string: "http://ip.jsontest.com/")!
    let request = NSMutableURLRequest(URL: url)
    request.setValue("application/json", forHTTPHeaderField: "Accept")
    let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
    let session = NSURLSession(configuration: configuration, delegate: self, delegateQueue: nil)
    responseData = NSMutableData()
    let task = session.dataTaskWithRequest(request)
    task.resume()
}

func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveData data: NSData) {
    responseData!.appendData(data)
}

func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError error: NSError?) {
    guard error == nil else {
        print(error!)
        return
    }

    do {
        guard let jsonObject = try NSJSONSerialization.JSONObjectWithData(responseData!, options: []) as? [String: AnyObject] else {
            print("response was not JSON dictionary")
            print("responseString: \(String(data: responseData!, encoding: NSUTF8StringEncoding))")
            return
        }

        print(jsonObject)
    } catch let parseError {
        print("JSON Error: \(parseError)")
    }
}