Menu

Tree [aefcab] master 0.1.8 /
 History

HTTPS access


File Date Author Commit
 Pods 2022-01-28 77。 77。 [aefcab] Pod 0.1.8
 RxNetworks 2022-01-28 77。 77。 [22382c] Update test case
 RxNetworks.xcodeproj 2022-01-28 77。 77。 [19bdcc] Remove rxcocoa
 RxNetworks.xcworkspace 2022-01-24 Zz Zz [09961c] Update Podfile
 Sources 2022-01-28 77。 77。 [3e10d8] Fix gzip manager code warning⚠️
 .gitignore 2022-01-24 Zz Zz [af3c77] Update gitignore
 LICENSE 2022-01-20 77。 77。 [eaf3ca] Update LICEMSE
 Podfile 2022-01-28 77。 77。 [19bdcc] Remove rxcocoa
 Podfile.lock 2022-01-28 77。 77。 [aefcab] Pod 0.1.8
 README.md 2022-01-28 77。 77。 [f09679] Update README
 README_CN.md 2022-01-25 Zz Zz [713315] Update README
 RxNetworks.podspec 2022-01-28 77。 77。 [aefcab] Pod 0.1.8

Read Me

RxNetworks

Carthage compatible
Releases Compatible
CocoaPods Compatible
Platform

🧚. RxSwift + Moya + HandyJSON + Plugins.👒👒👒


English | 简体中文

This is a set of infrastructure based on RxSwift + Moya

MoyaNetwork

This module is based on the Moya encapsulated network API architecture.

  • Mainly divided into 8 parts:
    • NetworkConfig: Set the configuration information at the beginning of the program.
      • addDebugging:Whether to introduce the debug mode plugin by default.
      • baseURL: Root path address to base URL.
      • baseParameters: Default basic parameters, like: userID, token, etc.
      • baseMethod: Default request method type.
      • updateBaseParametersWithValue: Update default base parameter value.
    • RxMoyaProvider: Add responsiveness to network requests, returning Single sequence.
    • NetworkUtil: Network related functions
      • defaultPlugin: Add default plugin.
      • transformAPIObservableJSON: Transforms a Observable sequence JSON object.
      • handyConfigurationPlugin: Handles configuration plugins.
    • PluginSubType: Inherit and replace the Moya plug-in protocol to facilitate subsequent expansion.
      • configuration: After setting the network configuration information, this method can be used in scenarios such as throwing data directly when the local cache exists without executing subsequent network requests.
      • lastNever: When the last network response is returned, this method can be used in scenarios such as key failure to re-obtain the key and then automatically re-request the network.
    • NetworkAPI: Add protocol attributes and encapsulate basic network requests based on TargetType.
      • ip: Root path address to base URL.
      • parameters: Request parameters.
      • plugins: Set network plugins.
      • stubBehavior: Whether to take the test data.
      • retry:Network request failure retries.
      • request: Network request method and return a Single sequence object.
    • NetworkAPI+Ext: Protocol default implementation scheme.
    • NetworkAPIOO: OOP converter, MVP to OOP, convenient for friends who are used to OC thinking
      • cdy_ip: Root path address to base URL.
      • cdy_path: Request path.
      • cdy_parameters: Request parameters.
      • cdy_plugins: Set network plugins.
      • cdy_testJSON: Network testing json string.
      • cdy_testTime: Network test data return time, the default is half a second.
      • cdy_HTTPRequest: Network request method and return a Single sequence object.
    • NetworkX: extension function methods etc.
      • toJSON: to JSON string.
      • toDictionary: JSON string to dictionary.
      • +=: Dictionary concatenation.

🎷 - OO Example 1:

class OOViewModel: NSObject {

    struct Input {
        let retry: Int
    }

    struct Output {
        let items: Observable<String>
    }

    func transform(input: Input) -> Output {
        return Output(items: input.request())
    }
}

extension OOViewModel.Input {
    func request() -> Observable<String> {
        var api = NetworkAPIOO.init()
        api.cdy_ip = NetworkConfig.baseURL
        api.cdy_path = "/ip"
        api.cdy_method = APIMethod.get
        api.cdy_plugins = [NetworkLoadingPlugin()]
        api.cdy_retry = self.retry

        return api.cdy_HTTPRequest()
            .asObservable()
            .compactMap{ (($0 as! NSDictionary)["origin"] as? String) }
            .catchAndReturn("")
            .observe(on: MainScheduler.instance)
    }
}

🎷 - MVP Example 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>()

    /// Configure the loading animation plugin
    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 Example 3:

class CacheViewModel: NSObject {

    struct Input {
        let count: Int
    }

    struct Output {
        let items: Observable<[CacheModel]>
    }

    func transform(input: Input) -> Output {
        let items = request(input.count).asObservable()

        return Output(items: items)
    }
}

extension CacheViewModel {

    func request(_ count: Int) -> Observable<[CacheModel]> {
        CacheAPI.cache(count).request()
            .mapHandyJSON(HandyDataModel<[CacheModel]>.self)
            .compactMap { $0.data }
            .observe(on: MainScheduler.instance) // the result is returned on the main thread
            .catchAndReturn([]) // return null on error
    }
}

🎷 - Chain Example 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("") // Exception thrown
    }

    func requestData(_ ip: String) -> Observable<NSDictionary> {
        return ChainAPI.test2(ip).request()
            .asObservable()
            .map { ($0 as! NSDictionary) }
            .catchAndReturn(["data": "nil"])
    }
}

🎷 - Batch Example 5:

class BatchViewModel: NSObject {
    let disposeBag = DisposeBag()
    let data = PublishRelay<NSDictionary>()

    /// Configure loading animation plugin
    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)
    }
}

MoyaPlugins

This module is mainly based on moya package network related plugins

  • At present, 6 plugins have been packaged for you to use:
    • Cache: Network Data Cache Plugin
    • Loading: Load animation plugin
    • Indicator: Indicator plugin
    • Warning: Network failure prompt plugin
    • Debugging: Network printing, built in plugin
    • GZip: Network data unzip plugin

🏠 - Simple to use, implement the protocol method in the API protocol, and then add the plugin to it:

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

HandyJSON

This module is based on HandyJSON package network data parsing

  • Roughly divided into the following 3 parts:
    • HandyDataModel: Network outer data model
    • HandyJSONError: Parse error related
    • RxHandyJSON: HandyJSON data parsing, currently provides two parsing solutions
      • Option 1: Combine HandyDataModel model to parse out data.
      • Option 2: Parse the data of the specified key according to keyPath, the precondition is that the json data source must be in the form of a dictionary.

🎷 - Example of use in conjunction with the network part:

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)
        .asDriver(onErrorJustReturn: [])
}

CocoaPods Install

Ex: Import Network Architecture API

- pod 'RxNetworks/MoyaNetwork'

Ex: Import Model Anslysis 

- pod 'RxNetworks/HandyJSON'

Ex: Import loading animation plugin

- pod 'RxNetworks/MoyaPlugins/Loading'

Remarks

The general process is almost like this, the Demo is also written in great detail, you can check it out for yourself.🎷

RxNetworksDemo

Tip: If you find it helpful, please help me with a star. If you have any questions or needs, you can also issue.

Thanks.🎇

About the author


License

RxNetworks is available under the MIT license. See the LICENSE file for more info.


MongoDB Logo MongoDB