Trong ứng dụng của chúng tôi đang được phát triển, chúng tôi đang sử dụng Dữ liệu cốt lõi với một cửa hàng sao lưu sqlite để lưu trữ dữ liệu của chúng tôi. Mô hình đối tượng cho ứng dụng của chúng tôi rất phức tạp. Ngoài ra, tổng số lượng dữ liệu do ứng dụng của chúng tôi phân phối quá lớn để phù hợp với gói ứng dụng iOS (iPhone/iPad/iPod Touch). Do thực tế là người dùng của chúng tôi thường chỉ quan tâm đến một tập hợp con dữ liệu, chúng tôi đã phân đoạn dữ liệu của mình theo cách mà ứng dụng gửi cùng với tập hợp con (mặc dù, ~ 100 MB) đối tượng dữ liệu trong gói ứng dụng. Người dùng của chúng tôi có tùy chọn tải xuống các đối tượng dữ liệu bổ sung (có kích thước ~ 5 MB đến 100 MB) từ máy chủ của chúng tôi sau khi họ thanh toán cho các nội dung bổ sung thông qua mua hàng trong ứng dụng iTunes. Tệp dữ liệu gia tăng (hiện có trong các cửa hàng sao lưu sqlite) sử dụng cùng phiên bản xcdatamodel làm dữ liệu đi kèm với gói; không có thay đổi đối với mô hình đối tượng. Các tệp dữ liệu gia tăng được tải xuống từ máy chủ của chúng tôi dưới dạng các tệp sqlite được nén. Chúng tôi không muốn bloat gói ứng dụng của chúng tôi bằng cách vận chuyển các nội dung gia tăng với ứng dụng. Ngoài ra, chúng tôi không muốn dựa vào các truy vấn trên webservice (vì mô hình dữ liệu phức tạp). Chúng tôi đã thử nghiệm tải xuống dữ liệu sqlite gia tăng từ máy chủ của chúng tôi. Chúng tôi đã có thể thêm kho lưu trữ dữ liệu đã tải xuống vào persistentStoreCoordinator được chia sẻ của ứng dụng. Cách hiệu quả để kết hợp hai Cửa hàng liên tục dữ liệu lõi iOS là gì?
{
NSError *error = nil;
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:defaultStoreURL options:options error:&error])
{
NSLog(@"Failed with error: %@", [error localizedDescription]);
abort();
}
// Check for the existence of incrementalStore
// Add incrementalStore
if (incrementalStoreExists) {
if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:incrementalStoreURL options:options error:&error])
{
NSLog(@"Add of incrementalStore failed with error: %@", [error localizedDescription]);
abort();
}
}
}
Tuy nhiên, có hai vấn đề với làm nó theo cách này.
- dữ liệu lấy kết quả (ví dụ, với NSFetchResultController) xuất hiện với dữ liệu từ incrementalStoreURL nối vào cuối của dữ liệu từ defaultStoreURL.
- Một số đối tượng được sao chép. Có nhiều thực thể với dữ liệu chỉ đọc trong mô hình dữ liệu của chúng tôi; chúng được nhân đôi khi chúng ta thêm persistent thứ haiCài đặt vào persistentStoreCoordinator.
Lý tưởng nhất, chúng tôi muốn Core Data hợp nhất đồ thị đối tượng từ hai cửa hàng liên tục thành một (không có mối quan hệ chia sẻ giữa hai cửa hàng tại thời điểm tải xuống dữ liệu). Ngoài ra, chúng tôi muốn xóa các đối tượng trùng lặp. Tìm kiếm trên web, chúng tôi đã thấy một số câu hỏi của những người cố gắng làm điều tương tự mà chúng tôi đang thực hiện - chẳng hạn như this answer và this answer. Chúng tôi đã đọc Marcus Zarra's blog on importing large data sets in Core Data. Tuy nhiên, không có giải pháp nào mà chúng tôi đã thấy có hiệu quả đối với chúng tôi. Chúng tôi không muốn đọc theo cách thủ công và lưu dữ liệu từ cửa hàng gia tăng vào cửa hàng mặc định vì chúng tôi nghĩ điều này sẽ rất chậm và dễ xảy ra lỗi trên điện thoại. Có cách nào hiệu quả hơn để thực hiện hợp nhất không?
Chúng tôi đã cố gắng giải quyết sự cố bằng cách triển khai quá trình di chuyển thủ công như sau. Tuy nhiên, chúng tôi đã không thể thành công để hợp nhất xảy ra. Chúng tôi không thực sự rõ ràng về giải pháp được đề xuất bởi câu trả lời 1 và 2 được tham chiếu ở trên. Blog của Marcus Zarra đã giải quyết một số vấn đề mà chúng tôi đã có ngay từ đầu dự án của chúng tôi, nhập dữ liệu lớn của chúng tôi vào iOS.
{
NSError *error = nil;
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
NSMigrationManager *migrator = [[NSMigrationManager alloc] initWithSourceModel:__managedObjectModel destinationModel:__managedObjectModel];
if (![migrator migrateStoreFromURL:stateStoreURL
type:NSSQLiteStoreType
options:options
withMappingModel:nil
toDestinationURL:destinationStoreURL
destinationType:NSSQLiteStoreType
destinationOptions:nil
error:&error])
{
NSLog(@"%@", [error userInfo]);
abort();
}
}
Dường như tác giả của câu trả lời 1 đã đọc dữ liệu của anh ấy từ cửa hàng gia tăng và lưu vào cửa hàng mặc định. Có lẽ, chúng tôi đã hiểu lầm giải pháp được đề xuất bởi cả hai bài viết 1 & 2. Kích thước dữ liệu của chúng tôi có thể ngăn cản chúng tôi đọc thủ công và chèn lại dữ liệu gia tăng của chúng tôi vào cửa hàng mặc định. Câu hỏi của tôi là: cách hiệu quả nhất để có được đồ thị đối tượng từ hai persistentStore (có cùng objectModel) để hợp nhất vào một persistentStore là gì?
Tự động di chuyển hoạt động khá tốt khi chúng tôi thêm thuộc tính thực thể mới vào biểu đồ đối tượng hoặc sửa đổi mối quan hệ. Có một giải pháp đơn giản để hợp nhất dữ liệu tương tự vào cùng một kho lưu trữ bền vững sẽ đủ kiên trì để dừng và tiếp tục lại - khi quá trình di chuyển tự động được thực hiện?
Marcus Zarra ở đâu khi tôi cần anh ấy? Tôi đã thực hiện một số tiến trình bằng cách sử dụng [NSPersistentStore migratePersistentStore: toURL: options: withType: error] method. Tôi chỉ cần thêm một vài mã để có được nơi tôi cần. – Sunny
Tôi đang vật lộn với cùng một thứ. Bạn có thể đăng những gì bạn đã đưa ra cho đến nay? Tôi bị lạc. – damon
Xong! Hãy cho tôi biết làm thế nào nó quay ra cho bạn. – Sunny