RxSwift学习-- 网络层的搭建

我们平常的网络请求基本步骤
1 发送Request
2 接受 Response
3 jsonmodel (我目前是有这一步的)

1 不利用三方框架的Rx网络层

在实际生产过程中,我们都会使用第三方的网络框架。但为了学习基本流程,我们最好还是实现自己的一套简易框架。

1.1 对URLSession 进行Rx扩展,让他用它Rx的功能

创建URLSession+Rx文件

func response(request: URLRequest) -> Observable<(HTTPURLResponse, Data)> {
        return Observable.create { observable in
            let task = self.base.dataTask(with: request) { (data, response, error) in
                //处理数据
                if let error = error {
                    observable.onError(error)
                    return
                }

                observable.onNext((response as! HTTPURLResponse, data!))
                observable.onCompleted()
            }
            task.resume()
            return Disposables.create(with: task.cancel)
        }
    }

我们拆分来看一下

func response(request: URLRequest) -> Observable<(HTTPURLResponse, Data)> {
        return Observable.create { observable in
      //请求
            return Disposables.create()
        }
    }

这几乎是rx扩展的基本样式,中间加上URLSesson的请求 和 请求之后发送 错误 或者完成信号就可以了。
我们来看一下成果

let request = URLRequest.init(url: URL.init(string: "")!)
let response = URLSession.shared.rx.response(request: request)

response.subscribe(onNext: { (response, data) in
            //数据处理
 }).addDisposableTo(bag)

数据处理这部分也挺恶心了,也应该封装起来
通常数据处理 我们先处理data -> json ,之后json ->model. 事实上 不是所有的VC需要的数据都是model.所以 我们要暴露json 和model 2个接口。供调用者选用

在处理数据之前要确定数据是否有效,根据返回的状态码来判断,
筛选出正常返回的数据

func data(request: URLRequest) -> Observable<Data> {
        return response(request: request).map { (response, data) in
            if 200..<300 ~= response.statusCode {
                return data
            } else {
                throw URLSessionError.failed
            }

        }
    }

json

func json(request: URLRequest) -> Observable<[String: Any]> {
        return data(request: request).map{ data  in
            let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String: Any]

            return json!
        }
    }

model
转化model 这一步 这里我没有自己用原生实现,Swift不支持运行时(不包含继承NSObject的类)这里偷偷的用一下三方吧ObjectMapper(用法 后面介绍)

func model<T: Mappable>(request: URLRequest, model: T.Type) -> Observable<T> {
        return json(request: request).map{ json in
            let object = Mapper<T>().map(JSONObject: json["data"])
            return object!
        }
    }

这里的转model 在实际情况下会出现许多问题。举个例子
商品列表 商品详情
商品详情是单纯的model
商品列表是 model的数组,所以根据不同情况可能还需要一个ModelArray的方法。和model的一样,就不在重复了。
我们到VM中看看我们的战果

let request = URLRequest.init(url: URL.init(string: "")!)
let response = URLSession.shared.rx.model(request: request, model: GoodsDetailModel.self)

response.subscribe(onNext: { model in
            //数据处理
        }).addDisposableTo(bag)

这样我们一个基本的rx 的网络层基本完成了。如果要使用可以放在一个NetWorkingService类 。避免于vm大量的耦合。具体封装方法 就看大家的想法啦。是集约型 还是 分散型,都看自己的喜好了

2 RxMoya

在生产中,强烈推荐RxMoya真的大而全。
这边我们简单的介绍使用方法
首先确定配置文件创建XXAPI.Swift
我随便写一个了

enum GoodsAPI {
    case goodsDetail(goodsID: String)
}

extension GoodsAPI: TargetType {
    var parameterEncoding: ParameterEncoding {
        return URLEncoding.default
    }

    var task: Task {
        return .request
    }

    var path: String {
        return ""
    }

    var base: String {
        return ""
    }

    var baseURL: URL {
        return URL.init(string: base)!
    }

    var parameters: [String: Any]? {
        switch self {
        case .goodsDetail(let id):
            return []
        default:
            return nil
        }
    }

    var method: Moya.Method {
        return .post
    }

    var sampleData: Data {
        return "".data(using: .utf8)!
    }



}

遵循TargetType 实现基本配置
然后在VM中调用

let service = RxMoyaProvider<GoodsAPI>()

    var goodsDetailModel: Observable<GoodsDetailModel> {
        return self.service.request(.goodsDetail(goodsID: "10133")).mapObject(GoodsDetailModel.self)
    }

这样就可以让VM中的model暴露给VC使用了。简单方便

=========
介绍下ObjectMapper的使用
1 遵循 Mappable协议
2 实现协议方法 init 和 mapping
这里的mapping 一定要写映射关系,毕竟没有运行时这种东西了。
注意的是如果返回的Int类型,你用String 是无法接受的(很难受)

struct GoodsDetailModel: Mappable {
    var goodsID: Int?
    var goodsInfo: String?
    var goodsName: String?
    var introduction: String?
    var label: String?
    var tag: String?
    var goodsPic: String?
    var xPrice: String?
    var yPrice: String?
    var number: Int?
    var batchNO: String?
    var activityGoods: Bool?

    init?(map: Map) {

    }

    mutating func mapping(map: Map) {
        goodsID <- map["goodsID"]
        goodsInfo <- map["goodsInfo"]
        goodsName <- map["goodsName"]
        introduction <- map["introduction"]
        label <- map["label"]
        tag <- map["tag"]
        goodsPic <- map["goodsPic"]
        xPrice <- map["xPrice"]
        yPrice <- map["yPrice"]
        number <- map["number"]
        batchNO <- map["batchNO"]
        activityGoods <- map["activityGoods"]
    }

}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 196,200评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,526评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,321评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,601评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,446评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,345评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,753评论 3 387
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,405评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,712评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,743评论 2 314
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,529评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,369评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,770评论 3 300
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,026评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,301评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,732评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,927评论 2 336

推荐阅读更多精彩内容