【问题标题】:NSURLSessionUploadTask how to read server responseNSURLSessionUploadTask 如何读取服务器响应
【发布时间】:2016-08-08 14:20:53
【问题描述】:

我正在使用 NSURLSessionUploadTask 上传文件。

我的代码有些部分不完整

let session:NSURLSession = NSURLSession(configuration: config, delegate: self, delegateQueue: NSOperationQueue .mainQueue())

let sessionTask:NSURLSessionUploadTask = session.uploadTaskWithStreamedRequest(request

但问题是我无法获得服务器发回的 JSON 响应。

以下委托也未触发,但其他委托正在触发

func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveData data: NSData)

我正在使用的代码:

func sendFileToServer1(fileName:String,fileData:NSData,serverURL:String){

let body = NSMutableData()

let mimetype = "application/octet-stream"
//        let mimetype = "video/quicktime"

let boundary = "Boundary-\(NSUUID().UUIDString)"
let url = NSURL(string: serverURL)

let request = NSMutableURLRequest(URL: url!)
request.HTTPMethod = "POST"
request.setValue("multipart/form-data; boundary=----\(boundary)", forHTTPHeaderField: "Content-Type")
body.appendData("------\(boundary)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("Content-Disposition:form-data; name=\"file\"; filename=\"\(fileName)\"\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("Content-Type: \(mimetype)\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData(fileData)
body.appendData("\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("------\(boundary)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("Content-Disposition:form-data; name=\"submit\"\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("Submit\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("------\(boundary)--\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
request.HTTPBody=body

let config:NSURLSessionConfiguration = NSURLSessionConfiguration.defaultSessionConfiguration()
let session:NSURLSession = NSURLSession(configuration: config, delegate: self, delegateQueue: NSOperationQueue .mainQueue())
let sessionTask:NSURLSessionUploadTask = session.uploadTaskWithStreamedRequest(request)
sessionTask.resume()
}

func URLSession(session: NSURLSession, didBecomeInvalidWithError error: NSError?) {
    print("error")
 }

func URLSession(session: NSURLSession, task: NSURLSessionTask, didSendBodyData bytesSent: Int64, totalBytesSent: Int64, totalBytesExpectedToSend: Int64) {
    print("Bytes sent:\(bytesSent) Total bytes sent:\(totalBytesSent) Total bytes expected to send:\(totalBytesExpectedToSend)")
}

func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveResponse response: NSURLResponse, completionHandler: (NSURLSessionResponseDisposition) -> Void) {
    print("response:\(response as! NSHTTPURLResponse)")
}

func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveData data: NSData) {
    print("data didReceiveData")
}

我已遵从代表

  1. NSURLSessionDataDelegate
  2. NSURLSessionDelegate
  3. NSURLSessionTaskDelegate

谢谢

【问题讨论】:

  • 据我所知,在上传任务中,无法读取服务器响应数据....我们可以获取服务器响应标头字段,但不能获取服务器发送的有效负载数据。如果我错了
  • 还有哪些代表被解雇了?
  • func URLSession(session: NSURLSession, task: NSURLSessionTask, didSendBodyData bytesSent: Int64, totalBytesSent: Int64, totalBytesExpectedToSend: Int64) {
  • 分享更多代码

标签: ios json nsurlsession nsurlsessionuploadtask server-response


【解决方案1】:

如果您在创建请求时创建数据,则不应使用uploadTaskWithStreamedRequest:。这是为了上传大量数据,您需要从文件中读取数据并一次编码一点,一次发送一点。 (如前所述,如果这样做,您必须提供 needNewBodyStream 方法。)

很有可能,您应该使用 uploadTaskWithRequest:fromData: 并将主体数据 blob 作为 fromData 参数提供。

您也不需要在请求中设置正文数据。 NSURLSession 通常会忽略它。

你也可以考虑uploadTaskWithRequest:fromData:completionHandler:,它可以让你指定一个块在上传完成时运行整个数据,从而使你不必提供一个委托方法来积累数据。

【讨论】:

  • 那么在这种情况下,我可以获得上传的百分比以及响应负载数据吗?
  • 认为当您使用完成处理程序时,上传的委托方法仍然会触发。但即使他们不这样做,NSURLSession 任务也完全支持键值观察,因此您始终可以观察任务上 countOfBytesSentcountOfBytesExpectedToSend 属性的变化,并在任何时候重新计算上传百分比这些值的变化。
【解决方案2】:

由于NSURLSessionUploadTaskNSURLSessionDataTask 的子类,您可以尝试使用NSURLSessionDataDelegate 中的方法:

func urlSession(_ session: NSURLSession, dataTask: NSURLSessionDataTask, didReceive response: NSURLResponse, completionHandler: (NSURLSession.ResponseDisposition) -> Void)

根据文档:

告诉代理数据任务收到了来自服务器的初始回复(标头)。

【讨论】:

  • 我无法获取服务器发回的 JSON 数据...我找不到任何其他方法可以提供服务器发回的 json 数据
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-15
  • 1970-01-01
  • 2015-02-21
  • 2014-10-06
  • 2012-04-03
  • 2015-05-23
相关资源
最近更新 更多