4

問題

私がこれまでに持っているのは、新しいローカルファイルを作成して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 "操作を完了できませんでした。(Cocoaエラー512)" UserInfo = 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 "操作を完了できませんでした。(Cocoaエラー512)" UserInfo = 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:、ドキュメントの名前変更には使用できません。

4

2 に答える 2

7

私はついにそれを解決しました。これはこれまでの私のコードです:

- (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");
}
于 2013-03-31T01:22:58.357 に答える
1

iCloudのURLを含む任意のURLでアイテムの名前を変更する簡単な方法があります。

url.setResourceValue(newName, forKey: NSURLNameKey)

私はこれを私のココアアプリのプロダクションコードで使用しています。

編集: Swift 5では、これは少し異なって見えますが、それでもうまく機能します:

var resourceValues = URLResourceValues()
resourceValues.name = newName
try previousFileURL.setResourceValues(resourceValues)
于 2016-03-17T00:17:01.253 に答える