Swift 4.2 Platforms iOS | watchOS | tvOS | macOS CocoaPods Carthage Swift Package Manager License MIT

⚠️由于此仓库即将被存档,我建议迁移到 NSPersistentContainer (iOS 10 及更高版本可用)。对于其他方便的助手,除了管理堆栈之外,我目前只使用 这个

AERecord

用于 Core Data 的超级棒的 Swift 小助手 (iOS, macOS, tvOS)

我制作这个是为了个人使用,但也欢迎您使用或贡献。更多示例请查看 SourcesTests

索引

介绍

AECoreDataUI 之前是 AERecord 的一部分,因此您可能也想查看一下。

为什么我们还需要另一个 Core Data 封装器? 您来告诉我!
受到许多不同 (剧透警告) 神奇的 解决方案的启发,我想要一些能够将复杂性和功能恰到好处地结合起来的东西。所有用于设置 Core Data 堆栈的样板代码,在整个项目和不同线程中传递正确的 NSManagedObjectContext,更不用说那些用于创建或查询数据的枯燥的 NSFetchRequest 样板代码 - 应该用这个变得更简单。

特性

用法

您可以查看 这个演示项目 作为示例。

创建 Core Data 堆栈

AERecord 中几乎所有内容都使用“可选”参数(如果您不指定任何内容,则具有默认值)。
所以您可以像这样加载(如果不存在则创建)CoreData 堆栈

do {
    try AERecord.loadCoreDataStack()
} catch {
    print(error)
}

或像这样

let myModel: NSManagedObjectModel = AERecord.modelFromBundle(for: MyClass.self)
let myStoreType = NSInMemoryStoreType
let myConfiguration = ...
let myStoreURL = AERecord.storeURL(for: "MyName")
let myOptions = [NSMigratePersistentStoresAutomaticallyOption : true]
do {
    try AERecord.loadCoreDataStack(managedObjectModel: myModel, storeType: myStoreType, configuration: myConfiguration, storeURL: myStoreURL, options: myOptions)
} catch {
    print(error)
}

或这些的任何组合。

如果出于任何原因您想完全删除您的堆栈并重新开始(例如,单独的演示数据堆栈),您可以像这样简单地做到这一点

do {
    try AERecord.destroyCoreDataStack() // destroy default stack
} catch {
    print(error)
}

do {
    let demoStoreURL = AERecord.storeURL(for: "Demo")
    try AERecord.destroyCoreDataStack(storeURL: demoStoreURL) // destroy custom stack
} catch {
    print(error)
}

同样,您可以删除所有实体中的所有数据(而不会弄乱堆栈),就像这样

AERecord.truncateAllData()

上下文操作

如果您不指定任何上下文,则使用当前线程的上下文 (Context.default)(以下所有示例都使用 Context.default)。

// get context
AERecord.Context.main // get NSManagedObjectContext for main thread
AERecord.Context.background // get NSManagedObjectContext for background thread
AERecord.Context.default // get NSManagedObjectContext for current thread

// execute NSFetchRequest
let request = ...
let managedObjects = AERecord.execute(fetchRequest: request) // returns array of objects

// save context
AERecord.save() // save default context
AERecord.saveAndWait() // save default context and wait for save to finish

// turn managed objects into faults (you don't need this often, but sometimes you do)
let objectIDs = ...
AERecord.refreshObjects(with: [objectIDs], mergeChanges: true) // turn objects for given IDs into faults
AERecord.refreshRegisteredObjects(mergeChanges: true) // turn all registered objects into faults

简易查询

简易查询助手创建为 NSManagedObject 扩展。
所有查询都在通用 NSManagedObject 上调用,如果您不指定任何上下文,则使用 Context.default(以下所有示例都使用 Context.default)。所有查找器都有用于 NSSortDescriptor 的可选参数,这些示例中未使用该参数。有关更多示例,请查看单元测试。

通用

如果您需要自定义 NSFetchRequest,您可以使用 createPredicate(with:)createFetchRequest(predicate:sortdDescriptors:),根据您的意愿进行调整,并使用 AERecord 执行。

// create request for any entity type
let attributes = ...
let predicate = NSManagedObject.createPredicate(with: attributes)
let sortDescriptors = ...
let request = NSManagedObject.createFetchRequest(predicate: predicate, sortDescriptors: sortDescriptors)

// set some custom request properties
request.someProperty = someValue

// execute request and get array of entity objects
let managedObjects = AERecord.execute(fetchRequest: request)

当然,所有常用的创建、查找、计数或删除实体的请求都已经存在,所以请继续阅读。

创建

NSManagedObject.create() // create new object

let attributes = ...
NSManagedObject.create(with: attributes) // create new object and sets it's attributes

NSManagedObject.firstOrCreate(with: "city", value: "Belgrade") // get existing object (or create new if it doesn't already exist) with given attribute

let attributes = ...
NSManagedObject.firstOrCreate(with: attributes) // get existing object (or create new if it doesn't already exist) with given attributes

查找第一个

NSManagedObject.first() // get first object

let predicate = ...
NSManagedObject.first(with: predicate) // get first object with predicate

NSManagedObject.first(with: "bike", value: "KTM") // get first object with given attribute name and value

let attributes = ...
NSManagedObject.first(with: attributes) // get first object with given attributes

NSManagedObject.first(orderedBy: "speed", ascending: false) // get first object ordered by given attribute name

查找全部

NSManagedObject.all() // get all objects

let predicate = ...
NSManagedObject.all(with: predicate) // get all objects with predicate

NSManagedObject.all(with: "year", value: 1984) // get all objects with given attribute name and value

let attributes = ...
NSManagedObject.all(with: attributes) // get all objects with given attributes

删除

let managedObject = ...
managedObject.delete() // delete object (call on instance)

NSManagedObject.deleteAll() // delete all objects

NSManagedObject.deleteAll(with: "fat", value: true) // delete all objects with given attribute name and value

let attributes = ...
NSManagedObject.deleteAll(with: attributes) // delete all objects with given attributes

let predicate = ...
NSManagedObject.deleteAll(with: predicate) // delete all objects with given predicate

计数

NSManagedObject.count() // count all objects

let predicate = ...
NSManagedObject.count(with: predicate) // count all objects with predicate

NSManagedObject.count(with: "selected", value: true) // count all objects with given attribute name and value

let attributes = ...
NSManagedObject.count(with: attributes) // count all objects with given attributes

去重

do {
    try NSManagedObject.distinctValues(for: "city") // get array of all distinct values for given attribute name
} catch {
    print(error)
}

do {
    let attributes = ["country", "city"]
    try NSManagedObject.distinctRecords(for: attributes) // get dictionary with name and values of all distinct records for multiple given attributes
} catch {
    print(error)
}

自动递增

如果您需要具有自动递增属性,只需创建一个 Int 类型的属性,并像这样获取下一个 ID

NSManagedObject.autoIncrementedInteger(for: "myCustomAutoID") // returns next ID for given attribute of Integer type

将托管对象转换为 fault

NSFetchedResultsController 旨在一次只监视一个实体,但是当存在稍微复杂的 UI(例如,也显示来自相关实体的数据)时,您有时必须手动刷新此相关数据,这可以通过将“监视的”实体对象转换为 fault 来完成。这是执行此操作的快捷方式(mergeChanges 参数默认为 true)。您可以在 Core Data 文档中阅读有关将对象转换为 fault 的更多信息。

let managedObject = ...
managedObject.refresh() // turns instance of managed object into fault

批量更新

批量更新是 iOS 8 中的“新”功能。它直接在持久化存储中执行操作,因此请谨慎使用,并首先阅读文档。顺便说一句,NSPredicate 在这里也是可选参数。

NSManagedObject.batchUpdate(properties: ["timeStamp" : NSDate()]) // returns NSBatchUpdateResult?

NSManagedObject.objectsCountForBatchUpdate(properties: ["timeStamp" : NSDate()]) // returns count of updated objects

NSManagedObject.batchUpdateAndRefreshObjects(properties: ["timeStamp" : NSDate()]) // turns updated objects into faults after updating them in persistent store

安装

许可证

AERecord 在 MIT 许可证下发布。有关详细信息,请参阅 LICENSE