RxNetworks

响应式插件网络架构
授权协议 MIT
开发语言 Swift
所属分类 iOS代码库、 网络(Networking)
软件类型 开源软件
地区 国产
投 递 者 莫誉
操作系统 iOS
开源组织
适用人群 未知
 软件概览

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

MoyaNetwork

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

  • 主要分为3部分:
    • NetworkConfig:在程序最开始处设置配置信息,全局通用
      • baseURL:根路径地址
      • baseParameters:默认基本参数,类似:userID,token等
      • baseMethod:默认请求类型
      • updateBaseParametersWithValue:更新默认基本参数数据
    • RxMoyaProvider:对网络请求添加响应式,返回Single序列
    • NetworkUtil:网络相关函数
      • defaultPlugin:添加默认插件
      • transformAPISingleJSON:转换Single序列对象
      • handyConfigurationPlugin:处理配置插件
    • PluginSubType:继承替换Moya插件协议,方便后序扩展
      • configuration:设置网络配置信息之后,开始准备请求之前,该方法可以用于密钥失效重新去获取密钥然后自动再次网络请求等场景
      • autoAgainRequest:自动再次开启上次失败的网络请求,该方法可以用于密钥失效重新去获取密钥然后自动再次网络请求等场景
    • NetworkAPI:在TargetType基础上增加协议属性和封装基础网络请求
      • ip:根路径地址
      • parameters:请求参数
      • plugins:插件
      • stubBehavior:是否走测试数据
      • request:网络请求方法
    • NetworkAPIOO:面向对象转换器,面向协议模式转面向对象,方便习惯OC思维的小伙伴
      • cdy_ip:根路径地址
      • cdy_path:请求路径
      • cdy_parameters:请求参数
      • cdy_plugins:插件
      • cdy_testJSON:测试数据
      • cdy_testTime:测试数据返回时间,默认半秒
      • cdy_HTTPRequest:网络请求方法
    • NetworkDebugging:调试打印模式
      • openDebugRequest:开启请求打印
      • openDebugResponse:开启结果打印

 - 面向对象使用示例1:

class OOViewModel: NSObject {
    
    let disposeBag = DisposeBag()
    
    let data = PublishRelay<String>()
    
    func loadData() {
        var api = NetworkAPIOO.init()
        api.cdy_ip = NetworkConfig.baseURL
        api.cdy_path = "/ip"
        api.cdy_method = .get
        api.cdy_plugins = [NetworkLoadingPlugin.init()]
        
        api.cdy_HTTPRequest()
            .asObservable()
            .compactMap{ (($0 as! NSDictionary)["origin"] as? String) }
            .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: []) // 错误时刻返回空
    }
}

MoyaPlugins

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

  • 目前已封装4款插件供您使用:

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

var plugins: APIPlugins {
    let cache = NetworkCachePlugin(cacheType: .networkElseCache)
    let loading = NetworkLoadingPlugin.init(delayHideHUD: 0.5)
    return [loading, cache]
}

HandyJSON

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

  • 大致分为以下3个部分:
    • HandyDataModel:网络外层数据模型
    • HandyJSONError:解析错误相关
    • RxHandyJSON:HandyJSON数据解析,目前提供两种解析方案
      • 方案1 - 结合HandyDataModel模型使用解析出data数据
      • 方案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'

 

 相关资料
  • 如果你不想重复造轮子,你可以选择一款响应式的框架,目前市面上类似的框架也有很多,像Bootstrap、Foundation,你也可以使用像H5 Boilerplate来创建响应式项目,但不论你使用何种方式,掌握底层的原理对于你来说比挑选一门框架更有意义。所以大家Fighting~~~

  • Kubernetes网络模型 IP-per-Pod,每个Pod都拥有一个独立IP地址,Pod内所有容器共享一个网络命名空间 集群内所有Pod都在一个直接连通的扁平网络中,可通过IP直接访问 所有容器之间无需NAT就可以直接互相访问 所有Node和所有容器之间无需NAT就可以直接互相访问 容器自己看到的IP跟其他容器看到的一样 Service cluster IP尽可在集群内部访问,外部请求需要通过

  • Container Network Interface (CNI) 最早是由CoreOS发起的容器网络规范,是Kubernetes网络插件的基础。其基本思想为:Container Runtime在创建容器时,先创建好network namespace,然后调用CNI插件为这个netns配置网络,其后再启动容器内的进程。现已加入CNCF,成为CNCF主推的网络模型。 CNI插件包括两部分: CNI

  • 当客户端发出请求时,“MonoJust”会打印在第4行,但“test”会在Http响应正文中返回。我知道发布者在订阅之前不会生成数据,那么为什么Http响应包含“test”而不是“MonoJust”?

  • 我正在使用截击来管理我的应用程序。有时,当响应很大时,我会在没有太多RAM的设备上获得OOM。我不确定如何解决这个问题。我知道Volley会将其响应存储在内存中,但我的应用程序太多地围绕着Volley,切换起来会很痛苦。我在使用改装时也遇到了问题。我尝试过使用JsonReader,但它似乎仍在发生。我有一个用于截击的自定义请求。它返回一个Gson JsonObject。这是我目前的代码,当响应数据

  • 本章介绍Kubernetes的网络模型以及常见插件的原理和使用方法。