iModel 0.0.6

iModel 0.0.6

测试已测试
语言语言 SwiftSwift
许可证 MIT
发布最后发布2016年1月
SPM支持 SPM

Jakub Zaczek 维护。



 
依赖
iService~> 0.0
iPromise~> 1.1
 

iModel 0.0.6

  • Jakub Zaczek

iModel

在一个包中提供验证、JSON 解析和异步远程通信。

安装

将此行代码复制到您的 podfile:

pod 'iModel', '~> 0.0'

请确保也添加 !use_frameworks

描述

iModel 是为了创建数据模型而创建的,它提供数据验证和具有无缝 JSON 解析的 CRUD(创建、读取、更新、删除)接口。

模型

Model 提供数据验证和属性观察的方式。

属性观察

所有标记为 dynamic 的属性都将被 obj-c KVO 观察。这意味着您必须将属性声明为 dynamic 以添加 KVO。

class SimpleModel: Model {
    public dynamic var id: Int = 0                  //this will be observed
    public var unobservableProperty: String = ""    //this won't
}

覆盖

property<T>(property: String, changedFromValue oldValue: T, toValue newValue: T)

对于属性变更的任何自定义行为。

验证

Model 有其 validationState。当创建 Model 对象时,其状态等于 Model.ValidationState.Empty。当模型属性发生变化时,它将过渡到 .Dirty 状态,并且 Model.dirtyProperties 数组将被填充为已更改的属性。然后,在用户调用 validate() 后,对象将过渡到 .Clean.Invalid 状态,具体取决于验证方法的结果。Model.validationErrors 可用于验证方法失败且对象为 .Invalid 时。Model 的最后 .Clean.Empty 状态可以通过调用 undo() 恢复。

添加验证方法

验证方法接收字段值作为参数,并返回一个 (Bool, String) 的元组。布尔标志指示字段的值是否有效,字符串值包含任何错误消息。

将您的验证方法定义为 public class func

class SimpleModel: Model {
    public dynamic var id: Int = 0

    public class func validateId(id: Int) -> (Bool, String) {
        if (id <= 0) {
            return (false, "Id should be greater that zero!")
        }
        return (true, "")
    }
}

然后,从例如 AppDelegate.didFinishLaunchingWithOptions 中调用 setValidationMethod(:forField)

SimpleModel.setValidationMethod(SimpleModel.validateId, forField: "id")

validateId() 会在每次 validate() 调用时被调用。

JsonModel

JsonModelModel 类扩展,提供了JSON文件解析工具。基本使用此类的方法是使用对应的json文件中的键命名所有属性。

注意:此类使用 NSJSONSerialization。

简单示例

假设我们有一个以下形式的JSON文件,形式为 NSData(由 NSURLRequest 返回)

{
    "id": 10,
    "first_name": "Matthew",
    "last_name": "Johnson",
    "age": 23
}

以下代码片段会将它解析为 JsonModel 对象

class Person: JsonModel {
    public dynamic var id: Int?
    public dynamic var firstName: String?           //can also be first_name
    public dynamic var lastName: String?            //can also be last_name
    public dynamic var age: Int?
}

// let data = ... - a NSData object
let matthew = Person(data: data)

print(matthew.toJsonDictionary())                   //this will print a [String: AnyObject] dict
高级配置

以下示例显示了更高级的配置

class SimpleNestedModel: JsonModel {
    public dynamic var value: String = ""
}

class SimpleJsonModel: JsonModel {
    public dynamic var id: Int = 0
    public dynamic var name: String = ""
    public dynamic var optionalValue: Int?
    public dynamic var nested: SimpleNestedModel?

    override public class func jsonPropertyExclusions() -> [String] {
        // we don't want to waste time parsing these:
        return ["please_parse_me", "important_value"]
    }

    override public class func jsonPropertyNames() -> [String: String] {
        // API returns some weird names, we want our own:
        return [
            "name_of_this_object": "name",
            "id_of_this_object": "id"
        ]
    }

    override public class func jsonPropertyParsingMethods() -> [String: (AnyObject) throws -> AnyObject] {
        // we have a nested JsonModel, lets parse it
        return ["nested": SimpleNestedModel.fromJsonDictionary]
    }

    override public class func jsonBeforeDeserialize(data: [String: AnyObject]) -> [String: AnyObject] {
        // modify the raw json dictionary however you want before parsing it into an object
        return data
    }

    override public class func jsonAfterSerialize(data: [String: AnyObject]) -> [String: AnyObject] {
        // modify the raw json dictionary however you want after serializing (before returning from 
        // toJsonDictionary
        return data
    }
}

RestfulModel

RestfulModelJsonModel 的子类,它包含其基类所具有的所有验证能力和JSON解析工具,并通过添加CRUD接口扩展了这些功能,允许向远程服务器(RESTful API)发送和接收数据。

RestfulModel 使用 iServiceiPromise 进行API通信和异步操作。它的CRUD接口模仿了iService的接口。

注意:以下方法应该在子类化时每次都重写

  1. urlOfService - 提供用于与API通信的服务URL
  2. path() - 提供对象的API标识符
基本用例
class Post: RestfulModel {
    public dynamic var id: Int?
    public dynamic var body: String?
    public dynamic var title: String?
    public dynamic var userId: Int?

    override public class func urlOfService() -> NSURL {
        return NSURL(string: "http://jsonplaceholder.typicode.com/post"
    }

    override public func path() -> String {
        return "\(id)"
    }
}
创建对象
let post = Post()
post.body = "A body"
post.title = "My first post!"
post.userId = 10

Post.create(post).then({ /*...*/ })
检索单个项
Post.retrieve("1").then({ (result: Post) in
    //we have our post here ...
})
检索过滤列表
Post.retrieve("userId": "1").then({ /*...*/ })    //HTTP GET on http://jsonplaceholder.typicode.com/post/?userId=1&
更新对象
// updating an object
let post = Post()
post.body = "new body"
post.id = 10

post.update().then({ /*...*/ })
删除对象
let post = Post()
post.id = 100

post.destroy().then({ /*...*/ })
高级行为

Restful模型提供了许多重写其基本功能的方法。根据需要重写以下任何一种方法。

  1. crudConfigureRequestFor... - 为每个CRUD方法配置请求
  2. crudAugmentCreate - 提供在发送 CREATE 请求前添加任何额外数据的方法
  3. crudAugmentUpdate- 提供在发送 UPDATE 请求前添加任何额外数据的方法
  4. crudAugmentRetrieve - 提供在将JSON数据解析为对象前添加任何额外数据的方法

有关这些方法的更多信息,请参阅文档。

文档

文档应可通过此处获取,尽管使用CocoaPods从代码生成文档的库似乎存在问题。目前请阅读注释——这也有助于您更好地理解库,并可能查找其中的一些问题!

许可证

许可证