未得到服务器响应,ios-如何在未完成的情况下获取NSURLSession中的服务器响应数据…

一些想法:

首先,使用NSURLSessionDelegate实例化您的会话,因为后台会话必须有一个委托:

NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:kSessionIdentifier];

self.session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];

其次,在没有完成处理程序的情况下实例化NSURLSessionDelegate,因为添加到后台会话的任务无法使用完成块。 另请注意,我使用的是文件网址,而不是completionHandler:

NSURLSessionTask *task = [self.session uploadTaskWithRequest:request fromFile:fileURL];

[task resume];

第三,实施相关的委托方法。 至少看起来像:

- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {

NSMutableData *responseData = self.responsesData[@(dataTask.taskIdentifier)];

if (!responseData) {

responseData = [NSMutableData dataWithData:data];

self.responsesData[@(dataTask.taskIdentifier)] = responseData;

} else {

[responseData appendData:data];

}

}

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {

if (error) {

NSLog(@"%@ failed: %@", task.originalRequest.URL, error);

}

NSMutableData *responseData = self.responsesData[@(task.taskIdentifier)];

if (responseData) {

// my response is JSON; I don't know what yours is, though this handles both

NSDictionary *response = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:nil];

if (response) {

NSLog(@"response = %@", response);

} else {

NSLog(@"responseData = %@", [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding]);

}

[self.responsesData removeObjectForKey:@(task.taskIdentifier)];

} else {

NSLog(@"responseData is nil");

}

}

请注意,以上代码利用了先前实例化的NSURLSessionDelegate(称为completionHandler)的优势(因为,令我非常恼火的是,这些“任务”委托方法是在“会话”级别完成的)。

最后,您要确保定义一个属性来存储completionHandler提供的NSURLSessionDelegate:

@property (nonatomic, copy) void (^backgroundSessionCompletionHandler)(void);

显然,让您的应用程序代表响应NSURLSessionDelegate,保存completionHandler,该方法将在下面的URLSessionDidFinishEventsForBackgroundURLSession方法中使用。

- (void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)())completionHandler {

// This instantiates the `NSURLSession` and saves the completionHandler.

// I happen to be doing this in my session manager, but you can do this any

// way you want.

[SessionManager sharedManager].backgroundSessionCompletionHandler = completionHandler;

}

然后确保您的NSURLSessionDelegate在后台会话完成后在主线程上调用此处理程序:

- (void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session {

if (self.backgroundSessionCompletionHandler) {

dispatch_async(dispatch_get_main_queue(), ^{

self.backgroundSessionCompletionHandler();

self.backgroundSessionCompletionHandler = nil;

});

}

}

仅当某些上传在后台完成时才调用。

正如您所看到的,有一些移动的部分,但这基本上是必需的。

THE END
< <上一篇
下一篇>>