1

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.

halfer
  • 19,824
  • 17
  • 99
  • 186
syedfa
  • 2,801
  • 1
  • 41
  • 74
  • Take a look at this tutorial: http://code.tutsplus.com/tutorials/ios-8-core-data-and-asynchronous-fetching--cms-22241 – Michał Ciuba Feb 07 '15 at 10:31
  • Thanks for your comment. I am familiar with that article, but unfortunately they don't give an example of canceling using NSProgress. – syedfa Feb 07 '15 at 23:08
  • Any progress on this? (No pun intended!) – 0xWood Apr 11 '15 at 17:18
  • Unfortunately no. I had to take an alternate approach to this issue. The solution I ended up using was provided in this solution: http://stackoverflow.com/questions/28730558/trying-to-implement-master-child-managed-object-context-when-doing-mass-delete-i – syedfa Apr 12 '15 at 17:32

0 Answers0