2011-10-21 10 views
31

Tôi đã có một Ứng dụng iPhone lưu trữ dữ liệu trong một tệp trong thư mục tài liệu cục bộ. Bây giờ tôi đã học về công nghệ iCloud và câu hỏi đầu tiên của tôi là: có cách nào để sử dụng iCloud như một thư mục khi thỉnh thoảng tôi kiểm tra phiên bản mới không?Cách sử dụng iCloud để lưu trữ và đồng bộ hóa các tệp ứng dụng

Ý tôi là: tôi có thể tránh sử dụng UIDocument, điều phối viên tệp và người thuyết trình tệp không? Tôi chỉ muốn biết nếu có thể điều trị iCloud như một thư mục đặc biệt và chỉ sử dụng NSFileManager để đẩy và lấy các tập tin.

Lưu ý cuối cùng: Tôi không sử dụng Dữ liệu cốt lõi hoặc bất kỳ cơ sở dữ liệu nào, tôi chỉ có tệp dữ liệu.

Edit:

Tôi đã đọc chính thức tài liệu của Apple iCloud do đó, không liên kết tôi với họ. Tôi chỉ cần một số ví dụ mã.

Trả lời

15

Tôi biết bạn cảm thấy thế nào, iCloud hơi khó khăn. Tuy nhiên, tôi nghĩ rằng không có cách nào xung quanh UIDocument, điều phối viên tập tin vv và chỉ đơn giản là sử dụng iCloud như một thư mục đơn giản.

Nếu bạn đang tìm kiếm một cách dễ dàng để hiểu mẫu mã, xin vui lòng có một cái nhìn vào bài đăng này:

iCloud basics and code sample

tôi bao gồm một mẫu mã đầy đủ trong đó bao gồm các tối thiểu trần của iCloud và khá nhiều công dụng nó giống như một thư mục. Có lẽ điều này khiến bạn khó sử dụng UIDocument, điều phối viên tập tin, vv ..

Nhưng, giống như bạn, tôi muốn có một cách tương thích dễ dàng hơn với ý tưởng thư mục tài liệu cũ tốt. Tuy nhiên, vì đây là iCloud và như iCloud làm nhiều việc hơn (như giữ mọi thứ đồng bộ trên các thiết bị khác nhau, liên tục cập nhật lên đám mây ...), sẽ không có cách nào xung quanh UIDocument, v.v.

+0

Tôi đồng ý, nếu bạn nói không có cách nào, tôi sẽ đọc hướng dẫn. Nhưng tôi nghĩ nên có một cách dễ dàng hơn để làm điều đó, như khi bạn viết hoặc đọc một tệp trong hộp cát ứng dụng. Cảm ơn – edo42

+0

Cảm ơn bạn đã liên kết. – Shajo

24

Điều gì "hoạt động" đối với tôi chỉ đơn giản:

NSFileManager *fm = [NSFileManager defaultManager]; 

NSURL *ubiq = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil]; 

if (ubiq == nil) { 
    return NO; 
} 

NSError *theError = nil; 

[fm setUbiquitous:true itemAtURL:backupUrl destinationURL:[[ubiq URLByAppendingPathComponent:@"Documents" isDirectory:true] URLByAppendingPathComponent:backupName] error:&theError]; 

Apple nói để gọi trên chuỗi không phải UI. Có các tập tin "di chuyển". Bạn có thể truy vấn cho họ qua NSMetaDataQuery như thế này:

self.query = [[NSMetadataQuery alloc] init]; 
[self.query setSearchScopes:[NSArray arrayWithObject:NSMetadataQueryUbiquitousDocumentsScope]]; 
NSPredicate *pred = [NSPredicate predicateWithFormat: @"%K like '*.db'", NSMetadataItemFSNameKey]; 
[self.query setPredicate:pred]; 
[[NSNotificationCenter defaultCenter] addObserver:self 
             selector:@selector(queryDidFinishGathering:) 
              name:NSMetadataQueryDidFinishGatheringNotification 
              object:self.query]; 

[self.query startQuery]; 

- (void)queryDidFinishGathering:(NSNotification *)notification { 
    NSMetadataQuery *query = [notification object]; 
    [query disableUpdates]; 
    [query stopQuery]; 

    [self loadData:query]; 

    [[NSNotificationCenter defaultCenter] removeObserver:self name:NSMetadataQueryDidFinishGatheringNotification object:query]; 

    self.query = nil; 
} 

Mẫu liệt kê thông qua các kết quả truy vấn:

- (void)loadData:(NSMetadataQuery *)query { 
    [self.backups removeAllObjects]; 

    for (NSMetadataItem *item in [query results]) { 
     NSURL *url = [item valueForAttribute:NSMetadataItemURLKey]; 
     [self.backups addObject:url.lastPathComponent]; 
    } 

    [_table reloadData]; 

    [self.loadingBackupIndicator stopAnimating]; 
    self.loadingIndicatorLabel.text = [NSString stringWithFormat: @"%d backups found", [self.backups count]]; 
} 

Và để bắt đầu "tải" của tập tin cụ thể:

NSFileManager *fm = [NSFileManager defaultManager]; 

NSURL *ubiq = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil]; 

if (ubiq == nil) { 
    return NO; 
} 

NSError *theError = nil; 

bool started = [fm startDownloadingUbiquitousItemAtURL:[[ubiq URLByAppendingPathComponent:@"Documents" isDirectory:true] URLByAppendingPathComponent:backupName] error:&theError]; 

NSLog(@"started download for %@ %d", backupName, started); 

if (theError != nil) { 
    NSLog(@"iCloud error: %@", [theError localizedDescription]); 
} 

Với séc cho tệp "đang được tải xuống":

- (BOOL)downloadFileIfNotAvailable { 
    NSNumber *isIniCloud = nil; 

    NSURL *ubiq = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil]; 

    NSURL *file = [[ubiq URLByAppendingPathComponent:@"Documents" isDirectory:true] URLByAppendingPathComponent:self.backupName]; 

    if ([file getResourceValue:&isIniCloud forKey:NSURLIsUbiquitousItemKey error:nil]) { 
     // If the item is in iCloud, see if it is downloaded. 
     if ([isIniCloud boolValue]) { 
      NSNumber* isDownloaded = nil; 
      if ([file getResourceValue:&isDownloaded forKey:NSURLUbiquitousItemIsDownloadedKey error:nil]) { 
       if ([isDownloaded boolValue]) { 
        [self.loadingBackupIndicator stopAnimating]; 
        self.loadingIndicatorLabel.text = @"Downloaded"; 

        .... 

        [[NSFileManager defaultManager] copyItemAtPath:[file path] toPath:restorePath error:&theError ]; 

        .... 

        return YES; 
       } 

       self.loadingCheckTimer = [NSTimer timerWithTimeInterval:3.0f target:self selector:@selector(downloadFileIfNotAvailable) userInfo:nil repeats:NO]; 
       [[NSRunLoop currentRunLoop] addTimer:self.loadingCheckTimer forMode:NSDefaultRunLoopMode]; 

       return NO; 
      } 
     } 
    } 

    return YES; 
} 

Tôi không mong đợi mã này dài và xin lỗi vì đã cung cấp các đoạn mã rất thô ở đây. Không có ý định nói ở trên có thể là một chất lượng sản xuất của mã, chỉ cần chia sẻ khái niệm.

tôi chưa nộp mà bên trong ứng dụng của tôi cho Apple, vì vậy không thể nói rằng sẽ là "chấp thuận" đến cửa hàng ứng dụng (nếu họ tìm thấy hoặc chăm sóc ...)

+3

chỉ cần lưu ý rằng phiên bản "sản xuất" của mã ở trên đã chuyển nó bên trong ứng dụng tới cửa hàng ứng dụng. –

+1

bạn có thể vui lòng cung cấp một dự án mẫu bao gồm mã trên. Vui lòng giúp tôi nếu có thể. – Gypsa

+0

@StanislavDvoychenko xin chào sir cho tôi một số ý tưởng về phần mã hóa icloud .means làm thế nào để strore và retrive vv plz .thanks trước – Bajaj

14

Bạn có thể tải những file riêng biệt để iCloud sử dụng NSFileManager.Tôi đăng một complete walkthrough về cách để làm điều đó trên blog của tôi, nhưng đây là mã NSFileManager liên quan:

NSURL *destinationURL = [self.ubiquitousURL URLByAppendingPathComponent:@"Documents/image.jpg"] 
[[NSFileManager defaultManager] setUbiquitous:YES 
            itemAtURL:sourceURL 
           destinationURL:destinationURL 
             error:&error] 
+0

Có cách nào để sao chép thay vì di chuyển không? – jjxtra

+1

Khi tôi thực hiện việc này, tôi đã thử tìm nạp tệp trong iCloud bằng cách sử dụng residentData = [[NSMutableArray alloc] initWithContentsOfURL: icloudURL]; nhưng điều này trả về 0 lần mỗi lần .. – coolcool1994

-1

Sử dụng mã này:

+ (NSString *)Pathsave { 
    NSString *os5 = @"5.0"; 

    NSString *currSysVer = [[UIDevice currentDevice] systemVersion]; 
    NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"]; 

    if ([currSysVer compare:os5 options:NSNumericSearch] == NSOrderedAscending) { 
     // Lower than 4 
     return path; 
    } else if ([currSysVer compare:os5 options:NSNumericSearch] == NSOrderedDescending) { 
     // 5.0.1 and above   
     return path; 
    } else { 
     // iOS 5 
     path = [NSHomeDirectory() stringByAppendingPathComponent:@"Library/Caches"]; 
     return path; 
    } 

    return nil; 
} 
6

Không có thực sự là một con đường xung quanh sử dụng UIDocument. Tôi đã cố gắng làm điều đó trong một trong những lần sử dụng iCloud đầu tiên của mình, nhưng hóa ra lại là một thảm họa mà không có UIDocument. Sử dụng UIDocument lúc đầu có vẻ như rất nhiều công việc phụ, nhưng nó không phải là.

Bạn có thể dễ dàng phân lớp UIDocument trong chưa đầy một giờ và làm cho nó hoạt động với bất kỳ loại tệp nào (chỉ cần đặt thuộc tính content là NSData). Nó cũng cung cấp nhiều lợi ích hơn các hệ thống tập tin tiêu chuẩn:

  • Thay đổi theo dõi
  • file giải quyết xung đột
  • Tài liệu hỗ trợ nhà nước
  • Tăng cường tiết kiệm/mở/tính năng gần

Thành thực mà nói, chi tiêu chỉ một hoặc hai giờ đọc trên tài liệu của Apple và sau đó sử dụng nó cũng có giá trị thời gian và sức mạnh bộ não. Bạn có thể tìm thấy bài viết khởi đầu tốt về bộ nhớ Tài liệu iCloud trong Apple's Developer Documentation.


Tôi đã viết một lớp con UIDocument sẽ hoạt động với bất kỳ loại tệp nào (đặc biệt là NSData). Bạn có thể xem, tải xuống và sửa đổi mã cho lớp con UIDocument trên GitHub.

Tạo tài liệu:

// Initialize a document with a valid file path 
iCloudDocument *document = [[iCloudDocument alloc] initWithFileURL:fileURL]; 

// Set the content of the document 
document.contents = content; 

// Increment the change count 
[document updateChangeCount:UIDocumentChangeDone]; 

Lưu một tài liệu hiện có:

// Save and close the document 
[document closeWithCompletionHandler:nil]; 

Lưu một tài liệu mới:

[document saveToURL:document.fileURL forSaveOperation:UIDocumentSaveForCreating completionHandler:nil]; 

Bạn cũng có thể đồng bộ tất cả các file được lưu trữ trong iCloud bằng cách sử dụng NSMetadataQuery. Apple cung cấp một ví dụ rất hay về việc sử dụng truy vấn NSMetadata để đồng bộ hóa các tệp ứng dụng. Ngoài ra hãy đảm bảo kiểm tra iCloud trước khi thực hiện các thao tác này (gợi ý: sử dụng phương thức ubiquityIdentityToken trên NSFileManager).


Bạn cũng có thể xem xét sử dụng thư viện nguồn mở như iCloud Document Sync. Dự án iCloud Document Sync giúp bạn lưu trữ và đồng bộ hóa các tệp ứng dụng dễ dàng:

Tích hợp iCloud vào các dự án tài liệu iOS với các phương thức mã một dòng. Đồng bộ hóa, tải lên, quản lý và xóa tài liệu khỏi iCloud một cách nhanh chóng và dễ dàng. Giúp để làm cho iCloud "chỉ làm việc" cho các nhà phát triển quá.

Trong hầu hết mọi phương thức Đồng bộ hóa tài liệu iCloud, tất cả những gì bạn phải làm là chuyển dữ liệu tệp dưới dạng tham số và sau đó xử lý phần còn lại (lưu, đồng bộ hóa, v.v.).

KHUYẾN CÁO: Tôi là nhà phát triển đóng góp cho dự án nguồn mở, Đồng bộ hóa tài liệu iCloud. Tuy nhiên, tôi tin rằng dự án này sẽ có lợi cho bạn, và có liên quan đến câu hỏi này. Đây không phải là quảng cáo hoặc quảng cáo.

+0

Đó chính xác là những gì tôi đã làm cuối cùng. – edo42

+0

Nếu trường hợp sử dụng của bạn là để đưa dữ liệu vào iCloud, bạn có thể làm điều đó với điều phối viên tập tin và không cần UIDocument. – Andy