MVVM+ReactiveCocoa+Swift4.0 iOS项目学习实践(2)
使用泛型+HandyJSON便捷解析数据模型
一、swift json数据解析
1、将网络数据转化为json,推荐使用SwiftyJSON
官网使用示例如下:
示例1:
let json = JSON(data: dataFromNetworking)
if let userName = json[0]["user"]["name"].string {
//Now you got your value
}
示例2:
let json = JSON(data: dataFromNetworking)
if let userName = json[999999]["wrong_key"]["wrong_name"].string {
//Calm down, take it easy, the ".string" property still produces the correct Optional String type with safety
} else {
//Print the error
print(json[999999]["wrong_key"]["wrong_name"])
}
2、json到数据模型的解析,推荐使用HandyJSON和ObjectMapper
2.1、HandyJSON官方使用示例:
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) {
// …
}
2.2、ObjectMapper官方使用示例:
class User: Mappable {
var username: String?
var age: Int?
var weight: Double!
var array: [Any]?
var dictionary: [String : Any] = [:]
var bestFriend: User? // Nested User object
var friends: [User]? // Array of Users
var birthday: Date?
required init?(map: Map) {
}
// Mappable
func mapping(map: Map) {
username <- map["username"]
age <- map["age"]
weight <- map["weight"]
array <- map["arr"]
dictionary <- map["dict"]
bestFriend <- map["best_friend"]
friends <- map["friends"]
birthday <- (map["birthday"], DateTransform())
}
}
struct Temperature: Mappable {
var celsius: Double?
var fahrenheit: Double?
init?(map: Map) {
}
mutating func mapping(map: Map) {
celsius <- map["celsius"]
fahrenheit <- map["fahrenheit"]
}
}
两个库本身都是十分便捷的库,本身无优劣之分,但针对我们的工程推荐使用HandyJSON,理由如下:
1、两个解析库都需要继承对应的协议,但HandyJSON不需要以固定的类型初始化对象,对代码的侵入性更少,解析过程简便代码量也有减少。
2、在ReactiveCocoa中所有的数据模型都要声明为@objc类型,所以要集成与NSObject,而ObjectMapper要继承于Mappable
二、使用泛型便捷解析网络数据
1、Swift中加入了泛型,泛型在编程中是一种灵活的语法,在函数、枚举、结构体、类中都得到了充分的应用。
2、泛型在实际的应用中有很多的用途,这里仅体现在网络数据解析解析中的作用,不做展开说明。
对于一个APP来说,一般会对应一套应用服务,一般一套的应用服务中返回的json数据,json的外部结构是相同的,内部对应不同的业务会有不同的json数据结构。
举例说明下:
{
returnCode = "";
costTime = 0;
message = "操作成功";
result = {
//具体的业务数据对象
};
}
以上为一套应用服务返回的数据,可以很明显的看出returnCode、costTime、message为有明确的数据类型,而result是个对象且每一个数据服务的对象不都相同。如果每一个数据接口都写一个model来解析数据,那么最外层的returnCode、costTime、message的解析就需要写多个。如果采用泛型来替代result的数据类型,就可以用一个基础的数据解析模型来实现数据的解析。创建一个基础的数据解析类型如下:
import UIKit
class MRBaseResponseModel<T>: NSObject {
var returnCode: String?
var costTime: Int?
var message: String?
var result:T?
}
如果需要解析具体的业务数据解析,创建对应的对象,然后替换泛型对象即可,示例如下:
class MRBaseResponseResult: NSObject {
//具体的属性
}
class test{
let model = MRBaseViewModel<MRBaseResponseResult>()
}
三、泛型+HandyJSON解析数据
在第二部分的代码中继承HandyJSON协议,实现泛型+HandyJSON的数据解析,示例如下:
import UIKit
import HandyJSON
class MRBaseResponseModel<T>: NSObject,HandyJSON {
var returnCode: String?
var costTime: Int?
var message: String?
var result:T?
required override init() {}
}
class MRBaseResponseResult: NSObject,HandyJSON {
var test: String?
//具体的属性
required override init() {}
}
class test: NSObject{
let model = MRBaseResponseModel<MRBaseResponseResult>.deserialize(from: "")
}
网友评论