在swift開發中,發起網絡請求大部分開發者應該都是使用Alamofire發起的網絡請求,至於請求完成后JSON解析這一塊有很多解決方案,我們今天這里使用HandyJSON來解析請求返回的數據並轉化成模型
關於HandyJSON,是由阿里一位大神推出的,能夠做到JSON轉Model一步到位,而且使用起來,非常簡潔方便 傳送門:https://github.com/alibaba/HandyJSON
具體的用法我們通過一個例子來解析:
import HandyJSON
enum AjaxResultState:Int,HandyJSONEnum {
case success = 0 //成功
case sessionError = 97 //登錄失敗
case errrorMessage = 99
case error = 100 //錯誤
}
class AjaxResult: HandyJSON {
var code : AjaxResultState = .success
var message : String?
var datas : Any?
var userId : String?
// @objc var my_date : Int = 0{
// willSet {
// print("newValue: ", newValue)
// }
// didSet {
// print("oldValue: ", oldValue)
// }
// }
//重寫set方法
@objc var handleTime : Int = 0{
willSet {
print("newValue: ", newValue)
}
}
//轉換數據完成
func didFinishMapping() {
self.userId = "234324324"
}
func mapping(mapper: HelpingMapper) {
//字段替換
//mapper.specify(property: &my_date, name: "handleTime")
}
required init() {
}
}
需要注意的點:
- 我們創建的類不需要繼承HandyJSON
- 可以實現mapping方法做字段的替換,有點像MJExtension里面的mj_replacedKeyFromPropertyName這個方法
func mapping(mapper: HelpingMapper) {
//字段替換
mapper.specify(property: &my_date, name: "handleTime")
}
- 實現方法didFinishMapping可以在字典模型完成之后做對解析的字段做額外處理,類似MJExtension中mj_keyValuesDidFinishConvertingToObject
func didFinishMapping() {
self.userId = "234324324"
}
- 可以重寫模型中某個屬性的set方法和get方法,但前提需要繼承自NSObject
class AjaxResult: NSObject,HandyJSON {
@objc var my_date : Int = 0{
willSet {
print("newValue: ", newValue)
}
didSet {
print("oldValue: ", oldValue)
}
}
required override init() {
}
}
class ContentModel: HandyJSON {
required init() {
}
var title : String?
}
- 字典轉模型的使用
var dict = [String: Any]()
dict["doubleOptional"] = 1.1
dict["stringImplicitlyUnwrapped"] = "hello"
dict["int"] = 1
if let object = BasicTypes.deserialize(from: dict) {
// ...
}
- 模型轉字典
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
- 有枚舉或者有結構體
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)
}
關於Alamofire我不多說了,熟悉AFNetworking的朋友都知道Alamofire是AFNetworking的swift版本詳細的用法請參考 https://github.com/Alamofire/Alamofire
具體使用我這里封裝了一個工具類
import UIKit
import Alamofire
import HandyJSON
class HttpRequestUtil: NSObject {
typealias HttpSuccess = ((_ result:AjaxResult) -> Void)
static func request( method:HTTPMethod,url:URLConvertible,parameters:Parameters? = nil,success:@escaping HttpSuccess){
Alamofire.request(url, method:method, parameters:parameters).responseJSON(completionHandler: { (response) in
if response.result.isSuccess {
if let jsonString = response.result.value {
//將返回的JSON數據轉換成AjaxResult模型的數據並將AjaxResult對象傳回
if let obj = AjaxResult.deserialize(from: jsonString as? Dictionary){
success(obj)
}else{
let ajax = AjaxResult()
ajax.code = .error
success(ajax)
}
}
}else{
let ajax = AjaxResult()
ajax.code = .error
success(ajax)
}
})
}
}
工具類的使用
HttpRequestUtil.request(method: .get, url: "https://cs.hxquan.cn/api/ad/list", parameters: ["spaceId":"4"]) { (result) in
if result.code == .success {
//將字典數組轉換成ContentModel的模型數組
if let datas = Array<ContentModel>.deserialize(from: result.datas as? NSArray){
print(datas)
//[Optional(t1.ContentModel),
//Optional(t1.ContentModel),
//Optional(t1.ContentModel),
//Optional(t1.ContentModel),
//Optional(t1.ContentModel),
//Optional(t1.ContentModel)]
}
}
}