2011-11-27 17 views
5

Tôi có ứng dụng iOS dựa trên tài liệu với lớp con UIDocument. Tôi cần để có thể di chuyển tệp mà nó đại diện trên hệ thống tệp. Tôi đã xem xét di chuyển nó với một số NSFileManager, nhưng điều này sẽ làm hỏng tài sản fileURL của UIDocument. Bất kỳ ý tưởng về cách giải quyết câu hỏi hóc búa này?Cách thích hợp để di chuyển UIDocument đến vị trí mới trên hệ thống tệp

Trả lời

5

Bạn có thể đổi tên UIDocument bằng cách đóng nó lần đầu tiên, và sau đó trong trình xử lý hoàn thành, di chuyển tệp bằng NSFileManager. Một khi tập tin đã được chuyển thành công, khởi tạo một thể hiện mới của lớp con UIDocument của bạn bằng cách sử dụng URL mới file:

NSURL *directoryURL = [_document.fileURL URLByDeletingLastPathComponent];  
NSFileManager *fileManager = [[NSFileManager alloc] init];  
NSString *filePath = [directoryURL.path stringByAppendingPathComponent:@"NewFileName"]; 

[_document closeWithCompletionHandler:^(BOOL success) { 
    NSError *error; 

    if (success) 
     success = [fileManager moveItemAtPath:_document.fileURL.path toPath:filePath error:&error]; 

    if (success) { 
     NSURL *url = [NSURL fileURLWithPath:filePath]; 

     // I handle opening the document and updating the UI in setDocument: 
     self.document = [[MyDocumentSubclass alloc] initWithFileName:[url lastPathComponent] dateModified:[NSDate date] andURL:url]; 
    } else { 
     UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:@"Unable to rename document" delegate:nil cancelButtonTitle:@"Dismiss" otherButtonTitles:nil]; 
     [alert show]; 
     NSLog(@"Unable to move document: %@", error); 
    } 
}]; 
+0

Mặc dù điều này sẽ hoạt động, bạn không phải lúc nào cũng có thể đóng tài liệu trước khi di chuyển mà không vi phạm đóng gói. – Elland

-1

Tôi thấy điều này trong đặc tả UIDocument lớp (5.1):

Thực hiện NSFilePresenter Giao thức

Lớp UIDocument thông qua giao thức NSFilePresenter. Khi một khách hàng khác cố gắng đọc tài liệu của ứng dụng dựa trên UIDocument, việc đọc đó bị tạm ngưng cho đến khi đối tượng UIDocument được trao cơ hội lưu bất kỳ thay đổi nào được thực hiện cho tài liệu.

Mặc dù một số triển khai không làm gì cả, UIDocument triển khai tất cả các phương thức NSFilePresenter. Cụ thể, UIDocument:

Thực hiện relinquishPresentedItemToReader: để chuyển tiếp các khối đến để .

Thực hiện relinquishPresentedItemToWriter: để kiểm tra xem ngày sửa đổi tệp có thay đổi hay không; nếu tệp mới hơn trước, nó gọi revertToContentsOfURL:completionHandler: với giá trị của thông số fileURL làm thông số URL.

Thực hiện presentedItemDidMoveToURL: để cập nhật URL tệp của tài liệu (fileURL).

Trong lớp con UIDocument của bạn, nếu bạn ghi đè phương thức NSFilePresenter, bạn luôn có thể gọi triển khai siêu lớp (super).

Tôi đã vô vọng tìm kiếm và tôi hy vọng những điều trên sẽ hữu ích. Tôi chưa thử nghiệm nó - Tôi đang nhảy vào nó ngay bây giờ.

Vì vậy, về cơ bản, nếu tôi không bỏ lỡ bất cứ điều gì ở đây, bạn phải di chuyển tài liệu bằng cách sử dụng NSFileManager và sau đó gọi presentedItemDidMoveToURL: trên tài liệu của bạn. Bạn có thể di chuyển tệp bằng cách sử dụng NSFileCoordinator, để đảm bảo bạn không gặp sự cố.

Vui lòng sửa mọi thứ trong câu trả lời này sai. Tôi vẫn là n00b trong tất cả nội dung đó.

+1

Đây là ý tưởng đúng, nhưng tôi không nghĩ bạn nên gọi trực tiếp 'presentationItemDidMoveToURL:', mà đúng hơn là gọi thông báo điều phối tệp. Lý do chính là bạn có thể có nhiều hơn một người trình bày tệp đang mở và việc gọi các phương thức thông báo sẽ đảm bảo tất cả họ đều nhận được nó. – Elland

2

Điều này có thể cũ nhưng vẫn có liên quan.

Những gì bạn muốn làm là như sau:

Đối với di chuyển: di chuyển tập tin bằng cách sử dụng NSFileCoordinator, bên trong khối của điều phối viên, hãy gọi

[fileCoordinator itemAtURL:URL willMoveToURL:toURL]; 
[fileManager moveItemAtURL:newURL toURL:toURL error:&moveError]; 
[fileCoordinator itemAtURL:URL didMoveToURL:toURL]; 

Đối với xóa: ghi đè lên lớp con UIDocument của bạn hoặc thực hiện các tập tin phương thức giao thức người trình bày accommodatePresentedItemDeletionWithCompletionHandler: để đóng tài liệu.

- (void)accommodatePresentedItemDeletionWithCompletionHandler:(void (^)(NSError *))completionHandler; 
{ 
[self closeWithCompletionHandler:^(BOOL success) { 
    NSError *err; 
    if (!success) 
     err = [NSError error]; // implement your error here if you want 

    completionHandler(err); 
}]; 
} 

Do đó đảm bảo nó sẽ xử lý chính xác việc di chuyển.