Skip to content
swift object serialize/deserialize of json
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
Serialize.xcodeproj
Serialize
SerializeTests
.travis.yml add swift 3.0 support Nov 8, 2016
LICENSE
README.md
swift-serialize.podspec

README.md

Serialize (swift 5.0)

Platform Language Build Status License

  • serialize swift object to json

  • deserialize json for swift custom class

建议在 Swift 4.0 以及之后的版本中使用原生的 JSONDecoder 和 JSONEncoder

Serialize Support

AnyObject (Most)

Deserialize Support

Type Description
Class 支持, 自动推断类型, 部分需要实现Serializeable或者ValueProvider
Enum 支持, 需要实现Serializeable或者ValueProvider
Struct 支持, 需要实现Serializeable或者ValueProvider
Tuple 不支持, 无法序列化/反序列化(临时类型), 无法映射(NSArray, NSDictionary)
Optional 支持, 自动推断元素
Collection 支持, 自动推断元素
Dictionary 支持, 自动推断KV类型
Set 支持, 自动推断元素(映射为数组)

特殊支持

  • NSDate
  • NSURL
  • NSData(Base64)
  • UIImage(Base64)

Usage

  • Use Source
  • Use Framework
  • Use CocoaPods

CocoaPods Podfile:

platform :ios, '8.0'
pod "swift-serialize"
use_frameworks!
let e1 = Example()

e1.val_int = 123
e1.val_bool = true
e1.val_double = 456.0
e1.val_string = "hello swift"
e1.val_array = [7, 8, 9]
e1.val_dictionary = [10 : 11, 12 : 13, 14 : 15]

// serialize
let json = serialize(e1)
let jsonData = try! Serialize.serializeToJSONData(e1)
let jsonString = try! Serialize.serializeToJSONString(e1)

print(jsonData!.length)
print(jsonString!)

// deserialize
let e2: Example? = Serialize.deserialize(json!)
let e3: Example? = Serialize.deserialize(json as Any, Example.self) as? Example

print(e1 == e2)
print(e2 == e3)

如何让struct/class支持Serialize

方法1: 使用ValueProvider

ValueProvider需要实现setValue:forSerialize:valueForSerialize:方法.

InitProvider只在反序列化的时候使用, 如果你不需要反序列化可以跳过.

序列化: 将直接获取成员因此并没有调用valueForSerialize:, 该函数作为保留函数.

反序列化: 将使用setValue:forSerialize:, 需要在方法里对每一个成员进行更新, 可以使用assign简化类型转换的代码

class Example : InitProvider, ValueProvider {
    var a: Optional<Int> = nil
    var b: Optional<String> = nil
    var c: Optional<Array<Int>> = nil

    var u1: Optional<NSURL> = nil
    var u2: Optional<NSURL> = nil

    required init() {}

    func valueForSerialize(key: String) -> Any? {
        return nil
    }

    func setValue(value: Any?, forSerialize key: String) {
        switch key {
            case "a": assign(&a, value)
            case "b": assign(&b, value)
            case "c": assign(&c, value)
            default: break
        }
    }
}

方法2: 使用Serializeable

Serializeable需要实现serializedeserialize:

class Example : Serializeable {
    var a: Optional<Int> = nil
    var b: Optional<String> = nil
    var c: Optional<Array<Int>> = nil

    var u1: Optional<NSURL> = nil
    var u2: Optional<NSURL> = nil

    required init() {}

    func serialize() -> AnyObject? {
        let dic = NSMutableDictionary()
        if let o = a.serialize() {
            dic["a"] = o
        }
        if let o = b.serialize() {
            dic["b"] = o
        }
        if let o = c.serialize() {
            dic["c"] = o
        }
        return dic.count != 0 ? dic : nil
    }
    static func deserialize(o: AnyObject) -> Self? {
        // 只处理NSDictionary的
        guard let dic = o as? NSDictionary where dic.count != 0 else {
            return nil
        }
        var tmp = self.init()

        if let v = Optional<Int>.deserialize(dic["a"] ?? NSNull()) {
            tmp.a = v
        }
        if let v = Optional<String>.deserialize(dic["b"] ?? NSNull()) {
            tmp.b = v
        }
        if let v = Optional<Array<Int>>.deserialize(dic["c"] ?? NSNull()) {
            tmp.c = v
        }
        return tmp
    }
}

方法3: 继承于NSObject

NSObject只会使用Serializeable, 他己经实现了serializedeserialize:.

大部分情况下都可以直接用系统的KVC(NSKeyValueCoding), 但也有一些情况是没有办法使用系统的KVC的.

你可以使用@objc来检查是否原生支持, 对于那些没有支持的, 你需要实现ValueProvider

class Example : NSObject, ValueProvider {

    // base type
    @objc var val_int: Int = 0
    @objc var val_bool: Bool = false
    @objc var val_double: Double = 0
    @objc var val_string: String?
    @objc var val_array: [Int] = []
    @objc var val_dictionary: [Int:Int] = [:]

    // 原生KVC不支持的类型
    var val_int_t: Int?
    var val_bool_t: Bool?
    var val_doulbe_t: Double?
    var val_array_t: [Int?]?
    var val_dictionary_t: [Int:Int?]

    // custom type
    @objc var val_custom: Custom?
    @objc var val_custom_array: [Custom]?
    @objc var val_custom_dictionary: [String:Custom]?

    class Custom : NSObject {
        var val: Example?
    }
    func valueForSerialize(key: String) -> Any? {
        return nil
    }
    func setValue(value: Any?, forSerialize key: String) {
        switch key {
            case "val_int_t": assign(&val_int_t, value)
            case "val_bool_t": assign(&val_doulbe_t, value)
            case "val_array_t": assign(&val_array_t, value)
            case "val_dictionary_t": assign(&val_dictionary_t, value)
            default: break
        }
    }
}

关于系统的KVC不支持的类型

Type Description
enum 除了@objc enum E : Int其他全部不支持
tuple 全部不支持
struct 全部不支持
class 自定义的类都不支持, 除了继承于NSObject
optional 大部分支持, 需要使用@objc来检查
You can’t perform that action at this time.