🧚. RxSwift + Moya + HandyJSON/Codable + Plugins.👒👒👒
English | 简体中文
基于 RxSwift + Moya 搭建响应式数据绑定网络API架构
该模块主要就是基于moya封装网络相关插件
- 目前已封装14款插件供您使用:
iOS 系统:
简单使用,在API协议当中实现该协议方法,然后将插件加入其中即可:
var plugins: APIPlugins {
let cache = NetworkCachePlugin.init(options: .cacheThenNetwork)
let loading = NetworkLoadingPlugin.init(options: .init(delay: 0.5))
let warning = NetworkWarningPlugin.init()
let shared = NetworkSharedPlugin.init()
let gzip = NetworkGZipPlugin.init()
return [loading, cache, warning, shared, gzip]
}
该模块是基于HandyJSON
封装网络数据解析
- 大致分为以下3个部分:
- HandyDataModel:网络外层数据模型
- HandyJSONError:解析错误相关
- RxHandyJSON:HandyJSON数据解析,目前提供两种解析方案
- 方案1 - 结合
HandyDataModel
模型使用解析出data
数据 - 方案2 - 根据
keyPath
解析出指定key的数据,前提条件数据源必须字典形式
- 方案1 - 结合
🎷 - 结合网络部分使用示例:
func request(_ count: Int) -> Driver<[CacheModel]> {
CacheAPI.cache(count).request()
.asObservable()
.mapHandyJSON(HandyDataModel<[CacheModel]>.self)
.compactMap { $0.data }
.observe(on: MainScheduler.instance) // 结果在主线程返回
.delay(.seconds(1), scheduler: MainScheduler.instance) // 延时1秒返回
.asDriver(onErrorJustReturn: []) // 错误时刻返回空
}
这个模块是序列化和反序列化数据,取代HandyJSON。
🎷 - 结合网络部分使用示例:
func request(_ count: Int) -> Observable<[CodableModel]> {
CodableAPI.cache(count)
.request(callbackQueue: DispatchQueue(label: "request.codable"))
.deserialized(ApiResponse<[CodableModel]>.self, mapping: CodableModel.self)
.compactMap({ $0.data })
.observe(on: MainScheduler.instance)
.catchAndReturn([])
}
这边提供多种多样的使用方案供您选择,怎么选择就看你心情;
🎷 - 面向对象使用示例1:
class OOViewModel: NSObject {
let userDefaultsCache = UserDefaults(suiteName: "userDefaultsCache")!
func request(block: @escaping (String) -> Void) {
let api = NetworkAPIOO.init()
api.ip = "https://www.httpbin.org"
api.path = "/headers"
api.method = APIMethod.get
api.plugins = [
NetworkLoadingPlugin(options: .init(text: "OOing..")),
NetworkCustomCachePlugin.init(cacheType: .cacheThenNetwork, cacher: userDefaultsCache),
NetworkIgnorePlugin(pluginTypes: [NetworkActivityPlugin.self]),
]
api.mapped2JSON = false
api.request(successed: { response in
guard let string = response.bpm.toJSONString(prettyPrint: true) else {
return
}
block(string)
})
}
}
🎷 - MVP使用示例2:
enum LoadingAPI {
case test2(String)
}
extension LoadingAPI: NetworkAPI {
var ip: APIHost {
return BoomingSetup.baseURL
}
var path: String {
return "/post"
}
var parameters: APIParameters? {
switch self {
case .test2(let string): return ["key": string]
}
}
}
class LoadingViewModel: NSObject {
let disposeBag = DisposeBag()
let data = PublishRelay<NSDictionary>()
/// 配置加载动画插件
let APIProvider: MoyaProvider<MultiTarget> = {
let configuration = URLSessionConfiguration.default
configuration.headers = .default
configuration.timeoutIntervalForRequest = 30
let session = Moya.Session(configuration: configuration, startRequestsImmediately: false)
let loading = NetworkLoadingPlugin.init()
return MoyaProvider<MultiTarget>(session: session, plugins: [loading])
}()
func loadData() {
APIProvider.rx.request(api: LoadingAPI.test2("666"))
.asObservable()
.subscribe { [weak self] (event) in
if let dict = event.element as? NSDictionary {
self?.data.accept(dict)
}
}.disposed(by: disposeBag)
}
}
🎷 - MVVM使用示例3:
class CacheViewModel: NSObject {
let disposeBag = DisposeBag()
struct Input {
let count: Int
}
struct Output {
let items: Driver<[CacheModel]>
}
func transform(input: Input) -> Output {
let elements = BehaviorRelay<[CacheModel]>(value: [])
let output = Output(items: elements.asDriver())
request(input.count)
.asObservable()
.bind(to: elements)
.disposed(by: disposeBag)
return output
}
}
extension CacheViewModel {
func request(_ count: Int) -> Driver<[CacheModel]> {
CacheAPI.cache(count).request()
.asObservable()
.deserialize(ApiResponse<[CacheModel]>.self)
.compactMap { $0.data }
.observe(on: MainScheduler.instance) // 结果在主线程返回
.delay(.seconds(1), scheduler: MainScheduler.instance) // 延时1秒返回
.asDriver(onErrorJustReturn: []) // 错误时刻返回空
}
}
🎷 - 链式请求使用示例4:
class ChainViewModel: NSObject {
struct Input { }
struct Output {
let data: Observable<NSDictionary>
}
func transform(input: Input) -> Output {
let data = chain().asObservable()
return Output(data: data)
}
func chain() -> Observable<NSDictionary> {
Observable.from(optional: "begin")
.flatMapLatest(requestIP)
.flatMapLatest(requestData(ip:))
.catchAndReturn([:])
}
}
extension ChainViewModel {
func requestIP(_ stirng: String) -> Observable<String> {
return ChainAPI.test.request()
.asObservable()
.map { (($0 as? NSDictionary)?["origin"] as? String) ?? stirng }
.observe(on: MainScheduler.instance)
}
func requestData(ip: String) -> Observable<NSDictionary> {
return ChainAPI.test2(ip).request()
.map { ($0 as! NSDictionary) }
.catchAndReturn(["data": "nil"])
.observe(on: MainScheduler.instance)
}
}
🎷 - 批量请求使用示例5:
class BatchViewModel: NSObject {
struct Input { }
struct Output {
let data: Observable<[String: Any]>
}
func transform(input: Input) -> Output {
let data = batch().asObservable()
return Output(data: data)
}
func batch() -> Observable<[String: Any]> {
Observable.zip(
BatchAPI.test.request(),
BatchAPI.test2("666").request(),
BatchAPI.test3.request()
)
.observe(on: MainScheduler.instance)
.map { [$0, $1, $2].compactMap {
$0 as? [String: Any]
}}
.map { $0.reduce([String: Any](), +==) }
.catchAndReturn([:])
}
}
Ex: 导入网络架构API
- pod 'Booming'
Ex: 导入加载动画插件
- pod 'NetworkHudsPlugin'
Ex: 导入数据解析
- pod 'RxNetworks/HandyJSON'
Ex: 导入响应式模块
- pod 'RxNetworks/RxSwift'
- 🎷 邮箱地址:[email protected] 🎷
- 🎸 GitHub地址:yangKJ 🎸
- 🎺 掘金地址:茶底世界之下 🎺
- 🚴🏻 简书地址:77___ 🚴🏻
当然如果您这边觉得好用对你有所帮助,请给作者一点辛苦的打赏吧。再次感谢感谢!!!
有空我也会一直更新维护优化 😁😁😁
救救孩子吧,谢谢各位老板。
🥺