NSURLSession - 数据为零
NSURLSession - data is nil
我在尝试使用 NSURLSession 委托方法获取数据时遇到问题。我想出了这个错误:
"Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'data parameter is nil'"
我不明白的是
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite {
CGFloat percentDone = (double)totalBytesWritten/(double)totalBytesExpectedToWrite;
NSLog(@"Pourcentage: %f", percentDone);
}
正在返回 1.000000,调用了以下委托方法
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
// Parse the JSON that came in
NSLog(@"DidComplete"); --> I can see this message
if (error) {
NSLog(@"Error in finishLoading: %@", error.localizedDescription); --> but this message is not displayed. There is no error, only data returning nil resulting in a crash...
}
else {
....
}
但是没有调用下面的方法
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *) response completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler {
NSLog(@"DidReceiveResponse"); --> not displayed
completionHandler(NSURLSessionResponseAllow);
}
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {
NSLog(@"DidReceiveData. Data: %@", data); --> not displayed
_downloadedData = [[NSMutableData alloc] init];
[_downloadedData appendData:data];
}
但是它应该在 didCompleteWithError 之前调用,不是吗?我假设无法调用其他处理附加数据的方法,然后数据为零。
我确信我可以在服务器端获取数据,因为当我使用块方法(而不是委托方法)时,NSData 对应于我正在寻找的内容。
奇怪的是,我这样更改配置会话后出现此错误:
NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *defaultSession2 = [NSURLSession sessionWithConfiguration: defaultConfigObject delegate: self delegateQueue: [NSOperationQueue mainQueue]];
NSURL *url = [NSURL URLWithString:@"http://localhost:8888/download_list.php"];
NSURLSessionDownloadTask *dataTask = [defaultSession2 downloadTaskWithURL:url];
这样的时候,我可以看到从服务器获取的NSData
NSURLSessionDataTask *dataTask = [defaultSession2 dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if(error == nil) {
NSString * text = [[NSString alloc] initWithData:data encoding: NSUTF8StringEncoding];
NSLog(@"Data = %@",text); -> text corresponds to the data I am looking for
}
}];
然而,用块调用委托是不可能的。
知道 "data" 是如何消失的吗?或者我应该在不使用该块时更改一些东西?
感谢您的帮助!
如果您这样调用 dataTaskWithURL
,didReceiveResponse
和 didReceiveData
委托方法将不会被调用:
NSURLSessionDataTask *dataTask = [defaultSession2 dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
...
}];
您正在提供完成处理程序,请求它为您捕获 response
和 data
。因此,为此,它不会调用委托方法。
如果您希望调用委托方法,您应该:
NSURLSessionDataTask *dataTask = [defaultSession2 dataTaskWithURL:url];
不过,坦率地说,您目前没有在这些方法中做任何重要的事情,所以我想知道您为什么要使用委托方法而不是完成处理程序。完成处理程序模式更简单。
顺便说一下,如果您要使用这些方法,请确保 didReceiveData
仅附加。在 didReceiveResponse
中实例化可变数据对象。可能需要多次 didReceiveData
调用才能收到整个响应,并且您的原始代码示例会截断结果。您可能想做类似的事情:
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *) response completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler {
NSLog(@"DidReceiveResponse"); // will now be displayed
_downloadedData = [[NSMutableData alloc] init];
completionHandler(NSURLSessionResponseAllow);
}
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {
NSLog(@"DidReceiveData. Data: %@", data); // will now be displayed
[_downloadedData appendData:data];
}
我在尝试使用 NSURLSession 委托方法获取数据时遇到问题。我想出了这个错误:
"Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'data parameter is nil'"
我不明白的是
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite {
CGFloat percentDone = (double)totalBytesWritten/(double)totalBytesExpectedToWrite;
NSLog(@"Pourcentage: %f", percentDone);
}
正在返回 1.000000,调用了以下委托方法
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
// Parse the JSON that came in
NSLog(@"DidComplete"); --> I can see this message
if (error) {
NSLog(@"Error in finishLoading: %@", error.localizedDescription); --> but this message is not displayed. There is no error, only data returning nil resulting in a crash...
}
else {
....
}
但是没有调用下面的方法
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *) response completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler {
NSLog(@"DidReceiveResponse"); --> not displayed
completionHandler(NSURLSessionResponseAllow);
}
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {
NSLog(@"DidReceiveData. Data: %@", data); --> not displayed
_downloadedData = [[NSMutableData alloc] init];
[_downloadedData appendData:data];
}
但是它应该在 didCompleteWithError 之前调用,不是吗?我假设无法调用其他处理附加数据的方法,然后数据为零。
我确信我可以在服务器端获取数据,因为当我使用块方法(而不是委托方法)时,NSData 对应于我正在寻找的内容。
奇怪的是,我这样更改配置会话后出现此错误:
NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *defaultSession2 = [NSURLSession sessionWithConfiguration: defaultConfigObject delegate: self delegateQueue: [NSOperationQueue mainQueue]];
NSURL *url = [NSURL URLWithString:@"http://localhost:8888/download_list.php"];
NSURLSessionDownloadTask *dataTask = [defaultSession2 downloadTaskWithURL:url];
这样的时候,我可以看到从服务器获取的NSData
NSURLSessionDataTask *dataTask = [defaultSession2 dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if(error == nil) {
NSString * text = [[NSString alloc] initWithData:data encoding: NSUTF8StringEncoding];
NSLog(@"Data = %@",text); -> text corresponds to the data I am looking for
}
}];
然而,用块调用委托是不可能的。
知道 "data" 是如何消失的吗?或者我应该在不使用该块时更改一些东西?
感谢您的帮助!
如果您这样调用 dataTaskWithURL
,didReceiveResponse
和 didReceiveData
委托方法将不会被调用:
NSURLSessionDataTask *dataTask = [defaultSession2 dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
...
}];
您正在提供完成处理程序,请求它为您捕获 response
和 data
。因此,为此,它不会调用委托方法。
如果您希望调用委托方法,您应该:
NSURLSessionDataTask *dataTask = [defaultSession2 dataTaskWithURL:url];
不过,坦率地说,您目前没有在这些方法中做任何重要的事情,所以我想知道您为什么要使用委托方法而不是完成处理程序。完成处理程序模式更简单。
顺便说一下,如果您要使用这些方法,请确保 didReceiveData
仅附加。在 didReceiveResponse
中实例化可变数据对象。可能需要多次 didReceiveData
调用才能收到整个响应,并且您的原始代码示例会截断结果。您可能想做类似的事情:
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *) response completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler {
NSLog(@"DidReceiveResponse"); // will now be displayed
_downloadedData = [[NSMutableData alloc] init];
completionHandler(NSURLSessionResponseAllow);
}
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {
NSLog(@"DidReceiveData. Data: %@", data); // will now be displayed
[_downloadedData appendData:data];
}