Chinthaka
Chinthaka

Reputation: 988

iOS queuing the upload tasks

In iOS I need to call same method number of time, but the app has to wait until the method completed it's first task. (I can not use bool value to check whether the function is running or not).

How can I queue the request or wait until it's previous task has finished? Is there a way I can use NSOperation or NSThread?

Thanks

This is my method I need to call multiple times

- (void)fetchJobs
{

    dispatch_queue_t queueLocal = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_group_t groupLocal = dispatch_group_create();

    UIApplication *app = [UIApplication sharedApplication];

    NSTimeInterval backgroundTime = app.backgroundTimeRemaining;
    NSLog(@"Background task remain time: %g seconds", (double)backgroundTime);


    [[NSNotificationCenter defaultCenter] postNotificationName:@"UPLOAD_PROCESS_START" object:nil];

    self.assetUpdateTaskID = [app beginBackgroundTaskWithExpirationHandler:^{
        dispatch_async(dispatch_get_main_queue(), ^{

            [self endTask];
        }); 
    }];

    dispatch_group_async(groupLocal, queueLocal, ^{

        NSEntityDescription *entity = [NSEntityDescription entityForName:@"Files" inManagedObjectContext:self.managedObjectContext];

        //Setup the fetch request
        NSFetchRequest *request = [[NSFetchRequest alloc] init];
        [request setEntity:entity];

        NSPredicate *predicate = [NSPredicate predicateWithFormat: @"uploaded like %@", [NSString stringWithFormat:@"0"]];
        [request setPredicate:predicate];

        NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"timeStamp" ascending:YES];
        [request setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]];

        NSError *error = nil;

        //fetch the records and handle an error
        NSArray *fetchResults = [self.managedObjectContext executeFetchRequest:request error:&error];


        if (fetchResults == nil) {
            NSLog(@"File Data fetching error : %@", [error localizedDescription]);
        }
        else{
            if ([fetchResults count] > 0) {            

                dispatch_apply([fetchResults count], queue, ^(size_t i){
                    NSLog(@"Loop count %zu", i);

                    Files *file = [fetchResults objectAtIndex:i]; 
                    self.manageObjectForFiles = file;
                    NSLog(@"Fetched File details -> Name: %@ & status: %@" , file.fileName, file.uploaded);                    

                    BOOL uploaded = [self filePosting:file.fileName];


                    if (uploaded) {

                        [self.managedObjectContext deleteObject:file];
                        NSError *error;

                        if (![self.managedObjectContext save:&error]) {
                            NSLog(@"File table update error : %@", [error description]);
                        }
                    }                     

                });
                /*
                for (int i = 0; i < [fetchResults count]; i++) {                    

                }*/
            }            
        }

        dispatch_async(dispatch_get_main_queue(), ^{

            [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;

            int remainJobs = [self fetchFileTableCount];
            if (remainJobs > 0) {

                [UIApplication sharedApplication].applicationIconBadgeNumber = remainJobs;
                [[NSNotificationCenter defaultCenter] postNotificationName:@"UPLOAD_REMAIN" object:nil];
            }
            else{
                [UIApplication sharedApplication].applicationIconBadgeNumber = 0;
                [[NSNotificationCenter defaultCenter] postNotificationName:@"UPLOAD_PROCESS_COMPLETED" object:nil];
                NSLog(@"-----------------------------------------------");
                NSLog(@"There are no more uploads");
                NSLog(@"-----------------------------------------------");
            }
            [self endTask];                                    

        });

    });

    dispatch_release(groupLocal);

}

Upvotes: 0

Views: 1259

Answers (1)

David Hoerl
David Hoerl

Reputation: 41642

You'd didn't say if the calls have to be serial of if they can be concurrent. If concurrent you can use NSOperation's mainQueue, suspend it, add all but the first call, then in your method, at the end, see if the queue is suspended and if so resume it.

With Grand Central Dispatch (CGD) you can more easily create a serial dispatch queue, and sort of do the same - suspend it, add all but the first call wrapped in a block, then at the end of the first call unsuspend the queue. If you need this to run on the main thread you can have the serial queue tied to the main GCD queue.

Upvotes: 1

Related Questions