测试已测试 | ✓ |
语言语言 | SwiftSwift |
许可证 | MIT |
发布最后发布 | 2017年3月 |
SwiftSwift 版本 | 3.0 |
SPM支持 SPM | ✗ |
由 Sam Williams 维护。
这是一个用于处理模型对象的框架。
pod 'ModelKit'
或者,仅包括某些组件
字段为您提供
基本用法
class Person {
let age = Field<Int>()
}
person.age.value = 10
对于多值字段,有 ArrayField
,它封装了一个描述单值类型的字段对象。
let tags = ArrayField(Field<String>(), name: "Tags")
内部字段负责验证、转换等。 ArrayField
拥有顶级属性,如 name
、key
等 - 但为了方便,它将在初始化时复制它们。
提供了一个一元后缀运算符 *
来将 Field
封装在 ArrayField
中。所以您也可以这样编写上面的声明
let tags = Field<String>(name: "Tags")*
简单的闭包验证
let age = Field<Int>().require { $0 > 0 }
规则也可以链接,表示 AND。顺序并不重要。
let age = Field<Int>().require { $0 > 0 }.require { $0 % 2 == 0 }
默认情况下,nil
值将被视为有效。要更改特定规则的此行为,将 allowNil: false
传递给 require
。
要验证字段值,请调用 field.validate()
,它返回一个 ValidationState
枚举
public enum ValidationState:Equatable {
case unknown
case invalid([String])
case valid
}
.invalid
案例的相关值是一个错误信息列表(例如,["必须大于0","是必需的"]
)。
字段将自动具有以下时间戳
updatedAt
:最后一个设置任何值的时间changedAt
:最后设置新值的时间(使用 ==
进行比较)该库包括 ValueObserver
和 ValueObservable
协议,用于泛型、类型安全的变化观察。字段实现了这两个协议。
一个 ValueObservable
可以有任意数量的已注册 ValueObserver
对象。 -->
运算符是 addObserver
方法的一个快捷键(<--
的作用相同,只是其参数的顺序相反)。当添加观察者时,观察事件会触发一次,之后每次设置字段值时都会触发。
如果观察者实现了ValueObserver
协议,其中包含一个valueChanged(observable, value: value)
方法,那么可以添加观察者。
field --> observer
或者,可以提供一个闭包。在不使用观察者对象的情况下,仅用owner
来识别每个闭包。
field --> owner { value in
print(value)
}
即使在没有给出观察者的情况下,我们仍然可以注册闭包。这实际上是在与空观察者注册闭包。
age --> { value in
print("Age was changed to \(value)")
}
由于Field
自身实现了ValueObservable
和ValueObserver
,可以使用-->
运算符创建两个字段值之间的链接。
sourceField --> destinationField
这将立即设置destinationField
的值为sourceField
的值,并在sourceField
的值每次发生变化时再次设置。
<-->
运算符是紧随其后<--
和-->
的快捷方式(并且只能在两个字段之间使用)。
field1 <--> field2
由于首先调用<--
,因此两个字段最初都将具有field2
的值。
注销观察者使用removeObserver
方法,或者-/->
运算符。可以用removeAllObservers()
移除所有观察者。
一个Model
对象会自动将其Field
属性的字典表示形式进行转换。
person.dictionaryValue()
// --> ["name": "Bob", "tags": ["red", "blue", "green"]]
如果你的字段的值是Model
的子类,你应该使用ModelField
子类。
let companies = ModelField<Company>()*
此库提供了一个基于Promise的数据存储抽象接口,该接口在ModelStore
协议中指定,以及几个具体的实现。
func create<T: Model>(model:T) -> Promise<T>
func update<T: Model>(model:T) -> Promise<T>
func delete<T: Model>(model:T) -> Promise<T>
func lookup<T: Model>(modelClass:T.Type, identifier:String) -> Promise<T>
func list<T: Model>(modelClass:T.Type) -> Promise<[T]>
这个存储库将模型存储在内存中。它为基于同步的标识符查找添加了一个lookupImmediately
方法。
这旨在作为你RESTful服务器接口的基类。它包括一些可覆盖的钩子,你可以为了满足特定的需求自定义它们,例如
defaultHeaders
handleError
constructResponse
RESTRouter
负责为资源位置生成路径。
collectionPath(for: Person.self)
instancePath(for: person)
如果你的模型符合HasOwnerField
,则可以自动生成嵌套路由,这将要求它指定一个所属字段。例如,如果某人的所属字段是它的company
字段,那么你可能得到它的实例路径为"/companies/10/employees/45"
。
它还包含一个可以用于自定义序列化的ValueTransformerContext
变量。例如
context.keyCase
- 指定键的 casing 风格(.snake
、.upperCamel
、.lowerCamel
)context.explicitNull
- 决定是否包含空值的键