Swift开发进阶Swift

RxSwift 深入浅出(七)网络封装

2018-08-25  本文已影响145人  Cooci_和谐学习_不急不躁

RxSwift 这个框架看我就够了,这一篇我重点介绍RxSwift对网络层的封装。搞RxSwift,我是认真的

RxSwift 宝图镇博,咔咔点赞~~~~

Rxswift

对于一个强大的框架,肯定不会放过繁重网络层的编写对开发者造成的伤害

import UIKit
import RxCocoa
import RxSwift

class RxSwiftNetVC: UIViewController{

    let surStr = "https://www.douban.com/j/app/radio/channels"
    let disposeB = DisposeBag()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.done, target: self, action: #selector(pushNewSearchVC))
        self.title = "RxNetworkDemo";
        self.view.backgroundColor = UIColor.orange
     
        testResponse()
        testData()
        testJson()
    }
    
    func testResponse(){
        
        let url = URL(string:surStr)
        
        URLSession.shared.rx.response(request: URLRequest(url: url!))
            .subscribe(onNext: { (response,data) in
                print("***************response******************")
                
                print("response == \(response) \n data = \(data)")
            }, onError: { (error) in
                print(error)
            })
            .disposed(by: disposeB)
    }
    
    func testData(){
        
        let url = URL(string:surStr)
        URLSession.shared.rx.data(request: URLRequest(url: url!))
            .subscribe(onNext: { (data) in
                print("***************data******************")
                print("data = \(data)")
            }, onError: { (error) in
                print(error)
            })
            .disposed(by: disposeB)
    }
    
    
    func testJson(){
        
        let url = URL(string:surStr)
        URLSession.shared.rx.json(url: url!)
            .subscribe(onNext: { (jsonData) in
                print("***************jsonData******************")
                print("jsonData = \(jsonData)")
            }, onError: { (error) in
                print(error)
            })
            .disposed(by: disposeB)
    }

    @objc func pushNewSearchVC(){
        self.navigationController?.pushViewController(RxSwiftNetVC(), animated: true)
    }

}

看着使用贼轻便,贼简单,是不是感觉会上瘾,下面我们来看看源码

public func response(request: URLRequest) -> Observable<(response: HTTPURLResponse, data: Data)> {
        return Observable.create { observer in

            // smart compiler should be able to optimize this out
            let d: Date?

            if Logging.URLRequests(request) {
                d = Date()
            }
            else {
               d = nil
            }

            let task = self.base.dataTask(with: request) { (data, response, error) in

                if Logging.URLRequests(request) {
                    let interval = Date().timeIntervalSince(d ?? Date())
                    print(convertURLRequestToCurlCommand(request))
                    #if os(Linux)
                        print(convertResponseToString(response, error.flatMap { $0 as? NSError }, interval))
                    #else
                        print(convertResponseToString(response, error.map { $0 as NSError }, interval))
                    #endif
                }
                
                guard let response = response, let data = data else {
                    observer.on(.error(error ?? RxCocoaURLError.unknown))
                    return
                }

                guard let httpResponse = response as? HTTPURLResponse else {
                    observer.on(.error(RxCocoaURLError.nonHTTPResponse(response: response)))
                    return
                }

                observer.on(.next((httpResponse, data)))
                observer.on(.completed)
            }

            task.resume()

            return Disposables.create(with: task.cancel)
        }
    }

惊叹,牛逼,对URLSession做了分类处理,封装了一套request,task

public func data(request: URLRequest) -> Observable<Data> {
        return response(request: request).map { pair -> Data in
            if 200 ..< 300 ~= pair.0.statusCode {
                return pair.1
            }
            else {
                throw RxCocoaURLError.httpRequestFailed(response: pair.0, data: pair.1)
            }
        }
    }

就是对response方法的封装

    public func json(request: URLRequest, options: JSONSerialization.ReadingOptions = []) -> Observable<Any> {
        return data(request: request).map { (data) -> Any in
            do {
                return try JSONSerialization.jsonObject(with: data, options: options)
            } catch let error {
                throw RxCocoaURLError.deserializationError(error: error)
            }
        }
    }

就是对data方法的封装

上一篇下一篇

猜你喜欢

热点阅读