2013-01-06 27 views
6

Tôi đang cố tải lên một thư mục cục bộ đầy đủ tài liệu vào thư mục iCloud từ xa. Tôi đã viết phương thức này để lặp qua mảng các tệp trong thư mục cục bộ, kiểm tra xem chúng đã tồn tại chưa và nếu chúng không tồn tại, hãy tải chúng lên iCloud. Lưu ý - mã này đang được thực hiện trên chuỗi nền chứ không phải là chuỗi chính.Tài liệu không tải lên iCloud khi sử dụng cho vòng lặp - iOS

//Get the array of files in the local documents directory 
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; 
NSArray *localDocuments = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:documentsDirectory error:nil]; 

//Compare the arrays then upload documents not already existent in iCloud 
for (int item = 0; item < [localDocuments count]; item++) { 
    //If the file does not exist in iCloud, upload it 
    if (![[iCloud previousQueryResults] containsObject:[localDocuments objectAtIndex:item]]) { 
      NSLog(@"Uploading %@ to iCloud...", [localDocuments objectAtIndex:item]); 
      //Move the file to iCloud 
      NSURL *destinationURL = [[[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil] URLByAppendingPathComponent:[NSString stringWithFormat:@"Documents/%@",[localDocuments objectAtIndex:item]]]; 
      NSError *error; 
      NSURL *directoryURL = [[NSURL alloc] initWithString:[documentsDirectory stringByAppendingPathComponent:[localDocuments objectAtIndex:item]]]; 
      BOOL success = [[NSFileManager defaultManager] setUbiquitous:YES itemAtURL:directoryURL destinationURL:destinationURL error:&error]; 
      if (success == NO) { 
       //Determine Error 
       NSLog(@"%@",error); 
      } 
    } else { 
      ... 
    } } 

Khi tôi chạy mã này Vòng lặp for hoạt động tốt - Tôi sử dụng báo cáo NSLog để tìm ra các tập tin đó là tải lên - và tất cả các tập tin được lưu trữ tại địa phương đó không phải là đã có trong iCloud là vụ phải bắt đầu tải lên . Sau khi vòng lặp For hoàn tất, tôi kiểm tra xem tài liệu nào hiện đang ở trong iCloud sử dụng developer.icloud.com. Chỉ một tệp (tệp sqlite mà ứng dụng của tôi tiếp tục tạo nhưng không bao giờ sử dụng) trong số nhiều tệp tải lên cục bộ được lưu trữ lên iCloud. Tại sao chỉ có một tệp tải lên khi sử dụng cho vòng lặp?

Khi tôi sử dụng cùng một mã để tải lên các tệp riêng lẻ (không có vòng lặp For), chúng tải lên iCloud một cách hoàn hảo. Tại sao một vòng lặp For cản trở việc tải lên các tệp? Điều này có liên quan đến vòng lặp For tiếp tục với dòng mã tiếp theo mà không phải chờ quá trình/dòng cuối cùng kết thúc thực thi không? Những gì đang xảy ra ở đây?

EDIT: Thông thường khi tôi tải tệp lớn lên iCloud (không sử dụng vòng lặp For), tôi có thể thấy trên trang web iCloud dev rằng tệp đang chờ tải lên gần như ngay lập tức. Tôi đang thử nghiệm tất cả mọi thứ qua WiFi và tôi đã chờ đợi một thời gian nhưng không có gì xuất hiện (ngoại trừ tệp sqlite).

EDIT: Tôi cũng kiểm tra tính khả dụng của iCloud theo một phương pháp khác, sau đó cho phép gọi đến phương thức này nếu iCloud khả dụng. Tôi cũng đã chắc chắn đọc qua tài liệu và xem các video WWDC trên trang web của Apple, tuy nhiên chúng phức tạp và không cung cấp nhiều lời giải thích cho những gì tôi đang cố gắng làm.

EDIT: Sau khi sửa đổi mã trên (thêm chức năng báo lỗi), bây giờ tôi nhận được thông báo lỗi này trong nhật ký:

Error Domain=NSCocoaErrorDomain Code=512 "The operation couldn’t be completed. (Cocoa error 512.)" UserInfo=0x1f5dd070 {NSUnderlyingError=0x208ad9b0 "The operation couldn’t be completed. (LibrarianErrorDomain error 2 - No source URL specified.)"} 

Điều này làm cho những điều khó hiểu hơn vì một trong các tập tin cập nhật thành công , trong khi những người khác thì không.

+0

Nếu không kiểm tra mã chi tiết, tôi sẽ hỏi bạn sẽ đợi bao lâu để xem chúng đã được tải lên chưa? iCloud không phải là bản tải lên tức thì do ứng dụng của bạn thực hiện, mà là một trình nền ẩn sẽ đồng bộ hóa nội dung "cuối cùng". Bây giờ, "cuối cùng" là bình thường khá damn nhanh, nhưng nó không phải là phụ nhanh thứ hai. –

+0

Điểm tốt, tuy nhiên thường khi tôi tải các tệp lớn lên iCloud (không sử dụng Vòng lặp For), tôi có thể thấy trên trang web iCloud dev rằng tệp đang * Tải lên đang chờ xử lý * gần như ngay lập tức. Tôi đang thử nghiệm tất cả mọi thứ qua WiFi và tôi đã chờ đợi một thời gian nhưng không có gì xuất hiện (ngoại trừ tệp sqlite). –

+2

Bạn có kiểm tra xem lệnh gọi 'setUbiquitous' có trả về' YES' không, và tại sao bạn không kiểm tra và báo lỗi nếu nó trả về 'NO'? Có một lý do mà phương thức này có tham số 'error'. –

Trả lời

6

OK, chỉnh sửa cuối cùng sẽ hữu ích. Lỗi này phàn nàn rằng URL nguồn (directoryURL trong mã của bạn) bị thiếu-- có thể vì đó là nil. Tại sao lại là nil? Bởi vì bạn đang tạo ra nó sai. Bạn đang sử dụng -[NSURL initWithString:] và tài liệu nói rằng:

This string must conform to URL format as described in RFC 2396. This method parses URLString according to RFCs 1738 and 1808.

Bạn đang đi qua đường dẫn tệp chứ không phải URL. Nếu bạn vượt qua NSURL nội dung nào đó mà URL đó không nhận dạng là URL hợp lệ, nó thường trả về nil. Dường như NSURL sẽ thường xuyên tạo URL tệp, nhưng thất bại là hành vi mong đợi ở đây. Từ những gì tôi có thể nói nó có vẻ hoạt động nếu tên tập tin không chứa không gian, nhưng đó không phải là tài liệu và không phải là một cái gì đó bạn có thể dựa vào.

Điều bạn cần làm là thay đổi dòng nơi bạn khởi tạo directoryURL để sử dụng thứ gì đó chấp nhận đường dẫn tệp. Một cái gì đó như:

NSURL *directoryURL = [NSURL fileURLWithPath:[documentsDirectory stringByAppendingPathComponent:[localDocuments objectAtIndex:item]]]; 

Ngoài ra, hãy chắc chắn để xác minh rằng directoryURL không phải là nil, chỉ trong trường hợp.

+2

Hoặc thậm chí còn trực tiếp sử dụng các phương thức trả về URL thay vì làm việc với đường dẫn và chuyển đổi chúng thành URL sau. – Sven

+0

Điểm tốt, chuyển sang 'contentsOfDirectoryAtURL: includingPropertiesForKeys: options: error:' cũng sẽ thực hiện công việc. –