【问题标题】:Rename an iCloud document重命名 iCloud 文档
【发布时间】:2012-12-30 18:39:38
【问题描述】:

问题

到目前为止,我所拥有的是创建新本地文件并删除 iCloud 文件的代码。

是否可以重命名 iCloud 文档以使其保留在 iCloud 中?

GarageBand 可以做到。可以重命名 iCloud 歌曲。重命名完成后,歌曲仍在 iCloud 中。不过 GarageBand 是 Apple 应用,因此它可能会使用私有 api。

我当前的代码:

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

更新:还是没有运气

我发现-setUbiquitous:itemAtURL:destinationURL:error: 不能用于重命名文档。

如果我在已经本地的文件上调用 [setUbiquitous:NO itemAtURL:oldLocalURL destinationURL:newLocalURL error:&error],那么:

Error Domain=NSCocoaErrorDomain Code=512 "无法进行操作 完全的。 (可可错误 512。)“用户信息 = 0x1fdf6730 {NSURL=file://localhost/var/mobile/Applications/4BABA000-B100-49FC-B928-B0F403FC75FF/Documents/LocalDrawing.td2/, NSUnderlyingError=0x20940e80 "操作无法完成。 (LibrarianErrorDomain 错误 2 - 无法禁用未同步的同步 项目。)”}

如果我在已经云的文件上调用 [setUbiquitous:YES itemAtURL:oldCloudURL destinationURL:newCloudURL error:&error],那么:

Error Domain=NSCocoaErrorDomain Code=512 "无法进行操作 完全的。 (可可错误 512。)“用户信息 = 0x208e9820 {NSURL=file://localhost/var/mobile/Library/Mobile%20Documents/22DR89XVRF~com~opcoders~triangle-draw/Documents/CloudDrawing.td2/, NSUnderlyingError=0x208d45b0 "操作无法完成。 (LibrarianErrorDomain 错误 2 - 无法在已同步的 项目。)”}

因此-setUbiquitous:itemAtURL:destinationURL:error: 不能用于重命名文档。

【问题讨论】:

    标签: ios icloud nsfilemanager uidocument nsfilecoordinator


    【解决方案1】:

    我终于解决了。到目前为止,这是我的代码:

    - (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");
    }
    

    【讨论】:

      【解决方案2】:

      有一种更简单的方法可以重命名任何给定 URL 上的项目,包括 iCloud URL。

      url.setResourceValue(newName, forKey: NSURLNameKey)
      

      我在我的可可应用程序的生产代码中使用它。

      编辑: 在 Swift 5 中,这看起来有点不同,但仍然运行良好:

      var resourceValues = URLResourceValues()
      resourceValues.name = newName
      try previousFileURL.setResourceValues(resourceValues)
      

      【讨论】:

        猜你喜欢
        • 2018-03-13
        • 2016-02-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-07-20
        相关资源
        最近更新 更多