Vellum 可通过 CocoaPods 获得。 要安装它,只需将以下行添加到您的 Podfile 中
pod 'Vellum'
在 Package.swift 中将它添加为您的 target 依赖项
dependencies: [
.package(url: "https://github.com/hainayanda/Vellum.git", .upToNextMajor(from: "1.2.3"))
]
在你的 target 中使用 Vellum
.target(
name: "MyModule",
dependencies: ["Vellum"]
)
然后在你使用它之前运行 swift build 来构建依赖项
Nayanda Haberty, hainayanda@outlook.com
Vellum 在 MIT 许可下可用。 有关更多信息,请参见 LICENSE 文件。
Vellum 使用 LRU 算法。 它包含两种类型的存储,即内存存储和磁盘存储。 两种大小都可以手动分配。
您需要做的就是从工厂获取 ArchiveManager 并存储您的对象,该对象实现了 Archivable 和 Codable,或者使用 typealias ArchiveCodable,它们是相同的
let archives = try! ArchivesFactory.shared.archives(
for: MyArchivable.self,
trySetMaxMemorySize: 10.megaByte,
trySetMaxDiskSize: 20.megaByte
)
// will insert object
archives.record(myObject)
let object = archives.access(archiveWithKey: "object_key")
Archivable 实际上只是一个协议,它具有将对象转换为数据或反之亦然的方法。 Archivable 确保对象也具有键
class User: Archivable {
var primaryKey: String { userName }
var userName: String = ""
var fullName: String = ""
var age: Int = 0
func archive() throws -> Data {
// do something to convert the object to Data
}
static func deArchive(fromData data: Data) throws -> Archivable {
// do something to convert the data to object
}
}
如果您的对象是 Codable,只需添加 Archivable 或使用 typealias ArchiveCodable,它们是相同的,您的对象将自动拥有这些方法。 您只需要添加您想要的 primaryKey 属性作为主键,只要该值是 String
struct User: Codable, Archivable {
var primaryKey: String { userName }
var userName: String
var fullName: String
var age: Int
}
要获取 ArchiveManager,您可以使用 ArchivesFactory。 您可以分配内存大小和磁盘大小的最大字节数。 但请记住,该大小仅适用于首次创建 ArchiveManager 时,如果已创建缓存管理器,则将忽略内存大小和磁盘大小。 如果您不分配内存大小或磁盘大小,它将使用默认值,内存为 1 兆字节,磁盘大小为 2 兆字节
let archives = try! ArchivesFactory.shared.archives(
for: User.self,
trySetMaxMemorySize: 10.kiloByte,
trySetMaxDiskSize: 20.kiloByte
)
// or not explicit
let sameArchives: ArchiveManager<User> = try! ArchivesFactory.shared.archives(
trySetMaxMemorySize: 10.kiloByte,
trySetMaxDiskSize: 20.kiloByte
)
ArchiveManager 具有一些可用的方法和属性,如下所示:
var maxSize: Int { get } 获取缓存的最大大小var currentSize: Int { get } 获取缓存当前使用的空间大小func latestAccessedTime(for key: String) -> Date? 获取具有相同键的对象上次访问的时间func deleteAllInvalidateArchives(invalidateTimeInterval: TimeInterval) 删除所有早于时间间隔的对象func record(_ object: Archive) 插入对象func update(_ object: Archive) 更新现有对象,如果没有则插入func access(archiveWithKey key: String) -> Archive? 获取具有给定键的对象func accessAll(limitedBy limit: Int) -> [Archive] 获取所有对象,最多限制为 limit 个func accessAll() -> [Archive] 获取缓存中存储的所有对象func delete(archiveWithKey key: String) 删除具有给定键的对象func deleteAll() 从缓存中删除所有对象func process(queries: [Query<Archive>]) -> [Archive] 处理查询。 这将在后面讨论您可以从缓存中进行查询。 有 3 种类型的查询,分别是
QueryFinder 通过其属性查找对象/结果QuerySorter 按其属性对结果进行排序QueryLimiter 按 limit 限制结果所有查询都可以组合,并将按顺序执行
let results = userCache.findWhere { archive in
archive.userName(.contains("premium"))
.fullName(.isNotEqual(nil))
}
.getResults()
上面的代码将查找缓存中所有 userName 包含 "premium" 且 fullName 不为 nil 的用户。 结果是 User 的数组
let results = userCache.sorted { by in
by.age(.ascending)
.fullName(.descending)
}
.getResults()
上面的代码将获取缓存中的所有用户,并按其年龄升序排序,然后按其 fullName 降序排序。 结果是排序后的 User 数组
您也可以添加 limit
let results = userCache.sorted { by in
by.age(.ascending)
.fullName(.descending)
}
.limitResults(by: 10)
.getResults()
上面的代码将限制结果最多为 10 个
如果您愿意,甚至可以组合查询
let results = userCache.findWhere { archive in
archive.userName(.contains("premium"))
.fullName(.isNotEqual(nil))
}
.sorted { by in
by.age(.ascending)
.fullName(.descending)
}
.limitResults(by: 10)
.getResults()
上面的代码将查找缓存中所有 userName 包含 "premium" 且 fullName 不为 nil 的用户,然后按其年龄升序排序,然后按其 fullName 降序排序。 结果限制为 10 个。
以下是可以与 QueryFinder 一起使用的 finder 列表
contains(string: ) 如果字符串属性包含给定字符串则匹配matches(regex: ) 如果字符串属性与给定的正则表达式匹配则匹配contains(with: ) 如果集合属性包含给定的元素则匹配contains(atLeastOne: ) 如果集合属性包含至少一个给定的元素则匹配contains(all: ) 如果集合属性包含所有给定的元素则匹配countEqual(with: ) 如果集合属性计数等于给定数字则匹配countGreater(than: ) 如果集合属性计数大于给定数字则匹配countLess(than: ) 如果集合属性计数小于给定数字则匹配countGreaterOrEqual(with: ) 如果集合属性计数大于或等于给定数字则匹配countLessOrEqual(with: ) 如果集合属性计数大于或等于给定数字则匹配isEqual(with: ) 如果属性等于给定值则匹配isNotEqual(with: ) 如果属性不等于给定值则匹配greater(than: ) 如果属性大于给定值则匹配less(than: ) 如果属性小于给定值则匹配greaterOrEqual(with: ) 如果属性大于或等于给定值则匹配lessOrEqual(with: ) 如果属性小于或等于给定值则匹配如果您想手动验证,您可以只使用 isValid(_ validator: (Property) -> Bool)
let results = userCache.findWhere { archive in
archive.userName(.isValid { $0.contains("premium") })
}
.getResults()
您可以使用 Archived property wrapper 来包装任何属性,因此如果分配它,它将自动将这些属性存储到 ArchiveManager 中
@Archived var user: User?
如果您希望该属性基于给定的主键具有初始值,只需传递该键
@Archived(initialPrimaryKey: "some") var user: User?
上面的代码将尝试在第一次属性加载时获取具有给定键的用户。