EZCoreData 0.7.3

EZCoreData 0.7.3

Marcelo Salloum 维护。



  • marcelosalloum

EZCoreData

Build Status Codacy Badge codecov Version License Platform

一个库,用于为 CoreData 构建基本的主和私有上下文,并提供一些实用方法

目录

示例项目

要运行示例项目,请先克隆此存储库,然后从 Example 目录中运行 pod install

安装

EZCoreData 可以通过 CocoaPods 获得使用。要安装它,只需将以下行添加到您的 Podfile 中

pod 'EZCoreData'

使用方法

设置

基本有两种启动EZCoreData的方法。推荐使用EZCoreData.shared实例。

import EZCoreData

class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Init Core Data
        EZCoreData.databaseName = "My_DB_Name"      // Initialize Core Data
        _ = EZCoreData.shared                       // Initialize Core Data
        return true
    }
...
}

或者,您可以在自己的类中保存EZCoreData的实例。例如AppDelegate。

import EZCoreData

class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?
    var ezCoreData: EZCoreData!

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Init Core Data
        ezCoreData = EZCoreData("My_DB_Namme") {
            // Handle completion
        }
        return true
    }
...
}

计数

设置好核心数据后,让我们运行一个简单的计数方法。假设您有一个名为Article的NSManagedObject子类,您可以按以下方式计数

let articleCount = Article.count()

很简单,对吧?顺便说一下,您可以在这里传递一个谓词,这样就可以计数符合该谓词的文章。例如

let articleCount = Article.count(NSPredicate(format: "title CONTAINS[c] 'Art'"))

创建 & 保存

let newArticle = Article.create()
newArticle?.id = Int.random(in: 0...400)
newArticle?.managedObjectContext?.saveContextToStore()

获取或创建

let newOrExistingArticle = Article.getOrCreate(attribute: "id", value: 2, context: context)
newOrExistingArticle.title = "EZCoreData lib was finally launched, and it looks great!"
newOrExistingArticle.save()

读取第一个

您可以根据给定属性读取第一个对象

let article = Article.readFirst(attribute: "id", value: "123")

或者,您可以通过您选择的谓词进行过滤

let article = try Article.readFirst(NSPredicate(format: "id == 123"))

如果不传递任何谓词,结果将是CoreData中的第一个Article。

阅读全部

同样,您可以传递属性或谓词来获取对象列表

let articleList = Article.readAllByAttribute("title", value: "Art")

或者谓词

let predicate = NSPredicate(format: "title CONTAINS[c] '\(searchTerm)' or authors CONTAINS[c] '\(searchTerm)'")
Article.readAll(predicate: predicate)

如同其他读取方法,如果不传递任何谓词,结果将是全部文章列表

let allArticles = Article.readAll()

删除一个

article.delete(context: context)

删除全部

您可以通过以下方式执行删除全部操作

Article.deleteAll()

或者删除子集

let remainingList = Article.readAll(predicate: NSPredicate(format: "title CONTAINS[c] 'Art'"))
Article.deleteAll(except: remainingList, context: context)

高级主题

异步方法

下面的示例只说明了Synic函数(没有try-catch错误处理部分),所以至少要说明一个异步方法作为示例:D

Article.readFirst(attribute: "title", value: "Art") { (awesomeResult) in
    switch awesomeResult {
    case .success(result: let articlesList):
        print(articlesList!)                 // Do something with your list of articles
    case .failure(error: let error):
        print(error.localizedDescription)    // Handle your error
    }
}

将JSON导入对象

假设我们有一个JSON数组或者是一个您想要导入到您的CoreData中的JSON对象。要做到这一点,您首先需要覆盖您在 NSManagedObjectContext 子类中的方法 open func populateFromJSON(_ json: [String: Any], context: NSManagedObjectContext),就像我们在您的示例项目中做的那样。

import CoreData
import EZCoreData


public class Article: NSManagedObject {
    /// Populates Article objects from JSON
    public override func populateFromJSON(_ json: [String : Any], context: NSManagedObjectContext) {
        guard let rawId = json["id"]\ else { return }
        self.id = id
        self.title = json["title"] as? String

        guard let tags = json["tags"] as? [[String: Any]] else { return }
        do {
            guard let tagObjects = try Tag.importList(tags, idKey: "id", shouldSave: false, context: context) else { return }
            self.addToTags(NSSet(array: tagObjects))
        } catch let error {
            print(error.localizedDescription)
        }
    }
}

覆盖方法 open func populateFromJSON(_ json: [String: Any], context: NSManagedObjectContext) 后,您可以像这样简单地导入一个对象:

let jsonObject: [String: Any] = [
    "id": 1,
    "title": "EZCoreData lib was finally launched, and it looks great!"
]
let article = importObject(jsonObject, shouldSave: true)

要从JSON导入对象列表,只需这样做

let jsonArray: [[String: Any]] = [
    [
        "id": 1,
        "title": "EZCoreData lib was finally launched, and it looks great!"
    ],
    [
        "id": 2,
        "title": "EZCoreData launch was delayed in 1 week"
    ],
]
let articlesList = Article.importList(jsonArray, idKey: "id", shouldSave: true)

您可以在本仓库的示例项目中查看该功能的代码示例。

错误处理

这个库中的大多数函数都有两个版本:同步和异步。它们处理错误的方式不同:同步函数:SYNC函数会抛出错误,用户可以使用do+try+catch或者至少使用try?try!来处理。 异步函数:ASYNC函数在内部处理错误,然后以非常文明的完成处理程序返回结果,这源自以下枚举

/// Handles any kind of results
public enum EZCoreDataResult<Object> {
    /// Handles success results
    case success(result: Object?)

    /// Handles failure results
    case failure(error: Error)
}

NSManagedObjectContext

这个库的设计是为了在主线程运行同步任务,在后台任务上运行异步任务。因此,在共享实例中包含两个内置的NSManagedObjectContext

  • EZCoreData.shared.mainThreadContext:用于库中的同步方法。在用户浪费时间等待CoreData结果时,建议使用主上下文。
  • EZCoreData.shared.privateThreadContext:用于库中的异步方法。建议在进行耗时任务或在用户不需要浪费时间等待结果时使用后台/私有上下文。

您还可以在便利方法中使用自己的NSMAnagedObjectContext。所有方法都有一个可选参数context: NSManagedObjectContext,如果您没有指定它们,则会使用默认上下文之一填充。重要的是要说明,预置的上下文应该可以正常工作,并有单元测试来保证这一点。

文件引用

  • EZCoreData:用于管理项目NSPersistentContainerNSManagedObjectContext的实例
  • EZCoreDataLogger:用于保存默认的LogLevel、Error和ResultCallback枚举,以及一些便于管理日志(错误、警告和信息日志)的便利方法
  • NSManagedObjectContext+Save:包含一个便利方法(实际上是方法的同步和/或异步版本),当您想要确保privateThreadContext的更改将传递给其父和兄弟
  • NSManagedObject+Create:一组用于创建和保存对象的便利方法
  • NSManagedObject+Read:包含计数对象和从数据库读取列表或单个对象的便利方法
  • NSManagedObject+Update:用于将对象导入数据库。包括getOrCreate方法
  • NSManagedObject+Delete:用于删除具有给定特征的列表对象,允许用户避免从特定列表中删除

作者

marcelosalloum, [email protected]

许可证

EZCoreData可用于MIT许可证下。有关更多信息,请参阅LICENSE文件。