2012-06-20 43 views
10

Tôi có một ứng dụng sử dụng MagicalRecord và tôi đang điền trước cơ sở dữ liệu với một lượng lớn dữ liệu được sử dụng để tham khảo. Trong cùng một mô hình dữ liệu đó, tôi có thông tin có thể xác định người dùng liên quan đến những thứ mà người dùng có thể thực hiện trong ứng dụng.MagicalRecord: nhiều cơ sở dữ liệu

Ứng dụng bị từ chối vì dữ liệu được điền trước được cho là được đánh dấu là "không sao lưu". Vì vậy, tôi muốn có dữ liệu đó trong một kho dữ liệu riêng biệt để tôi có thể giữ dữ liệu người dùng có thể sao lưu được.

Có cách nào để có hai kho dữ liệu riêng biệt sử dụng MagicalRecord không?

Trả lời

15

Tôi nghĩ là có thể, nhưng không quá dễ dàng. Như bạn đã biết, để làm việc với nhiều cơ sở dữ liệu, bạn nên mang theo một số thay đổi cho PersistentStoreCoordinator, do đó, nó sẽ có hai số PersistentStores. Sau đó, ngăn xếp Dữ liệu cốt lõi của bạn sẽ trông giống như sau: enter image description here

Cách khác là hai tạo hai PersistentStoreCoordinators riêng biệt, mỗi bộ chứa một cửa hàng.

Trong bản ghi Magical, có một số phương pháp lớp để thêm cửa hàng trong NSPersistentStoreCoordinator + MagicalRecord.h.

  • (NSPersistentStore *) MR_addInMemoryStore;
  • (NSPersistentStore *) MR_addAutoMigratingSqliteStoreNamed: (NSString *) storeFileName;
  • (NSPersistentStore *) MR_addSqliteStoreNamed: (id) storeFileName withOptions: (__ autoreleasing NSDictionary *) tùy chọn;

Tôi nghĩ rằng đây là nơi bạn có thể làm điều mình muốn.

Ngoài ra tôi nên đề cập đến, đó là toàn bộ proccess lập stack đi trong MagicalRecord + Setup.h

+ (void) setupCoreDataStackWithStoreNamed:(NSString *)storeName 

Vì vậy, bạn có thể thêm cửa hàng và điều phối viên của bạn ở đó. Tôi chưa bao giờ tự mình quản lý, đó chỉ là một cuộc điều tra ngắn gọn về một giải pháp khả thi.

6

Tôi đã có thể giải quyết vấn đề này bằng cách sử dụng cấu hình. Vì Magical Record luôn gửi null cho tham số cấu hình, tôi đã tách rời setupCoreDataStackWithAutoMigratingSqliteStoreNamed và thay thế bằng một phương thức hỗ trợ nhiều cấu hình.

Vì Bản ghi Magical thực hiện tốt công việc xử lý tự động di chuyển, trước tiên tôi gọi setupCoreDataStackWithAutoMigratingSqliteStoreNamed, tiếp theo là dọn dẹp và sau đó tôi cung cấp mã thay thế của mình.

Tôi có một mô hình đối tượng với các đối tượng dữ liệu hạt giống được gán cấu hình "Seed" và các đối tượng người dùng được gán cho cấu hình "User". Magical Record đã được khởi tạo để nó có thể tự động di chuyển nếu cần thiết.

+(void) RB_setupMultipleStores:(NSString *) seedStoreName userStore:(NSString *) userStoreName 
/* change persistent store to one with multiple configurations. Assumes Magical Record is initialized. */ 
{ 
NSError * error= nil; 

[MagicalRecord cleanUp]; 

NSManagedObjectModel * model = [NSManagedObjectModel MR_defaultManagedObjectModel]; 

NSURL *seedURL = [NSPersistentStore MR_urlForStoreName:[seedStoreName stringByAppendingString:@".sqlite"]]; 

NSPersistentStoreCoordinator * coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model]; 

NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: 
         [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, 
         [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, 
         nil]; 

NSPersistentStore * seedStore =[coordinator 
            addPersistentStoreWithType:NSSQLiteStoreType 
            configuration:@"Seed" 
            URL:seedURL 
            options:options 
            error:&error]; 
if (!seedStore || error) 
{ 
    NSLog(@"Error setting up seed store:%@ for %@", [error localizedDescription], seedURL); 
    exit(-1); 
} 

NSURL *userURL = [NSPersistentStore MR_urlForStoreName:[userStoreName stringByAppendingString:@".sqlite"]]; 

NSPersistentStore * userStore = [coordinator 
           addPersistentStoreWithType:NSSQLiteStoreType 
           configuration:@"User" 
           URL:userURL 
           options:options 
           error:&error]; 

if (!userStore || error) 
{ 
    NSLog(@"Error setting up user store:%@ for %@", [error localizedDescription], userURL); 
    exit (-1); 
} 
[NSPersistentStoreCoordinator MR_setDefaultStoreCoordinator:coordinator]; 

[NSManagedObjectContext MR_initializeDefaultContextWithCoordinator:coordinator]; 
} 

Ngoài ra, MR 3.0 có các ngăn xếp đồng thời có thể khắc phục sự cố sau khi hoàn tất.

+0

Xin chào @Ron, cửa hàng nào bạn chuyển đến setupCoreDataStackWithAutoMigratingSqliteStoreNamed khi bạn có hai trong số đó? Người không có hạt giống? – DAN

0

Giữ dữ liệu cho các thực thể Dữ liệu cốt lõi khác nhau trong các tệp lưu trữ khác nhau được hỗ trợ tốt và khá đơn giản. Tuy nhiên, MagicalRecrd không cung cấp bất kỳ phương thức tiện lợi nào để thiết lập ngăn xếp Dữ liệu cốt lõi của bạn theo cách này. Bạn chỉ cần phân bổ stack theo cách thủ công và yêu cầu MagicalRecord sử dụng NSPersistentStoreCoordinator bạn tạo. Đây là cách tôi đã làm nó trong nhanh chóng:

import Foundation 
import CoreData 
import MagicalRecord 

class CoreDataSetup { 
    static func setupAutoMigratingStack(withContentConfigurationName contentConfigurationName: String, userConfirgurationNameName: String) { 
     MagicalRecord.cleanUp() 

     let managedObjectModel = NSManagedObjectModel.MR_defaultManagedObjectModel() 
     let persistentStoreCoordinator = NSPersistentStoreCoordinator(managedObjectModel: managedObjectModel!) 

     let contentURL = NSPersistentStore.MR_urlForStoreName(contentConfigurationName + ".sqlite") 
     let userURL = NSPersistentStore.MR_urlForStoreName(userConfirgurationNameName + ".sqlite") 
     let options = [ 
      NSMigratePersistentStoresAutomaticallyOption : true, 
      NSInferMappingModelAutomaticallyOption: true, 
      NSSQLitePragmasOption: ["journal_mode": "DELETE"] 
     ] 
     do { 
      try persistentStoreCoordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: contentConfigurationName, URL: contentURL, options: options) 
      try persistentStoreCoordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: userConfirgurationNameName, URL: userURL, options: options) 

      NSPersistentStoreCoordinator.MR_setDefaultStoreCoordinator(persistentStoreCoordinator) 
      NSManagedObjectContext.MR_initializeDefaultContextWithCoordinator(persistentStoreCoordinator) 
     } catch { 
      print("Error adding persistent store to coordinator: \(error) ") 
     } 
    } 
} 

Lưu ý rằng trong mã của tôi, tôi đang đề cập đến ý tưởng của mình trong những "hạt giống" cửa hàng là "nội dung" và các cửa hàng do người dùng định nghĩa là "người sử dụng".

Để hoàn thành khía cạnh thứ hai của câu hỏi, hãy định cấu hình cửa hàng nội dung để không sao lưu, bạn chỉ cần phát xung quanh các URL nơi bạn lưu trữ từng cửa hàng, đặt cửa hàng nội dung vào thư mục tạm thời không được sao lưu và sao chép nó vào vị trí đó khởi chạy từ gói ứng dụng của bạn nếu nó không tồn tại.

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