Swift掌控Moya的⽹络请求数据解析与缓存
Moya 在Swift开发中起着重要的⽹络交互作⽤,但是还有不如之处,⽐如⽹络不可⽤时,返回的 Response 为 nil,这时还得去解析相应的 Error
Codable 可以帮助我们快速的解析数据,但是⼀旦声明的属性类型与json中的不⼀致,将⽆法正常解析; ⽽且对于模型中⾃定义属性名的处理也⼗分繁琐
解决的⽅案有很多,不过我⽐较习惯使⽤ MoyaMapper ,不仅可以解决上述问题,还提供了多种模型转换、数据互转、多种数据类型任意存储的便捷⽅法。掌控Moya的⽹络请求、数据解析与缓存简直易如反掌。
MoyaMapper是基于Moya和SwiftyJSON封装的⼯具,以Moya的plugin的⽅式来实现间接解析,⽀持RxSwift
GitHub:
特点
⽀持json 转 Model ⾃动映射 与 ⾃定义映射
⽆视 json 中值的类型,Model 中属性声明的是什么类型,它就是什么类型
⽀持 json字符串 转Model
插件⽅式,全⽅位保障Moya.Response,拒绝各种⽹络问题导致 Response 为 nil,将各式各样的原因导致的数据加载失败进⾏统⼀处理,开发者只需要关注 Response
可选 - ⽀持数据随意缓存( JSON 、 Number 、String、 Bool、 Moya.Response )
可选 - ⽀持⽹络请求缓存
数据解析
⼀、插件注⼊
附:
1、定义适⽤于项⽬接⼝的 ModelableParameterType
// statusCodeKey、tipStrKey、 modelKey 可以任意指定级别的路径,如: "error>used"
struct NetParameter:ModelableParameterType{
var successValue ="000"
var statusCodeKey ="retStatus"
var tipStrKey ="retMsg"
var modelKey ="retBody"
}
2、在 MoyaProvider 中使⽤ MoyaMapperPlugin 插件,并指定 ModelableParameterType let lxfNetTool =MoyaProvider<LXFNetworkTool>(plugins:[MoyaMapperPlugin(NetParameter())])  使⽤ MoyaMapperPlugin 插件是整个 MoyaMapper 的核⼼所在!
⼆、Model声明
Model 需遵守 Modelable 协议
MoyaMapper ⽀持模型⾃动映射 和 ⾃定义映射
不需要考虑源json数据的真实类型,这⾥统⼀按 Model 中属性声明的类型进⾏转换
1、⼀般情况下如下写法即可
struct CompanyModel:Modelable{
var name :String=""
var catchPhrase :String=""
init(){}
}
2、如果⾃定义映射,则可以实现⽅法 mutating func mapping(_ json: JSON)
struct CompanyModel:Modelable{
var name :String=""
var catchPhrase :String=""
init(){}
mutating func mapping(_ json:JSON){
self.name = json["nickname"].stringValue
}
}
3、⽀持模型嵌套
struct UserModel:Modelable{
var id :String=""
var name :String=""
var company :CompanyModel=CompanyModel()
init(){}
}
三、Response 解析
1、以下⽰例皆使⽤了 MoyaMapperPlugin ,所以不需要指定 解析路径
2、如果没有使⽤ MoyaMapperPlugin 则需要指定 解析路径,否则⽆法正常解析
ps: 解析路径 可以使⽤ a>b 这种形式来解决多级路径的问题
解析⽅法如下列表所⽰
⽅法描述 (⽀持RxSwift)
toJSON Response 转 JSON ( | )
电脑不出声音怎么办
fetchString获取指定路径的字符串( | )
fetchJSONString获取指定路径的原始json字符串 ( | )
mapResult Response -> MoyaMapperResult (Bool, String) ( | )
会计初级职称mapObject Response -> Model ( | )
mapObjResult Response -> (MoyaMapperResult, Model) ( | )
行到水穷处坐看云起时什么意思
mapArray Response -> [Model]( | )
五一节快乐mapArrayResult Response -> (MoyaMapperResult, [Model]) ( | )
除了 fetchJSONString 的默认解析路径是根路径之外,其它⽅法的默认解析路径为插件对象中的 modelKey 如果接⼝请求后 json 的数据结构与下图类似,则使⽤ MoyaMapper 是最合适不过了
// Normal
let model = response.mapObject(MMModel.self)
print("name -- \(model.name)")
print("github -- \(model.github)")
// 打印json
print(response.fetchJSONString())
// Rx
rxRequest.mapObject(MMModel.self)
.subscribe(onSuccess:{(model)in
print("name -- \(model.name)")
print("github -- \(model.github)")
}).disposed(by: disposeBag)
附:
// Normal
let models = response.mapArray(MMModel.self) let name = models[0].name
print("count -- \(unt)")
print("name -- \(name)")
// 打印 json 模型数组中第⼀个的name
print(response.fetchString(keys:[0,"name"]))
// Rx
rxRequest.mapArray(MMModel.self)
.subscribe(onSuccess:{ models in
let name = models[0].name
print("count -- \(unt)")
大队长竞选稿
print("name -- \(name)")
}).disposed(by: disposeBag)
附:
// Normal
let(isSuccess, tipStr)= response.mapResult()
print("isSuccess -- \(isSuccess)")
print("tipStr -- \(tipStr)")
// Rx
rxRequest.mapResult()
.subscribe(onSuccess:{(isSuccess, tipStr)in晚婚婚假规定
print("isSuccess -- \(isSuccess)")// 是否为 "000"
print("retMsg -- \(retMsg)")// "缺少必要参数"
}).disposed(by: disposeBag)
附:
统⼀处理⽹络请求结果
在APP的实际使⽤过程中,会遇到各种各样的⽹络请求结果,如:服务器挂了、⼿机⽆⽹络,此时 Moya 返回的 Response 为 nil,这样我们就不得不去判断 Error。但是使⽤ MoyaMapperPlugin 就可以让我们只关注 Response
// MoyaMapperPlugin 的初始化⽅法
public init<T:ModelableParameterType>(
_ type: T,
transformError:Bool=true
)
type :ModelableParameterType⽤于定义字段路径,做为全局解析数据的依据
transformError :Bool是否当⽹络请求失败时,⾃动转换请求结果,默认为true
当请求失败的时候,此时的 sponse 为 nil,根据transformError是否为true 判断是否创建⼀个⾃定义的 response 并返回出去。
➡ 本来可以请求到的数据内容