ObjectMapperAdditions 13.1.0

ObjectMapperAdditions 13.1.0

测试已测试
Lang语言 SwiftSwift
许可 MIT
发布最新发布2023 年 5 月
SPM支持 SPM

Anton Plebanovich 维护。



 
依赖关系
ObjectMapper>= 0
RoutableLogger>= 12.0
 

  • 作者
  • Anton Plebanovich

ObjectMapperAdditions

Carthage compatible Swift Package Manager compatible Version License Platform CI Status

  • 添加简单的调用以在输出 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部分,请添加以下框架: ObjectMapperAdditionsObjectMapperRoutableLogger

如果您将使用REALM部分,请添加以下框架: ObjectMapperAdditionsObjectMapperAdditionsRealmObjectMapperRealmRealmSwiftRoutableLogger

使用方法

核心功能

当应用在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种基本类型转换可以使用:BoolTransformDoubleTransformIntTransformStringTransform。但对于基本类型来说,使用 TypeCastTransform 更简单,它会自动将类型转换到正确的类型。

还支持使用 EnumTypeCastTransformBoolDoubleIntString 的原始可表示枚举类型进行类型转换。

此外,此动态库还扩展了简化包含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`,`Double?` -> `RealmProperty`,`Bool?` -> `RealmProperty` 等。

Swift数组可以通过这种方式转换为Realm数组:[String] -> List[Int] -> List[Double] -> List[Bool] -> List等。

请务必检查类型为RealmPropertyList的属性既不是动态的也不是可选的。尽管它们被定义为var,但如果是模型添加到Realm中,应该将它们视为常量处理。使用.value修改RealmOptional的值,或者使用.removeAll()append(objectsIn:)方法修改List的内容。

有关更多详细信息,请参阅示例和测试项目。

贡献

欢迎任何形式的贡献!您可以通过GitHub上的pull requests和issues来贡献。

作者

Anton Plebanovich, [email protected]

许可协议

ObjectMapperAdditions遵循MIT许可协议。更多信息请参阅LICENSE文件。