【KakaJSON手册】02_JSON转Model_02_数据类型

由于JSON格式的能表达的数据类型是比较有限的,所以服务器返回的JSON数据有时无法自动转换成客户端想要的数据类型。

比如服务器返回的时间可能是个毫秒数1565480696,但客户端想要的是Date类型

再比如客户端想要的是浮点数Double类型,但服务器返回的可能是字符串类型"6.45"

再比如客户端想要的是Bool类型,但服务器返回的可能是"true"、"1"、0

再比如客户端想要的是高精度浮点数NSDecimalNumber类型,服务器为了维持精度可能返回字符串"0.1234567890123456789"

上述不同类型之间的匹配转换问题,KakaJSON已经内置了常用的解析功能,全部自动转换,不用做任何额外的配置。本文会介绍一些常见的数据类型匹配、转换功能。

Int struct Student: Convertible { var age1: Int8 = 6 var age2: Int16 = 0 var age3: Int32 = 0 var age4: Int64 = 0 var age5: UInt8 = 0 var age6: UInt16 = 0 var age7: UInt32 = 0 var age8: UInt64 = 0 var age9: UInt = 0 var age10: Int = 0 } let json: [String: Any] = [ "age1": "suan8fa8", "age2": "6suan8fa8", "age3": "6", "age4": 6.66, "age5": NSNumber(value: 6.66), "age6": Int32(6), "age7": true, "age8": "FALSE", "age9": Decimal(6.66), "age10": NSDecimalNumber(value: 6.66) ] let student = json.kk.model(Student.self) // 解析失败,所以使用默认值6 XCTAssert(student?.age1 == 6) // 解析到前面的数字6 XCTAssert(student?.age2 == 6) XCTAssert(student?.age3 == 6) XCTAssert(student?.age4 == 6) XCTAssert(student?.age5 == 6) XCTAssert(student?.age6 == 6) // true为1,false为0 XCTAssert(student?.age7 == 1) // 字符串true\TRUE\YES\yes都为1,字符串false\FALSE\NO\no都为0 XCTAssert(student?.age8 == 0) XCTAssert(student?.age9 == 6) XCTAssert(student?.age10 == 6) Float struct Student: Convertible { var height1: Float = 0.0 var height2: Float = 0.0 var height3: Float = 0.0 var height4: Float = 0.0 var height5: Float = 0.0 var height6: Float = 0.0 var height7: Float = 0.0 } let longFloatString = "0.12345678" let longFloat: Float = 0.12345678 let json: [String: Any] = [ "height1": "6.66suan8fa8", "height2": longFloatString, "height3": NSDecimalNumber(string: longFloatString), "height4": Decimal(string: longFloatString) as Any, "height5": 666, "height6": true, "height7": "NO" ] let student = json.kk.model(Student.self) XCTAssert(student?.height1 == 6.66) XCTAssert(student?.height2 == longFloat) XCTAssert(student?.height3 == longFloat) XCTAssert(student?.height4 == longFloat) XCTAssert(student?.height5 == 666.0) // true为1.0,false为0.0 XCTAssert(student?.height6 == 1.0) // 字符串true\TRUE\YES\yes都为1.0,字符串false\FALSE\NO\no都为0.0 XCTAssert(student?.height7 == 0.0) Double struct Student: Convertible { var height1: Double = 0.0 var height2: Double = 0.0 var height3: Double = 0.0 var height4: Double = 0.0 var height5: Double = 0.0 var height6: Double = 0.0 var height7: Double = 0.0 } let longDoubleString = "0.1234567890123456" let longDouble: Double = 0.1234567890123456 let json: [String: Any] = [ "height1": "6.66suan8fa8", "height2": longDoubleString, "height3": NSDecimalNumber(string: longDoubleString), "height4": Decimal(string: longDoubleString) as Any, "height5": 666, "height6": true, "height7": "NO" ] let student = json.kk.model(Student.self) XCTAssert(student?.height1 == 6.66) XCTAssert(student?.height2 == longDouble) XCTAssert(student?.height3 == longDouble) XCTAssert(student?.height4 == longDouble) XCTAssert(student?.height5 == 666.0) // true为1.0,false为0.0 XCTAssert(student?.height6 == 1.0) // 字符串true\TRUE\YES\yes都为1.0,字符串false\FALSE\NO\no都为0.0 XCTAssert(student?.height7 == 0.0) Bool struct Student: Convertible { var rich1: Bool = false var rich2: Bool = false var rich3: Bool = false var rich4: Bool = false var rich5: Bool = false var rich6: Bool = false } let json: [String: Any] = [ "rich1": 100, "rich2": 0.0, "rich3": "1", "rich4": NSNumber(value: 0.666), "rich5": "true", "rich6": "NO" ] let student = json.kk.model(Student.self) // 数值0为false,数值非0都是true XCTAssert(student?.rich1 == true) XCTAssert(student?.rich2 == false) XCTAssert(student?.rich3 == true) // 0.666是非0,所以为true XCTAssert(student?.rich4 == true) // 字符串true\TRUE\YES\yes都为true XCTAssert(student?.rich5 == true) // 字符串false\FALSE\NO\no都为false XCTAssert(student?.rich6 == false) String // 不管是String、NSString,还是NSMutableString,都是等效支持的 struct Student: Convertible { var name1: String = "" var name2: String = "" var name3: NSString = "" var name4: NSString = "" var name5: NSMutableString = "" var name6: NSMutableString = "" var name7: String = "" var name8: String = "" } let longDecimalString = "0.123456789012345678901234567890123456789" var longDecimalNumber = NSDecimalNumber(string: longDecimalString) let json: [String: Any] = [ "name1": 666, "name2": NSMutableString(string: "777"), "name3": [1,[2,3],"4"], "name4": longDecimalNumber, "name5": 6.66, "name6": false, "name7": NSURL(fileURLWithPath: "/users/mj/desktop"), "name8": URL(string: "http://www.520suanfa.com") as Any ] let student = json.kk.model(Student.self) XCTAssert(student?.name1 == "666") XCTAssert(student?.name2 == "777") // 这里相当于默认调用了数组的description方法 XCTAssert(student?.name3 == "[1, [2, 3], \"4\"]") XCTAssert(student?.name4 == longDecimalString as NSString) XCTAssert(student?.name5 == "6.66") XCTAssert(student?.name6 == "false") XCTAssert(student?.name7 == "file:///users/mj/desktop") XCTAssert(student?.name8 == "http://www.520suanfa.com") Decimal struct Student: Convertible { var money1: Decimal = 0 var money2: Decimal = 0 var money3: Decimal = 0 var money4: Decimal = 0 var money5: Decimal = 0 var money6: Decimal = 0 } let longDoubleString = "0.1234567890123456" let longDouble: Double = 0.1234567890123456 let longDecimalString = "0.123456789012345678901234567890123456789" var longDecimalNumber = NSDecimalNumber(string: longDecimalString) let json: [String: Any] = [ "money1": longDouble, "money2": true, "money3": longDecimalNumber, "money4": longDecimalString, "money5": 666, "money6": "NO" ] let student = json.kk.model(Student.self) XCTAssert(student?.money1 == Decimal(string: longDoubleString)) XCTAssert(student?.money2 == 1) XCTAssert(student?.money3 == Decimal(string: longDecimalString)) XCTAssert(student?.money4 == Decimal(string: longDecimalString)) XCTAssert(student?.money5 == 666) XCTAssert(student?.money6 == 0) NSDecimalNumber struct Student: Convertible { var money1: NSDecimalNumber = 0 var money2: NSDecimalNumber = 0 var money3: NSDecimalNumber = 0 var money4: NSDecimalNumber = 0 var money5: NSDecimalNumber = 0 var money6: NSDecimalNumber = 0 } let longDoubleString = "0.1234567890123456" let longDouble: Double = 0.1234567890123456 let longDecimalString = "0.123456789012345678901234567890123456789" var longDecimal = Decimal(string: longDecimalString)! var longDecimalNumber = NSDecimalNumber(string: longDecimalString) let json: [String: Any] = [ "money1": longDouble, "money2": true, "money3": longDecimal, "money4": longDecimalString, "money5": 666.0, "money6": "NO" ] let student = json.kk.model(Student.self) XCTAssert(student?.money1 == NSDecimalNumber(string: longDoubleString)) XCTAssert(student?.money2 == true) XCTAssert(student?.money2 == 1) XCTAssert(student?.money3 == longDecimalNumber) XCTAssert(student?.money4 == longDecimalNumber) XCTAssert(student?.money5 == 666) XCTAssert(student?.money6 == false) XCTAssert(student?.money6 == 0) NSNumber struct Student: Convertible { var money1: NSNumber = 0 var money2: NSNumber = 0 var money3: NSNumber = 0 var money4: NSNumber = 0 var money5: NSNumber = 0 var money6: NSNumber = 0 } let longDoubleString = "0.1234567890123456" let longDouble: Double = 0.1234567890123456 let json: [String: Any] = [ "money1": longDouble, "money2": true, "money3": Decimal(string: longDoubleString) as Any, "money4": longDoubleString, "money5": 666.0, "money6": "NO" ] let student = json.kk.model(Student.self) XCTAssert(student?.money1 == NSNumber(value: longDouble)) XCTAssert(student?.money2 == true) XCTAssert(student?.money2 == 1) XCTAssert(student?.money2 == 1.0) XCTAssert(student?.money3 == NSNumber(value: longDouble)) XCTAssert(student?.money4 == NSNumber(value: longDouble)) XCTAssert(student?.money5 == 666) XCTAssert(student?.money5 == 666.0) XCTAssert(student?.money6 == false) XCTAssert(student?.money6 == 0) XCTAssert(student?.money6 == 0.0) Optional // ?再多都不是问题 struct Student: Convertible { var rich1: Bool = false var rich2: Bool? = false var rich3: Bool?? = false var rich4: Bool??? = false var rich5: Bool???? = false var rich6: Bool????? = false } let rich1: Int????? = 100 let rich2: Double???? = 0.0 let rich3: String??? = "0" let rich4: NSNumber?? = NSNumber(value: 0.666) let rich5: String? = "true" let rich6: String = "NO" let json: [String: Any] = [ "rich1": rich1 as Any, "rich2": rich2 as Any, "rich3": rich3 as Any, "rich4": rich4 as Any, "rich5": rich5 as Any, "rich6": rich6 ] let student = json.kk.model(Student.self) XCTAssert(student?.rich1 == true) XCTAssert(student?.rich2 == false) XCTAssert(student?.rich3 == false) XCTAssert(student?.rich4 == true) XCTAssert(student?.rich5 == true) XCTAssert(student?.rich6 == false) URL // 支持URL和NSURL struct Student: Convertible { var url1: NSURL? var url2: NSURL? var url3: URL? var url4: URL? } let url = "http://520suanfa.com/红黑树" let encodedUrl = "http://520suanfa.com/%E7%BA%A2%E9%BB%91%E6%A0%91" let json: [String: Any] = [ "url1": url, "url2": URL(string: encodedUrl) as Any, "url3": url, "url4": NSURL(string: encodedUrl) as Any ] let student = json.kk.model(Student.self) XCTAssert(student?.url1?.absoluteString == encodedUrl) XCTAssert(student?.url2?.absoluteString == encodedUrl) XCTAssert(student?.url3?.absoluteString == encodedUrl) XCTAssert(student?.url4?.absoluteString == encodedUrl) Data // 支持NSData和Data struct Student: Convertible { var data1: NSData? var data2: NSData? var data3: Data? var data4: Data? } let utf8 = String.Encoding.utf8 let str = "RedBlackTree" let data = str.data(using: utf8)! let json: [String: Any] = [ "data1": str, "data2": data, "data3": str, "data4": NSData(data: data) ] let student = json.kk.model(Student.self) XCTAssert(String(data: (student?.data1)! as Data, encoding: utf8) == str) XCTAssert(String(data: (student?.data2)! as Data, encoding: utf8) == str) XCTAssert(String(data: (student?.data3)!, encoding: utf8) == str) XCTAssert(String(data: (student?.data4)!, encoding: utf8) == str) Enum // 遵守一下ConvertibleEnum协议即可支持带有RawValue的Enum类型 enum Grade: String, ConvertibleEnum { case perfect = "A" case great = "B" case good = "C" case bad = "D" } struct Student: Convertible { var grade1: Grade = .perfect var grade2: Grade = .perfect } let json: [String: Any] = [ "grade1": "C", "grade2": "D" ] let student = json.kk.model(Student.self) XCTAssert(student?.grade1 == .good) XCTAssert(student?.grade2 == .bad) // 换个浮点数试试 enum Grade2: Double, ConvertibleEnum { case perfect = 8.88 case great = 7.77 case good = 6.66 case bad = 5.55 } struct Student2: Convertible { var grade1: Grade2 = .perfect var grade2: Grade2 = .perfect var grade3: Grade2 = .perfect var grade4: Grade2 = .perfect } let json2: [String: Any] = [ "grade1": "5.55kaka", "grade2": 6.66, "grade3": NSNumber(value: 7.77), "grade4": NSDecimalNumber(string: "8.88") ] let student2 = json2.kk.model(Student2.self) XCTAssert(student2?.grade1 == .bad) XCTAssert(student2?.grade2 == .good) XCTAssert(student2?.grade3 == .great) XCTAssert(student2?.grade4 == .perfect)

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wsxgxp.html