如何等待完成dataTaskWithRequest?

时间:2015-10-15 12:15:21

标签: ios asynchronous nsurlsession

我如何等待dataTaskWithRequest完成?我需要在网络提取完全结束后执行一些任务。

4 个答案:

答案 0 :(得分:5)

如果您确实需要同步请求,则可以使用信号量

我在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

答案 1 :(得分:4)

我认为,这种方法在课堂内是显而易见的

NSURLSessionDataTask *task = [defaultSession dataTaskWithRequest:request
                                               completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error)
{
    // code after completion of task
}];
[task resume];

答案 2 :(得分:2)

- (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);
    }
}];

答案 3 :(得分:1)

让我们在dataTaskWithRequest的完成块中完成您的任务。 在此之前,您可以显示活动指示器以阻止用户触摸屏幕上的任何内容。

示例:

activityIndicator.startAnimating()

let task : NSURLSessionDataTask = session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in
   activityIndicator.stopAnimating()
  // do your stuff here

});