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

423 阅读3分钟

一、错误提示

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 UIKitimport 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            }        }    }}