当使用一个ManagedObjectContext和PersistentStoreCoordinator与两个商店时如何保存数据 [英] How to Save Data When Using One ManagedObjectContext and PersistentStoreCoordinator with Two Stores

查看:257
本文介绍了当使用一个ManagedObjectContext和PersistentStoreCoordinator与两个商店时如何保存数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

PROBLEM STATEMENT



尝试将记录保存到分配给同一个的两个SQLite存储之一的读/ PersistentStoreCoordinator,我的iPhone应用程式崩溃。保存记录时的一个明显问题是PersistentStoreCoordinator不知道在哪个Store中保存数据(只因为我不知道如何做到这一点)。



首先,我将提供大图片,以确保我的方法是健全的。



这是一个简化的





=https://i.stack.imgur.com/OG2zB.jpgalt =种子数据>



用户输入场景





CURRENT IMPLMENTATION



核心数据实现





数据存储和检索





当然,在查看选择列表来选择属性时,用户应该没有证据,

 >   - (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
if(_persistentStoreCoordinator == nil){
NSArray * bundles = @ [[NSBundle bundleForClass:[self class]]];
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[NSManagedObjectModel mergedModelFromBundles:bundles]];

NSError * error;
// -------------------------------------------- ------
//设置USER DATA持久存储的选项。
NSDictionary * options = @ {NSMigratePersistentStoresAutomativelyOption:@YES,
NSInferMappingModelAutomaticallyOption:@YES};
// -------------------------------------------- ------
//将USER DATA存储添加到持久存储协调器。
NSPersistentStore * persistentStore = [_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:self.persistentStorePathForUserData
options:options
error:&
// -------------------------------------------- ------
//设置SEED DATA持久存储的选项。
options = @ {NSMigratePersistentStoresAutomaticallyOption:@YES,
NSInferMappingModelAutomaticallyOption:@YES,
NSReadOnlyPersistentStoreOption:@YES};
// -------------------------------------------- ------
//将SEED DATA存储添加到持久存储协调器。
persistentStore = [_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:self.persistentStorePathForSeedData
options:options
error:&
}
return _persistentStoreCoordinator;
}

重要目标



请记住以下内容:


  1. 我希望如果可能的话,做种子数据更新而不必在幕后管理数据版本(即,仅提供应用更新仅新的或改变的种子数据记录,并以某种方式处理删除)或在代码中实现版本检查功能以处理用户从版本升级的情况n到n + 5。

  2. 用户数据和种子数据不应包含两者之间的任何重复记录,并使用相同的ManagedObjectModel。因此,从数据和模型的角度来看,不需要合并两个商店或将一个商店迁移到另一个商店。

RESEARCH



在这种情况下,
将对象从多个商店保存到单个持久存储
两个商店合并,随后提取所有记录,复制和保存上下文。我希望不必合并,然后检查成千上万的记录重复。 (请参阅上述重要目标2)



在这种情况下,
什么是合并两个iOS核心数据持久存储的有效方式?
某些实体是只读的,其他是读/写的。在我的应用程序中,种子数据存储中的所有实体都是只读的,并且用户数据存储中的相同实体是读/写的。所以我不认为迁移是适用的。 (请参阅上述重要目标2)



在Apple的 Core Data Programming Guide ,图4 显示使用两个商店的核心数据实现,但同样,每个商店配置有单独的和不同的对象。在我的应用程序中,每个对象出现在每个商店中。



这里提出的解决方案,
将两个SQLite存储组合成一个
相对于具有两个存储而在不同存储中的对象之间没有关系似乎相关,但没有详细信息



我已经浏览了前三个章节, Core Data(第2版),Marcus Zarra ,但他没有使用两个不需要迁移的商店。然而,第3章确实提供了一个非常清楚的版本化示例。 (这是复杂性导致我到上面的重要目标#1)



这个解决方案,建议使用多个配置的ManagedObjectModel,但每个实体被分配给一个且仅一个配置。我不知道该解决方案如何或甚至可以推断到我的情况。



也许这里提出的解决方案, NSPersistentStoreCoordinator与两种类型的永久性存储?,接近我需要的。不幸的是,只有请求得到解决。在类NSManagedObjectContext中,我没有看到类似于NSFetchRequest方法setAffectedStores的方法,用于保存。

解决方案

=http://www.raywenderlich.com =nofollow noreferrer> Ray Wenderlich 转介到麦克风Pringle ,Mic提出了一个管理对象模型架构,利用它我能够在坚持我的目标的同时解决问题。解决方案的关键是利用抽象实体作为用户和种子实体的父实体。





使用这种架构,可以创建两个分配给单独存储的配置:
1)UserData - 位于用户文档目录中的r / w存储。





2)SeedData - r only store位于App Bundle中。





缺点是记录必须为种子数据实体维护ID(因为配置之间不允许存在关系),但巨大的优点是可以对种子数据进行更改或添加,而不影响用户的条目,并且不必采用任何繁琐的解决方案在此问题的原始帖子的RESEARCH部分讨论。


PROBLEM STATEMENT

When attempting to save a record to a read/write store that is one of two SQLite stores assigned to the same PersistentStoreCoordinator, my iPhone app crashes. One obvious issue when saving a record is the PersistentStoreCoordinator does not know in which Store to save the data (only because I don't know how to make this happen).

First I will provide the big picture to make sure my approach is sound. Then I will supply the implementation details.

BACKGROUND

This is a simplified example representing the key aspects of the actual app I am working on.

Seed Data

User Input Scenario

CURRENT IMPLEMENTATION

Core Data Implementation

Data Storage and Retrieval

Of course, there should be no evidence to the user, when looking at pick lists to make a choice for an attribute, that the choices come from two different Stores.

Persistent Store Coordinator Setup

- (NSPersistentStoreCoordinator*)persistentStoreCoordinator {
   if (_persistentStoreCoordinator == nil) {
       NSArray *bundles = @[[NSBundle bundleForClass:[self class]]];
       _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[NSManagedObjectModel mergedModelFromBundles:bundles]];

       NSError *error;
       //--------------------------------------------------
       // Set options for the USER DATA Persistent Store.
       NSDictionary *options = @{NSMigratePersistentStoresAutomaticallyOption : @YES,
                                       NSInferMappingModelAutomaticallyOption : @YES};
       //--------------------------------------------------
       // Add the USER DATA Store to the Persistent Store Coordinator.
       NSPersistentStore *persistentStore = [_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
                                                                                   configuration:nil
                                                                                             URL:self.persistentStorePathForUserData
                                                                                         options:options
                                                                                           error:&error];
       //--------------------------------------------------
       // Set options for the SEED DATA Persistent Store.
       options = @{NSMigratePersistentStoresAutomaticallyOption : @YES,
                         NSInferMappingModelAutomaticallyOption : @YES,
                                NSReadOnlyPersistentStoreOption : @YES};
       //--------------------------------------------------
       // Add the SEED DATA Store to the Persistent Store Coordinator.
       persistentStore = [_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
                                                                configuration:nil
                                                                          URL:self.persistentStorePathForSeedData
                                                                      options:options
                                                                        error:&error];
   }
   return _persistentStoreCoordinator;
}

IMPORTANT GOALS

Keep in mind the following:

  1. I would prefer, if at all possible, to do seed data updates without having to manage data versions behind the scenes (i.e. supplying with app updates only Seed Data records that are new or changed and somehow handling deletions) or implementing version-checking functionality in the code to handle a situation in which a user is upgrading from version n to n+5.
  2. User Data and Seed Data should not contain any duplicate records between the two and use the same ManagedObjectModel. So from data and model perspectives, there should be no need to merge the two stores or migrate one store to another.

RESEARCH

In this case, Save objects from multiple stores to single persistent store, the two Stores were merged followed by fetching all the records, culling out the duplicates, and saving the context. I'm hoping not to have to merge and then check thousands of records for duplicates. (See Important Goal #2 above.)

In this case, What is an efficient way to Merge two iOS Core Data Persistent Stores?, certain entities are read-only and others are read/write. In my app, all entities in the Seed Data Store are read-only and the same entities in the User Data Store are read/write. So I don't think migration is applicable. (See Important Goal #2 above.)

In Apple's, Core Data Programming Guide under "Persistent Store Coordinator", Figure 4 "Advanced persistence stack" shows a Core Data implementation using two Stores, but again, each Store is configured with separate and distinct objects. In my app, each object appears in each Store.

The solution proposed here, Combining Two SQLite Stores Into One, relative to having two stores without relationships between the objects in the different stores seems relevant, but no details are provided to compare to what I have implemented.

I have gone through the first three chapters of, Core Data (2nd Edition), by Marcus Zarra, but he doesn't get into using two stores that don't require migration. Chapter 3, however, does provide a very clear example of versioning. (It's complexity lead me to Important Goal #1 above.)

This solution, Which persistent store is used by default in core data in iPhone, suggests using multiple configurations of the ManagedObjectModel, but each entity is assigned to one and only one configuration. I'm not sure how, or even if, this solution can be extrapolated to my situation.

Maybe the solution proposed here, NSPersistentStoreCoordinator with two types of persistent stores?, is close to what I need. Unfortunately, only requests are addressed. I don't see a method analogous to NSFetchRequest method, setAffectedStores, in Class NSManagedObjectContext for saves.

解决方案

Thanks to Ray Wenderlich's referral to Mic Pringle, Mic proposed a Managed Object Model architecture with which I was able to solve the issue while adhering to my goals. The key to the solution is utilizing an abstract entity as a parent entity to user and seed entities.

With this architecture, it is possible to create two Configurations that are assigned to separate stores: 1) UserData - r/w store located in the User's Documents directory.

2) SeedData - r only store located in the App Bundle.

The downside is that record ID's must be maintained for the seed data entities (since relationships are not allowed between Configurations), but the huge upside is that changes or additions can be made to the seed data without affecting the user's entries AND without having to adopt any of the cumbersome solutions discussed in the RESEARCH section of the original post of this question.

这篇关于当使用一个ManagedObjectContext和PersistentStoreCoordinator与两个商店时如何保存数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆