Swfit 网络请求 : Moya+RxSwift+ObjectMapper (MVVM)

Swift版本 : 4.1
Moya版本 : 11.0.2
Moya/RxSwift版本 : 11.0.2
ObjectMapper版本 : 3.3.0
RxSwift版本 : 4.2.0

参考博文 : Moya+RxSwift+ObjectMapper实现MVVM模式
PS : 这里要注意的是,因为版本不一样,在使用的时候,方法也会有细微的变化.


架构模式图:

Swfit 网络请求 : Moya+RxSwift+ObjectMapper (MVVM)_第1张图片
架构图

1.先定义网络请求

import UIKit
import Moya

extension MoyaApi : TargetType {
    
    var baseURL: URL {
        return URL(string: "http://jsonplaceholder.typicode.com")!
    }
    
    var path: String {
        switch self {
        case .Show:
            return "/posts"
        case .Create(_, _, _):
            return "/posts"
        }
    }
    
    var method: Moya.Method {
        switch self {
        case .Show:
            return .get
        case .Create(_, _, _):
            return .post
        }
    }
    
    var sampleData: Data {
        switch self {
        case .Show:
            return "[{\"userId\": \"1\", \"Title\": \"Title String\", \"Body\": \"Body String\"}]".data(using: String.Encoding.utf8)!
        case .Create(_, _, _):
            return "Create post successfully".data(using: String.Encoding.utf8)!
        }
    }

    var task: Task {
        return .requestPlain
    } // 请求任务

    var headers: [String : String]?{ return ["Content-type" : "application/json"] }
}

//请求方法
enum MoyaApi {
    case Show
    case Create(title: String, body: String, userId: Int)
}

2.创建模型

import UIKit
import ObjectMapper

class MoyaModel: Mappable {
    var id: Int?
    var title: String?
    var body: String?
    var userId: Int?
    
    
    required init?(map: Map) {
    }
    
    func mapping(map: Map) {
        id <- map["id"]
        title <- map["title"]
        body <- map["body"]
        userId <- map["userId"]
    }
}

3.创建模型转换方法(这部分参照其他博文)

mapObject(type: TopicModel.self)为对Observable的扩展方法解析成TopicModel对象
mapArray(type: TopicModel.self)为对Observable的扩展方法解析成[TopicModel]数组

import Foundation
import RxSwift
import Moya
import ObjectMapper

extension Observable {
    func mapObject(type: T.Type) -> Observable {
        return self.map { response in
            guard let dict = response as? [String: Any] else {
                throw RxSwiftMoyaError.ParseJSONError
            }
            return Mapper().map(JSON: dict)!
        }
    }
    
    func mapArray(type: T.Type) -> Observable<[T]> {
        return self.map { response in
            
            guard let array = response as? [Any] else {
                throw RxSwiftMoyaError.ParseJSONError
            }
            
            guard let dicts = array as? [[String: Any]] else {
                throw RxSwiftMoyaError.ParseJSONError
            }
            
            return Mapper().mapArray(JSONArray: dicts)
        }
    }
}

enum RxSwiftMoyaError: String {
    case ParseJSONError
    case OtherError
}

extension RxSwiftMoyaError: Swift.Error { }

4.创建ViewModel(因为版本不一样,里面的方法调用和别的博文有差别)

import Foundation
import RxSwift
import Moya

class ViewModel {
    private let provider = MoyaProvider()
    func getPosts() -> Observable<[MoyaModel]> {
        return provider.rx.request(.Show).filterSuccessfulStatusCodes().mapJSON().asObservable().mapArray(type: MoyaModel.self)
    }

    func createPost(title: String, body: String, userId: Int) -> Observable {
        return provider.rx.request(.Create(title: title, body: body, userId: userId)).mapJSON().asObservable().mapObject(type: MoyaModel.self)
    }
}

5.简单使用

class ViewController: UIViewController {
    
    let viewModel = ViewModel()
    var model : MoyaModel?

    override func viewDidLoad() {
        super.viewDidLoad()
        
        viewModel.getPosts().subscribe(onNext: { (modelArr) in
            self.model = modelArr[0]
            print(modelArr[0].title)
            print(modelArr[0].id)
            print(modelArr[0].userId)
        }, onError: { (error) in
            print(error)
        }, onCompleted: {
            print("完成")
        }) {
            print("结束")
        }
    }
}

你可能感兴趣的:(Swfit 网络请求 : Moya+RxSwift+ObjectMapper (MVVM))