NSURLSession中500错误的响应数据在哪里?

时间:2016-07-21 07:23:01

标签: nsurlsession nshttpurlresponse

我的iOS应用程序中有以下Swift代码:

session?.dataTaskWithRequest(urlRequest, completionHandler: { (data, response, error) -> Void in
    if let httpResponse = response as? NSHTTPURLResponse {
        var dataString:String?
        if data != nil {
            // Print the response as a string
            dataString = String(data: data!, encoding: NSUTF8StringEncoding)!
            if RequestManager.verbose { print("Response data: \(dataString)") }
        } else {
            if RequestManager.verbose { print("Response data: \(response?.description)") }
        }
        //[...]

当对Web服务API的调用成功时,这可以正常工作:response!.statusCode已正确设置,并且传递给完成处理程序的data可以从JSON解析为有用的对象。

但是,当服务器响应是错误时,例如500,然后data是零字节,我只能看到标题信息,而不是响应的主体。

以下是使用代理应用程序Charles从模拟器收集的示例响应:

  

HTTP / 1.1 500内部服务器错误
  转移编码:分块
  服务器:Microsoft-IIS / 8.0
  X-Powered-By:ASP.NET
  Set-Cookie:ARRAffinity = 00000000000000000000888888888888888888888888aaaaaaaaaaaaaaaaaaaa; Path = /; Domain = blah-testing.azurewebsites.net
  日期:星期四,2016年7月21日05:57:44 GMT

     

{“ExceptionType”:“异常”,“消息”:“不在你的Nelly上”,“StackTrace”:“在D:\ Users \ timregan \ Source \ Repos \中的Blah.Controllers.CustomersController.Get() ServerSideCode \ Blah \ ApiControllers \ CustomersController.cs:第37行\ r \ n在lambda_method(Closure,Object,Object [])\ r \ n在Microsoft.AspNetCore.Mvc.Internal.ObjectMethodExecutor.Execute(Object target,Object []参数)\ r \ n在Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.d__28.MoveNext()\ r \ n ---从抛出异常的上一个位置的堆栈跟踪结束--- \ r \ n在系统中。 Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.d__18.MoveNext()\ r \ n中的Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\ r \ n.n ---从抛出异常的上一个位置开始的堆栈跟踪结束--- \ r \ n在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)\ r \ n,在System.Runtime.Com上的System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)\ r \ n pilerServices.TaskAwaiter.GetResult()\ r \ n在Microsoft.AspNetCore.Builder.RouterMiddleware.d__4.MoveNext()\ r \ n ---从先前位置抛出异常的堆栈跟踪结束--- \ r \ n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)\ r \ n在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)\ r \ n在System.Runtime.CompilerServices.TaskAwaiter.GetResult()\ r \ n \ n在Microsoft.AspNetCore.Authentication.AuthenticationMiddleware 1.<Invoke>d__18.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware 1.d__18.MoveNext()\ r \ n ---从抛出异常的上一个位置的堆栈跟踪结束--- \ r \ n在系统中。在Blah.Startup的System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)\ r \ n的Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)\ r \ n。&lt;&gt; c。&lt; b__6_0&gt; d。 D:\ Users \ timregan \ Source \ Repos \ ServerSideCode \ Blah \ Startup.cs中的MoveNext():第59行“,”StatusCode“:500}

但是在Xcode中,同样的反应却少得多。标题元素都在NSHTTPURLResponse对象中,但dataTaskWithRequest完成处理程序的其他参数没有任何内容:data为零字节,errornil 。哪里有响应的主体与服务器错误堆栈跟踪消失了?如何在Swift中访问它?

1 个答案:

答案 0 :(得分:1)

IIRC,默认情况下,NSURLSession在获得非200标题后停止请求数据,因此它不会浪费时间下载您可能不需要的正文数据。

如果您想每次实际检索身体数据:

  • 实施in_array委托方法,并始终返回URLSession:dataTask:didReceiveResponse:completionHandler:
  • 实施NSURLSessionResponseAllow方法并使其完成处理程序始终将URLSession:task:willPerformHTTPRedirection:newRequest:completionHandler:作为新请求传递,以便不会重定向重定向。

认为应该足够了,除非我忘记了某处的其他委托方法。