之前一直是使用oc开发项目,最近新项目打算用Swift开发,不得不说Swift确实优秀,第一感受是不用处理.h和.m,只需要在Swift里面开发,大大的折叠了文件数量减半;由于是新手,但是在开发过程中还是不可避免的遇到了一些问题,比如我在oc中和后台对接中,请求数据和解析我一般都是用AFNetworking和YYModel,但是当我在Swift中想要使用YYModel来解析JSON数据并保存模型的时候傻眼了,不能使用,Swift的模型概念不一样,然后我就查资料,网上推荐了很多第三方解析框架,但我挨个试了下都不是很喜欢(包括Swift自带的),总感觉太繁琐,而且我们后端接口有很多不规范的地方,比如isVip、id之类的,有时候他返回的是double类型,有时候又是bool类型,在我定义模型变量类型的时候很难受,经常出现测试没问题,上线出问题,某个value解析不出来导致App异常,后来我慢慢研究了下做出了我的解决方案,我不管你给的是什么类型,我定义了什么类型,就自动强转为什么类型,经测试很好用,我不知道大佬有没有别的高招,但是对于一个初学者和自行摸索者,我把我的想法分享出来,欢迎点评与提建议。(废话完成)
使用框架如下:
Pods:
pod 'ObjectMapper'
pod 'Alamofire'
然后创建一个AllModelManagers.Swift(举例),在里面粘贴如下代码:
**import** ObjectMapper
// **MARK: 定义一个通用的 ForceConvertType 泛型转换器******
**struct** ForceConvertType<T>: TransformType {
**func** transformFromJSON(_ value: **Any**?) -> T? {
**guard** **let** value = value **else** { **return** **nil** }
// 直接尝试强制转换为目标类型
**if** **let** typedValue = value **as**? T {
**return** typedValue
}
// 类型不匹配时,尝试其他类型转换
**if** T.**self** == Int.**self**, **let** stringValue = value **as**? String, **let** intValue = Int(stringValue) {
**return** intValue **as**? T
} **else** **if** T.**self** == String.**self**, **let** intValue = value **as**? Int {
**return** String(intValue) **as**? T
} **else** **if** T.**self** == Double.**self**, **let** stringValue = value **as**? String, **let** doubleValue = Double(stringValue) {
**return** doubleValue **as**? T
} **else** **if** T.**self** == Float.**self**, **let** stringValue = value **as**? String, **let** floatValue = Float(stringValue) {
**return** floatValue **as**? T
} **else** **if** T.**self** == Bool.**self**, **let** intValue = value **as**? Int {
**return** (intValue != 0) **as**? T
} **else** **if** T.**self** == Bool.**self**, **let** stringValue = value **as**? String {
**let** lowercasedValue = stringValue.lowercased()
**return** (lowercasedValue == "true" || lowercasedValue == "1") **as**? T
} **else** **if** T.**self** == [String].**self**, **let** stringArray = value **as**? [String] {
**return** stringArray **as**? T
} **else** **if** T.**self** == [String: **Any**].**self**, **let** dictionary = value **as**? [String: **Any**] {
**return** dictionary **as**? T
} **else** **if** T.**self** == Date.**self**, **let** stringValue = value **as**? String {
// 支持日期格式解析,尝试多种格式
**let** dateFormats = ["yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy/MM/dd", "MM/dd/yyyy"]
**let** dateFormatter = DateFormatter()
**for** format **in** dateFormats {
dateFormatter.dateFormat = format
**if** **let** date = dateFormatter.date(from: stringValue) {
**return** date **as**? T
}
}
}
// 处理失败,返回 nil
**return** **nil******
}
**func** transformToJSON(_ value: T?) -> **Any**? {
**if** **let** value = value {
// 转换回 JSON 格式时,处理特定类型
**if** T.**self** == Date.**self**, **let** date = value **as**? Date {
**let** dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss" // 统一日期格式
**return** dateFormatter.string(from: date)
}
}
**return** value
}
}
然后只需要在创建模型的时候如下在mapping方法里面追加ForceConvertType(),即可后患无忧了,再出问题前端就不背锅:
**struct** TestModel: Mappable {
var ageValue: Int = 0
var isVip: Bool = false
var avatar: String = ""
var imageList: [string] = []
**init**?(map: Map) { }
**mutating** **func** mapping(map: Map) {
ageValue <- (map["age"], ForceConvertType())
isVip <- (map["isVip"], ForceConvertType())
avatar <- (map["avatar"], ForceConvertType())
imageList <- (map["imageList"], ForceConvertType())
}
}