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:f开发者_开发技巧inalFilePath];
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.
Are you setting your error to null upon instantiation? If you don't the memory that the NSError
points to will not be NULL, and your logic will be tripped.
Do this:
NSError *error = NULL;
NOT this:
NSError *error;
精彩评论