KeyedMapper 1.13.0

KeyedMapper 1.13.0

测试已测试
语言语言 SwiftSwift
许可 MIT
发布最新版本2020 年 2 月
SPM支持 SPM

Blair McArthur 维护。



  • Blair McArthur

Build Status codebeat badge codecov CocoaPods

KeyedMapper

⚠️注意:此库已被 Codable 协议取代,建议使用该协议。

KeyedMapper 非常受到 Lyft 的 Mapper 的启发。我想得到一个类似于 Mapper 的东西,但是有枚举键和一些其他支持,比如 NilConvertibleReverseMappable,所以我创造了 KeyedMapper

需求

  • Xcode 11
  • Swift 5(自 1.13 版开始,之前版本支持 Swift 3)
  • iOS 8+

用法

转换
extension NSTimeZone: Convertible {
    public static func fromMap(_ value: Any) throws -> NSTimeZone {
        guard let name = value as? String else {
            throw MapperError.convertible(value: value, expectedType: String.self)
        }
        
        guard let timeZone = self.init(name: name) else {
            throw MapperError.custom(field: nil, message: "Unsupported timezone \(name)")
        }
        
        return timeZone
    }
}
可空转换
enum NilConvertibleEnum {
    case something
    case nothing
}

extension NilConvertibleEnum: NilConvertible {
    static func fromMap(_ value: Any?) throws -> NilConvertibleEnum {
        if let _ = value {
            return .something
        } else {
            return .nothing
        }
    }
}
默认转换
enum DefaultConvertibleEnum: Int, DefaultConvertible {
    case firstCase = 0
}
映射
struct SubObject {
    let property: String
}

extension SubObject: Mappable {
    enum Key: String, JSONKey {
        case property
    }

    init(map: KeyedMapper<SubObject>) throws {
        self.property = try map.from(.property)
    }
}

extension SubObject: ReverseMappable {
    func toKeyedJSON() -> [SubObject.Key : Any?] {
        return [.property : property]
    }
}

struct Object {
    let property: String
    let optionalProperty: String?
    let convertibleProperty: NSTimeZone
    let optionalConvertibleProperty: NSTimeZone?
    let nilConvertibleProperty: NilConvertibleEnum
    let arrayProperty: [String]
    let optionalArrayProperty: [String]?
    let mappableProperty: SubObject
    let optionalMappableProperty: SubObject?
    let defaultConvertibleProperty: DefaultConvertibleEnum
    let optionalDefaultConvertibleProperty: DefaultConvertibleEnum?
    let twoDArrayProperty: [[String]]
    let optionalTwoDArrayProperty: [[String]]?
}

extension Object: Mappable {
    enum Key: String, JSONKey {
        case property
        case optionalProperty
        case convertibleProperty
        case optionalConvertibleProperty
        case nilConvertibleProperty
        case arrayProperty
        case optionalArrayProperty
        case mappableProperty
        case optionalMappableProperty
        case defaultConvertibleProperty
        case optionalDefaultConvertibleProperty
        case twoDArrayProperty
        case optionalTwoDArrayProperty
    }
    
    init(map: KeyedMapper<Object>) throws {
        self.property = try map.from(.property)
        self.optionalProperty = map.optionalFrom(.optionalProperty)
        self.convertibleProperty = try map.from(.convertibleProperty)
        self.optionalConvertibleProperty = map.optionalFrom(.optionalConvertibleProperty)
        self.nilConvertibleProperty = try map.from(.nilConvertibleProperty)
        self.arrayProperty = try map.from(.arrayProperty)
        self.optionalArrayProperty = map.optionalFrom(.optionalArrayProperty)
        self.mappableProperty = try map.from(.mappableProperty)
        self.optionalMappableProperty = map.optionalFrom(.optionalMappableProperty)
        self.defaultConvertibleProperty = try map.from(.defaultConvertibleProperty)
        self.optionalDefaultConvertibleProperty = map.optionalFrom(.optionalDefaultConvertibleProperty)
        self.twoDArrayProperty = try map.from(.twoDArrayProperty)
        self.optionalTwoDArrayProperty = map.optionalFrom(.optionalTwoDArrayProperty)
    }
}

let JSON: NSDictionary = [
    "property" : "propertyValue",
    "convertibleProperty" : NSTimeZone(forSecondsFromGMT: 0).abbreviation as Any,
    "arrayProperty" : ["arrayPropertyValue1", "arrayPropertyValue2"],
    "mappableProperty" : ["property" : "propertyValue"],
    "defaultConvertibleProperty" : DefaultConvertibleEnum.firstCase.rawValue,
    "twoDArrayProperty" : [["twoDArrayPropertyValue1"], ["twoDArrayPropertyValue2"]]
]

let object = try Object.from(JSON)
逆向映射
extension Object: ReverseMappable {
    func toKeyedJSON() -> [Object.Key : Any?] {
        return [
            .property : property,
            .optionalProperty : optionalProperty,
            .convertibleProperty : convertibleProperty,
            .optionalConvertibleProperty : optionalConvertibleProperty,
            .nilConvertibleProperty : nilConvertibleProperty,
            .arrayProperty : arrayProperty,
            .optionalArrayProperty : optionalArrayProperty,
            .mappableProperty : mappableProperty.toJSON(),
            .optionalMappableProperty : optionalMappableProperty?.toJSON(),
            .defaultConvertibleProperty : defaultConvertibleProperty,
            .optionalDefaultConvertibleProperty : optionalDefaultConvertibleProperty,
            .twoDArrayProperty : twoDArrayProperty,
            .optionalTwoDArrayProperty : optionalTwoDArrayProperty
        ]
    }
}

let outJSON = object.toJSON()