追踪是一个用 Swift 编写的框架,使你能够轻松地将你的缓存(CoreData、Realm 等)和 UI 层分开。这个想法基于优秀的 文章。正如你可以从这篇文章中读到的,你可以使用这个框架来轻松更新你的 UITableView 或其他东西。
在这种情况下,我们使用内置的 mapper。对于这个,你的简单对象必须支持协议 Mappable
。所以,让我们创建一些模型
import Tracing
// MARK: - Storable
protocol Storable: class {
static var entityName: String { get }
}
// MARK: - NSManagedObject
extension Storable where Self: NSManagedObject {
static var entityName: String {
return NSStringFromClass(self).components(separatedBy: ".").last ?? ""
}
init(in context: NSManagedObjectContext) {
guard let entity = NSEntityDescription.entity(forEntityName: Self.entityName, in: context) else {
fatalError("Cannot create entity for entity name: \(Self.entityName)")
}
self.init(entity: entity, insertInto: context)
}
}
// MARK: - CategoryModelObject
class CategoryModelObject: NSManagedObject, Storable {
@NSManaged var id: Int64
@NSManaged var name: String
@NSManaged var positions: NSSet
}
// MARK: - PositionModelObject
class PositionModelObject: NSManagedObject, Storable {
@NSManaged var id: Int64
@NSManaged var name: String
@NSManaged var price: Double
@NSManaged var category: CategoryModelObject?
}
// MARK: - CategoryPlainObject
class CategoryPlainObject: Mappable {
let id: Int64
let name: String
var positions: [PositionPlainObject] = [] // Array of objects
required init(with resolver: Resolver) throws {
self.id = try resolver.value("id")
self.name = try resolver.value("name")
self.positions = (try? resolver.value("positions")) ?? []
}
}
// MARK: - CategoryPlainObject
class PositionPlainObject: Mappable {
let id: Int64
let name: String
let price: Double
var category: CategoryPlainObject? = nil // Nested object
required init(with resolver: Resolver) throws {
self.id = try resolver.value("id")
self.name = try resolver.value("name")
self.price = try resolver.value("price")
self.category = try? resolver.value("category")
}
}
好的,我们有两个模型对象类(CategoryModelObject,PositionModelObject)和两个简单对象类(CategoryPlainObject,PositionPlainObject)。现在你可以使用 Tracing
/// Create request for cache
let request = CacheRequest(entityName: CategoryModelObject.entityName)
/// Create tracker that tracks changes with CategoryModelObject (Your NSManagedObject)
/// and notify you about this with CategoryPlainObject (Your plain object)
let tracker = Tracing.coreTracker(cacheType: CategoryModelObject.self, plainType: CategoryPlainObject.self)
/// Setup the tracker
tracker.setup(with: request, context: context) { transactionBatch in
/// Transactions with inserted objects
transactionBatch.insertedTransactions
/// Transactions with updated objects
transactionBatch.updatedTransactions
/// Transactions with removed objects
transactionBatch.removedTransactions
/// Transactions with moved objects
transactionBatch.movedTansactions
/// Checking for empty
transactionBatch.isEmpty
/// Or you can get inserted/updated/removed/moved objects
for category in transactionBatch.insertedObjects {
/// CategoryPlainObject
category
/// Use category's simple properties
category.id
category.name
/// And nested objects
category.positions
}
}
class CategoryMapper: CacheMapper {
typealias CacheType = CategoryModelObject
typealias PlainType = CategoryPlainObject
func map(from cacheObject: CategoryModelObject) throws -> CategoryPlainObject {
/// Map CategoryModelObject to CategoryPlainObject
}
}
/// And use it
let mapper = CategoryMapper()
let tracker = Tracing.coreTracker(with: mapper)
let name = CategoryModelObject.entityName
let filter = "id > 5"
let sortDesriptor = SortDescriptor(withKey: "name", ascending: true)
let request = CacheRequest(entityName: name, predicate: filter, sortDescriptors: [sortDesriptor])
如果你不想使用任何依赖管理器,你可以手动将 Tracing 集成到你的项目中。
打开终端,使用cd
命令进入您的顶级项目目录,如果您尚未将项目初始化为Git仓库,请运行以下命令
$ git init
通过运行以下命令将跟踪(Tracing)添加为Git 子模块
$ git submodule add https://github.com/incetro/Tracing.git
打开新的Tracing
文件夹,并将Tracing.xcodeproj
拖入您的应用程序Xcode项目的项目导航器中。
它应该嵌套在您的应用程序的蓝色项目图标下。它在上面还是下面所有其他Xcode组中并不重要。
在项目导航器中选择Tracing.xcodeproj
,并验证部署目标与您的应用程序目标匹配。
接下来,在项目导航器中选择您的应用程序项目(蓝色项目图标)以导航到目标配置窗口,并在侧边栏的“Targets”下选择应用程序目标。
在该窗口顶部的标签栏中,打开“General”面板。
点击“Embedded Binaries”部分下的+
按钮。
您将看到两个不同的Tracing.xcodeproj
文件夹,每个文件夹中都有一个不同于另一个的Tracing.framework
版本,它们嵌套在“Products”文件夹中。
您可以选择任何“Products”文件夹,但您必须选择顶部的还是底部的
Tracing.framework
。
为iOS选择顶部的Tracing.framework
,为OS X选择底部的。
您可以通过检查项目的构建日志来验证您选择了哪个,构建目标将是
Tracing iOS
、Tracing macOS
、Tracing tvOS
或Tracing watchOS
之一。
就是这样!
Tracing.framework
已自动添加为目标依赖项、链接框架和嵌入框架,在复制文件构建阶段进行,这就是您在模拟器和设备上构建所需的全部内容。
incetro,[email protected]
跟踪(Tracing)在MIT许可证下可用。有关更多信息,请参阅LICENSE文件。