您的位置:首页 > 移动开发 > Swift

moya+RxSwift+HandyJSON 学习

2017-08-03 10:34 447 查看
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<T: HandyJSON>(_ type: T.Type) -> Observable<T> {
return flatMap { response -> Observable<T> in
return Observable.just(try response.mapModel(T.self))
}
}
}

extension Response {
func mapModel<T: HandyJSON>(_ type: T.Type) throws -> T {

let jsonString = String.init(data: data, encoding: .utf8)
guard let object = JSONDeserializer<T>.deserializeFrom(json: jsonString) else {
throw MoyaError.jsonMapping(self)
}
return object
}
}

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

3.下边就可以发送一个简单的网络请求了:
class BTLDiscoveryViewController: BTLBaseViewController {

let provider = RxMoyaProvider<BTLDiscoveryApiService>()

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.
}
*/

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: