7

How do I rename a document file with an open UIDocument without closing and reopening the document? Closing (saving), moving, and reopening the document takes too long.

I have the following code that moves the file:

NSFileCoordinator* fileCoordinator = [[NSFileCoordinator alloc] initWithFilePresenter:nil];
[fileCoordinator coordinateWritingItemAtURL:oldPath
                                    options:NSFileCoordinatorWritingForMoving
                           writingItemAtURL:newPath
                                    options:NSFileCoordinatorWritingForReplacing
                                      error:&coordinatorError
                                 byAccessor:^(NSURL *newURL1, NSURL *newURL2) {
  // Rename the file.
  NSFileManager* fileManager = [NSFileManager defaultManager];
  [fileCoordinator itemAtURL:oldPath willMoveToURL:newPath];
  [fileManager moveItemAtURL:newURL1 toURL:newURL2 error:nil];
  [fileCoordinator itemAtURL:oldPath didMoveToURL:newPath];
}];

According to the documentation UIDocument implements presentedItemDidMoveToURL: to update its fileURL (see https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIDocument_Class/)

However, when the above code is called with the document open, it hangs, presumably waiting for a lock on oldPath (-[NSFileCoordinator(NSPrivate) _blockOnAccessClaim:]). Works fine if there is no living UIDocument.

Related, top answer suggests to close and reopen the UIDocument: What is the proper way to move a UIDocument to a new location on the file-system

1 Answer 1

9

The solution was to use a background queue to avoid the deadlock:

dispatch_async(dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0), ^(void) {

  NSError *coordinatorError = nil;

  NSFileCoordinator* fileCoordinator = [[NSFileCoordinator alloc] initWithFilePresenter:nil];
  [fileCoordinator coordinateWritingItemAtURL:oldPath
                                    options:NSFileCoordinatorWritingForMoving
                           writingItemAtURL:newPath
                                    options:NSFileCoordinatorWritingForReplacing
                                      error:&coordinatorError
                                 byAccessor:^(NSURL *newURL1, NSURL *newURL2) {
    // Rename the file.
    NSFileManager* fileManager = [NSFileManager defaultManager];
    [fileCoordinator itemAtURL:oldPath willMoveToURL:newPath];
    [fileManager moveItemAtURL:newURL1 toURL:newURL2 error:nil];
    [fileCoordinator itemAtURL:oldPath didMoveToURL:newPath];
  }];

});

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.