一个 Core Data 封装器,利用泛型的强大功能,使您可以处理自定义模型对象。
Y—Persistence 基于 Apache 2.0 许可证 发布。
文档自动从源代码注释生成,并呈现为通过 GitHub Pages 托管的静态网站:https://yml-org.github.io/ypersistence-ios/
PersistenceManager
用作 Core Data 的 NSPersistentContainer
的封装器,并且还提供托管对象上下文以执行核心数据操作。
您需要为每个 NSPersistentContainer
实例化一个 PersistenceManager
。 这应该在应用程序启动时完成。 然后,您应该使用依赖注入将其传递给需要它的类。
标准初始化器允许您指定模型名称、合并策略和捆绑包。 它为合并策略和捆绑包提供了合理的默认值,但您需要提供模型名称。
首次使用之前,您需要在持久性管理器上调用 load
,这是一个异步操作。 通常它很快,但在需要迁移时可能需要几秒钟。
import YPersistence
final class AppCoordinator {
let persistenceManager = PersistenceManager(modelName: "MyModel")
func configure(completion: @escaping () -> Void) {
// configure analytics, network, etc.
...
// configure persistence
persistenceManager.load { _ in
completion()
}
}
}
每个持久性管理器都有三种方法来提供托管对象上下文
mainContext
返回主上下文,仅适用于主线程上的只读操作。
workerContext
返回一个新的私有队列上下文,适用于短期的添加、编辑或删除操作。
contextForThread
返回一个适用于仅在当前线程上进行只读操作的上下文。 从主线程调用时,它将返回 mainContext
。 从后台线程调用时,它将为该线程创建一个新的私有队列上下文(如果尚未存在)并缓存它。
在大多数简单的用例中,您甚至不需要担心管理上下文,因为对于保存和删除操作,将创建一个本地 workerContext
,对于提取操作,将使用适当的 contextForThread
。 对于高级用例,我们支持传入您希望使用的上下文。
重要提示: 所有写入 Core Data 容器的操作都应通过短期的 worker 上下文完成。 读取可以从任何上下文完成,只要它与创建上下文的线程相同。
Y—Persistence 利用泛型的强大功能,使您可以执行常见的操作(例如提取、保存和删除),而无需为每个实体(SQL 表)创建单独的查询。 它还允许您在 Core Data NSManagedObject
和通用模型对象(结构体或类)之间进行转换。 为了使此工作正常进行,模型对象需要符合不同的协议。
// a business object
struct Person {
let personId: String
let name: String
}
// a managed object
class PersonRecord: NSManagedObject {
@NSManaged var id: String!
@NSManaged var name: String!
}
CoreModel
协议用于表示任何唯一可识别的模型对象。 它要求模型对象具有唯一标识符,但该标识符可以是任何适当的类型(String
、Int
或 UUID
是常见类型)。 本质上,Y—Persistence 中使用的所有模型对象(无论是 JSON 模型对象还是 Core Data NSManagedObject
)都需要符合 CoreModel
。
UidType: UniqueIdentifier
将用作唯一标识符的字段的类型。uid: UidType
此对象的唯一标识符extension Person: CoreModel {
typealias UidType = String
public var uid: String { personId }
}
extension PersonRecord: CoreModel {
typealias UidType = String
public var uid: String { id ?? "" }
}
DataRecord
协议用于表示任何 Core Data 记录。 它扩展了 CoreModel
,因此我们的记录需要是唯一可识别的(以便我们可以提取、删除或保存)。 它需要
entityName: String
Core Data 实体(SQL 表)的名称uidKey: String
用作唯一键的属性(SQL 列)的名称。 默认为“uid”。extension PersonRecord: DataRecord {
static var entityName: String { "PersonRecord" }
static var uidKey: String { "id" }
}
ModelRepresentable
协议用于表示可以与模型对象(可以是符合 CoreModel
的任何结构体或类)关联的任何 Core Data 记录。 这将用于帮助在 Core Data 记录和业务模型对象之间进行转换。
ModelType: CoreModel
此类型记录的关联模型对象。uid: ModelType.UidType
记录的唯一标识符(与关联模型的唯一标识符匹配)。extension PersonRecord: ModelRepresentable {
typealias ModelType = Person
}
RecordFromModel
协议用于表示可以从关联模型对象填充的任何 Core Data 记录。 常见用例:从 API 调用返回的模型对象将记录保存到 Core Data。
func fromModel(_ model: ModelType)
从模型对象填充 Core Data 记录。extension PersonRecord: RecordFromModel {
func fromModel(_ model: Person) {
id = model.personId
name = model.name
}
}
RecordToModel
协议用于表示可用于填充关联模型对象的任何 Core Data 记录。 常见用例:从 Core Data 中提取记录作为模型对象,这些模型对象可以在 API POST 请求中使用(或作为线程安全的模型对象移交给 UI)。
func toModel() -> ModelType
将 Core Data 记录转换为模型对象。extension PersonRecord: RecordToModel {
func toModel() -> Person {
Person(
personId: id ?? "",
name: name ?? ""
)
}
}
符合上述某些协议允许 Y—Persistence 执行通用操作,例如提取、保存和删除,而无需为 Core Data 模型中的每个不同实体(SQL 表)构建唯一查询。
可以通过单个 uid 或 uid 数组完成提取,并且可以返回记录(NSManagedObject
子类)或模型。
func fetchPerson(uid: String) throws -> Person? {
try persistenceManager.fetchModel(entity: PersonRecord.self, uid: uid)
}
func fetchPeople(uids: [String]) throws -> [Person] {
try persistenceManager.fetchModel(entity: PersonRecord.self, uids: uids)
}
可以通过传递 uid 或传递单个或多个模型对象(从中提取 uid)来执行删除。
func deletePeople(by uids: [String]) throws {
try persistenceManager.deleteRecords(entity: PersonRecord.self, uids: uids)
}
func delete(person: Person) throws {
try persistenceManager.deleteModel(entity: PersonRecord.self, model: person)
}
func delete(people: [Person]) throws {
try persistenceManager.deleteModels(entity: PersonRecord.self, models: people)
}
可以对模型对象数组执行保存,并且可以选择覆盖现有记录。 当用远程模型替换本地记录时使用 shouldOverwrite: true
,或者当您缓存分页提取的结果时使用 false
。
func save(people: [Person]) throws {
try persistenceManager.save(
entity: PersonRecord.self,
models: people,
shouldOverwrite: true
)
}
您可以通过将其添加为包依赖项来将 Y—Persistence 添加到 Xcode 项目。
brew install swiftlint
sudo gem install jazzy
克隆 repo 并在 Xcode 中打开 Package.swift
。
我们使用 语义版本控制。
{major}.{minor}.{patch}
例如
1.0.5
我们为我们的框架采用简化的分支策略。
main
main
分支出来main
。main
被标记为每次发布更新后的版本号feature/{ticket-number}-{short-description}
bugfix/{ticket-number}-{short-description}
例如
feature/CM-44-button
bugfix/CM-236-textview-color
在提交拉取请求之前,您应该
swiftlint
并确认没有违规行为。jazzy
并确认您具有 100% 的文档覆盖率。git rebase -i HEAD~{commit-count}
将您最后的 {commit-count} 个提交合并到功能块中。main
)的 HEAD 已更新,请使用 git rebase main
变基您的分支。提交拉取请求时
合并拉取请求时
1.0.5
)您可以使用以下终端命令直接从源代码生成自己的本地文档集
jazzy
这会在 /docs
下生成一组文档。 默认配置在默认配置文件 .jazzy.yaml
文件中设置。
要查看其他文档选项,请键入
jazzy --help
每次将提交推送到 main
时,GitHub Action 都会自动运行,该 Action 运行 Jazzy 以生成我们 GitHub 页面上的文档:https://yml-org.github.io/ypersistence-ios/