I recently started playing around with the iPhone file system, at first I had some trouble understanding some concepts but I think that in the end I got them straight and flowing.
My problem is that I am trying to copy a file from the mail app (or any app that opens my app with a file type my app supports) by implementing the application:openURL:sourceApplication:annotation:
method to the Documents Directory (NSDocumentDirectory
), but my app seems to fail when doing this.
I created a BOOL
with the value that my file manager returns when copying the file ([fileManager copyItenAtPath:filePath toPath:newFilePath error:&error];
where newFilePath is my Documents Directory) and then check against it, and then NSLog if there was failure or success, I always get failure.
In an attempt to find out what was going on with my Documents directory I enabled file sharing, and instead of seeing the file I copied, I get an Inbox folder, and upon copying that folder to the Desktop I see that my files are in there. Why is this behavior? How can I get the result that I want?
I read somewhere in Apple documentation that when UIDocumentInteractionController
opens a file it copies it to the Inbox folder, but obviously, my app does not make use of UIDocumentInteractionController
.
Thank you in advance, your help is very much appreciated.
EDIT STARTS HERE
Here is my original code:
//AppDelegate.m
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication (NSString *)sourceApplication annotation:(id)annotation
{
rootFolder.fileURLFromLaunch = url; //Passing the URL on to aproperty on a different class
[[NSNotificationCenter defaultCenter] postNotificationName:@"ApplicationDidOpenFile" object:nil]; // notifying that the URL was passed and a file was opened
return YES;
}
This is the class that does all the work with the file:
//RootFolder.m
- (void)copyFileIntoApp
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0];
NSString *filePath = [fileURLFromLaunch path];
NSString *displayName = [filePath lastPathComponent];
NSError *error = NULL;
NSString *finalFilePath = [NSString stringWithFormat:@"%@/%@", documentsPath, displayName];
if ([fileManager fileExistsAtPath:finalFilePath]) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"File already exists!" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
[alert show];
[alert release];
} else {
BOOL success = [fileManager copyItemAtPath:filePath toPath:finalFilePath error:&error];
if (success) {
NSLog(@"success");
Document *document = (Document *) [NSEntityDescription insertNewObjectForEntityForName:@"Document" inManagedObjectContext:managedObjectContext];
[document setFilename:displayName];
[document setPath:finalFilePath];
if (![managedObjectContext save:&error]) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Please try again or restart the app" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
[alert show];
[alert release];
}
[fileArray insertObject:document atIndex:0];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade];
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:YES];
} else {
NSLog(@"failure %@ ", [error localizedDescription]);
}
}
}
I hope that sets things more clearly.
I get an Inbox folder, and upon copying that folder to the Desktop I see that my files are in there. Why is this behavior? How can I get the result that I want?
Because your app is sandboxed and does not have access to files that are not in its own directory. When the user tells iOS that he wants to open a file with a specific app iOS copies the file into the inbox directory.
Post the complete code of application:openURL:sourceApplication:annotation:
.
Your "I'm doing this and that" is not very helpful because there is a flaw between this and that. The algorithm you explained with your words is correct, but there is clearly a bug in your implementation.
So please post the full code of this method.
Edit: I tested the relevant parts of your code and they seem to work.
I would check that fileManager
is not nil. That would explain why you don't see an error message.