HandyJSON第三方库的日常使用与错误记录

一、错误提示

1、更新Xcode10.2,Swift5.0出现错误提示

Undefined symbols for architecture x86_64:
"_swift_getFieldAt", referenced from:
HandyJSON.Metadata.Class._propertyDescriptionsAndStartPoint() -> ([HandyJSON.Property.Description], Swift.Int32?)? in Metadata.o
HandyJSON.Metadata.Struct.propertyDescriptions() -> [HandyJSON.Property.Description]? in Metadata.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
 
更改 podfile
pod 'HandyJSON', '5.0.0-beta'
如果不行的话 更新本地cocoapods的spec资源配置信息。
pod repo update
笔者是使用的第二种方法进行解决的。
 

二、HandyJSON的使用

1、基本操作:序列化与反序列化

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) {
            print(object.int)
            print(object.doubleOptional!)
            print(object.stringImplicitlyUnwrapped!)
        }
        
        print("-----------------------------")
        
        //序列化
        let objectOne = BasicTypes()
        objectOne.int = 1
        objectOne.doubleOptional = 2.2
        objectOne.stringImplicitlyUnwrapped = "world"
        
        print(objectOne.toJSON()!)
        print("-----------------------------")
        print(objectOne.toJSONString()!)
        print("-----------------------------")
        print(objectOne.toJSONString(prettyPrint: true)!)
        print("-----------------------------")

2、基本数据类型

class BasicTypesTwo: HandyJSON {
    var bool: Bool = true
    var intOptional: Int?
    var doubleImplicitlyUnwrapped: Double!
    var anyObjectOptional: Any?
    
    var arrayInt: Array<Int> = []
    var arrayStringOptional: Array<String>?
    var setInt: Set<Int>?
    var dictAnyObject: Dictionary<String, Any> = [:]
    
    var nsNumber = 2
    var nsString: NSString?
    
    required init() {}
}


let object = BasicTypesTwo()
        object.intOptional = 1
        object.doubleImplicitlyUnwrapped = 1.1
        object.anyObjectOptional = "StringValue"
        object.arrayInt = [1, 2]
        object.arrayStringOptional = ["a", "b"]
        object.setInt = [1, 2]
        object.dictAnyObject = ["key1": 1, "key2": "stringValue"]
        object.nsNumber = 2
        object.nsString = "nsStringValue"
        
        let jsonString = object.toJSONString()!
        
        if let object = BasicTypesTwo.deserialize(from: jsonString) {
            print(object.arrayStringOptional!)
            print(object.dictAnyObject)
            //....
        }

3、指定解析路径

  HandyJSON支持指定从哪个具体路径开始解析,反序列化到Model。

class Cat: HandyJSON {
    var id: Int64!
    var name: String!
    
    required init() {}
}

let json = "{"code":200,"msg":"success","data":{"cat":{"id":12345,"name":"Kitty"}}}"
        if let cat = Cat.deserialize(from: json, designatedPath: "data.cat") {
            print(cat.name!)
            print(cat.id!)
        }

4、组合对象

  注意,如果Model的属性不是基本类型或集合类型,那么它必须是一个服从HandyJSON协议的类型。

  如果是泛型集合类型,那么要求泛型实参是基本类型或者服从HandyJSON协议的类型。

class Component: HandyJSON {
    var aInt: Int?
    var aString: String?
    
    required init() {}
}
class Composition: HandyJSON {
    var aInt: Int?
    var comp1: Component?
    var comp2: Component?
    
    required init() {}
}


let jsonString = "{"num":12345,"comp1":{"aInt":1,"aString":"aaaaa"},"comp2":{"aInt":2,"aString":"bbbbb"}}"
        
        if let composition = Composition.deserialize(from: jsonString) {
            print(composition.comp1?.aString! as Any)
            print(composition.comp2?.aInt! as Any)
        }

5、继承

  如果子类要支持反序列化,那么要求父类也服从HandyJSON协议。

let jsonString = "{"id":12345,"color":"black","name":"cat"}"
        
        if let cat = Cat.deserialize(from: jsonString) {
            print(cat)
        }

6、JSON数组

  如果JSON的第一层表达的是数组,可以转化它到一个Model数组。

let jsonArrayString: String? = "[{"name":"Bob","id":"1"}, {"name":"Lily","id":"2"}, {"name":"Lucy","id":"3"}]"
        if let cats = [Cat].deserialize(from: jsonArrayString) {
            cats.forEach({ (cat) in
                print(cat?.name! as Any)
                print(cat?.id! as Any)
            })
        }

7、字典 -> 模型

class BasicTypes: HandyJSON {
    var int: Int = 2
    var doubleOptional: Double?
    var stringImplicitlyUnwrapped: String!
    
    required init() {}
}


var dict = [String: Any]()
        dict["doubleOptional"] = 1.1
        dict["stringImplicitlyUnwrapped"] = "hello"
        dict["int"] = 1
        if let object = BasicTypes.deserialize(from: dict) {
            print(object.doubleOptional as Any)
            print(object.stringImplicitlyUnwrapped as Any)
            print(object.int)
        }

8、自定义解析规则

  开发中某些关键字段为避免混淆,可以使用其他关键字替换

class Person: HandyJSON {
    var ID: Int64!
    var username: String!
    var parents: (String, String)?
    
    required init() {}
    
    func mapping(mapper: HelpingMapper) {
        mapper <<<
            self.ID <-- "cat_id"
        mapper <<<
            self.username <-- "name"
    }
}


let jsonString = "{"cat_id":12345,"name":"Kitty","parent":"Tom/Lily","friend":{"id":54321,"name":"Lily"}}"
        
        if let person = Person.deserialize(from: jsonString) {
            print(person.ID as Any)
            print(person.username as Any)
        }

9、日常开发接口测试

class CarList : HandyJSON {
    var ID : String!
    var pic : String?
    var comname : String?
    var address : String?
 
    required init() {
    }
    func mapping(mapper: HelpingMapper) {
        mapper <<<
            self.ID <-- "id"
    }
}

//返回json样式
//成功:
//{
//    "status": 1,
//    "result": [{
//        "id": "1",
//        "pic": "图片地址",
//        "comname": "汽车美容店",
//        "address": "广东省"
//    }]
//}
//失败:
//{
//    "status":0,
//    "msg":"获取失败,请稍后重试..."
//}
let dict = ["pagesize":10,"page":1,"address":""] as [String : Any]
 NANetworkHandler.shareInstance.postRequest("https://******/submit_ajax.ashx?action=APP_GetBusiness", params: dict, success: { (response) in
            let resultJson = response
            if resultJson["status"] as! Int  == 1 {
                if let carArr = [CarList].deserialize(from: (resultJson["result"] as! Array) ) {
                    carArr.forEach({ (car) in
                        print("(String(describing: car?.ID))")
                        print("(String(describing: car?.pic))")
                        print("(String(describing: car?.comname))")
                        print("(String(describing: car?.address))")
                    })
                    
                }
            }else if response["status"] as! Int == 0 {
                //...
            }
            
            
        }) { ( err) in
              //...
        }

附:

Alamofire简单封装

import UIKit
import Alamofire

public typealias Success = (_ dict : [String:Any])->()
public typealias Failure = (_ error : Error)->()
class NANetworkHandler : NSObject {
    
    static var shareInstance : NANetworkHandler {
        struct Share {
            static let instance = NANetworkHandler()
        }
        return Share.instance
    }
    
    //GET请求
    func getRequest(
        _ urlString: String,
        params: Parameters? = nil,
        success: @escaping Success,
        failure: @escaping Failure)
    {
        request(urlString, params: params, method: .get, success, failure)
    }

    //POST请求
    func postRequest(
        _ urlString: String,
        params: Parameters? = nil,
        success: @escaping Success,
        failure: @escaping Failure)
    {
        request(urlString, params: params, method: .post, success, failure)
    }
    
    //图片上传
    func upLoadImageRequest(urlString : String, params:[String:String], imgArr:[UIImage], name: [String],success : @escaping Success, failure : @escaping Failure){
        
        let headers = ["content-type":"multipart/form-data"]
        
        Alamofire.upload(
            multipartFormData: { multipartFormData in
                
                if imgArr.count == 0 {
                    return
                }
                //此处循环上传多占图片
                for (index, value) in imgArr.enumerated() {
                    let imageData = UIImage.jpegData(value)(compressionQuality: 0.5)!
                    let formatter = DateFormatter()
                    formatter.dateFormat = "yyyyMMddHHmmss"
                    let str = formatter.string(from: Date())
                    let fileName = str+"(index)"+".jpg"

                    multipartFormData.append(imageData, withName: "imageUpload", fileName: fileName, mimeType: "image/png")
                }
        },
            to: urlString,
            headers: headers,
            encodingCompletion: { encodingResult in
                switch encodingResult {
                case .success(let upload, _, _):
                    upload.responseJSON { response in
                        if let value = response.result.value as? [String: Any] {
                            success(value as [String : Any])
                        }
                    }
                    break
                case .failure(let err):
                    failure(err)
                    break
                }
        }
        )
    }
    
    private func request(_ urlString: String,
                         params:Parameters? = nil,
                         method:HTTPMethod,
                         _ success:@escaping Success,
                         _ failure:@escaping Failure){
        let manager = Alamofire.SessionManager.default
        manager.session.configuration.timeoutIntervalForRequest = 15
        manager.request(urlString, method: method, parameters: params, encoding: JSONEncoding.default, headers: nil).responseJSON { (response) in
            switch response.result {
            case .success:
                if let value = response.result.value as? [String: Any] {
                    success(value as [String : Any])
                }
                break
            case .failure(let err):
                failure(err)
                break
            }
        }
    }
}
原文地址:https://www.cnblogs.com/xjf125/p/10704369.html