ObjectMapperAdditions
- 添加简单的调用以在输出 JSON 中包含空值。
- 添加将 JSON 值类型转换为指定类型的能力。
- 添加将 Swift 基本类型数组映射到 Realm 数组的能力。
- 添加
TimestampTransform
以简单地将 UNIX 时间戳转换过来或转换出去。 - 添加
ISO8601JustDateTransform
以简单地转换到或从 ISO8601 日期 字符串。因为 ObjectMapper 的ISO8601DateTransform
实际上是转换日期和时间的。
示例
要运行示例项目,请先克隆仓库,然后从 Example 目录运行 pod install
。
安装
Swift Package Manager
- 在Xcode中选择《文件》>《添加包...
- 将以下内容复制粘贴到搜索栏:
https://github.com/APUtils/ObjectMapperAdditions
‼️ 请确保选择《直到下一个主要版本》并如果需要,将下限设置为《13.0.0》。14.2 Xcode中有一个bug,它默认不选择高于9.0.0的版本‼️ - 点击《添加包》
- 选择《ObjectMapperAdditions》以添加核心功能
- 可选地,选择《ObjectMapperAdditionsRealm》以添加《Realm》相关功能
- 点击《添加包》
CocoaPods
ObjectMapperAdditions可通过CocoaPods使用。
要安装核心功能,只需将以下行添加到您的Podfile中
pod 'ObjectMapperAdditions/Core', '~> 13.1'
要将Realm转换添加到您的项目中,将以下行添加到您的Podfile中
pod 'ObjectMapperAdditions/Realm', '~> 13.1'
Carthage 已废弃
请查看官方指南
Cartfile
github "APUtils/ObjectMapperAdditions" ~> 13.1
如果不需要REALM部分,请添加以下框架: ObjectMapperAdditions
,ObjectMapper
,RoutableLogger
。
如果您将使用REALM部分,请添加以下框架: ObjectMapperAdditions
,ObjectMapperAdditionsRealm
,ObjectMapper
,Realm
,RealmSwift
,RoutableLogger
。
使用方法
核心功能
当应用在JSON中接收到Int而不是String类型的值时,即使后端开发者说它会返回String类型,这也是一个常见的案例。更糟糕的是,有时它可能是String,有时则可能是其他类型,这会让你看起来像是发布了一个未经过充分测试的损坏应用。
在完成了几项项目之后,我为自己制定了一条规则:“永远不要相信后端!”。我总是使字段为可选的,并将值转换为我会使用的类型。目前我正在使用一个优秀的框架 ObjectMapper
映射我的对象,但它没有我需要的转换工具,所以我就编写了这个单独的动态库。
示例模型
import Foundation
import ObjectMapper
import ObjectMapperAdditions
struct MyModel: Mappable {
var string: String?
var stringsArray: [String]?
var double: Double?
var myOtherModel: MyOtherModel?
var myOtherModelsArray: [MyOtherModel]?
init?(map: Map) {}
mutating func mapping(map: Map) {
// You could specify proper type transform directly
string <- (map["string"], StringTransform.shared)
// Or you could just use TypeCastTransform
string <- (map["string"], TypeCastTransform())
// No doubt it also works with Double
double <- (map["double"], TypeCastTransform())
// Works with arrays too but for TypeCastTransform you must specify type
stringsArray <- (map["stringsArray"], TypeCastTransform<String>())
// Or just use StringTransform directly
stringsArray <- (map["stringsArray"], StringTransform.shared)
// No need to transform your types. They should specify transforms by themselfs.
myOtherModel <- map["myOtherModel"]
myOtherModelsArray <- map["myOtherModelsArray"]
}
}
目前有4种基本类型转换可以使用:BoolTransform
,DoubleTransform
,IntTransform
和 StringTransform
。但对于基本类型来说,使用 TypeCastTransform
更简单,它会自动将类型转换到正确的类型。
还支持使用 EnumTypeCastTransform
对 Bool
,Double
,Int
和 String
的原始可表示枚举类型进行类型转换。
此外,此动态库还扩展了简化包含NULL值的JSON创建功能。只需在 BaseMappable
对象或数组/集合上调用 .toJSON(shouldIncludeNilValues: true)
即可。
日期转换器示例用法
// If date in timestamp format (1506423767)
date <- (map["date"], TimestampTransform.shared)
// If date in ISO8601 full-date format (yyyy-MM-dd)
date <- (map["date"], ISO8601JustDateTransform.shared)
有关更多详细信息,请参阅示例和测试项目。
Realm特性
ObjectMapperAdditions的这个部分解决了使用ObjectMapper和Realm在一个模型中遇到的问题。从ObjectMapper-Realm 中获取的 RealmListTransform
用于将自定义类型转换成Realm列表,但它不能转换简单类型的数组或可选值。
import Foundation
import ObjectMapper
import ObjectMapperAdditions
import RealmSwift
class MyRealmModel: Object, Mappable {
@objc dynamic var id: Int = 0
@objc dynamic var double: Double = 0
let optionalDouble = RealmProperty<Double?>()
@objc dynamic var string: String?
@objc dynamic var myOtherRealmModel: MyOtherRealmModel?
let myOtherRealmModels = List<MyOtherRealmModel>()
var strings: List<String> = List<String>()
override class func primaryKey() -> String? { "id" }
override init() {
super.init()
}
required init?(map: ObjectMapper.Map) {
super.init()
// Primary kay should not be reassigned after object is added to the Realm so we make sure it is assigned during init only
id <- (map["id"], IntTransform.shared)
}
func mapping(map: ObjectMapper.Map) {
performMapping {
// Read-only primary key
id >>> map["id"]
// Same as for ordinary model
double <- (map["double"], DoubleTransform.shared)
// Using ObjectMapperAdditions's RealmPropertyTypeCastTransform
optionalDouble <- map["optionalDouble"]
// Custom transform support
// optionalDouble <- (map["optionalDouble"], DoubleTransform.shared)
// You could also use RealmPropertyTransform if you don't like type cast but you need to declare `optionalDouble` as a `var` then
// optionalDouble <- (map["optionalDouble"], RealmPropertyTransform<Double>())
string <- (map["string"], StringTransform.shared)
myOtherRealmModel <- map["myOtherRealmModel"]
// Using ObjectMapper+Realm's RealmListTransform to transform custom types
myOtherRealmModels <- map["myOtherRealmModels"]
// Using ObjectMapperAdditions's RealmTypeCastTransform
strings <- map["strings"]
// // Custom transform support
// strings <- (map["strings"], StringTransform.shared)
// You could also use RealmTransform if you don't like type cast but you need to declare `optionalDouble` as a `var` then
// strings <- (map["strings"], RealmTransform())
}
}
}
Swift的可选值以此方式转换为Realm的可选值:`Int?` -> `RealmProperty
Swift数组可以通过这种方式转换为Realm数组:[String]
-> List
,[Int]
-> List
,[Double]
-> List
,[Bool]
-> List
等。
请务必检查类型为RealmProperty
和List
的属性既不是动态的也不是可选的。尽管它们被定义为var
,但如果是模型添加到Realm中,应该将它们视为常量处理。使用.value
修改RealmOptional
的值,或者使用.removeAll()
和append(objectsIn:)
方法修改List
的内容。
有关更多详细信息,请参阅示例和测试项目。
贡献
欢迎任何形式的贡献!您可以通过GitHub上的pull requests和issues来贡献。
作者
Anton Plebanovich, [email protected]
许可协议
ObjectMapperAdditions遵循MIT许可协议。更多信息请参阅LICENSE文件。