Reputation: 45190
I'm making a backup managrer for my App (via iCloud). I did some tests and the basics worked. But few days later it stopped. I'm using NSMetadataQuery
for searching if backup file exists. My backup files are named e.g. Backup29112011154133.xml
where numbers represent date of the backup (formatted as ddMMyyyyHHmmss
). I check for it in -viewDidAppear
:
- (void)viewDidAppear:(BOOL)animated {
[self checkForRemoteFile];
}
- (void)checkForRemoteFile {
NSURL *ubiq = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];
if (ubiq) {
NSMetadataQuery *query = [[NSMetadataQuery alloc] init];
[query setSearchScopes:[NSArray arrayWithObject:NSMetadataQueryUbiquitousDocumentsScope]];
NSPredicate *pred = [NSPredicate predicateWithFormat:@"%K like 'Backup*'",NSMetadataItemFSNameKey];
[query setPredicate:pred];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(queryDidFinishGathering:) name:NSMetadataQueryDidFinishGatheringNotification object:query];
[query startQuery];
} else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"iCloud is unavailable at the moment" message:nil delegate:self cancelButtonTitle:@"Close" otherButtonTitles:nil];
[alert setTag:TAG_ALERT_NOICLOUD];
[alert show];
}
}
- (void)queryDidFinishGathering:(NSNotification *)notif {
NSMetadataQuery *query = [notif object];
[query disableUpdates];
[query stopQuery];
[self loadRemoteFile:query];
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSMetadataQueryDidFinishGatheringNotification object:query];
}
- (void)loadRemoteFile:(NSMetadataQuery *)query {
if ([query resultCount] == 1) {
canRestore = YES;
NSMetadataItem *item = [query resultAtIndex:0];
// parse the backup file
[self.tableView reloadData];
} else {
canRestore = NO;
modifDate = @"never";
backupInfoLoaded = YES;
[self.tableView reloadData];
}
}
The problem is that - (void)queryDidFinishGathering:(NSNotification *)notif
is never executed. I put breakpints and NSLogs ion there but nothing happend.
I also tried to check for other notifications e.g. 'query did start gathering' and 'query process'. Only 'query did start' notification is posted.
I also have AppID with iCloud registered and entitlements file attached.
Can you help me out what's going on? Maybe I missed something?
Upvotes: 5
Views: 3849
Reputation: 2891
This problem still persists. I have been able to trace it to the following divergence:
for example
[NSPredicate predicateWithFormat:@"%K like[cd] %@", NSMetadataItemFSNameKey, @"*"]
then it will work as expected (posting all four query lifecycle notifications).
as in
[NSPredicate predicateWithFormat:@"%K BEGINSWITH %@", NSMetadataItemPathKey, [self cloudDocumentsURL].path]
OR
[NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects:namePred, pathPred, nil]];
Then only the initial notification will be posted.
I have tried literally hundreds of combinations of these configurable variables in multiple test and intended-for-production apps over the last year and have yet to find a counterexample to this hypothesis.
Unfortunately, NSMetadataQuery just doesn't work for ubiquitous stores (as of 10.8).
My workaround is to get the raw results from the query and work mostly on a bound NSArrayController which can have its results filtered. This will mean refactoring away from query.results for most existing code and there is a performance hit (presumably) but it is the only way I have found. I would love an alternative.
Upvotes: 1
Reputation: 45190
ivar
for NSMetadataQuery
.I don't know why the application can't read data without NSMetadataquery ivar.
Upvotes: 9
Reputation: 322
First of all NSMetadataQuery doesn't works if startQuery was called not from the MaintThread. There is possibility that predicate fails for every path also. Following code works for me.
NSURL *mobileDocumentsDirectoryURL = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];
...
query.predicate = [NSPredicate predicateWithFormat:[NSString stringWithFormat:@"%%K like \"%@*\"", [mobileDocumentsDirectoryURL path]], NSMetadataItemPathKey];
[query startQuery];
Upvotes: 17
Reputation: 1928
Unfortunately there have been many problems with iCloud and using NSMetaDataQuery
. To be honest with you the best source as of now for all your iCloud related questions is the Apple Developer Forums. Today Apple released iOS 5.1 beta, and the release notes STILL say that NSMetaDataQuery isn't functioning properly. It's extremely frustrating that iCloud still isn't working properly, but sadly there's nothing we can do.
Upvotes: 2