Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rename document without closing UIDocument

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

like image 439
Taylor Avatar asked Sep 07 '15 02:09

Taylor


1 Answers

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];
  }];

});
like image 105
Taylor Avatar answered Sep 28 '22 06:09

Taylor