ios多个网络请求之间的处理(Swift版)

2,337 阅读2分钟

前文ios多个网络请求之间的处理(OC版)介绍了OC中对于网络请求的处理。本文浅谈一下RXSwift如何运用在Swift中。才踏入rx的大门,若有不正确的地方,欢迎大家在评论区留言和讨论。共同进步💪。 点击OC版

juejin.cn/post/707889…

前文OC版中介绍的几种方法在swift中同样适用,不过就是替换下API的适用罢了。本文主要介绍RXSwift的使用。

1. 多个网络请求之间顺序执行

eg:这里我们有一个需求:首先通过用户的账号和密码获取到token,然后通过token获取用户的信息。

1.在没使用rx之前我们可能会很容易的写出以下代码

我们先用enum简单封装一个网络请求。日常开发中的网络需求基本山是异步的,这里为了演示rx的使用,就简单的处理了。

private enum API {

    // 闭包的形式
    /// 获取token
    static func token_clourse(userName: String,
                      password: String,
                      completed:(String?,Error?) -> ()) {
        print("userName = \(userName),password = \(password),\(Thread.current)")
        completed("09b123123",nil)
    }

    /// 通过token获取用户信息
    static func userInfo_clourse(token: String,
                         completed:(String?,Error?) -> ()) {
        completed("用户的信息为xxx",nil)
    }
}

然后我们在控制器中进行调用:

//可以看到闭包嵌套非常难看,这仅仅是2个闭包。可想而知随着需求的扩展,闭包的嵌套层次可能越来越多
API.token_clourse(userName: "小白不是小白", password: "123456") { token, error in
            guard let token = token else {
                return
            }
            print("token = \(token)")
            API.userInfo_clourse(token: token) { userInfo, error in
                if let userInfo = userInfo {
                    print("userInfo = \(userInfo)")
                }
            }
        }

看看结果: image.png

2.我们看看使用了rx后的代码:

首先向刚才的API枚举中添加如下代码:

    // RX
    static func token_rx(userName: String,
                      password: String) -> Observable<String> {
        print("userName = \(userName),password = \(password)")
        return Observable.just("09b123123")
    }
    
    static func userInfo_rx(token: String) -> Observable<String> {
        return Observable.just("用户的信息为xxx")
    }

这里的Observable其实对应了Collection中的Sequence。只不过Observable比Sequence多了可以异步或同步发出event事件的能力。具体讲解后续可能会出一期具体文章。

然后我们在控制器中进行调用:

// 这代码量是不是简洁多了,这种函数式编程不仅减少了闭包的嵌套层次,同时让代码阅读起来很舒服
// 控制器中加一句代码:private let disposeBag = DisposeBag() 
// 垃圾袋,用于回收obsever的。将obsever的声明周期交给垃圾袋,当垃圾袋denit后,其中的内容也就被释放了。
API.token_rx(userName: "小白不是小白", password: "123456")
            .flatMapLatest(API.userInfo_rx)
            .subscribe(
                onNext: {
                    print("userInfo = \($0)")
                }
            )
            .disposed(by: disposeBag)

看看结果: image.png

2. 多个网络请求执行完后,在执行其他操作

eg:这里有一个需求:获取到banner的数据和列表的数据后,更新UI。我们看看如何使用rx来完成 同样我们首先向刚才的API枚举中添加如下代码:

// RX

    /// 获取banner的数据
    static func bannerData_rx() -> Observable<[String]> {
        return Observable.just(["banner1","banner2"])
    }

    /// 获取列表的数据
    static func listData_rx() -> Observable<[String]> {
        return Observable.just(["list1","list2"])
    }

然后我们在控制器中进行调用:

// 通过zip操作符,将两个网络请求组装成一个新的可观察序列
Observable
            .zip(
                API.bannerData_rx(),
                API.listData_rx()
            )
            .subscribe(
                onNext: {
                    print("banners = \($0)\nlist = \($1)")
                    DispatchQueue.main.async {
                        print("刷新UI")
                    }
                }
            )
            .disposed(by: disposeBag)

看看结果: image.png