RxSwift+Moya实现的网络请求

step1:
用cocoapods集成Moya和SwiftyJSON,Podfile如下:

# Uncomment the next line to define a global platform for your project
platform :ios, '9.0'

target 'demo' do
  # Comment the next line if you're not using Swift and don't want to use dynamic frameworks
  use_frameworks!

  # Pods for demo

pod 'Moya/RxSwift', '~> 11.0'
pod 'SwiftyJSON', '~> 4.0'
end

step2:
创建一个工具类NetTool.swift,实现moyatarget的extension:

public enum netTool {
    
    case zen
    case userProfile(String)

}

// 测试url:
// MARK: - get请求 https://api.github.com/zen  https://api.github.com/users/ashfurrow
extension netTool: Moya.TargetType {
    public var baseURL: URL {
        return URL(string: "https://api.github.com")!
    }
    
    public var path: String {
        switch self {
        case .zen:
            return "/zen"
        case .userProfile(let name):
            return "/users/\(name)"
        }
    }
    
    public var method: Moya.Method {
        return .get
    }
    
    public var sampleData: Data {
        return "Test data".data(using: .utf8)!
    }
    
    public var task: Moya.Task {
        switch self {
        default:
            return .requestPlain
        }
    }
    
    public var headers: [String : String]? {
        return nil
    }
}

step3:
接下来就可以直接用moya+rx实现网络请求:

        let provider = MoyaProvider()
        
        provider.rx.request(.zen, callbackQueue: DispatchQueue.main)
            .asObservable()
            .mapString()
            .subscribe(onNext: { (s) in
                print(s)
            }, onError: { (e) in
                print(e)
            })
            .disposed(by: dispose)

//mapString:把Observable转换成Observable
//备注:moya的作者只提供了mapString和mapJSON/mapImage这些方法;

step4:
实现myMapJSON和mapObject使我们的请求实现JSON转Model
给ObservableType增加扩展实现Observable

public extension ObservableType where E == Moya.Response {
    
    public func myMapJSON() -> Observable {
        return flatMap{ (response) -> Observable in
            return Observable.just(try response.mapToJSON())
        }
    }
}

fileprivate extension Moya.Response {
    
    fileprivate func mapToJSON() throws -> JSON {
        do {
            let json = try JSON(mapJSON())
            print("\n\n\(json)\n")
            return json
        } catch {
            throw Moya.MoyaError.jsonMapping(self)
        }
    }
    

给ObservableType增加扩展实现Observable

extension ObservableType where E == JSON {
    public func mapObject(to type: T.Type) -> Observable {
        return flatMap { json -> Observable in
            return Observable.just(json.mapObject(to: type))
        }
    }
}

fileprivate extension JSON {
    fileprivate func mapObject(to type: T.Type) -> T {
        return T(json: self)
    }
}

// 此处使用了T(json: self),配合了protocol - Parseable

step5:
见证奇迹的时刻到了:

        provider.rx.request(.userProfile("ashfurrow"))
            .asObservable()
            .myMapJSON()
            .mapObject(to: GitHubModel.self)
            .subscribe(onNext: { (model) in
                print(model.avatar_url ?? "")
                print(model.company ?? "")
            }, onError: { (e) in
                print(e)
            })
            .disposed(by: dispose)
运行结果

Demo地址:https://github.com/kepingchang/MoyaRequestDemo

推荐一个小工具:


JSONConvertericon

JSONConverter

你可能感兴趣的:(RxSwift+Moya实现的网络请求)