iOS NSURLSessionのピット(The data couldn’t be read because it isn’t in the correct format)
4141 ワード
概要
#pragma mark -
- (void)test{
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:delegateObject delegateQueue:[NSOperationQueue mainQueue]];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:@"api.com"];
request.HTTPBody = para//
NSURLSessionTask *task = [session dataTaskWithRequest:request];
[task resume];
}
#pragma mark - NSURLSessionDelegate method
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler
{
DeLog(@"1。 %s",__FUNCTION__);
completionHandler(NSURLSessionResponseAllow);
}
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
{
NSError *error;
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:self.recevieData options:NSJSONReadingMutableLeaves error:&error];
if (error)
{
NSLog(@"initSDK error === %@",error.localizedDescription);
}
}
-(void)URLSession:(NSURLSession *)session didBecomeInvalidWithError:(NSError *)error{
}
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(nullable NSError *)error
{
[session finishTasksAndInvalidate];
}
印刷結果:
initSDK error === The data couldn’t be read because it isn’t in the correct format
ぶんせき
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
のdataは完全なデータではない場合がある.[NSByteCountFormatter stringFromByteCount:data countStyle:NSByteCountFormatterCountStyleFile]
印刷、完全data
=2KB
、エラーdata
=1KB
.data
=2KB
/data
=1KB
はランダムに現れる.data
は実はjson
で、それぞれdata
をNSDictionary
とNSString
に変えて、NSDictionary
=nil
で、NSString
は値がありますが、完全なjson
の一部data
=1KB
のとき、-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
は実際に2回呼び出されます.私は前後2回のdata
をつなぎ合わせて、ちょうど完全なjson
です.一方、data
=2KB
の場合、解決する
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
得られるdata
は必ずしも最終的なdata
ではなく、複数回呼び出される可能性がある以上、純粋で完全なjson
を得るためには、NSURLSessionDelegate
の多くの方法の中で呼び出さなければならない.また、要求プロセス全体が完了した後、最後に呼び出される方法であり、この方法はまだ1回しか呼び出されない.- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(nullable NSError *)error
はこの問題を完璧に解決した.通常、session
を放出するので、この方法にも含まれます.#pragma mark - NSURLSessionDelegate method
#pragma mark - , data
NSMutableData *_data;
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
{
if(_data)
{
_data = [[NSMutableData alloc] init];
}
[_data appendData:data];
}
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(nullable NSError *)error
{
#pragma _data, json
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:_data options:NSJSONReadingMutableLeaves error:&error];
[session finishTasksAndInvalidate];
}
data
=1KB
が発生しない場合