MHCoreDataKit 1.4.0

MHCoreDataKit 1.4.0

Milen Halachev维护。



  • 作者:
  • Milen Halachev

MHCoreDataKit

Build Status

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 - 这是 CoreDataStackCoreDataStackInitializationProtocol 的默认、非常基本的实现。
  • 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>.sqlite
  • deleteAll() - 默认情况下,这将删除以下文件夹 - 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() - 移除所有持久存储。