iOS swift HandyJSON组合Alamofire发起网络请求并转换成模型

在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)]
                }
            }
        }