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

 

全部评论

相关推荐

头像
11-26 15:46
已编辑
中南大学 后端
字节国际 电商后端 24k-35k
点赞 评论 收藏
分享
Yushuu:你的确很厉害,但是有一个小问题:谁问你了?我的意思是,谁在意?我告诉你,根本没人问你,在我们之中0人问了你,我把所有问你的人都请来 party 了,到场人数是0个人,誰问你了?WHO ASKED?谁问汝矣?誰があなたに聞きましたか?누가 물어봤어?我爬上了珠穆朗玛峰也没找到谁问你了,我刚刚潜入了世界上最大的射电望远镜也没开到那个问你的人的盒,在找到谁问你之前我连癌症的解药都发明了出来,我开了最大距离渲染也没找到谁问你了我活在这个被辐射蹂躏了多年的破碎世界的坟墓里目睹全球核战争把人类文明毁灭也没见到谁问你了😆
点赞 评论 收藏
分享
vegetable_more_exercise:1-1.5万,没错啊,最少是1人民币,在区间内
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务