Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rename an iCloud document

The problem

What I have so far is code that creates a new local file and deletes the iCloud file.

Is it possible to rename an iCloud document, so that it stays in iCloud?

GarageBand can do it. It's possible to rename an iCloud song. After the rename is done, the song is still in iCloud. However GarageBand is an Apple app, so it may use private apis.

My current code:

- (void)moveFrom:(NSURL*)sourceURL
          moveTo:(NSString*)destinationName
      completion:(void (^)())completion
{
    MyDocument *document = [[MyDocument alloc] initWithFileURL:sourceURL];
    [document openWithCompletionHandler:^(BOOL success)
    {
        NSURL *fileURL = [self.localRoot URLByAppendingPathComponent:destinationName];
        DLog(@"Create %@", fileURL);
        [document saveToURL:fileURL
           forSaveOperation:UIDocumentSaveForCreating
          completionHandler:^(BOOL success)
        {
            NSLog(@"Saved %@", fileURL);
            [document closeWithCompletionHandler:^(BOOL success) {
                // Delete the old document from a secondary thread
                dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^()
                {
                    NSFileCoordinator* fileCoordinator = [[NSFileCoordinator alloc] initWithFilePresenter:nil];
                    [fileCoordinator coordinateWritingItemAtURL:sourceURL
                                                        options:NSFileCoordinatorWritingForDeleting
                                                          error:nil
                                                     byAccessor:^(NSURL* writingURL) {
                        NSFileManager* fileManager = [[NSFileManager alloc] init];
                        [fileManager removeItemAtURL:writingURL error:nil];
                        DLog(@"Deleted %@", sourceURL);
                        completion();
                    }];
                });
            }];
        }];
    }];
}

Update: Still no luck

I have found out that -setUbiquitous:itemAtURL:destinationURL:error: cannot be used for renaming documents.

If I invoke [setUbiquitous:NO itemAtURL:oldLocalURL destinationURL:newLocalURL error:&error] on an already local file, then:

Error Domain=NSCocoaErrorDomain Code=512 "The operation couldn’t be completed. (Cocoa error 512.)" UserInfo=0x1fdf6730 {NSURL=file://localhost/var/mobile/Applications/4BABA000-B100-49FC-B928-B0F403FC75FF/Documents/LocalDrawing.td2/, NSUnderlyingError=0x20940e80 "The operation couldn’t be completed. (LibrarianErrorDomain error 2 - Cannot disable syncing on a unsynced item.)"}

If I invoke [setUbiquitous:YES itemAtURL:oldCloudURL destinationURL:newCloudURL error:&error] on an already cloud file, then:

Error Domain=NSCocoaErrorDomain Code=512 "The operation couldn’t be completed. (Cocoa error 512.)" UserInfo=0x208e9820 {NSURL=file://localhost/var/mobile/Library/Mobile%20Documents/22DR89XVRF~com~opcoders~triangle-draw/Documents/CloudDrawing.td2/, NSUnderlyingError=0x208d45b0 "The operation couldn’t be completed. (LibrarianErrorDomain error 2 - Cannot enable syncing on a synced item.)"}

Thus -setUbiquitous:itemAtURL:destinationURL:error: cannot be used for renaming documents.

like image 297
neoneye Avatar asked Feb 17 '23 20:02

neoneye


1 Answers

I have finally solved it. This is my code so far:

- (void)_moveURL:(NSURL*)sourceURL
         destURL:(NSURL*)destinationURL
         success:(void (^)())successBlock
         failure:(void (^)(NSError *))failureBlock
{
    NSParameterAssert(sourceURL);
    NSParameterAssert(destinationURL);
    NSParameterAssert(successBlock);
    NSParameterAssert(failureBlock);

    // Do the actual renaming
    __block NSError *moveError = nil;
    __block BOOL moveSuccess = NO;
    void (^accessor)(NSURL*, NSURL*) = ^(NSURL *newURL1, NSURL *newURL2) {
        NSFileManager *fileManager = [[NSFileManager alloc] init];
        moveSuccess = [fileManager moveItemAtURL:sourceURL toURL:destinationURL error:&moveError];
    };

    // Coordinate renaming
    NSError *coordinatorError = nil;
    NSFileCoordinator *coordinator = [[NSFileCoordinator alloc] initWithFilePresenter:nil];
    [coordinator coordinateWritingItemAtURL:sourceURL
                                    options:NSFileCoordinatorWritingForMoving
                           writingItemAtURL:destinationURL
                                    options:NSFileCoordinatorWritingForReplacing
                                      error:&coordinatorError
                                 byAccessor:accessor];
    if (moveSuccess) {
        successBlock();
        return;
    }
    if (moveError) {
        failureBlock(moveError);
        return;
    }
    if (coordinatorError) {
        failureBlock(coordinatorError);
        return;
    }
    NSAssert(NO, @"should not happen");
}
like image 74
neoneye Avatar answered Mar 04 '23 13:03

neoneye