MoyaMapper是基于Moya和SwiftyJSON封装的工具,以Moya的plugin的方式来实现间接解析,支持RxSwift
📖 详细的使用请查看手册 https://MoyaMapper.github.io
Feature
- 支持
json转Model自动映射 与 自定义映射 - 无视
json中值的类型,Model中属性声明的是什么类型,它就是什么类型 - 支持
json字符串转Model - 支持定义默认值策略、解析策略
- 插件方式,全方位保障
Moya.Response,拒绝各种网络问题导致Response为nil - Optional - 支持数据随意缓存(
JSON、Number、String、Bool、Moya.Response) - Optional - 支持网络请求缓存
Usage
映射
一、插件
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声明
1、
MoyaMapper支持模型自动映射2、不需要考虑源json数据的真实类型,这里统一按
Model中属性声明的类型进行转换
一般情况下如下写法即可
struct CompanyModel: Modelable {
var name : String = ""
var catchPhrase : String = ""
mutating func mapping(_ json: JSON) {
}
}如果键名需要自定义,则可以在方法 mutating func mapping(_ json: JSON) 中实现
struct CompanyModel: Modelable {
var name : String = ""
var catchPhrase : String = ""
mutating func mapping(_ json: JSON) {
self.name = json["nickname"].stringValue
}
}支持模型嵌套
struct UserModel: Modelable {
var id : String = ""
var name : String = ""
var company : CompanyModel = CompanyModel()
mutating func mapping(_ json: JSON) {
}
}三、Response 解析
1、以下示例皆使用了
MoyaMapperPlugin,所以不需要指定解析路径2、如果没有使用
MoyaMapperPlugin则需要指定解析路径,否则无法正常解析ps:
解析路径可以使用a>b这种形式来解决多级路径的问题
解析方法如下列表所示
| 方法 | 描述 (支持RxSwift) |
|---|---|
| toJSON | Response 转 JSON ( toJSON | rx.toJSON) |
| fetchString | 获取指定路径的字符串( fetchString | rx.fetchString) |
| fetchJSONString | 获取指定路径的原始json字符串 ( fetchJSONString | rx.fetchJSONString ) |
| mapResult | Response -> MoyaMapperResult (Bool, String) ( mapResult | rx.mapResult ) |
| mapObject | Response -> Model ( mapObject | rx.mapObject) |
| mapObjResult | Response -> (MoyaMapperResult, Model) ( mapObjResult | rx.mapObjResult) |
| mapArray | Response -> [Model]( mapArray | rx.mapArray) |
| mapArrayResult | Response -> (MoyaMapperResult, [Model]) ( mapArrayResult | rx.mapArrayResult) |
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 -- \(models.count)")
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 -- \(models.count)")
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)缓存
// 缓存
@discardableResult
MMCache.shared.cache`XXX`(value : XXX, key: String, cacheContainer: MMCache.CacheContainer = .RAM) -> Bool
// 取舍
MMCache.shared.fetch`XXX`Cache(key: String, cacheContainer: MMCache.CacheContainer = .RAM)
缓存成功与否都会返回一个 Bool 值,但不会强制接收
| XXX 所支持类型 | |
|---|---|
| Bool | - |
| Float | - |
| Double | - |
| String | - |
| JSON | - |
| Modelable | [Modelable] |
| Moya.Response | - |
| Int | UInt |
| Int8 | UInt8 |
| Int16 | UInt16 |
| Int32 | UInt32 |
| Int64 | UInt64 |
其中,除了
Moya.Response之外,其它类型皆是通过JSON来实现缓存
所以,如果你想清除这些类型的缓存,只需要调用如下方法即可
@discardableResult
func removeJSONCache(_ key: String, cacheContainer: MMCache.CacheContainer = .RAM) -> Bool
@discardableResult
func removeAllJSONCache(cacheContainer: MMCache.CacheContainer = .RAM) -> Bool清除 Moya.Response 则使用如下两个方法
@discardableResult
func removeResponseCache(_ key: String) -> Bool
@discardableResult
func removeAllResponseCache() -> Bool再来看看MMCache.CacheContainer
enum CacheContainer {
case RAM // 只缓存于内存的容器
case hybrid // 缓存于内存与磁盘的容器
}这两种容器互不相通,即 即使
key相同,使用hybrid来缓存后,再通过RAM取值是取不到的。
- RAM : 仅缓存于内存之中,缓存的数据在APP使用期间一直存在
- hybrid :缓存于内存与磁盘中,APP重启后也可以获取到数据
缓存网络请求
内部缓存过程:
- APP首次启动并进行网络请求,网络数据将缓存起来
- APP再次启动并进行网络请求时,会先加载缓存,再加载网络数据
- 其它情况只会加载网络数据
- 每次成功请求到数据都会进行数据更新
// Normal
func cacheRequest(
_ target: Target,
cacheType: MMCache.CacheKeyType = .default,
callbackQueue: DispatchQueue? = nil,
progress: Moya.ProgressBlock? = nil,
completion: @escaping Moya.Completion
) -> Cancellable
// Rx
func cacheRequest(
_ target: Base.Target,
callbackQueue: DispatchQueue? = nil,
cacheType: MMCache.CacheKeyType = .default
) -> Observable<Response>可对
Moya请求后的Response进行缓存。 其实与Moya自带的方法相比较只多了一个参数cacheType: MMCache.CacheKeyType,定义着缓存中的key,默认为default
下面是 MMCache.CacheKeyType 的定义
/**
let cacheKey = [method]baseURL/path
- default : cacheKey + "?" + parameters
- base : cacheKey
- custom : cacheKey + "?" + customKey
*/
public enum CacheKeyType {
case `default`
case base
case custom(String)
}
如果你想缓存
多页列表数据的最新一页的数据,则可以使用base或者custom(String)
/*
* APP第一次启动并进行网络请求,网络数据将缓存起来
* APP再次启动并进行网络请求时,会先加载缓存,再加载网络数据
* 其它情况只会加载网络数据
* 每次成功请求到数据都会进行数据更新
*/
lxfNetTool.rx.cacheRequest(.data(type: .all, size: 10, index: 1))
.subscribe(onNext: { response in
log.debug("statusCode -- \(response.statusCode)")
log.debug(" ===== cache =====")
}).disposed(by: disposeBag)
// 传统方式
/*
let _ = lxfNetTool.cacheRequest(.data(type: .all, size: 10, index: 1)) { result in
guard let resp = result.value else { return }
log.debug("statusCode -- \(resp.statusCode)")
}
*/打印结果
// 第一次使用
statusCode -- 200
// 关闭并重新打开APP,再请求一下
statusCode -- 230
statusCode -- 200
// 然后再请求一下
statusCode -- 200
Installation
| Swift | MoyaMapper | Moya |
|---|---|---|
| 5.X | >=3.0.0 | >=14.0.0 |
| 5.X | >=2.0.0 | >=11.0.0 |
| 4.x | <=1.2.3 | >=11.0.0 |
CocoaPods
- 默认安装
MoyaMapper默认只安装Core下的文件
pod 'MoyaMapper'- RxSwift拓展
pod 'MoyaMapper/Rx'- 缓存拓展
pod 'MoyaMapper/MMCache'- Rx缓存
pod 'MoyaMapper/RxCache'Carthage
在你的 Cartfile 文件中添加如下内容:
github "MoyaMapper/MoyaMapper"
接着运行 carthage update --no-use-binaries --platform ios.
License
MoyaMapper is available under the MIT license. See the LICENSE file for more info.
Author
- LinXunFeng
- email: [email protected]
- Blogs: LinXunFeng‘s Blog | 掘金 | 简书
![]() |
![]() |
![]() |
|---|---|---|






