Alexey K
Alexey K

Reputation: 6723

How to wait for finish dataTaskWithRequest?

How can I wait for finish of dataTaskWithRequest ? I need to perform some tasks after network fetch is completely over.

Upvotes: 5

Views: 10855

Answers (4)

vijay
vijay

Reputation: 165

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

Call this method like so:

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

Upvotes: 1

Dennis Pashkov
Dennis Pashkov

Reputation: 944

If you really need synchronous request, you can use semaphores.

I've implemented a small category on NSURLSession to provide this functionality.

In .h file:

@import Foundation.NSURLSession;

@interface NSURLSession (Additions)

+ (NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse **)response error:(NSError **)error;

@end

In .m file:

@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

Upvotes: 7

katleta3000
katleta3000

Reputation: 2494

I think, that method is obvious inside the class

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

Upvotes: 3

dirtydanee
dirtydanee

Reputation: 6151

lets just do your tasks in the completion block of dataTaskWithRequest. Until than you can display an activity indicator to block the user from touching anything on the screen.

Example:

activityIndicator.startAnimating()

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

});

Upvotes: 0

Related Questions