Code Monkey home page Code Monkey logo

rxnetworks's Introduction

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 3 parts:
    • NetworkConfig: Set the configuration information at the beginning of the program.
      • 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.
      • transformAPISingleJSON: Transforms a Single sequence 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, before starting to prepare the request, this method can be used in scenarios such as key invalidation, re-acquiring the key and then automatically re-requesting the network.
      • 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.
      • request: Network request method and return a Single sequence object.
    • 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 {
    
    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 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 {

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

๐ŸŽท - 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] (data1, data2, data3) in
            guard var data1 = data1 as? Dictionary<String, Any>,
                  let data2 = data2 as? Dictionary<String, Any>,
                  let data3 = data3 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 plug-ins

  • At present, 4 plug-ins have been packaged for you to use:

๐Ÿ  - 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(delayHideHUD: 0.5)
    return [loading, cache]
}

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.


rxnetworks's People

Contributors

safina008 avatar

Stargazers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.