测试已测试 | ✗ |
语言语言 | SwiftSwift |
许可证 | MIT |
发布最新版本 | 2016 年 12 月 |
SwiftSwift 版本 | 3.0 |
SPM支持 SPM | ✓ |
由Jiri Trecak维护。
极容易使用、功能强大的 Swift 对象(+模型映射器),将使创建数据模型变得轻松。
累了吗?这是可以理解的。这就是为什么我制作了这个示例。你会发现它和你通常看到的不同——看看这个。只需下载并在 XCode 中运行。
Warp 现在支持 Swift 3.0 及以上。寻找与 Swift 2.2 兼容的版本?我们也有——切换到 2.2 分支。
大多数应用程序都有共同点——它们急需下载原始数据,并从中创建对象。不常见的是你需要整个数据库来存储它们——只是将它们作为内存中的对象就足够了。
如果你像 95% 的人来说,只想下载和展示数据,并从内存中使用它们,请继续,享受吧。
如果你需要对整个数据库执行搜索、取年控制等等,那么这就不适合你(使用 Realm、CD 或者即将到来的协议支持)。与此同时,请看看我的其他库——你肯定会用到它。
哦,如果你喜欢这个库并在某处使用了它,给我发条消息——毕竟,你省下的时间你会用来做什么呢?
不说废话了,让我们创建我们的模型。您可以通过扩展任何类使其成为 WRPObject
的子类开始。
class User : WRPObject
就这样。您的 User 已经获得了超能力——它可以 序列化、反序列化,支持远程 属性、关系等等,以下这些您会找到。
让我们假设您有以下对象定义
class User : WRPObject {
// Properties
var name : String!
var email : String?
var userId : Int = 0
var active : Bool = true
var createdAt : NSDate!
var latitude : Double = 0
var longitude : Double = 0
// Relationships
var messages : [Message] = []
}
为了使 Warp 知道如何获取您的数据,您只需提供两种方法
映射属性
Warp 几乎可以序列化您提供的任何属性。您只需提供描述,Warp 即处理余下部分。Warp 的与众不同之处在于,它的 描述涵盖了所有可能遇到的常见场景,无需复杂的技巧或闭包等,阅读起来就像一本书。
func propertyMap() -> [WRPProperty] {
return [
// Bind remote string "name" to the same local "name", must exist
WPRProperty(remote: "name", type: .String, optional: false),
// Bind remote string "email_address" to local "email", optional
WPRProperty(remote: "email_address", bindTo: "email", type: .String),
// Bind remote Bool "active" to local "active"
WPRProperty(remote: "active", type: .Bool),
// Bind remote NSDate "created_at" to local "createdAt", must exist, specific date format
WPRProperty(remote: "created_at", bindTo: "createdAt", type: .Date, optional: false, format: "yyyy-MM-dd")
]
}
这样,您可以映射所有属性 —— 只需组合初始化属性即可。现在有两种 特别需要的情况
func propertyMap() -> [WRPProperty] {
return [
...
// When the data for objects are deeper than on first level, you can use dot notation to flatten it:
// { "_geoloc" : { "lat" : 50, "lon" : 50 }} can be mapped as
WPRProperty(remote: "_geoloc.lat", bindTo: "latitude", type: .Double),
WPRProperty(remote: "_geoloc.lon", bindTo: "longitude", type: .Double),
// Warp can also bind one property from multiple sources, which is excellent when you have, for example,
// multiple databases, each with different key. Specify primary key
// if there is chance that more of them can show at once and one has priority:
WPRProperty(remotes: ["id", "objectId", "object_id"], primaryRemote: "objectId", bindTo: "userId", type: .Int),
]
}
映射关系
对象很棒,但通常,当您从REST点获取一些数据时,您希望 创建一个对象链。
例如,用户可以收到一个调用中获得的消息。 Warp 支持这一点,而且作为锦上添花的特色,它还可以创建对象之间的关系,甚至带相反的引用。
func relationMap() -> [WRPRelation] {
return [
// We create relationship for messages:
// Bind remote "messages" to local "messages". Each message has property "user",
// which we mark as the inverse. We can have multiple messages, therefore .ToMany relationship is used. Each message has only one user,
// therefore .ToOne is used in inverse.
WPRRelation(remote: "messages", bindTo: "messages", inverseBindTo: "user", modelClass: Message.self, optional: true, relationType: .ToMany, inverseRelationType: .ToOne)
]
}
我们这样声明后,就会得到以下对象链
User {
Configured properties
messages : [
message1 : Message,
message2 : Message,
message3 : Message
]
}
由于一切都有反向关系,您可以立即从消息访问用户:user.messages.first().user
。这正是关系数据库功能的一个准确反映,但无需实际数据库。棒极了。
您可以有无限数量的嵌套对象,深度无限 —— 只需为每个对象提供一个 relationMap()
即可。然后您可以轻松执行类似 user.configuration.colors.first()!.configuration.user
的操作,尽管这完全是无意义的,但有助于说明。
现在您能够描述模型结构作为整体,让我们看看如何创建对象。
对象创建
// Fetch data from server using Alamofire, AFNetworking, Moya or any other
Alamofire.request(.GET, "/user", parameters: ["id": "my-user-id"])
.responseJSON { response in
if let JSON = response.result.value {
// This produces FULLY configured user, including messages
// print(user.messages.count) > '3'
let user = User(fromJSON: JSON)
}
}
只需一行代码,所有配置就完成了。您可以根据需要使用 fromJSON:
或 fromDictionary:
。支持在下一次版本中创建多个对象的 fromArray:
。
对象更新
使用 updateWithJSONString()
或 updateWithDictionary()
方法更新您已经创建的对象——这将保留您在更新数据结构中未提到的属性,并更新其余部分,包括关系。
序列化
有时,您可能需要将对象序列化以进行存储或更新服务器上的信息。请使用如下方法实现:
// Create user
let user = User(fromDictionary: dict)
// Serialize it back
let dictionary = user.toDictionary()
// Serialize it, but exclude keys that are not interesting.
// Following with exclude messages on serialization
let dictionary = user.toDictionaryWithout(["messages"])
// You can also ONLY include keys that you want to have
let dictionary = user.toDictionaryWith(["email", "name"])
// You can also use WPRSerializationOption.IncludeNullProperties to serialize <null> where optionals are nil
重要提示:对象使用 REMOTE 键进行序列化,因此序列化输出将与源数据相同。
CocoaPods 是安装 Warp 的首选方法
pod 'Warp'
如果您还没有使用 CocoaPods,现在是时候了。您也可以使用 Swift Package Manager 下载它。
Carthage 支持即将到来。
Warp 适合大多数开发者,因为它涵盖了所有基本内容。就目前而言,仍有一些内容需要进一步完善。以下是完整的特性列表,Warp 一旦完善将包含的特性
我乐意接受 Pull Requests(并且我鼓励您这样做)。如果您遇到任何错误或者您想要看到哪些增强功能,请提交一个 issues。请确保您将 PR 目标设置为 Develop 分支。
或者,如果您想更多地了解我,请查看我的作品集。
MIT 许可证 (MIT)
版权所有 © 2016 Jiří Třečák
在此,任何人免费获得此软件及其相关的文档文件(以下简称“软件”)的副本,都可以在不受限制的情况下处理该软件,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或销售软件的副本,并允许将软件提供给人,以便他们可以这样做,前提是遵守以下条件:
上述版权声明和本许可声明应包括在软件的所有副本或其主要部分中。
本软件按“原样”提供,除非对商售性、适用于特定目的和不受侵权之保证,否则不提供任何明确的或暗示的保证,包括但不限于对适销性、适用于特定目的和不受侵权之保证。在任何情况下,作者或版权所有者都不应对因合同、侵权或任何其他原因引起的任何索赔、损害或其他法律责任负责,不管此等索赔、损害或其他责任是由软件引起的、与其相关的还是因使用或以其他方式进行处置而引起的。