moya+RxSwift+HandyJSON 学习

Moya是对 Alamofire的进一步封装,项目中准备着手使用moya来实现网络请求,使用moya简化了网络请求,简洁明了,方便维护,同时提供便利的单元测试入口,在swift中使用这个网络请求是一个不错的选择。

首先使用pod 导入moya,RxSwift,HandyJosn库
#将json数据转化成model
pod "HandyJSON",     '~> 1.6.1'

#moya 对Alamofire 进行一次的封装
pod "Moya", '~> 8.0.5'

pod 'Moya/RxSwift'

#Swift函数响应式编程的一个开源库
pod "RxSwift", '~> 3.6.1'

1.定义一个枚举类型遵循targetType协议
  协议里的方法有:
public protocol TargetType {

    /// The target's base `URL`.
    var baseURL: URL { get }

    /// The path to be appended to `baseURL` to form the full `URL`.
    var path: String { get }

    /// The HTTP method used in the request.
    var method: Moya.Method { get }

    /// The parameters to be encoded in the request.
    var parameters: [String: Any]? { get }

    /// The method used for parameter encoding.
    var parameterEncoding: ParameterEncoding { get }

    /// Provides stub data for use in testing.
    var sampleData: Data { get }

    /// The type of HTTP task to be performed.
    var task: Task { get }

    /// Whether or not to perform Alamofire validation. Defaults to `false`.
    var validate: Bool { get }
}
举个列子说明下:
enum BTLDiscoveryApiService {
    case loadHomePageData(AnyObject)
}

extension BTLDiscoveryApiService:TargetType {
    
    var baseURL: URL {
        return URL.init(string: BTLApiConfigMacro.API_Default_ServerAddress)!
    }
    
    var path: String {
        return ""
    }
    
    var method: Moya.Method {
        switch self {
            case .loadHomePageData(_):
            return .get
        }
    }
    
    var parameters: [String: Any]? {
        switch self {
            case .loadHomePageData(let reqMod):
                 let reqMod = reqMod as! BTLDiscoveryReqMod
                 return [BTLApiConfigMacro.API_Request_Key:reqMod.toJSONString()!]
        }
    }
    
    var parameterEncoding: ParameterEncoding {
        return URLEncoding.default
    }
    
    var sampleData: Data {
        return "".data(using: String.Encoding.utf8)!
    }
    
    var task: Task {
        return .request
    }
    
    var validate: Bool {
        return false
    }
}
1.新建请求model继承HandyJson
class BTLBaseReqModel: HandyJSON {
    /** 手机唯一标识符 */
    var imei:String?
  
    required init() {
        imei = "test"
    }
}
class BTLDiscoveryReqMod: BTLBaseReqModel {
    var productCode:String?
    required init() {
        super.init()
    }
}
请求返回数据model
class BTLBaseResModel: HandyJSON {
    
    /** 响应状态    200成功,其他失败 */
    var status:NSInteger?
    
    /** 建议的错误消息 */
    var message:String?
    
    /** 弹出窗的错误消息 级别重要 */
    var dialogMessage:String?
    
    /** 弹出窗的标题消息 */
    var dialogTitle:String?
    
    /** 响应消息编码 */
    var code:String?
    
    /** 登录信息token 如有值,则置换新的token */
    var token:String?
    
    /** 接口响应的时间戳 */
    var timestamp:String?
    
    required init() {
        
    }
}

class BTLDiscoveryResMod: BTLBaseResModel {
    
    var productId:String?
    var productName:String?
    required init() {
        
    }
}
2.为了将网络请求返回的数据直接转化成model,写了一个modelTool扩展.
extension ObservableType where E == Response {
    public func mapModel(_ type: T.Type) -> Observable {
        return flatMap { response -> Observable in
            return Observable.just(try response.mapModel(T.self))
        }
    }
}

extension Response {
    func mapModel(_ type: T.Type) throws -> T {
        
        let jsonString = String.init(data: data, encoding: .utf8)
        guard let object = JSONDeserializer.deserializeFrom(json: jsonString) else {
            throw MoyaError.jsonMapping(self)
        }
        return object
    }
}

注:JSONDeserializer.deserializeFrom(json: jsonString),这里使用的就是handyJson方法来实现将json格式数据转化成目标model


3.下边就可以发送一个简单的网络请求了:
class BTLDiscoveryViewController: BTLBaseViewController {
    
    let provider = RxMoyaProvider()
    
    let dispose = DisposeBag()

  
    override func viewDidLoad() {
        super.viewDidLoad()
        
        loadData()
    }
    
    
    func loadData() {
        let reqMod:BTLDiscoveryReqMod = BTLDiscoveryReqMod()
        reqMod.productCode = "080300105127"
        provider.request(.loadHomePageData(reqMod)).mapModel(BTLDiscoveryResMod.self).subscribe(onNext: { (model) in
            
            
        }, onError: { (error) in
            
        }, onCompleted: { 
            
        }) { 
            
        }.addDisposableTo(dispose)
        
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    

    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // Get the new view controller using segue.destinationViewController.
        // Pass the selected object to the new view controller.
    }
    */

}




你可能感兴趣的:(iOS)