1

I'm using iCloud document service to sync two devices. In code, I have added NSMetadataQueryDidFinishGatheringNotification and NSMetadataQueryDidUpdateNotification. But the NSMetadataQueryDidUpdateNotification has never been called.

code:

- (void)loadGrocery{
  //0. initialize NSMetadataQuery
  self.query = [[NSMetadataQuery alloc] init];
  //1. set its searchScopes to iCloud's Document directories
  [self.query setSearchScopes:[NSArray arrayWithObject:NSMetadataQueryUbiquitousDocumentsScope]];
  //2. set its predicate (match certain file name)
  NSPredicate *pred = [NSPredicate predicateWithFormat:@"%K LIKE 'Item_*'",NSMetadataItemFSNameKey];
  [self.query setPredicate:pred];

  //3.1 add notification when NSMetadataQuery finished gathering
  [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(queryDidFinishGathering:) name:NSMetadataQueryDidFinishGatheringNotification object:self.query];
  //3.2 add notification when NSMEtadataQuery detects a update
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(queryDidFinishUpdating:) name:NSMetadataQueryDidUpdateNotification object:self.query];
  //4. start query
  [self.query startQuery];
}

//3.1 handle the notification when NSMetadataQuery finished gathering
-(void)queryDidFinishGathering:(NSNotification *) notification{
  NSLog(@"query did finish gathering");
  //1. query: disable and stop
  [self.query disableUpdates];
  [self.query stopQuery];
  //2. query: remove the observer
  [[NSNotificationCenter defaultCenter] removeObserver:self name:NSMetadataQueryDidFinishGatheringNotification object:self.query];
  //3. query: handle the result
  [self loadData:self.query];
  [self.query startQuery];
}

//3.2 handle the notification when NSMetadataQuery finish updating
-(void)queryDidFinishUpdating:(NSNotification *)notification{
  NSLog(@"query did finish updating");
  [self.query stopQuery];
  [self loadData:self.query];
  [self.query startQuery];
}

the insertNewObject method is as following, which save to iCloud file, thus updates should occur after this.

- (void)insertNewObject:(id)sender {
NSLog(@"insertNewObject");
GroceryItem *newGroceryItem = [GroceryItem createNewItem];
[newGroceryItem saveToURL:[newGroceryItem fileURL] forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success) {
    if(success){
        NSLog(@"save newGroceryItem success");
    [newGroceryItem openWithCompletionHandler:^(BOOL success) {
        if(success){
            NSLog(@"open newGroceryItem success");
            [self.objects insertObject:newGroceryItem atIndex:0];
            NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
            [self.tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
        }else{
            NSLog(@"open newGroceryItem failed");
        }
    }];}
    else{
        NSLog(@"open newGroceryItem failed");
    }
}];

}

in this code, I need to load data only one time when I receive NSMetadataQueryDidFinishGatheringNotification. Thus I remove the observer for this notification. But for NSMetadataQueryDidUpdateNotification, the method -(void)queryDidFinishUpdating:(NSNotification *)notification is never called when I run on two different devices(iCloud both enabled) after invoke the insertNewObject method. Can anyone tell me why? This is the example project in book " iCloud for Developers" written by Cesare Rocchi.

Johnson
  • 491
  • 1
  • 3
  • 13
  • It appears that `GroceryItem` is a subclass of `UIDocument`? If this is so, are you subclassing any of the `UIDocument` methods? Did you follow the subclassing notes (call `super` or use file coordinators)? – MichaelR Oct 10 '15 at 03:30

0 Answers0