I used as described in the Apple Docs NSMetadataQuery to search my iCloud file. I have only one file and I know its name. My problem is that sometimes this file doesn't exist (I guess because it has not yet been downloaded) and NSMetadataQuery is unable to find it.
Ever tried to force download with NSFileManager startDownloadingUbiquitousItemAtURL:error:
and it returns me an error. (Read EDIT)
My solution is that I created the file the first time, then I guess it exists and I open it with UIDocument. But It couldn't exist or it could be the first time the user opens the app. I can't be sure of these things. My first question is: if UIDocument opens the file, it means that it found the file somewhere. How could it use the file if it DOESN'T EXIST?
And then, second question: If I app which has to manage multiple files or files with unknown name. How can I find them if NSMetadataQuery doesn't work.
EDIT:
if startDownloadingUbiquitousItemAtURL
should be used to start downloading a file, how can I know when the file finished downloading (perhaps with a notification)? But, a more important thing: How can I download the file if is always says (removed original names)?
Error Domain=NSPOSIXErrorDomain Code=2 "The operation couldn’t be completed.
No such file or directory" UserInfo=0x166cb0 {
NSDescription=Unable to get real path for Path
'/private/var/mobile/Library/Mobile Documents/teamid~com~team~app/Documents/file.extension'
}
Use Finder to View iCloud Drive Files on a Mac If you don't see an iCloud Drive option, go to Finder > Preferences from the menu bar. Then click Sidebar and enable the iCloud Drive option. Interact with these files and folders the same way you would any other file or folder on your Mac.
Changes you make to a downloaded file appear only on your computer unless you subsequently upload the file to iCloud Drive. in the iCloud Drive toolbar. The files are downloaded to the location specified in your web browser's settings.
Open the document you were working on. Click on File > Info. Under “Manage Documents” click on the name of the file you were working on. Click on “Restore” and just like that the file should reappear.
I suggest the following load routine for iCloud files. It involves 4 steps:
NSPredicate *pred = [NSPredicate predicateWithFormat:@"NOT %K.pathExtension = '.'", NSMetadataItemFSNameKey];
will return all files which have an extension, like jpg, txt, dat etc.)Here is the code that exemplifies these four steps:
- (void)loadData:(NSMetadataQuery *)query {
// (4) iCloud: the heart of the load mechanism: if texts was found, open it and put it into _document; if not create it an then put it into _document
if ([query resultCount] == 1) {
// found the file in iCloud
NSMetadataItem *item = [query resultAtIndex:0];
NSURL *url = [item valueForAttribute:NSMetadataItemURLKey];
MyTextDocument *doc = [[MyTextDocument alloc] initWithFileURL:url];
//_document = doc;
doc.delegate = self.viewController;
self.viewController.document = doc;
[doc openWithCompletionHandler:^(BOOL success) {
if (success) {
NSLog(@"AppDelegate: existing document opened from iCloud");
} else {
NSLog(@"AppDelegate: existing document failed to open from iCloud");
}
}];
} else {
// Nothing in iCloud: create a container for file and give it URL
NSLog(@"AppDelegate: ocument not found in iCloud.");
NSURL *ubiq = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];
NSURL *ubiquitousPackage = [[ubiq URLByAppendingPathComponent:@"Documents"] URLByAppendingPathComponent:@"text.txt"];
MyTextDocument *doc = [[MyTextDocument alloc] initWithFileURL:ubiquitousPackage];
//_document = doc;
doc.delegate = self.viewController;
self.viewController.document = doc;
[doc saveToURL:[doc fileURL] forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success) {
NSLog(@"AppDelegate: new document save to iCloud");
[doc openWithCompletionHandler:^(BOOL success) {
NSLog(@"AppDelegate: new document opened from iCloud");
}];
}];
}
}
- (void)queryDidFinishGathering:(NSNotification *)notification {
// (3) if Query is finished, this will send the result (i.e. either it found our text.dat or it didn't) to the next function
NSMetadataQuery *query = [notification object];
[query disableUpdates];
[query stopQuery];
[self loadData:query];
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSMetadataQueryDidFinishGatheringNotification object:query];
_query = nil; // we're done with it
}
-(void)loadDocument {
// (2) iCloud query: Looks if there exists a file called text.txt in the cloud
NSMetadataQuery *query = [[NSMetadataQuery alloc] init];
_query = query;
//SCOPE
[query setSearchScopes:[NSArray arrayWithObject:NSMetadataQueryUbiquitousDocumentsScope]];
//PREDICATE
NSPredicate *pred = [NSPredicate predicateWithFormat: @"%K == %@", NSMetadataItemFSNameKey, @"text.txt"];
[query setPredicate:pred];
//FINISHED?
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(queryDidFinishGathering:) name:NSMetadataQueryDidFinishGatheringNotification object:query];
[query startQuery];
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSLog(@"AppDelegate: app did finish launching");
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
// Override point for customization after application launch.
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
self.viewController = [[[ViewController alloc] initWithNibName:@"ViewController_iPhone" bundle:nil] autorelease];
} else {
self.viewController = [[[ViewController alloc] initWithNibName:@"ViewController_iPad" bundle:nil] autorelease];
}
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
// (1) iCloud: init
NSURL *ubiq = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];
if (ubiq) {
NSLog(@"AppDelegate: iCloud access!");
[self loadDocument];
} else {
NSLog(@"AppDelegate: No iCloud access (either you are using simulator or, if you are on your phone, you should check settings");
}
return YES;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With