MHCoreDataKit
MHCoreDataKit 是一组有用的工具,其目标是通过简化使用 CoreData 的复杂度来使开发者的生活更轻松。
亮点
- 提供单个 Core Data 栈抽象
- 提供默认的 Core Data 栈实现
- 类型友好且方便的实体观察
- 类型友好、方便且无样板代码的 NSFetchRequest 设置和执行
- 方便的 NSManagedObject 初始化
- 只关注模型名称和可选配置名称 - 忘记管理存储和模型 URL
内容
该库提供了更方便使用的 CoreData 类的实用程序和扩展,减少了样板代码。
安装
Carthage
将 github "KoCMoHaBTa/MHCoreDataKit"
添加到您的 Cartfile
,然后直接嵌入框架到您的项目中。
Cocoapods
在 Podfile
中添加 pod 'MHCoreDataKit'
子模块
手动
详细资料
核心SATA堆栈协议面向抽象和通用接口
您可能已经听说过Core Data 堆栈了。您可能也已经知道设置和使用它有多么不方便。更重要的是,您可能已经在使用自定义堆栈,并且正在犹豫是否应该使用iOS 10中新引入的本地堆栈,或者迁移到它是否太不方便了。
简单来说,Core Data 堆栈在最后将提供一个供代码处理的NSManagedObjectContext
实例,其中实现细节并不重要。
为了便于您与 Core Data 堆栈一起工作,您可以使用以下工具:
CoreDataStack
- 这是一个定义 Core Data 堆栈基本类型的协议。它本身提供了执行任务和将持久存储添加到其上下文中的便捷方法。您可以使用它对应用程序进行抽象,并为任何堆栈实现它。CoreDataStackInitializationProtocol
- 这是一个定义 Core Data 堆栈初始化的协议,提供了通过自动模型查找执行初始化的默认便捷实现。NSPersistentContainer
的扩展,实现了 CoreDataStack - 如果您的应用程序正在使用 CoreDataStack 而不是具体实现,则您可以稍后始终切换到 NSPersistentContainer 或其他自定义实现,而无需更改您的应用程序代码。DefaultCoreDataStack
- 这是 CoreDataStack 和 CoreDataStackInitializationProtocol 的默认、非常基本的实现。AnyCoreDataStack
- 这是 CoreDataStack 的类型擦除器,用于 NSPersistentContainer 的实现。
DefaultCoreDataStack
如何使用 如果您只是寻找 Core Data 堆栈的简单实现,您可以使用默认实现,如下所示:
let modelName = "<#T##The name of your Core Data model#>"
let modelBundle = Bundle.main
let storeType = NSSQLiteStoreType
let options: [AnyHashable: Any] = [NSMigratePersistentStoresAutomaticallyOption: true, NSInferMappingModelAutomaticallyOption: true]
let stack = try DefaultCoreDataStack(modelName: modelName, modelBundle: modelBundle, storeType: storeType, configurationName: nil, storeName: nil, options: options)
let mainContext = stack.context
此代码将执行以下操作:
- 它将在您应用程序的主 Bundle 中查找具有提供名称的模型
- 如果模型被找到,则将其加载,否则会抛出异常
- 然后它将初始化一个
NSPersistentStoreCoordinator
实例,并使用提供选项添加 SQLite 存储。 - 最后,将会创建一个 NSManagedObject 实例,您可以通过堆栈的
context
属性访问它。
您总是可以调整输入参数或使用 CoreDataStackInitializationProtocol
的其他构造函数之一。
存储位置是基于 NSPersistentStore
扩展生成的。
便捷的实体观察
如果您听说过托管对象通知
您可能已经知道使用它们的麻烦。更不用说从Swift中使用它们了。
由于使用托管对象通知缺乏便利性和严格的类型 - 因此诞生了EntityObserver
。
它的目标是
- 易于使用
- 处理观察细节
- 将类型友好的对象传给您
如何使用它
let observer = EntityObserver<<#T##Entity#>>()
observer.observeChanges { (inserted, updated, deleted) in
//handle any changes
}
或者您只能接收特定类型变化的通知
let observer = EntityObserver<<#T##Entity#>>()
observer.observeChanges(for: .inserted) { (inserted, _, _) in
//handle inserted objects
}
或者对即将被删除的对象进行操作
let observer = EntityObserver<<#T##Entity#>>()
observer.observeChanges(upon: .willSave, for: .deleted) { (_, _, deleted) in
//handle objects are are about to be deleted
}
您可以根据需要始终调整参数。
Core Data 扩展
每当您与 Core Data 的不明确或不方便的 API 作斗争时,例如,一味地书写同一字符串样式的谓词进行查找请求,就像寻找模型并实例化它,或者决定将存储位置以及如何管理它们。
为了帮助解决这些问题,下面是现有 Core Data 类的以下扩展
NSManagedObject
如果你与 core data 打过交道,你肯定知道创建 NSManagedObject 的实例是多么不方便。但现在不必了,通过自动实体查找,您可以创建实例,就像这样
便利的初始化方法(context: NSManagedObjectContext, insert: Bool) throws
便利的初始化方法(insertingInto context: NSManagedObjectContext) throws
创建 NSFetchRequest 最初是如此简单,但结果却很麻烦,并且对于 Swift 来说不方便。苹果通过引入以下方法解决了这个问题
class func fetchRequest() -> NSFetchRequest
但是,这只能在 iOS 10+ 上使用。因此,为了方便和替换,您可以在 iOS 8+ 上的任何 NSManagedObject 子类中使用的
public static func makeFetchRequest() -> NSFetchRequest
创建实体观察者更加简单
public static func makeObserver(with context: NSManagedObjectContext? = nil) -> EntityObserver
NSFetchRequest
您将在 NSFetchRequest 上找到各种有用的扩展方法,这些方法将帮助您快速配置它以适应您最常用的需求。
//Assuming that you have NSManagedObject subclass named Person
//fetching all persons
let context: NSManagedObjectContext = //...
let allPersons: [Person] = try Person.makeFetchRequest().fetchingAll().execute(with: context)
//fetching persons with name John
let johnPersons = try Person.makeFetchRequest().fetchingBy(key: "name", value: "John").execute(with: context)
//fetching persons with name John from Canada
let result = try Person.makeFetchRequest().fetchingBy(pairs: ["name": "John", "country": "Canada"]).execute(with: context)
//fetching persons that have Senior or Lead job title, sorted by years of experience
//note that we are calling `fetchingFor` rather than `fetchingBy`
let experiencedPersons = try Person.makeFetchRequest().fetchingFor(key: "jobTitle", values: ["Senior", "Lead"]).sortedBy(key: "yearsOfExperience").execute(with: context)
请注意,每个这些配置方法都会为查找请求生成一个新的谓词,因此更改它们会导致应用最后调用的谓词。但是,您始终可以使用 configured(with: #<#T##NSPredicate?#>)
功能应用自定义谓词。
NSManagedObjectModel
通过名称查找模型创建实例。
便利构造函数?init?(name: String, bundle: Bundle = .main)
NSPersistentStore
您会发现一些便利的扩展来管理存储目录。
defaultDirectory
- 这是默认目录,所有存储都会放这里。您可以在应用程序入口处更改它,或者保留默认值,将存储放置在 Library/Application Support 目录中。commonDirectory()
- 这在默认目录内创建一个通用存储目录,存储在这里。默认为 Library/Application Support/CoreDataStores/directory(forStoreName:configurationName:in:)
此方法根据存储名称和可选配置名称返回持久存储目录URL。使用默认值将生成以下URL - Library/Application Support/CoreDataStores/Default/<storeName>
/url(forStoreName:configurationName:withExtension:in:)
此方法根据输入参数和/或默认值返回持久存储URL。使用默认值将生成以下URL - Library/Application Support/CoreDataStores/Default/<storeName>
/<storeName>
.sqlitedeleteAll()
- 默认情况下,这将删除以下文件夹 - Library/Application Support/CoreDataStores/detele(forStoreName:configurationName:in:)
此方法根据存储名称和可选配置名称删除持久存储目录。使用默认值将删除以下URL - Library/Application Support/CoreDataStores/Default/<storeName>
/
NSPersistentStoreCoordinator
在 NSPersistentStoreCoordinator 上的扩展提供了便利方法,根据存储名称和配置名称添加、删除和检索存储,而不是直接使用URL。
addPersistentStore(ofType:configurationName:storeName:options:)
- 根据名称添加持久存储。persistentStore(forName:configurationName:)
- 根据名称查找并返回持久存储。removePersistentStore(forName:configurationName:)
- 根据名称删除持久存储。removePersistentStores(forConfigurationName:)
- 移除所有与给定配置名称匹配的持久存储。removeAllPersistentStores()
- 移除所有持久存储。