追踪 1.0.1

追踪 1.0.1

测试已测试
语言语言 SwiftSwift
许可证 MIT
发布上次发布2017年7月
SwiftSwift 版本3.0
SPM支持 SPM

incetro 维护。



追踪 1.0.1

  • incetro

追踪

追踪是一个用 Swift 编写的框架,使你能够轻松地将你的缓存(CoreData、Realm 等)和 UI 层分开。这个想法基于优秀的 文章。正如你可以从这篇文章中读到的,你可以使用这个框架来轻松更新你的 UITableView 或其他东西。

功能

  • [x] 精美的对象观察
  • [x] 通过 Transformer 进行通用标准映射
  • [x] 支持 custom mappers
  • [x] 支持 Generics

使用方法

与 CoreData 的简单使用

在这种情况下,我们使用内置的 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
    }
}

定制 mapper

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])

要求

  • iOS 9.0+ / macOS 10.12+ / tvOS 9.0+ / watchOS 2.0+
  • Xcode 8.1, 8.2, 8.3, 和 9.0
  • Swift 3.0, 3.1, 3.2, 和 4.0

通讯

  • 如果你 发现了一个错误,请提交一个问题。
  • 如果你 有一个功能请求,请提交一个问题。
  • 如果你 想要贡献,提交一个 pull request。

安装

手动

如果你不想使用任何依赖管理器,你可以手动将 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 iOSTracing macOSTracing tvOSTracing watchOS之一。

  • 就是这样!

    Tracing.framework已自动添加为目标依赖项、链接框架和嵌入框架,在复制文件构建阶段进行,这就是您在模拟器和设备上构建所需的全部内容。

作者

incetro,[email protected]

许可证

跟踪(Tracing)在MIT许可证下可用。有关更多信息,请参阅LICENSE文件。