2017-10-02 17 views
5

Tôi đang cố gắng tìm ra cách đổi tên một thể hiện của một lớp con UIDocument trong thư mục iCloud. Tôi đã cố gắng tiết kiệm tài liệu với các URL mới ...Đổi tên tài liệu UIDocument trong iCloud

func renameDocument(to name: String) { 

    let targetURL = document.fileURL.deletingLastPathComponent().appendingPathComponent(name) 
     .appendingPathExtension("<extension>") 

    document.save(to: targetURL, for: .forCreating) { success in 
     guard success else { 
      // This always fails 
      return 
     } 
     // Success 
    } 
} 

... nhưng điều này không thành công với ...

Error Domain=NSCocoaErrorDomain Code=513 "“<new-file-name>” couldn’t be moved because you don’t have permission to access “<folder>”." UserInfo={NSSourceFilePathErrorKey=/private/var/mobile/Containers/Data/Application/1A9ACC2B-81EF-4EC9-940E-1C129BDB1914/tmp/(A Document Being Saved By My App)/<new-file-name>, NSUserStringVariant=( Move ), NSDestinationFilePath=/private/var/mobile/Library/Mobile Documents/com~apple~CloudDocs/<folder>/<new-file-name>, NSFilePath=/private/var/mobile/Containers/Data/Application/1A9ACC2B-81EF-4EC9-940E-1C129BDB1914/tmp/(A Document Being Saved By My App)/<new-file-name>, NSUnderlyingError=0x1c4e54280 {Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted"}}

... và chỉ cần một động thái đơn giản ...

func renameDocument(to name: String) { 
    let targetURL = document.fileURL.deletingLastPathComponent().appendingPathComponent(name) 
     .appendingPathExtension("<extension>") 

    do { 
     try FileManager.default.moveItem(at: document.fileURL, to: targetURL) 
    } catch { 
     // This always fails 
    }   
    // Success 
} 

… không thành công thứ i ...

Error Domain=NSCocoaErrorDomain Code=513 "“<old-file-name>” couldn’t be moved because you don’t have permission to access “<folder>”." UserInfo={NSSourceFilePathErrorKey=/private/var/mobile/Library/Mobile Documents/com~apple~CloudDocs/<folder>/<old-file-name>, NSUserStringVariant=( Move ), NSDestinationFilePath=/private/var/mobile/Library/Mobile Documents/com~apple~CloudDocs/<folder>/<new-file-name>, NSFilePath=/private/var/mobile/Library/Mobile Documents/com~apple~CloudDocs/<folder>/<old-file-name>, NSUnderlyingError=0x1c4c4d8c0 {Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted"}}

Cả hai làm việc tốt cho các tập tin địa phương, và đổi tên file iCloud hoạt động OK trong bộ điều khiển xem UIDocumentBrowserViewController gốc.

Tôi đoán là có một số quyền thiếu ở đâu đó cho phép ứng dụng ghi vào thư mục iCloud.

Đối với thông tin, các info.plist chứa tất cả các phím sau ...

  • LSSupportsOpeningDocumentsInPlace
  • NSExtensionFileProviderSupportsEnumeration
  • UISupportsDocumentBrowser
+0

là tài liệu mở khi bạn đang cố gắng để đổi tên nó? – theMikeSwan

+0

Nó dường như không tạo ra bất kỳ sự khác biệt cho dù nó mở hay đóng. –

+0

Hãy xem https://developer.apple.com/documentation/foundation/filemanager/1413989-setubiquitous xem liệu điều đó có hữu ích không. Tôi khá chắc chắn rằng một số phương pháp quản lý tệp thông thường không hoạt động trong vùng chứa iCloud (mặc dù iOS 11 có thể đã thay đổi mọi thứ…) – theMikeSwan

Trả lời

1

Bạn làm điều này trong bối cảnh NSFileCoordinator? Điều này là bắt buộc. Bạn không cần bất kỳ cài đặt info.plist nào ngoài số NSUbiquitousContainers.

Dưới đây là mã của tôi để đặt tên nhiều tài liệu iCloud:

/// 
/// move cloudFile within same store - show errors 
/// 
- (void)moveCloudFile:(NSURL *)url toUrl:(NSURL *)newURL 
{ 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), 
    ^{ 
     NSError *coordinationError; 
     NSFileCoordinator *coordinator = [[NSFileCoordinator alloc] initWithFilePresenter:nil]; 

     [coordinator coordinateWritingItemAtURL:url options:NSFileCoordinatorWritingForMoving 
           writingItemAtURL:newURL options:NSFileCoordinatorWritingForReplacing 
                 error:&coordinationError 
            byAccessor: 
     ^(NSURL *readingURL, NSURL *writingURL){ 
      if ([self moveFile:readingURL toUrl:writingURL]) 
       [coordinator itemAtURL:readingURL didMoveToURL:writingURL]; 
     }]; 
     if (coordinationError) { 
      MRLOG(@"Coordination error: %@", coordinationError); 
      [(SSApplication *)SSApplication.sharedApplication fileErrorAlert:coordinationError]; 
     } 
    }); 
} 

/// 
/// 
/// move file within same store - show errors 
/// 
- (BOOL)moveFile:(NSURL *)url toUrl:(NSURL *)newURL 
{ 
    NSFileManager *manager = NSFileManager.defaultManager; 
    NSError *error; 

    if ([manager fileExistsAtPath:newURL.path]) 
     [self removeFile:newURL]; 

    if ([manager moveItemAtURL:url toURL:newURL error:&error] == NO) { 
     MRLOG(@"Move failed: %@", error); 
     [(SSApplication *)SSApplication.sharedApplication fileErrorAlert:error]; 
     return NO; 
    } 
    return YES; 
} 
+0

Rất vui khi xem tùy chọn nào mà người khác đã sử dụng để thực hiện việc này. Tốt hơn nhiều so với những gì tôi đang sử dụng. Nhưng tôi nghĩ bạn đã không sử dụng FileManager mặc định trong một Điều phối viên. – Sojourner9

Các vấn đề liên quan