问题
I have a document-based iOS application with a UIDocument
subclass. I need to be able to move the file it represents on the file-system. I have considered moving it with an NSFileManager
, but this would mess up the UIDocument
's fileURL
property. Any ideas on how to solve this little conundrum?
回答1:
You can rename a UIDocument by first closing it, and then in the completion handler, moving the file using NSFileManager. Once the file has been successfully moved, initialize a new instance of your UIDocument subclass using the new file URL:
NSURL *directoryURL = [_document.fileURL URLByDeletingLastPathComponent];
NSFileManager *fileManager = [[NSFileManager alloc] init];
NSString *filePath = [directoryURL.path stringByAppendingPathComponent:@"NewFileName"];
[_document closeWithCompletionHandler:^(BOOL success) {
NSError *error;
if (success)
success = [fileManager moveItemAtPath:_document.fileURL.path toPath:filePath error:&error];
if (success) {
NSURL *url = [NSURL fileURLWithPath:filePath];
// I handle opening the document and updating the UI in setDocument:
self.document = [[MyDocumentSubclass alloc] initWithFileName:[url lastPathComponent] dateModified:[NSDate date] andURL:url];
} else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:@"Unable to rename document" delegate:nil cancelButtonTitle:@"Dismiss" otherButtonTitles:nil];
[alert show];
NSLog(@"Unable to move document: %@", error);
}
}];
回答2:
This might be old but still relevant.
What you want to do is the following:
For moving: move your file using NSFileCoordinator, inside the coordinator's block, call
[fileCoordinator itemAtURL:URL willMoveToURL:toURL];
[fileManager moveItemAtURL:newURL toURL:toURL error:&moveError];
[fileCoordinator itemAtURL:URL didMoveToURL:toURL];
For deleting: overwrite your UIDocument subclass or implement the file presenter protocol method accommodatePresentedItemDeletionWithCompletionHandler:
to close the document.
- (void)accommodatePresentedItemDeletionWithCompletionHandler:(void (^)(NSError *))completionHandler;
{
[self closeWithCompletionHandler:^(BOOL success) {
NSError *err;
if (!success)
err = [NSError error]; // implement your error here if you want
completionHandler(err);
}];
}
Thus ensuring it will correctly handle being moved.
回答3:
I found this in the UIDocument
class specification (5.1):
Implementation of
NSFilePresenter
ProtocolThe
UIDocument
class adopts theNSFilePresenter
protocol. When another client attempts to read the document of aUIDocument
-based application, that reading is suspended until theUIDocument
object is given an opportunity to save any changes made to the document.Although some implementations do nothing,
UIDocument
implements allNSFilePresenter
methods. Specifically,UIDocument
:Implements
relinquishPresentedItemToReader:
to forward the incoming block toperformAsynchronousFileAccessUsingBlock:
.Implements
relinquishPresentedItemToWriter:
to check if the file-modification date has changed; if the file is newer than before, it callsrevertToContentsOfURL:completionHandler:
with the value of thefileURL
as the URL parameter.Implements
presentedItemDidMoveToURL:
to update the document’s file URL (fileURL
).In your
UIDocument
subclass, if you override aNSFilePresenter
method you can always invoke the superclass implementation (super
).
I was hopelessly searching too and I hope the above helps. I haven't tested it yet — I'm jumping on it right now.
So basically, if I don't miss anything here, you have to move the document using NSFileManager
and then call presentedItemDidMoveToURL:
on your document. You have probably to move the file using NSFileCoordinator
, to make sure you don't get problems.
Please correct everything in this answer that's wrong. I'm still a n00b in all that stuff.
来源:https://stackoverflow.com/questions/8284137/what-is-the-proper-way-to-move-a-uidocument-to-a-new-location-on-the-file-system