Tag: 核心数据

自动预加载核心数据的SQLite文件的框架

tl; 博士—我已经发布了一个框架来为NSPersistentContainer预加载SQLite文件。 查看有关GitHub存储库的更多详细信息。 riywo / PreloadedPersistentContainer PreloadedPersistentContainer –使用预加载的SQLite数据扩展NSPersistentContainer的框架。 这支持… github.com 尽管我尚未完成任何iOS应用程序开发,但我想说Core Data是我最喜欢的iOS开发框架之一。 它是非常完善的ORM,与其他UIKit等框架本机集成,因此我可以使用它在精美的UI中提供一些数据。 我面临的一个问题是预加载数据。 我想加载约10,000条其他程序生成的数据记录。 使用Core Data(和我也喜欢的Codable),我可以通过OO方式插入记录,但是加载需要一些时间,因此我不想在启动应用程序时运行预加载过程。 由于Core Data通常由SQLite支持,因此可以选择在iOS开发之外制作SQLite数据库文件。 但是,这种方式具有很大的缺点,例如同步方案和组件紧密耦合。 我想使用Core Data进行预加载,但是我不想在iOS应用中运行它。 现在,只有一种解决方案。 在构建阶段在macOS上预加载。 我搜索了一些文章,但几乎所有文章都需要一些手动操作,例如拖放。 我不想每次更新原始数据时都这样做! 然后,有一篇文章使我有种感觉-核心数据:自动预加载主数据-这已经很老了(2013年),但对我来说是正确的方法! 因此,我深入研究了这种方法,并最终获得了Xcode 9的解决方案。但是我也认为,可以以某种方式推广这种想法。 尽管我从未编写过任何Framework,但我也开始学习Framework,并意识到它需要多平台支持,因为预加载在macOS上运行,而该应用在iOS上运行。 这个跨平台的框架也很棘手,但是在另一篇文章的帮助下-使用单元测试为iOS,OS X和tvOS创建Swift框架,并通过CocoaPods和Swift Package Manager进行分发-我可以开发我想要的框架。 干得好! riywo / PreloadedPersistentContainer PreloadedPersistentContainer –使用预加载的SQLite数据扩展NSPersistentContainer的框架。 这支持… github.com 在开发过程中,我遇到了很多问题: 如何使Core Data模型可识别多个目标? (目标成员) 什么是计划? 对我的项目有什么影响? (控制构建/测试/运行过程) 为什么我的扩展功能无法从我的测试代码中使用? (简单-公开) Bundle.main在我的单元测试中不起作用(Bundle(for:type(of:self))) 同样,我的单元测试无法识别模型(与Bundle.main相同,需要指定.mom来代替) 如何仅在单元测试中覆盖主捆绑包? (测试非公共功能+包装器公共功能; […]

掌握CoreData(第2部分核心数据栈)

核心数据栈 了解核心数据堆栈非常重要。 许多开发人员不花时间去学习它,这在使用Core Data时使他们的生活陷于瘫痪。 核心数据堆栈是框架对象的集合,这些框架对象是核心数据初始化过程的一部分, 可以在应用程序中的对象与外部数据存储之间进行调解 。 该堆栈提供了与数据模型层对象关联的所有功能或任务。 我们在第1部分中讨论的功能 核心数据堆栈由以下对象组成→一个或多个托管对象上下文连接到单个持久性存储协调器,该协调器又连接到一个或多个持久性存储。 托管对象上下文(MOC) 它的主要职责是管理一组托管对象(实体)。 受管对象上下文通常在内存中维护实体的状态。 完成对此类对象的操作后,您将保存此类MOC,通常将其保存到持久性存储协调器到持久性存储 它位于核心数据堆栈的顶部,您的应用程序将与大多数应用程序进行交互,因此它是暴露给应用程序其余部分的应用程序 应用程序可以为每个堆栈创建一个或多个 MOC。 上下文连接到持久性存储协调器或来自父上下文 它提供缓存,更改跟踪,延迟加载,重做,撤消和验证功能 持久性存储协调员(PSC) NSPersistentStoreCoordinator的实例。 协调器是核心数据堆栈中的中心对象。 持久存储协调器的作用是管理多个/单个存储 ,并向其管理对象上下文提供单个统一存储的外观,如下图所示,该图协调器与多个存储进行通信。 它具有对托管对象模型的引用,如下图2.1所示。 持久性存储协调员可以交谈或引用堆栈中的大多数组件 永久商店 您可以将持久性存储视为数据库文件(Sqlite),其中的每个记录均包含托管对象(实体)的最后保存值。 核心数据还提供了一个内存存储,其存储时间不超过流程生命周期的时间 我们可以在每个堆栈上创建多个持久性存储 Core Data为持久性存储提供了三种本机文件类型:二进制,XML和SQLite。 如果您希望Core Data与自定义文件格式或服务器进行互操作,则可以实现自己的商店类型 被管理对象 NSManagedObject的实例。 它代表持久性存储中的记录 向托管对象上下文注册托管对象。 在任何给定的上下文中,最多存在一个与持久存储中给定记录相对应的托管对象实例 托管对象模型 托管对象模型是一组对象,这些对象一起构成了一个蓝图,描述了您在应用程序中使用的托管对象 您的应用程序中使用的模型对象的架构 持久对象库 持久性对象存储在应用程序中的对象之间映射,并在持久性存储中记录。 Core Data支持的不同文件类型有不同的持久对象存储类 如果要支持自定义文件类型,也可以实现自己的文件 您不会直接创建持久对象存储。 相反,Core Data在发送时会为您创建适当类型的存储 向持久性存储协调器发送的addPersistentStoreWithType:configuration:URL:options:error:消息。 摘要 在这一部分中,我们讨论了核心数据栈。 这部分目的是将理论上的东西放在一个地方。 如果您对核心数据栈一无所知,请不要担心我们何时进行编码部分,当我引用这些要点时,这些要点将变得清楚。 […]

核心数据CRUD

在本教程中,您将学习如何使用Core Data框架从持久性存储中插入,获取,更新和删除数据。 您将执行的步骤: 使用集成的核心数据创建一个新项目 创建一个新实体 将数据插入持久性存储 提取实体的所有数据 使用实体的ID提取实体的托管对象 更新管理对象的数据 删除托管对象 清除实体的所有数据 如果您遇到以下任何问题,可以在此处下载完整的源代码项目。 1.使用集成的核心数据创建一个新项目 创建新项目时,请选中“ 使用核心数据”选项。 因此,Xcode将为您准备使用骨架数据的框架 Xcode创建项目之后。 Xcode为您添加了2件事: AppDelegate.swift文件中的几行代码 [项目名称] .xcdatamodeld文件 打开AppDelegate.swift文件,您将看到一些代码行,如下所示: 接下来,选择菜单编辑器->创建NSManagedObject子类 。 遵循Xcode的指南为您创建NSManagedObject的子类 3.将数据插入持久性存储 要将数据插入持久性存储中,首先,需要实例化一个托管对象,为其属性填充内容并保存上下文。 将以下代码段添加到您的视图控制器中: 运行该应用程序,一切都会正常进行,并出现错误。 4.提取实体的所有数据 首先,您需要阅读以下一些文章,以了解如何从持久性存储中获取数据: NSFetchRequest 用于从持久性存储中检索数据的搜索条件的描述。 取(_:) 返回满足给定提取请求指定的条件的对象数组。 显示插入的内容。 将以下方法添加到视图控制器中: 运行该应用程序,该人的信息应显示在控制台日志中 5.使用实体的ID提取实体的托管对象 每个管理对象都有一个全局ID。 使用此全局ID,您可以获得托管对象。 全局ID的格式如下: x-coredata://F172B5AC-C592–42AC-8110-D968E3B69FC9/Person/p8 要获取托管对象的全局ID,请使用以下代码行: managedObject.objectID.uriRepresentation().absoluteString 从此全局ID可以使用以下代码行获取托管对象: managedObjectContext.persistentStoreCoordinator?.managedObjectID(forURIRepresentation: URL(string: globalID)!) 将以下代码段添加到您的视图控制器中,以显示第一人称的信息: 运行该应用程序并查看控制台日志。 6.更新管理对象的数据 要更新托管对象,只需更新该托管对象的属性并保存上下文。 将以下代码段添加到您的视图控制器中: 运行应用程序并检查控制台日志 […]

掌握CoreData(第3部分:核心数据中的CRUD)

为了演示核心数据的基础知识,让我们创建一个单视图iOS应用,并选择“ 使用核心数据”或下载入门项目。 如果您有一个现有项目,但未选中“ 使用核心数据”复选框,则仍然可以添加核心数据,我将在后面的部分中进行介绍。 创建项目后,您将看到添加的文件如CrudOperationCoreData.xcdatamodeld 。 我将在Todo应用程序上演示CRUD操作。 最终版应用可以执行以下功能 用户可以添加任务 用户可以删除任务 用户可以看到所有任务 当您使用CrudOperationCoreData.xcdatamodeld文件时,您将看到一个工具,可用于配置代表数据模型的实体。 您可以为每个实体定义一些事物,但对我们而言, 属性和关系将是最重要的。 到目前为止,我们已经完成了创建并获得核心数据支持的项目。 在CrudOperationCoreData.xcdatamodeld中,我们用数据库术语定义Entity或表,并定义属性(数据库术语列)。 “ xcdatamodeld ”是一个称为“ 受管对象模型 ”的文件,其中,如上一部分所述,定义了应用程序的所有架构。 我说过,我们将 深入讨论时 将称为 第2部分 ,因为我们在该部分的理论方面进行了很多讨论。 托管对象模型 托管对象模型是一组对象,这些对象一起构成了一个蓝图,描述了您在应用程序中使用的托管对象 您的应用程序中使用的模型对象的架构 正如我们在第2部分中讨论的那样,我们需要创建Core Data堆栈才能使用Core Data,但是我们还没有创建堆栈。 事实是,当我们在创建项目时选中“ 使用核心数据”时,它会自动在AppDelegate文件中创建堆栈代码。 打开AppDelegate文件 当您看到代码时,您几乎看不到您在Core Data stack Part 2中学到的任何东西。 但是您可以看到NSPersistentContainer的惰性属性 NSPersistentContainer NSPersistentContainer通过处理托管对象模型(NSManagedObjectModel),持久性存储协调器(NSPersistentStoreCoordinator)和托管对象上下文(NSManagedObjectContext)的创建,简化了核心数据堆栈的创建和管理。 可从iOS 10获得 当您跳到NSPersistentContainer类定义时,您将在此处看到所有Core Data堆栈组件。 创建记录核心数据 将记录添加到核心数据的过程具有以下任务 从appdelegate单例对象引用persistentContainer 从persistentContainer创建/访问单例托管对象上下文 使用Task创建一个实体(代表ToDo任务) 使用此任务实体创建新记录 设置每个键的记录值 将其保存到磁盘(永久存储)。 […]

精通CoreData(第17部分,多线程并发策略上下文UndoManager)

这一部分是上一部分的延续。 必须查看使用父子策略解决的临时问题。 现在,在这一部分中,我们将使用undo manager解决此问题。 要了解什么是临时更改问题,请参考上一部分 在第二部分中,我们说 托管对象上下文(MOC) 托管对象上下文提供缓存,更改跟踪,延迟加载, 重做,撤消和验证功能 撤消管理员 UndoManager提供了一种简单的方法来向您的托管对象上下文添加撤消/重做功能。 它是托管对象上下文的Instance属性。 如果您遵循这些教程,请下载入门项目或删除应用程序。 首先注释掉这些行, 如图1所示。 从流程图了解撤消管理器 如您在图2中看到的,我们执行了许多任务以了解undo manager的工作方式 首先,我们启动/开始撤消组以跟踪我们将执行的更改。 此时撤消管理器开始跟踪更改 将用户1添加到托管对象上下文中,并将其引用到撤消堆栈 将用户2添加到托管对象上下文中,并将其引用到撤消堆栈 结束撤消组(这很重要,否则应用程序将崩溃) 执行context.undo撤消更改 如您所见, 用户1和用户2现在已删除并移至重做堆栈中 现在出现执行重做用户1和用户2 如您在图3中看到的,我们将流程图论证明为代码 已创建“托管对象上下文”的undoManager实例属性。 默认情况下,在iOS中,其值为nil 通过调用beginUndoGrouping ,我们开始跟踪对象并将其分组到撤消堆栈中 在托管对象上下文中添加了两个用户对象 endUndoGrouping将结束该组。 这个非常重要 最后,我们通过执行撤消和重做操作来查看日志 如您所见,撤消操作后未打印任何User对象。 通过重做在控制台上打印的两个用户对象 注意:首先beginUndoGrouping将分组级别增加到2。 嵌套撤消组 在最后一个撤消组中执行撤消操作 如图4所示undoNestedGroup组撤消添加用户2时的最后一个组。 如您所见,我们在第一个撤消组上添加了用户,在第二个或最后一个撤消组上添加了用户2。 通过执行undoNestedGroup ,它将撤消添加了User2的最后一个撤消组。 现在,第一个撤消组成为再次调用undoNestedGroup之后的最后一个撤消组,它将删除User1, 如图4所示。 如您在图5中看到的,我们使用代码进行了证明。 执行撤消嵌套组撤消最后一组。 有很多事情你应该知道 undo →如有必要,关闭顶级撤消组,并调用undoNestedGroup() 。 undoNestedGroup →在最后一个撤消组(顶级或嵌套)中执行撤消操作,将重做堆栈上的操作记录为单个组 […]