HandyJSON is a framework written in Swift which to make converting model objects to and from JSON easy on iOS.

Overview

HandyJSON

To deal with crash on iOS 14 beta4 please try version 5.0.3-beta

HandyJSON is a framework written in Swift which to make converting model objects( pure classes/structs ) to and from JSON easy on iOS.

Compared with others, the most significant feature of HandyJSON is that it does not require the objects inherit from NSObject(not using KVC but reflection), neither implements a 'mapping' function(writing value to memory directly to achieve property assignment).

HandyJSON is totally depend on the memory layout rules infered from Swift runtime code. We are watching it and will follow every bit if it changes.

Build Status Carthage compatible Cocoapods Version Cocoapods Platform Codecov branch

中文文档

交流群

群号: 581331250

交流群

Sample Code

Deserialization

class BasicTypes: HandyJSON {
    var int: Int = 2
    var doubleOptional: Double?
    var stringImplicitlyUnwrapped: String!

    required init() {}
}

let jsonString = "{\"doubleOptional\":1.1,\"stringImplicitlyUnwrapped\":\"hello\",\"int\":1}"
if let object = BasicTypes.deserialize(from: jsonString) {
    print(object.int)
    print(object.doubleOptional!)
    print(object.stringImplicitlyUnwrapped)
}

Serialization

let object = BasicTypes()
object.int = 1
object.doubleOptional = 1.1
object.stringImplicitlyUnwrapped = “hello"

print(object.toJSON()!) // serialize to dictionary
print(object.toJSONString()!) // serialize to JSON string
print(object.toJSONString(prettyPrint: true)!) // serialize to pretty JSON string

Content

Features

  • Serialize/Deserialize Object/JSON to/From JSON/Object

  • Naturally use object property name for mapping, no need to specify a mapping relationship

  • Support almost all types in Swift, including enum

  • Support struct

  • Custom transformations

  • Type-Adaption, such as string json field maps to int property, int json field maps to string property

An overview of types supported can be found at file: BasicTypes.swift

Requirements

  • iOS 8.0+/OSX 10.9+/watchOS 2.0+/tvOS 9.0+

  • Swift 3.0+ / Swift 4.0+ / Swift 5.0+

Installation

To use with Swift 5.0/5.1 ( Xcode 10.2+/11.0+ ), version == 5.0.2

To use with Swift 4.2 ( Xcode 10 ), version == 4.2.0

To use with Swift 4.0, version >= 4.1.1

To use with Swift 3.x, version >= 1.8.0

For Legacy Swift2.x support, take a look at the swift2 branch.

Cocoapods

Add the following line to your Podfile:

pod 'HandyJSON', '~> 5.0.2'

Then, run the following command:

$ pod install

Carthage

You can add a dependency on HandyJSON by adding the following line to your Cartfile:

5.0.2 ">
github "alibaba/HandyJSON" ~> 5.0.2

Manually

You can integrate HandyJSON into your project manually by doing the following steps:

  • Open up Terminal, cd into your top-level project directory, and add HandyJSON as a submodule:
git init && git submodule add https://github.com/alibaba/HandyJSON.git
  • Open the new HandyJSON folder, drag the HandyJSON.xcodeproj into the Project Navigator of your project.

  • Select your application project in the Project Navigator, open the General panel in the right window.

  • Click on the + button under the Embedded Binaries section.

  • You will see two different HandyJSON.xcodeproj folders each with four different versions of the HandyJSON.framework nested inside a Products folder.

It does not matter which Products folder you choose from, but it does matter which HandyJSON.framework you choose.

  • Select one of the four HandyJSON.framework which matches the platform your Application should run on.

  • Congratulations!

Deserialization

The Basics

To support deserialization from JSON, a class/struct need to conform to 'HandyJSON' protocol. It's truly protocol, not some class inherited from NSObject.

To conform to 'HandyJSON', a class need to implement an empty initializer.

class BasicTypes: HandyJSON {
    var int: Int = 2
    var doubleOptional: Double?
    var stringImplicitlyUnwrapped: String!

    required init() {}
}

let jsonString = "{\"doubleOptional\":1.1,\"stringImplicitlyUnwrapped\":\"hello\",\"int\":1}"
if let object = BasicTypes.deserialize(from: jsonString) {
    //
}

Support Struct

For struct, since the compiler provide a default empty initializer, we use it for free.

struct BasicTypes: HandyJSON {
    var int: Int = 2
    var doubleOptional: Double?
    var stringImplicitlyUnwrapped: String!
}

let jsonString = "{\"doubleOptional\":1.1,\"stringImplicitlyUnwrapped\":\"hello\",\"int\":1}"
if let object = BasicTypes.deserialize(from: jsonString) {
    //
}

But also notice that, if you have a designated initializer to override the default one in the struct, you should explicitly declare an empty one(no required modifier need).

Support Enum Property

To be convertable, An enum must conform to HandyJSONEnum protocol. Nothing special need to do now.

enum AnimalType: String, HandyJSONEnum {
    case Cat = "cat"
    case Dog = "dog"
    case Bird = "bird"
}

struct Animal: HandyJSON {
    var name: String?
    var type: AnimalType?
}

let jsonString = "{\"type\":\"cat\",\"name\":\"Tom\"}"
if let animal = Animal.deserialize(from: jsonString) {
    print(animal.type?.rawValue)
}

Optional/ImplicitlyUnwrappedOptional/Collections/...

'HandyJSON' support classes/structs composed of optional, implicitlyUnwrappedOptional, array, dictionary, objective-c base type, nested type etc. properties.

class BasicTypes: HandyJSON {
    var bool: Bool = true
    var intOptional: Int?
    var doubleImplicitlyUnwrapped: Double!
    var anyObjectOptional: Any?

    var arrayInt: Array<Int> = []
    var arrayStringOptional: Array<String>?
    var setInt: Set<Int>?
    var dictAnyObject: Dictionary<String, Any> = [:]

    var nsNumber = 2
    var nsString: NSString?

    required init() {}
}

let object = BasicTypes()
object.intOptional = 1
object.doubleImplicitlyUnwrapped = 1.1
object.anyObjectOptional = "StringValue"
object.arrayInt = [1, 2]
object.arrayStringOptional = ["a", "b"]
object.setInt = [1, 2]
object.dictAnyObject = ["key1": 1, "key2": "stringValue"]
object.nsNumber = 2
object.nsString = "nsStringValue"

let jsonString = object.toJSONString()!

if let object = BasicTypes.deserialize(from: jsonString) {
    // ...
}

Designated Path

HandyJSON supports deserialization from designated path of JSON.

class Cat: HandyJSON {
    var id: Int64!
    var name: String!

    required init() {}
}

let jsonString = "{\"code\":200,\"msg\":\"success\",\"data\":{\"cat\":{\"id\":12345,\"name\":\"Kitty\"}}}"

if let cat = Cat.deserialize(from: jsonString, designatedPath: "data.cat") {
    print(cat.name)
}

Composition Object

Notice that all the properties of a class/struct need to deserialized should be type conformed to HandyJSON.

class Component: HandyJSON {
    var aInt: Int?
    var aString: String?

    required init() {}
}

class Composition: HandyJSON {
    var aInt: Int?
    var comp1: Component?
    var comp2: Component?

    required init() {}
}

let jsonString = "{\"num\":12345,\"comp1\":{\"aInt\":1,\"aString\":\"aaaaa\"},\"comp2\":{\"aInt\":2,\"aString\":\"bbbbb\"}}"

if let composition = Composition.deserialize(from: jsonString) {
    print(composition)
}

Inheritance Object

A subclass need deserialization, it's superclass need to conform to HandyJSON.

class Animal: HandyJSON {
    var id: Int?
    var color: String?

    required init() {}
}

class Cat: Animal {
    var name: String?

    required init() {}
}

let jsonString = "{\"id\":12345,\"color\":\"black\",\"name\":\"cat\"}"

if let cat = Cat.deserialize(from: jsonString) {
    print(cat)
}

JSON Array

If the first level of a JSON text is an array, we turn it to objects array.

class Cat: HandyJSON {
    var name: String?
    var id: String?

    required init() {}
}

let jsonArrayString: String? = "[{\"name\":\"Bob\",\"id\":\"1\"}, {\"name\":\"Lily\",\"id\":\"2\"}, {\"name\":\"Lucy\",\"id\":\"3\"}]"
if let cats = [Cat].deserialize(from: jsonArrayString) {
    cats.forEach({ (cat) in
        // ...
    })
}

Mapping From Dictionary

HandyJSON support mapping swift dictionary to model.

var dict = [String: Any]()
dict["doubleOptional"] = 1.1
dict["stringImplicitlyUnwrapped"] = "hello"
dict["int"] = 1
if let object = BasicTypes.deserialize(from: dict) {
    // ...
}

Custom Mapping

HandyJSON let you customize the key mapping to JSON fields, or parsing method of any property. All you need to do is implementing an optional mapping function, do things in it.

We bring the transformer from ObjectMapper. If you are familiar with it, it’s almost the same here.

(fromJSON: { (rawString) -> (String, String)? in if let parentNames = rawString?.characters.split(separator: "/").map(String.init) { return (parentNames[0], parentNames[1]) } return nil }, toJSON: { (tuple) -> String? in if let _tuple = tuple { return "\(_tuple.0)/\(_tuple.1)" } return nil }) // specify 'friend.name' path field in json map to 'friendName' property mapper <<< self.friendName <-- "friend.name" } } let jsonString = "{\"cat_id\":12345,\"name\":\"Kitty\",\"parent\":\"Tom/Lily\",\"friend\":{\"id\":54321,\"name\":\"Lily\"}}" if let cat = Cat.deserialize(from: jsonString) { print(cat.id) print(cat.parent) print(cat.friendName) } ">
class Cat: HandyJSON {
    var id: Int64!
    var name: String!
    var parent: (String, String)?
    var friendName: String?

    required init() {}

    func mapping(mapper: HelpingMapper) {
        // specify 'cat_id' field in json map to 'id' property in object
        mapper <<<
            self.id <-- "cat_id"

        // specify 'parent' field in json parse as following to 'parent' property in object
        mapper <<<
            self.parent <-- TransformOf<(String, String), String>(fromJSON: { (rawString) -> (String, String)? in
                if let parentNames = rawString?.characters.split(separator: "/").map(String.init) {
                    return (parentNames[0], parentNames[1])
                }
                return nil
            }, toJSON: { (tuple) -> String? in
                if let _tuple = tuple {
                    return "\(_tuple.0)/\(_tuple.1)"
                }
                return nil
            })

        // specify 'friend.name' path field in json map to 'friendName' property
        mapper <<<
            self.friendName <-- "friend.name"
    }
}

let jsonString = "{\"cat_id\":12345,\"name\":\"Kitty\",\"parent\":\"Tom/Lily\",\"friend\":{\"id\":54321,\"name\":\"Lily\"}}"

if let cat = Cat.deserialize(from: jsonString) {
    print(cat.id)
    print(cat.parent)
    print(cat.friendName)
}

Date/Data/URL/Decimal/Color

HandyJSON prepare some useful transformer for some none-basic type.

class ExtendType: HandyJSON {
    var date: Date?
    var decimal: NSDecimalNumber?
    var url: URL?
    var data: Data?
    var color: UIColor?

    func mapping(mapper: HelpingMapper) {
        mapper <<<
            date <-- CustomDateFormatTransform(formatString: "yyyy-MM-dd")

        mapper <<<
            decimal <-- NSDecimalNumberTransform()

        mapper <<<
            url <-- URLTransform(shouldEncodeURLString: false)

        mapper <<<
            data <-- DataTransform()

        mapper <<<
            color <-- HexColorTransform()
    }

    public required init() {}
}

let object = ExtendType()
object.date = Date()
object.decimal = NSDecimalNumber(string: "1.23423414371298437124391243")
object.url = URL(string: "https://www.aliyun.com")
object.data = Data(base64Encoded: "aGVsbG8sIHdvcmxkIQ==")
object.color = UIColor.blue

print(object.toJSONString()!)
// it prints:
// {"date":"2017-09-11","decimal":"1.23423414371298437124391243","url":"https:\/\/www.aliyun.com","data":"aGVsbG8sIHdvcmxkIQ==","color":"0000FF"}

let mappedObject = ExtendType.deserialize(from: object.toJSONString()!)!
print(mappedObject.date)
...

Exclude Property

If any non-basic property of a class/struct could not conform to HandyJSON/HandyJSONEnum or you just do not want to do the deserialization with it, you should exclude it in the mapping function.

class NotHandyJSONType {
    var dummy: String?
}

class Cat: HandyJSON {
    var id: Int64!
    var name: String!
    var notHandyJSONTypeProperty: NotHandyJSONType?
    var basicTypeButNotWantedProperty: String?

    required init() {}

    func mapping(mapper: HelpingMapper) {
        mapper >>> self.notHandyJSONTypeProperty
        mapper >>> self.basicTypeButNotWantedProperty
    }
}

let jsonString = "{\"name\":\"cat\",\"id\":\"12345\"}"

if let cat = Cat.deserialize(from: jsonString) {
    print(cat)
}

Update Existing Model

HandyJSON support updating an existing model with given json string or dictionary.

class BasicTypes: HandyJSON {
    var int: Int = 2
    var doubleOptional: Double?
    var stringImplicitlyUnwrapped: String!

    required init() {}
}

var object = BasicTypes()
object.int = 1
object.doubleOptional = 1.1

let jsonString = "{\"doubleOptional\":2.2}"
JSONDeserializer.update(object: &object, from: jsonString)
print(object.int)
print(object.doubleOptional)

Supported Property Type

  • Int/Bool/Double/Float/String/NSNumber/NSString

  • RawRepresentable enum

  • NSArray/NSDictionary

  • Int8/Int16/Int32/Int64/UInt8/UInt16/UInt23/UInt64

  • Optional/ImplicitUnwrappedOptional // T is one of the above types

  • Array // T is one of the above types

  • Dictionary // T is one of the above types

  • Nested of aboves

Serialization

The Basics

Now, a class/model which need to serialize to JSON should also conform to HandyJSON protocol.

class BasicTypes: HandyJSON {
    var int: Int = 2
    var doubleOptional: Double?
    var stringImplicitlyUnwrapped: String!

    required init() {}
}

let object = BasicTypes()
object.int = 1
object.doubleOptional = 1.1
object.stringImplicitlyUnwrapped = “hello"

print(object.toJSON()!) // serialize to dictionary
print(object.toJSONString()!) // serialize to JSON string
print(object.toJSONString(prettyPrint: true)!) // serialize to pretty JSON string

Mapping And Excluding

It’s all like what we do on deserialization. A property which is excluded, it will not take part in neither deserialization nor serialization. And the mapper items define both the deserializing rules and serializing rules. Refer to the usage above.

FAQ

Q: Why the mapping function is not working in the inheritance object?

A: For some reason, you should define an empty mapping function in the super class(the root class if more than one layer), and override it in the subclass.

It's the same with didFinishMapping function.

Q: Why my didSet/willSet is not working?

A: Since HandyJSON assign properties by writing value to memory directly, it doesn't trigger any observing function. You need to call the didSet/willSet logic explicitly after/before the deserialization.

But since version 1.8.0, HandyJSON handle dynamic properties by the KVC mechanism which will trigger the KVO. That means, if you do really need the didSet/willSet, you can define your model like follow:

class BasicTypes: NSObject, HandyJSON {
    dynamic var int: Int = 0 {
        didSet {
            print("oldValue: ", oldValue)
        }
        willSet {
            print("newValue: ", newValue)
        }
    }

    public override required init() {}
}

In this situation, NSObject and dynamic are both needed.

And in versions since 1.8.0, HandyJSON offer a didFinishMapping function to allow you to fill some observing logic.

class BasicTypes: HandyJSON {
    var int: Int?

    required init() {}

    func didFinishMapping() {
        print("you can fill some observing logic here")
    }
}

It may help.

Q: How to support Enum property?

It your enum conform to RawRepresentable protocol, please look into Support Enum Property. Or use the EnumTransform:

enum EnumType: String {
    case type1, type2
}

class BasicTypes: HandyJSON {
    var type: EnumType?

    func mapping(mapper: HelpingMapper) {
        mapper <<<
            type <-- EnumTransform()
    }

    required init() {}
}

let object = BasicTypes()
object.type = EnumType.type2
print(object.toJSONString()!)
let mappedObject = BasicTypes.deserialize(from: object.toJSONString()!)!
print(mappedObject.type)

Otherwise, you should implement your custom mapping function.

String? in if let _type = enumType { switch (_type) { case EnumType.type1: return "type1" case EnumType.type2: return "type2" } } return nil }) } required init() {} } ">
enum EnumType {
    case type1, type2
}

class BasicTypes: HandyJSON {
    var type: EnumType?

    func mapping(mapper: HelpingMapper) {
        mapper <<<
            type <-- TransformOf<EnumType, String>(fromJSON: { (rawString) -> EnumType? in
                if let _str = rawString {
                    switch (_str) {
                    case "type1":
                        return EnumType.type1
                    case "type2":
                        return EnumType.type2
                    default:
                        return nil
                    }
                }
                return nil
            }, toJSON: { (enumType) -> String? in
                if let _type = enumType {
                    switch (_type) {
                    case EnumType.type1:
                        return "type1"
                    case EnumType.type2:
                        return "type2"
                    }
                }
                return nil
            })
    }

    required init() {}
}

Credit

  • reflection: After the first version which used the swift mirror mechanism, HandyJSON had imported the reflection library and rewrote some code for class properties inspecting.
  • ObjectMapper: To make HandyJSON more compatible with the general style, the Mapper function support Transform which designed by ObjectMapper. And we import some testcases from ObjectMapper.

License

HandyJSON is released under the Apache License, Version 2.0. See LICENSE for details.

Comments
  • 反馈一个升级 iOS13.4Beta 后遇到的闪退问题

    反馈一个升级 iOS13.4Beta 后遇到的闪退问题

     # Crashlytics - plaintext stacktrace downloaded by frank at Sat, 08 Feb 2020 09:19:43 GMT
    # Platform: ios
    # Version: 1.5.5.4451
    # Date: 2020-02-08T08:46:00Z
    # OS Version: 13.4.0 (17E5223h)
    # Device: iPhone X
    # RAM Free: 3.7%
    # Disk Free: 11.8%
     
    #6. Crashed: UserInfoService
    0  libsystem_platform.dylib       0x192cb4a0c _platform_memmove + 284
    1  libswiftCore.dylib             0x1a0b382cc <redacted> + 28
    2  HandyJSON                      0x1074c2158 static AnyExtensions.write(_:to:) + 41 (AnyExtensions.swift:41)
    3  HandyJSON                      0x1074d1168 static _ExtendCustomModelType._transform(dict:to:) + 72 (ExtendCustomModelType.swift:72)
    4  HandyJSON                      0x1074d04f0 static _ExtendCustomModelType._transform(dict:) + 135 (ExtendCustomModelType.swift:135)
    5  HandyJSON                      0x1074cde38 static JSONDeserializer.deserializeFrom(dict:designatedPath:) + 356 (<compiler-generated>:356)
    6  HandyJSON                      0x1074ce3d0 static JSONDeserializer.deserializeFrom(json:designatedPath:) + 1012 (<compiler-generated>:1012)
    7  HandyJSON                      0x1074cdfc4 static HandyJSON.deserialize(from:designatedPath:) + 39 (Deserializer.swift:39)
    8  XApp                           0x104a8a590 closure #1 in UserInfoService.loadCachedUserInfo(with:) + 4377290128 (<compiler-generated>:4377290128)
    9  Xapp                           0x104ab9d94 thunk for @escaping @callee_guaranteed () -> () + 4377484692 (<compiler-generated>:4377484692)
    10 libdispatch.dylib              0x192c729a8 <redacted> + 24
    11 libdispatch.dylib              0x192c73524 <redacted> + 16
    12 libdispatch.dylib              0x192c50b3c <redacted> + 564
    13 libdispatch.dylib              0x192c5154c <redacted> + 396
    14 libdispatch.dylib              0x192c5a84c <redacted> + 580
    15 libsystem_pthread.dylib        0x192cc3b74 _pthread_wqthread + 272
    16 libsystem_pthread.dylib        0x192cc6740 start_wqthread + 8
    
    opened by fanthus 46
  • xocde9.3beta , swift4.1/swift3.3,4.0.0-beta.1, json转model 出现异常。必现

    xocde9.3beta , swift4.1/swift3.3,4.0.0-beta.1, json转model 出现异常。必现

    NominalType.swift 文件,第69行
    var numberOfFields: Int { return Int(pointer.pointee.numberOfFields)//出现异常代码 }

    warning: could not execute support code to read Objective-C class data in the process. This may reduce the quality of type information available.

    bug 
    opened by wzi90921 24
  • 提一个建议,望改进

    提一个建议,望改进

    大家都知道,现在网络请求的数据多数以json格式解析,json格式有个好处是在控制台打印出来后有结构性,结构层次一清二楚,虽然也可以将请求的json格式转换成json字符串,但是通过字符串转换相当的不直观,不知道能不能以json格式转换?我吃了几次亏,后台接口写的字段和实际的并不相符,我建模型的时候字段老是对不上,还在傻傻的去找错误!实际上json字符串一长串,根本就不好找。

    归根结底,现在只支持jsonString -> model, 并不支持json -> model 其实我觉得提供额外方法(最偷懒的做法)也快,直接将返回的json序列化成字符串再调用现有的接口即可

    opened by Mosaics 12
  • Undefined symbols

    Undefined symbols "_swift_getFieldAt"

    试了一下Xcode 10.2,编译提示: Undefined symbols for architecture x86_64: "_swift_getFieldAt", referenced from: HandyJSON.Metadata.Class._propertyDescriptionsAndStartPoint() -> ([HandyJSON.Property.Description], Swift.Int32?)? in Metadata.o HandyJSON.Metadata.Struct.propertyDescriptions() -> [HandyJSON.Property.Description]? in Metadata.o

    尝试把pod项目中swift version改成4.2也是一样

    opened by miku1958 11
  • 请教下大神,我序列化的时候怎么排除某些字段

    请教下大神,我序列化的时候怎么排除某些字段

    因为有2个字段是UIImage类型 但是我实现了 func mapping(mapper: HelpingMapper) { mapper >>> self.image mapper >>> self.thumbnailImage } 这个函数没效果,序列化也会失败,请教下我该怎么写

    bug 
    opened by ac1217 11
  • How to specify mapper for serialization?

    How to specify mapper for serialization?

    When I try to serialize a Date and some custom fields. Serializing a Date crashes, and I don't see how to provide a serialization mapper. Am I missing something or is it a missing feature?

    opened by francescortiz 8
  • iOS 15 crash堆栈  _propertyDescriptionsAndStartPoint 请问handyjson还在维护么?

    iOS 15 crash堆栈 _propertyDescriptionsAndStartPoint 请问handyjson还在维护么?

    _propertyDescriptionsAndStartPoint (:0) propertyDescriptions (Metadata.swift:214) _transform (ExtendCustomModelType.swift:140) _transform (ExtendCustomModelType.swift:135) deserializeFrom (Deserializer.swift:78) deserialize (Deserializer.swift:33)

    opened by programer001 7
  • pod update 之后报错了,是新版本兼容问题吗

    pod update 之后报错了,是新版本兼容问题吗

    Undefined symbols for architecture x86_64: "_swift_getFieldAt", referenced from: HandyJSON.Metadata.Class._propertyDescriptionsAndStartPoint() -> ([HandyJSON.Property.Description], Swift.Int32?)? in Metadata.o HandyJSON.Metadata.Struct.propertyDescriptions() -> [HandyJSON.Property.Description]? in Metadata.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation)

    opened by cavanlee 7
  • 很奇怪的编译错误

    很奇怪的编译错误

    Xcode版本:Version 8.2.1 (8C1002) Swift版本:3.0 错误信息: Command failed due to signal: Segmentation fault: 11

    import Foundation
    import HandyJSON
    
    struct Meeting: HandyJSON {
    
        /** 主键 */
        var id = ""
        /** 名称 */
        var name = ""
        /** 安全码 */
        var secret = ""
        var creator: User?
       // ==================编译正常================
        var noerror: [User]?
        /** 创建时间 */
        var createTime = ""
        /** 流列表 */
        var streams: [StreamInfo]?
        // =================编译错误=================
        var error: StreamInfo?
    
    }
    
    import Foundation
    import HandyJSON
    
    struct User: HandyJSON  {
        
        /** 主键 */
        var id = ""
        /** 账号 */
        var username = ""
        /** 昵称 */
        var nickname = ""
        /** 邮箱 */
        var email = ""
        /** 手机 */
        var mobilePhone = ""
        /** 身份证号 */
        var idcard = ""
        /** 创建时间 */
        var createTime = ""
        
    }
    
    import Foundation
    import HandyJSON
    
    struct StreamInfo: HandyJSON  {
    
        /** 主键 */
        var id = ""
        /** app */
        var app = ""
        /** tcURL */
        var tcUrl = ""
        /** 流主键 */
        var streamId = ""
        /** 客户端主键 */
        var clientId = ""
        /** IP地址 */
        var ip = ""
        /** vHost */
        var vHost = ""
        /** pageUrl */
        var pageUrl = ""
        /** 创建人 */
        var creator: User!
        /** 创建时间 */
        var createTime = ""
        /** 所属会议 */
        var meeting: Meeting!
    }
    
    opened by songpo 7
  • 对枚举类型的实现效果不佳

    对枚举类型的实现效果不佳

    我们通常会针对服务端下发的数字转化成枚举 enum ResourceType : Int { case 新闻 = 1 case 自媒体 = 2 case 帖子 = 3 case 问答 = 4 case 话题 = 5 case Unknown = -1 } 在ObjectMapper里只要直接放上去这个,在用默认map就可以反序列化 初始化默认使用Unknown, 当服务端下发6,7等客户端无法识别的类型时还是会保存Unknown不变 HandyJSON能否实现类似效果,另外HandyJSON这个协议加到enum上会有入侵性

    opened by donyang 7
  • 关于HandyJSON在swift4.1报错以及后续更新问题

    关于HandyJSON在swift4.1报错以及后续更新问题

    最近大家更新swift4.1之后多多少少出了一些问题,不过问题有大神已经解决,并且经过验证确实可行,希望大家暂时按照解决方案解决;对于比较关心的更新问题,我在联系作者,可能因为作者那边比较忙,暂时没有回复,希望大家还是可以继续支持,有消息会及时通知大家。此外,QQ群人数已满,节后我看下开一个2群,到时候把群号贴出来(现在的群是由作者建立的,我是管理,所以后面建立2群的话,一样的性质)

    opened by CodeKingL 6
  • Unable to determine Swift version for the following pods

    Unable to determine Swift version for the following pods

    • HandyJSON does not specify a Swift version and none of the targets (packager) integrating it have the SWIFT_VERSION attribute set. Please contact the author or set the SWIFT_VERSION attribute in at least one of the targets that integrate this pod. 能不能在.podspec文件加上s.swift_version = 'X.X'
    opened by jnckjian 0
  • Not work with  RealmSwift.xcframework

    Not work with RealmSwift.xcframework

    import Foundation import RealmSwift import HandyJSON

    class HomeHandyJson: Object, HandyJSON { // @Persisted

    @Persisted var is_expire: String?
    
    @Persisted   var use_result_imgs: MyResullt?
    
    required  override init(){
        super.init()
    } 
    

    }

    class MyResullt: Object, HandyJSON { @Persisted var imgs: List required override init(){ super.init() } }

    class ImgsSSxxx: Object, HandyJSON { @Persisted var attachment_id: String? @Persisted var fileName: String? @Persisted var seal_id: String? @Persisted var confirm_status: Int? @Persisted var path: String? @Persisted var path_thumbnail: String? @Persisted var fileLength: Int? @Persisted var oss_url: String? @Persisted var fileSize: String? required override init(){ super.init() } }

                    let realm = try! Realm()
              
                    try! realm.write {
                      //can not add to realm  and  bb is nil 。when i remove  @Persisted and Object  it can be a HomeHandyJson
                        let bb = HomeHandyJson.deserialize(from: responseDic["data"] as! [String : Any])
    
                        realm.add(bb!)
                    }
    
    opened by locooo 1
  • 建议在README中显著标注「不建议使用」

    建议在README中显著标注「不建议使用」

    诚然HandyJSON很好用,我是刚学iOS开发不久的,之前最终决定使用HandyJSON作为项目的JSON解析框架。看到issues里很多讨论HandyJSON写内存不稳定,升级系统版本必崩溃等问题(我暂时没有遇到,并且在我决定使用HandyJSON前就知道这些隐含问题了,之所以仍然使用是因为找不到更好更方便的解决方案),而且作者也已经不建议使用了#466,我认为应该更加负责任一些,在README的显著位置标注「不建议再使用」,给后面像我这样的初来者提个醒。目前我已经有了更好的解决方案(仅针对我的单个项目),并迁移到官方的Codable了,其实Codable大部分功能也都能实现

    opened by kylechandev 0
  • 为啥toJSON方法转字典后,并不是自己创建的属性名

    为啥toJSON方法转字典后,并不是自己创建的属性名

    var wId : String? = ""

    override func mapping(mapper: HelpingMapper) { mapper <<< self.wId <-- "id" }

    toJSON之后获取的key是“id”而不是wId,这么玩的吗

    opened by bruceFighting 0
Releases(4.1.3)
Owner
Alibaba
Alibaba Open Source
Alibaba
ObjectMapper is a framework written in Swift that makes it easy for you to convert your model objects to and from JSON.

ObjectMapper is a framework written in Swift that makes it easy for you to convert your model objects (classes and structs) to and from J

Tristan Himmelman 9k Jan 2, 2023
JSONExport is a desktop application for Mac OS X which enables you to export JSON objects as model classes with their associated constructors, utility methods, setters and getters in your favorite language.

JSONExport JSONExport is a desktop application for Mac OS X written in Swift. Using JSONExport you will be able to: Convert any valid JSON object to a

Ahmed Ali 4.7k Dec 30, 2022
JSONNeverDie - Auto reflection tool from JSON to Model, user friendly JSON encoder / decoder, aims to never die

JSONNeverDie is an auto reflection tool from JSON to Model, a user friendly JSON encoder / decoder, aims to never die. Also JSONNeverDie is a very important part of Pitaya.

John Lui 454 Oct 30, 2022
AlamofireObjectMappe - An Alamofire extension which converts JSON response data into swift objects using ObjectMapper

AlamofireObjectMapper An extension to Alamofire which automatically converts JSON response data into swift objects using ObjectMapper. Usage Given a U

Tristan Himmelman 2.6k Dec 29, 2022
🌟 Super light and easy automatic JSON to model mapper

magic-mapper-swift ?? Super light and easy automatic JSON to model mapper Finish writing README.md Ability to map NSManagedObject Ability to convert m

Adrian Mateoaea 26 Oct 6, 2019
JSEN (JSON Swift Enum Notation) is a lightweight enum representation of a JSON, written in Swift.

JSEN /ˈdʒeɪsən/ JAY-sən JSEN (JSON Swift Enum Notation) is a lightweight enum representation of a JSON, written in Swift. A JSON, as defined in the EC

Roger Oba 8 Nov 22, 2022
JSONJoy - Convert JSON to Swift objects

JSONJoy Convert JSON to Swift objects. The Objective-C counterpart can be found here: JSONJoy. Parsing JSON in Swift has be likened to a trip through

Dalton 350 Oct 15, 2022
An extension for Alamofire that converts JSON data into Decodable objects.

Swift 4 introduces a new Codable protocol that lets you serialize and deserialize custom data types without writing any special code and without havin

Nikita Ermolenko 749 Dec 5, 2022
Elevate is a JSON parsing framework that leverages Swift to make parsing simple, reliable and composable

Elevate is a JSON parsing framework that leverages Swift to make parsing simple, reliable and composable. Elevate should no longer be used for

Nike Inc. 611 Oct 23, 2022
Mappable - Flexible JSON to Model converter, specially optimized for immutable properties

Mappable is a lightweight, flexible, easy-to-use framework to convert JSON to model, specially optimized for immutable property initializatio

Leave 27 Aug 26, 2022
Swift parser for JSON Feed — a new format similar to RSS and Atom but in JSON.

JSONFeed Swift parser for JSON Feed — a new format similar to RSS and Atom but in JSON. For more information about this new feed format visit: https:/

Toto Tvalavadze 31 Nov 22, 2021
Swift-json - High-performance json parsing in swift

json 0.1.4 swift-json is a pure-Swift JSON parsing library designed for high-per

kelvin 43 Dec 15, 2022
JSON-Practice - JSON Practice With Swift

JSON Practice Vista creada con: Programmatic + AutoLayout Breve explicación de l

Vanesa Giselle Korbenfeld 0 Oct 29, 2021
Ss-json - High-performance json parsing in swift

json 0.1.1 swift-json is a pure-Swift JSON parsing library designed for high-per

kelvin 43 Dec 15, 2022
JSONHelper - ✌ Convert anything into anything in one operation; JSON data into class instances, hex strings into UIColor/NSColor, y/n strings to booleans, arrays and dictionaries of these; anything you can make sense of!

JSONHelper Convert anything into anything in one operation; hex strings into UIColor/NSColor, JSON strings into class instances, y/n strings to boolea

Baris Sencan 788 Jul 19, 2022
An iOS framework for creating JSON-based models. Written in Swift.

An iOS framework for creating JSON-based models. Written in Swift (because it totally rules!) Requirements iOS 8.0+ Xcode 7.3 Swift 2.2 Installation E

Oven Bits 448 Nov 8, 2022
Model framework for Cocoa and Cocoa Touch

Mantle Mantle makes it easy to write a simple model layer for your Cocoa or Cocoa Touch application. The Typical Model Object What's wrong with the wa

null 11.3k Dec 31, 2022
Argo is a library that lets you extract models from JSON or similar structures in a way that's concise, type-safe, and easy to extend

Argo is a library that lets you extract models from JSON or similar structures in a way that's concise, type-safe, and easy to extend. Using Argo

thoughtbot, inc. 3.5k Dec 20, 2022
SwiftyJSON makes it easy to deal with JSON data in Swift.

SwiftyJSON SwiftyJSON makes it easy to deal with JSON data in Swift. Platform Build Status *OS Linux Why is the typical JSON handling in Swift NOT goo

SwiftyJSON 21.7k Jan 3, 2023