【发布时间】:2015-10-15 12:15:20
【问题描述】:
如何等待dataTaskWithRequest 的完成?网络抓取完全结束后,我需要执行一些任务。
【问题讨论】:
标签: ios asynchronous nsurlsession
如何等待dataTaskWithRequest 的完成?网络抓取完全结束后,我需要执行一些任务。
【问题讨论】:
标签: ios asynchronous nsurlsession
如果确实需要同步请求,可以使用信号量。
我在NSURLSession 上实现了一个小类别来提供此功能。
在 .h 文件中:
@import Foundation.NSURLSession;
@interface NSURLSession (Additions)
+ (NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse **)response error:(NSError **)error;
@end
在 .m 文件中:
@implementation NSURLSession (Additions)
+ (NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse *__autoreleasing *)responsePointer error:(NSError *__autoreleasing *)errorPointer
{
dispatch_semaphore_t semaphore;
__block NSData *result = nil;
semaphore = dispatch_semaphore_create(0);
void (^completionHandler)(NSData * __nullable data, NSURLResponse * __nullable response, NSError * __nullable error);
completionHandler = ^(NSData * __nullable data, NSURLResponse * __nullable response, NSError * __nullable error)
{
if ( errorPointer != NULL )
{
*errorPointer = error;
}
if ( responsePointer != NULL )
{
*responsePointer = response;
}
if ( error == nil )
{
result = data;
}
dispatch_semaphore_signal(semaphore);
};
[[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:completionHandler] resume];
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
return result;
}
@end
【讨论】:
我认为,该方法在类中很明显
NSURLSessionDataTask *task = [defaultSession dataTaskWithRequest:request
completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error)
{
// code after completion of task
}];
[task resume];
【讨论】:
- (void) loginRequest:(NSString*) username withPassword:(NSString *) password callback:(void (^)(NSError *error, BOOL success))callback
{
NSURLSessionDataTask *dataTask = [self.session dataTaskWithRequest:request
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error){
if (error) {
// Handle error, optionally using
callback(error, NO);
}
else {
callback(nil, YES);
}
}];
[dataTask resume];
}
像这样调用这个方法:
[self loginRequest:@"myUsername" password:@"password" callback:^(NSError *error, BOOL success) {
if (success) {
NSLog(@"My response back from the server after an unknown amount of time");
}
else {
NSLog(@"%@", error);
}
}];
【讨论】:
让我们在 dataTaskWithRequest 的完成块中完成您的任务。 直到您可以显示活动指示器以阻止用户触摸屏幕上的任何内容。
例子:
activityIndicator.startAnimating()
let task : NSURLSessionDataTask = session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in
activityIndicator.stopAnimating()
// do your stuff here
});
【讨论】: