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