从NSUrlConnection迁移至NSUrlSession时GET请求的两类异常问题咨询
从NSURLConnection切换到NSURLSession的问题解决思路
嘿,我之前在从NSURLConnection迁移到NSURLSession时也踩过类似的坑,给你拆解下这两个问题的解决办法:
问题1:DidReceiveData返回的数据被截断
这其实是NSURLSession的正常行为——didReceiveData:会被多次调用,每次返回的只是当前接收到的部分数据,而不是整个响应体。你不能直接用单次回调里的NSData来处理,必须把这些片段拼接起来,直到请求完成。
解决步骤:
- 在你的类中声明一个可变数据容器,用来存储所有接收到的片段:
@property (nonatomic, strong) NSMutableData *totalReceivedData;
- 在发起请求前初始化这个容器:
// 初始化数据任务前 self.totalReceivedData = [NSMutableData data];
- 在
didReceiveData:中拼接数据:
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data { [self.totalReceivedData appendData:data]; // 这里不要尝试解析数据!等全部接收完再处理 }
- 在请求完成的回调中处理完整数据:
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error { if (!error) { // 这里的totalReceivedData就是完整的响应内容 NSString *fullResponseString = [[NSString alloc] initWithData:self.totalReceivedData encoding:NSUTF8StringEncoding]; // 接下来用这个完整字符串处理XML解析 } else { NSLog(@"请求出错: %@", error.localizedDescription); } // 清空容器,避免影响下一次请求 self.totalReceivedData = nil; }
问题2:处理数据时DidCompleteWithError被调用且error为null
这也是NSURLSession的设计逻辑:didCompleteWithError:是请求生命周期的结束回调,不管请求成功还是失败都会触发。当error为null时,说明请求已经成功完成,所有数据都已经通过didReceiveData:传递完毕了。
你之前可能误解了这个方法的作用——它不是只有出错时才会调用,而是用来通知你请求已经结束,是时候处理最终结果(或者错误)的地方。正确的流程就是:在didReceiveData:中只做数据拼接,在didCompleteWithError:中做最终的解析和业务处理。
额外注意事项
- 如果你的XML解析需要完整的数据源,推荐使用
NSXMLParser,把拼接好的totalReceivedData传给它,不要尝试用部分数据解析,否则会导致XML格式错误。 - 确保你的NSURLSession配置合理,比如设置了足够长的超时时间,避免大响应体还没接收完就被判定超时。
内容的提问来源于stack exchange,提问作者Tobe
相关产品推荐
相关产品推荐

