. RxSwift + Moya + HandyJSON + Plugins.


English | 简体中文

基于 RxSwift + Moya 搭建响应式数据绑定网络API架构

MoyaNetwork

该模块是基于Moya封装的网络API架构

  • 主要分为以下8部分:
    • NetworkConfijsonyaug:在程序最开始处设置配置信息,全局通用

      • addDebugging:是否开启动画制作软件默认加入调试插件
      • baseURL:根路径地址线程池
      • baseParameters:默认基本参数,类似:userID,token等
      • baseMethod:默认请求类型
      • updateBaseParametersWithValue:更新http://192.168.1.1登录默认基本jsonyau参数数据
    • RxMoyaProvider:对网络请求添加响应式,返回Observable序列
    • NetworkUtil:网络相关函数

      • defaulhttp协议tPlugin:添加默认插件
      • transformAPIObservableJSON:转换成可观察序列JSON对象
      • handyConfigurationPlugin:处理配置插件
    • PluginSubType:继承替换Moya插件协议,方便后序扩展

      • con线程是什么意思figurati动画片猫和老鼠on:设置网络配置信息之后,开始准备请求之前,该方法可以用于本地缓存存在时直接抛出数据而不用再执行后序网络请求等场动画片小猪佩奇
      • lastNever:最后的最后网络响应返回线程的概念时刻,该方法可以用于密钥失效重新去获取密钥然后自动再次网络请求等场景
    • Netwo动画制作软件rkAPI:在TargetType基础上增加协议属性和封装基础网络请动画片小猪佩奇

      • ip:根路径地址
      • parameters:请求参数
      • plugins:插件数组
      • stubBehavior:是否走测试数据
      • retry:请求失败重试次数
      • request:网络请求方法,返回可观察序列JSON对象
    • NetworkAPI+Ext:NetworkAPI协议默认动画实现方案
    • NetworkAPI线程数越多越好吗OO:面向对象转换器,面向协议模式转面向对象,方便习惯OC思维的小伙伴

      • cdy_ip:根路径json解析地址
      • cdy_path:请求路径
      • cdy_parameters:请求参数
      • cdy_plugins:插件
      • cdy_testJSON:测试数据
      • cdy_testTimjson格式e:测试数据返回时间,默认半秒
      • cdy_retry:请求失败重试次数
      • cdy_动画HTTPRequest:网络请求方法
    • Netjson怎么读workX:扩展函数方法等

      • toJSON:对象转JSON字符串
      • toDictionary:JSON字符串转字典
      • +=:字典拼线程撕裂者

– 面向对象使用示例1:

class OOViewModel: NSObject {
  let disposeBag = DisposeBag()
  let data = PublishRelay<String>()
  func loadData() {
    var api = NetworkAPIOO.init()
    api.cdy_ip = "https://www.httpbin.org"
    api.cdy_path = "/ip"
    api.cdy_method = .get
    api.cdy_plugins = [NetworkLoadingPlugin.init()]
        api.cdy_retry = 3
    api.cdy_HTTPRequest()
      .asObservable()
      .compactMap{ (($0 as! NSDictionary)["origin"] as? String) }
            .catchAndReturn("")
      .bind(to: data)
      .disposed(by: disposeBag)
  }
}

– MVP使用示例2线程和进程的区别是什么:

enum LoadingAPI {
  case test2(String)
}
extension LoadingAPI: NetworkAPI {
  var ip: APIHost {
    return NetworkConfig.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()
      .mapHandyJSON(HandyDataModel<[CacheModel]>.self)
      .compactMap { $0.data }
      .observe(on: MainScheduler.instance) // 结果在主线程返回
      .delay(.seconds(1), scheduler: MainScheduler.instance) // 延时1秒返回
      .asDriver(onErrorJustReturn: []) // 错误时刻返回空
  }
}

– 链式请求使用示例4:

class ChainViewModel: NSObject {
  let disposeBag = DisposeBag()
  let data = PublishRelay<NSDictionary>()
  func chainLoad() {
    requestIP()
      .flatMapLatest(requestData)
      .subscribe(onNext: { [weak self] data in
        self?.data.accept(data)
      }, onError: {
        print("Network Failed: \($0)")
      }).disposed(by: disposeBag)
  }
}
extension ChainViewModel {
  func requestIP() -> Observable<String> {
    return ChainAPI.test.request()
      .asObservable()
      .map { ($0 as! NSDictionary)["origin"] as! String }
      .catchAndReturn("") // 异常抛出
  }
  func requestData(_ ip: String) -> Observable<NSDictionary> {
    return ChainAPI.test2(ip).request()
      .asObservable()
      .map { ($0 as! NSDictionary) }
      .catchAndReturn(["data": "nil"])
  }
}

– 批量请求使用示例5:

class BatchViewModel: 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 batchLoad() {
    Observable.zip(
      APIProvider.rx.request(api: BatchAPI.test).asObservable(),
      APIProvider.rx.request(api: BatchAPI.test2("666")).asObservable(),
      APIProvider.rx.request(api: BatchAPI.test3).asObservable()
    ).subscribe(onNext: { [weak self] in
      guard var data1 = $0 as? Dictionary<String, Any>,
         let data2 = $1 as? Dictionary<String, Any>,
         let data3 = $2 as? Dictionary<String, Any> else {
           return
         }
      data1 += data2
      data1 += data3
      self?.data.accept(data1)
    }, onError: {
      print("Network Failed: \($0)")
    }).disposed(by: disposeBag)
  }
}

MoyaPl动画片少儿小猪佩奇ugins

该模块主要就是基于moya封装网络相关插件

  • RxSwift前已封装6款插件供您使用:
    • Cache:网络数json文件怎么打开据缓存插件线程
    • Loading:加载动画插件
    • Indicator:指示器插件
    • Warni线程数越多越好吗ng:网络失败提示插件
    • Debugging:调试日志插件
    • GZip:解压缩插件

– 简单使用,在API协议当中实现该协议方法,然后将插件加入其中即可:

var plugins: APIPlugins {
  let cache = NetworkCachePlugin(cacheType: .networkElseCache)
  let loading = NetworkLoadingPlugin.init(delayHideHUD: 0.5)
    loading.changeHudCallback = { (hud) in
        hud.detailsLabel.textColor = UIColor.yellow
    }
  return [loading, cache]
}

HandyJSON

该模块是基于HandyJSON封装网络数据解析

  • 大致分为以下3个部分:
    • Ha线程的几种状态ndyDataModel:网络外层数据模型
    • HandyJSONError线程撕裂者:解析错误相关
    • RxHandyJSON:HandyJSO线程数N数据解析,目前提供两种http协议解析方案

      • 方案1http://192.168.1.1登录 结合HandyDataModel模型使用解析RxSwiftdata数据
      • 方案2 – 根据keyPath解析出指定key的数据,前提条件数据源必须字典形式

– 结合网络部分使用示例:

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: []) // 错误时刻返回空
}

CocoaPods Install动画制作软件

Ex: 导入网络架构API
- pod 'RxNetworks/MoyaNetwork'
Ex: 导入数据解析
- pod 'RxNetworks/HandyJSON'
Ex: 导入加载动画插件
- pod 'RxNetworks/MoyaPlugins/Loading'

动画

  • 搞OC的小伙伴们也可以使用我的另一款网络插件jsonpKJNetworkPlugin
  • 再分享一个M线程是什么意思VVM + RxSwift + CTMediatror + MJRefresh + DZNEmptyDataSet 组件化思路的基础架构,喜欢就去用吧别犹豫。
  • 再附上一个开发加速库KJCategoriesDemo地址 喜欢的老板们可以点个星

DHTTPemo

大体流程差不多就是这样,Dem线程的概念o也写的很详细,大家可以自己去看看

RxNetworksDemo

提示:如果觉得有帮助,请帮json数据忙点个星 ⭐..

谢谢.

  • 后序有相关插件,也会慢慢补充..

✌️