一款宿主iOS 8应用程序。
一个或多个iOS 8扩展(WatchKit、Share等)与宿主应用程序捆绑在一起。
宿主应用程序和所有扩展共享相同的Core Data SQLite存储在共享应用程序组容器中。
每个应用程序/扩展都有自己的NSPersistentStoreCoordinator和NSManagedObjectContext。
每个持久性存储协调器使用一个持久性存储,该持久性存储与所有其他持久性存储共享组容器中的相同SQLite资源。
应用程序和所有扩展使用一个通用代码库,用于从Internet上的远程API资源同步内容。
导致问题的事件序列。
用户启动主机应用程序。它开始从远程API资源获取数据。根据API响应创建核心数据模型对象,并将其“upserted”到主机应用程序的托管对象上下文中。每个API实体都有一个唯一ID,用于在远程API后端中标识它。通过“upsert”,我指的是对于每个API实体,只有在找不到给定唯一ID的现有条目时,主机应用程序才会在Core Data中创建新条目。
同时,用户还启动了主机应用程序的其中一个扩展程序。它也从同一个远程API执行某种类型的提取。在解析API响应时,它还尝试执行“upsert”操作。
问题:如果主机应用程序和扩展程序同时尝试为同一个API实体upsert Core Data条目会发生什么?为了看到这可能是如何发生的,请看一下upsert的事件序列:
Core Data Upsert Sequence:
- API解析代码解析给定API实体的uniqueID。
- 解析器执行Core Data获取,以匹配谓词中uniqueID等于解析的uniqueID的任何条目。
- 如果找不到现有条目,则解析器会为此API实体插入一个新的Core Data条目,并将其uniqueID属性设置为解析的uniqueID。
- 解析器保存托管对象上下文,将新条目数据推送到SQLite后备存储。
详细问题
假设主机应用程序和扩展名独立地同时解析相同API实体的API响应。 如果在它们完成步骤4之前,主机应用程序和扩展名都在步骤3达到,则它们都会尝试为相同的uniqueID插入新的Core Data条目。 当它们到达步骤4并在各自的托管对象上下文上调用save:
时,Core Data将快乐地创建重复条目。
INSERT OR IGNORE
+UPDATE
combo。否则,我需要一种“锁定”持久存储的SQLite后备存储的方法,这听起来像是麻烦的食谱。是否有已知的方法来解决iOS 8扩展引入的这个相当新颖的问题?