Swift 在哪里使用dataTaskWithRequest方法?

Swift 在哪里使用dataTaskWithRequest方法?,swift,nsurlsession,Swift,Nsurlsession,我知道上面的用法 public func dataTaskWithRequest(request: NSURLRequest, completionHandler: (NSData?, NSURLResponse?, NSError?) -> Void) -> NSURLSessionDataTask 但是这种方法的用途是什么呢?我对它的用法感到困惑。我看到的所有示例都使用第一种方法。该方法不返回任何数据、要处理的错误或任何响应?或者是您以某种方式将其封装为任务,然后在队列中运行

我知道上面的用法

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

但是这种方法的用途是什么呢?我对它的用法感到困惑。我看到的所有示例都使用第一种方法。该方法不返回任何数据、要处理的错误或任何响应?或者是您以某种方式将其封装为任务,然后在队列中运行

如果为自定义
NSURLSession
指定了委托,则使用后一种方法。数据不会返回到闭包,而是会话调用您的代理的
didReceiveData
,您必须单独实现

不过,实现委托方法需要做更多的工作,所以通常只在绝对必要的情况下才这样做(例如,您希望在数据进入时处理数据,而不是等待所有数据进入;您需要委托方法来自定义重定向和质询的处理;您正在使用下载或上载任务而不是数据任务执行后台
NSURLSession
;等等)


例如,要发出一个简单的GET请求,需要JSON响应,您可以定义您的类以符合,并且可以选择(在Objective-C和Swift 2中分别称为
NSURLSessionDelegate
NSURLSessionDataDelegate
NSURLSessionTaskDelegate
),然后在Swift 3中执行以下操作:

public func dataTaskWithRequest(request: NSURLRequest) -> NSURLSessionDataTask 
或者,在Swift 2中:

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)")
    }
}
显然,除非您也需要一些更复杂的委托方法,否则您不会这样做,但我想展示一个最低限度的实现(这有助于我们欣赏完成处理程序的格式副本)

直接在完成处理程序中返回
数据
响应
错误


URLSessionDataDelegate
协议一起使用。需要实现几个方法。在几个阶段中,调用委托方法来处理数据


协议方法提供了对加载过程的更精细的控制,例如处理凭据请求和重定向控制。

没有完成处理程序进行加载有什么好处?1)实时流是“处理数据时进来”的一个好例子吗?2) 在一个班级里有多个任务会有点困难吗?我的意思是,您必须在每个委托方法中继续使用if语句。3)
DidReceiveData
方法只是在任务进入时基本上消耗任务,而
didCompleteWithError
则是在任务完成后做什么?4) “您希望在数据进入时进行处理”1。是的,流媒体协议就是一个很好的例子,尽管我们不必经常这么做。2.在一个类中处理多个请求并不难,但无可否认,这比完成处理程序模式要麻烦得多。3.是的,这是一种常见的模式,在
didReceiveData
中捕获数据(要么附加到
data
对象,要么流到
OutputStream
),然后在
didComplete
中启动后处理。4.是的,再次感谢。我不明白你为什么要有一个警卫和一个捕手。为什么需要两层错误处理?我实际上有三层。
error
对象的
guard
用于确保没有基本的网络错误(例如,没有互联网连接等)。
NSJSONSerialization
guard
是为了防止web服务器响应的JSON不是字典(这是极不可能的,也不是我们经常担心的错误)。捕获是为了防止响应根本不是JSON(例如,web服务器报告了一些错误,如404-未找到资源)。因此,第一个和第三个错误超出了我们的控制范围,必须进行检查。第二个由你决定。
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)")
    }
}
public func dataTaskWithRequest(request: NSURLRequest, completionHandler: (NSData?, NSURLResponse?, NSError?) -> Void) -> NSURLSessionDataTask
public func dataTaskWithRequest(request: NSURLRequest) -> NSURLSessionDataTask