测试已测试 | ✓ |
语言语言 | SwiftSwift |
许可 | MIT |
发布最新发布 | 2016年3月 |
SPM支持 SPM | ✗ |
由 Dan Thorpe 维护。
依赖项 | |
ValueCoding | ~> 1.3 |
YapDatabase | ~> 2 |
阅读我的关于 YapDatabase & YapDatabaseExtensions 的介绍博客文章,以及 YapDatabaseExtensions 2 的后续文章。
YapDatabaseExtensions 是一组方便的 API,用于处理 YapDatabase。如果您不熟悉 YapDatabase,它是一个为 iOS 和 Mac 提供的强大键值数据库 - 去了解一下!
虽然 YapDatabase 非常好,但它缺乏一些必备的便利性和 Swift 支持。特别是,YapDatabase 严重依赖于 AnyObject
类型,这对于 Objective-C 来说是可以接受的,但对于 Swift 来说意味着没有类型精确度。同样,将结构体或枚举等值类型保存到 YapDatabase 中也存在问题。此框架通过 2015 年的发展来解决这些问题。
对编码和解码值类型的支持,以前是 Saveable
和 Archiver
协议,已重命名并移动到自己的项目。 ValueCoding 是此框架的依赖项(以及 YapDatabase 本身)。有关更多信息,请参阅其 README。然而,基本上,如果您之前在版本 2.1 之前使用过此项目,您可能需要重命名一些类型 - Xcode 应该会提供修复选项。"Saveable" 现在是 "ValueCoding",其嵌套类型之前称为 "ArchiverType" 现在称为 "Coder",此类型必须符合协议,之前为 "Archiver",现在为 "CodingType"。看看这一切是如何混乱的?现在已修复。
Persistable
此协议表明支持从和写入 YapDatabase 所需的条件。对象在数据库中通过集合(也用作 String
)内的键(一个 String
)进行引用。
public protocol Identifiable {
typealias IdentifierType: CustomStringConvertible
var identifier: IdentifierType { get }
}
public protocol Persistable: Identifiable {
static var collection: String { get }
var metadata: MetadataType? { get set }
}
只要有关联标识符类型即可,例如 NSUUID
或 Int
,令牌属性允许类型支持。
虽然 YapDatabase 不要求这样做,但对于这组扩展而言,必须要求相同类型的值存储在同一个集合中 - 这是一个静态属性。
此外,还有一个由键集和数据集合组成的结构体 YapDB.Index
,这用于内部访问的所有方法。定义在 Persistable
扩展上的属性提供了对 键
和 索引
的访问。
YapDatabase 支持在主对象旁边存储元数据。YapDatabaseExtensions 支持将元数据作为 Persistable
类的可选属性自动读取和写入。
默认情况下,所有符合 Persistable
的类型都会获得一个默认合成的 MetadataType
Void
。因此,如果您不需要或不需要元数据类型,就不需要做什么。
要支持自定义元数据类型,只需将以下内容添加到您的 Persistable
类型中,例如:
struct MyCustomValue: Persistable, ValueCoding {
typealias Coder = MyCustomValueCoder
static let collection = “MyCustomValues”
var metadata: MyCustomMetadata? = .None
let identifier: NSUUID
}
其中类型(MyCustomMetadata
如上所述)实现 NSCoding
或 ValueCoding
。
在创建新项目时,在将项目保存到数据库之前设置元数据属性。然后 YapDatabaseExtensions 将正确保存 YapDatabase 内部的元数据。不需要在主对象中编码元数据。当读取具有有效 MetadataType
的对象时,YapDatabaseExtensions 将自动读取、解码并设置项目的元数据,然后再返回项目。
注意,之前的元数据协议 ObjectMetadataPersistable
和 ValueMetadataPersistable
已被废弃,以支持 Persistable
。
由于泛型协议,ValueCoding
和 CodingType
具有自反属性,因此必须正确实现以使得 APIs 可用。这意味着等式 ValueCoding.Coder.ValueType == Self
必须满足。所有 API 都使用其泛型 where 子句中的这一事实来表示。这意味着如果您的 ValueCoding
类型不是其 Coder
的 ValueType
,则您的代码将无法编译。
因此,以下表格描述了六个有效的 Persistable
类型模式:
项目编码 | 元数据编码 | 模式 |
---|---|---|
NSCoding |
无元数据 | 对象 |
NSCoding |
NSCoding |
包含对象元数据的对象 |
NSCoding |
ValueCoding |
包含值元数据的对象 |
ValueCoding |
无元数据 | 值 |
ValueCoding |
NSCoding |
包含对象元数据的值 |
ValueCoding |
ValueCoding |
包含值元数据的值 |
YapDatabaseExtensions 提供两种风格的 API。功能 API 在 YapDatabase
类型、YapDatabaseReadTransaction
、YapDatabaseReadWriteTransaction
和 YapDatabaseConnection
上工作。持久化 API 直接在您的 Persistable
类型上工作,并接收作为参数的 YapDatabase
类型。
以下“功能”API可直接在 YapDatabase
类型上使用。
// Get a YapDatabaseConnection
let connection = db.newConnection()
// Write a single item
connection.write(item)
// Write an array of items, using one transaction.
connection.write(items)
// Write asynchronously
connection.asyncWrite(item) { print(“did finish writing”) }
connection.asyncWrite(items) { print(“did finish writing”) }
// Create a write transaction block for multiple writes.
connection.write { transaction in
transaction.write(item)
transaction.write(items)
}
// Write many items asynchronously
connection.asyncWrite({ transaction in
transaction.write(item)
transaction.write(items)
}, completion: { print(“did finish writing”) })
阅读
if let item: Item? = connection.readAtIndex(index) {
// etc
}
if let meta: Item.MetadataType? = connection.readMetadataAtIndex(index) {
// etc
}
let items: [Item] = connection.readAtIndexes(indexes)
if let item: Item? = connection.readByKey(index) {
// etc
}
let items: [Item] = connection.readByKeys(keys)
let all: [Item] = connection.readAll()
connection.read { transaction in
let a: Item? = transaction.readAtIndex(index)
let b: Item? = transaction.readByKey(key)
let c: [Item] = transaction.readAtIndexes(indexes)
let d: [Item] = transaction.readByKeys(keys)
let all: [Item] = transaction.readAll()
let meta: [Item.MetadataType] = transaction.readMetadataAtIndexes(indexes)
}
Persistable
API所有 API 都在单个或多个 Persistable
项目上工作。要写入数据库:
// Use a YapDatabaseReadWriteTransaction.
let written = item.write(transaction)
// Write synchronously using a YapDatabaseConnection.
let written = item.write(connection)
// Write asynchronously using a YapDatabaseConnection.
item.asyncWrite(connection) { written in
print(“did finishing writing”)
}
// Return an NSOperation which will perform an sync write on a YapDatabaseConnection.
let write: NSOperation = item.write(connection)
从数据库读取项目略有不同。
// Read using a YapDB.Index.
if let item = Item.read(transaction).byIndex(index) {
// etc - item is correct type, no casting required.
}
// Read an array of items from an array of YapDB.Index(s)
let items = Item.read(transaction).atIndexes(indexes)
// Read using a key
if let item = Item.read(transaction).byKey(key) {
// etc - item is correct type, no casting required.
}
// Read an array of items from an array of String(s)
let items = Item.read(transaction).byKeys(keys)
if let allItems = Item.read(transaction).all() {
// etc - an array of Item types.
}
// Get the Items which exist for the given keys, and return the [String] keys which are missing.
let (items, missingKeys) = Item.read(transaction).filterExisting(someKeys)
同样,如果需要直接在 YapDatabaseConnection
上工作,可以使用以下方法:
if let item = Item.read(connection).byIndex(index) {
// etc - item is correct type, no casting required.
}
if let item = Item.read(connection).byKey(key) {
// etc - item is correct type, no casting required.
}
if let allItems = Item.read(connection).all() {
// etc - an array of Item types.
}
let (items, missingKeys) = Item.read(connection).filterExisting(someKeys)
YapDatabaseExtensions 通过 CocoaPods 提供。要安装它,只需要将以下行添加到您的 Podfile:
pod 'YapDatabaseExtensions'
如果您不希望 Persistable
上有扩展 API,可以像这样集成 Functional subspec:
pod 'YapDatabaseExtensions/Functional’
API 文档在 CocoaDocs.org 上有提供。
要开始在这个仓库的 YapDatabaseExtensions.xcodeproj
中工作,您需要使用 Carthage 来下载和构建项目的依赖项,使用命令 carthage checkout
和 carthage build
。
丹尼尔·索普,@danthorpe
YapDatabaseExtensions 在 MIT 许可下提供。有关更多信息,请参阅 LICENSE 文件。