KakaJSON手册02_JSON转Model_02_数据类型

Posted mjios

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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)

以上是关于KakaJSON手册02_JSON转Model_02_数据类型的主要内容,如果未能解决你的问题,请参考以下文章

ios kvc json转model的简单现实

根据post请求调取app接口,map对象转字符串,json对象转字符串

001_manifest.json手册

Python中model转dict

Spring MVC json view如何把Model 解析成json 字符串?

python json格式转xml格式