Trying to cancel on Asynchronous Fetch with NSProgress using Core Data in iOS 8

1k Views Asked by At

I am working on iOS application using Core Data where I am fetching results from Core Data asynchronously. I need to figure out a way to implement a cancellation function of this fetch in case the user decides that they have been waiting too long, and wish to cancel the fetch part way through. I know this is possible using Core Data in iOS 8 using NSProgress, but I can't find any examples or sample code on how to do this.

Here is my sample fetch method:

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"MyObject"];
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"read == %@", @(NO)];

NSPersistentStoreAsynchronousFetchResultCompletionBlock resultBlock = ^(NSAsynchronousFetchResult *result) {
   NSLog(@"Number of Unread Items: %ld", (long)result.finalResult.count);   

   [result.progress removeObserver:self
                        forKeyPath:@"completedUnitCount"
                           context:ProgressObserverContext];

   [result.progress removeObserver:self
                        forKeyPath:@"totalUnitCount"
                           context:ProgressObserverContext];
};

NSAsynchronousFetchRequest *asyncFetch = [[NSAsynchronousFetchRequest alloc]
                                          initWithFetchRequest:fetchRequest
                                          completionBlock:resultBlock];

[context performBlock:^{
    //Assumption here is that we know the total in advance and supply it to the NSProgress instance
    NSProgress *progress = [NSProgress progressWithTotalUnitCount:preComputedCount];
    [progress becomeCurrentWithPendingUnitCount:1];

    NSAsynchronousFetchResult *result = (NSAsynchronousFetchResult *)[context 
                                                               executeRequest:asyncFetch 
                                                                        error:nil];

    [result.progress addObserver:self
                 forKeyPath:@"completedUnitCount"
                    options:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew
                    context:ProgressObserverContext];

    [result.progress addObserver:self
                 forKeyPath:@"totalUnitCount"
                    options:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew
                    context:ProgressObserverContext];

    [progress resignCurrent];
}];

I realize that by cancelling my fetch using NSProgress, I through an NSUserCancelled Error, but again, I would like to see an example of how this is done.

0

There are 0 best solutions below