看了一篇文章http://www.tuicool.com/articles/FJ3MFvV ,但是其中使用的是Moya+RxSwift。而且,我百度,google了大半天,看来看去都还是这一篇文章。
但是,我不想在辛苦学习了ReactiveCocoa之后,再去学习RxSwift,所以,仔细研究了源码之后,就有了这篇Moya+ReactiveCocoa。半夜了,也不写的多详细,直接把代码放出来,大家看了之后就明白了。等有时间了,再详细的解说。
首先定义网络请求API枚举
enum RequestAPI {
case login(account: String, pwd: String)
}
然后,此枚举遵守TargetType协议
extension RequestAPI: TargetType {
//网络请求前缀
var baseURL: NSURL {
return NSURL(string: NetHelper.shareInstance.baseUrl)!
}
//网络请求具体的path
var path: String {
switch self {
case .login(account: _, pwd: _):
return "login.thm"
}
}
//网络请求方法。。一般是.POST .GET
var method: ReactiveMoya.Method {
switch self {
default:
return .POST
}
}
//网络请求参数
var parameters: [String : AnyObject]? {
switch self {
case .login(account: let name, pwd: let pwd):
return ["account": name, "passwd": pwd]
}
}
//下面这两个,暂时还不知道什么用
var sampleData: NSData {
return "{}".dataUsingEncoding(NSUTF8StringEncoding)!
}
var multipartBody: [MultipartFormData]? {
return nil
}
}
然后,再定义网络请求的错误类型。我在这里就直接copy对方的源码,不想再仔细写了
enum NetRequestError: ErrorType {
case ORMNoRepresentor
case ORMNotSuccessfulHTTP
case ORMNoData
case ORMCouldNotMakeObjectError
/**
* 业务错误
*/
case ORMBizError(resultCode: Int?, resultMsg: String?)
}
enum BizStatus: String {
case BizSuccess = "1000"
case BizError
}
let RESULT_CODE = "code"
let RESULT_MSG = "msg"
let RESULT_DATA = "info"
在最后,直接是重点。。。。转换成信号
private func resultFromJSON<T where T: Mappable>(jsonData: JSON, classType: T.Type) -> T? {
guard let object = jsonData.dictionaryObject else {
return nil
}
return T(JSON: object)
}
struct NetHelper {
private(set) var baseUrl: String
swift的单例写法
static let shareInstance = NetHelper(url: "www.baidu.com")
隐藏初始化方法
private init(url: String) {
self.baseUrl = url
}
let requestProvider = ReactiveCocoaMoyaProvider<RequestAPI>()
}
extension SignalProducer {
/**
转化成model信号
- parameter type: model类型
- returns: model信号
*/
func mapResponseToObject<T: Mappable>(type: T.Type) -> SignalProducer<T?, NetRequestError> {
//这个地方报黄色警报,不要担心
guard let producer = self as? SignalProducer<ReactiveMoya.Response, ReactiveMoya.Error> else {
return SignalProducer<T?, NetRequestError>(error: NetRequestError.ORMNoRepresentor)
}
let transform: Signal<ReactiveMoya.Response, ReactiveMoya.Error> -> Signal<T?, NetRequestError> = {
responseSignal in
let (resultSignal, resultObserver) = Signal<T?, NetRequestError>.pipe()
responseSignal.observe({ event in
switch event {
case .Next(let response):
guard (200...209) ~= response.statusCode else {
return resultObserver.sendFailed(NetRequestError.ORMNotSuccessfulHTTP)
}
let json = JSON(data: response.data)
guard let code = json[RESULT_CODE].string else {
return resultObserver.sendFailed(.ORMCouldNotMakeObjectError)
}
guard code == BizStatus.BizSuccess.rawValue else {
return resultObserver.sendFailed(NetRequestError.ORMBizError(resultCode: code, resultMsg: json[RESULT_MSG].stringValue))
}
guard let info: JSON = json[RESULT_DATA] else {
return resultObserver.sendFailed(.ORMNoData)
}
if type == CommonInfo.self {
resultObserver.sendNext(resultFromJSON(json, classType: type))
} else {
resultObserver.sendNext(resultFromJSON(info, classType: type))
}
default:
break
}
})
return resultSignal
}
return producer.lift(transform)
}
/**
转换model数组
*/
func mapResponseToObjArray<T: Mappable>(type: T.Type) -> SignalProducer<[T], NetRequestError> {
//这个地方报黄色警报,不要担心
guard let producer = self as? SignalProducer<ReactiveMoya.Response, ReactiveMoya.Error> else {
return SignalProducer<[T], NetRequestError>(error: NetRequestError.ORMNoRepresentor)
}
let transform: Signal<ReactiveMoya.Response, ReactiveMoya.Error> -> Signal<[T], NetRequestError> = { responseSignal in
let (resultSignal, resultObserver) = Signal<[T], NetRequestError>.pipe()
responseSignal.observe({ event in
switch event {
case .Next(let response):
guard (200...209) ~= response.statusCode else {
return resultObserver.sendFailed(NetRequestError.ORMNotSuccessfulHTTP)
}
let json = JSON(data: response.data)
guard let code = json[RESULT_CODE].string else {
return resultObserver.sendFailed(NetRequestError.ORMCouldNotMakeObjectError)
}
guard code == BizStatus.BizSuccess.rawValue else {
return resultObserver.sendFailed(NetRequestError.ORMBizError(resultCode: json[RESULT_CODE].int, resultMsg: json[RESULT_MSG].string))
}
guard let objectsArray = json[RESULT_DATA].array else {
return resultObserver.sendFailed(NetRequestError.ORMNoData)
}
let objects = objectsArray.flatMap({ resultFromJSON($0, classType: type) })
resultObserver.sendNext(objects)
default:
break
}
})
return resultSignal
}
return producer.lift(transform)
}
}
这个是我们网络请求的最外面的一层数据形式
import ObjectMapper
/**
* 定义网络请求基本数据
* 我们的网络请求返回的数据类型一般为
* {
"code": "1000",
"msg": "success"
"info": {
}
}
*/
struct Comminfo {
var info: AnyObject?
var code: String?
var msg: String?
}
extension Comminfo: Mappable {
init?(_ map: Map) {}
mutating func mapping(map: Map) {
info <- map["info"]
code <- map["code"]
msg <- map["msg"]
}
}