美文网首页程序员RxSwift
Swift - RxSwift的使用详解17(特征序列1:Sin

Swift - RxSwift的使用详解17(特征序列1:Sin

作者: 八级大狂风AM | 来源:发表于2018-03-20 09:20 被阅读1792次

    通过之前的一系列文章,关于可被观察的序列(Observable)我们应该都了解的查不多了。 除了ObservableRxSwift 还为我们提供了一些特征序列(Traits):SingleCompletableMaybeDriverControlEvent

    我们可以将这些 Traits 看作是 Observable 的另外一个版本。它们之间的区别是:

    • Observable 是能够用于任何上下文环境的通用序列。
    • Traits 可以帮助我们更准确的描述序列。同时它们还为我们提供上下文含义、语法糖,让我们能够用更加优雅的方式书写代码。

    一、Single

    1,基本介绍

    SingleObservable 的另外一个版本。但它不像 Observable 可以发出多个元素,它要么只能发出一个元素,要么产生一个 error 事件。

    • 发出一个元素,或一个 error 事件
    • 不会共享状态变化

    2,应用场景

    Single 比较常见的例子就是执行 HTTP 请求,然后返回一个应答或错误。不过我们也可以用 Single 来描述任何只有一个元素的序列。

    3,SingleEvent

    为方便使用,RxSwift 还为 Single 订阅提供了一个枚举(SingleEvent):

    • .success:里面包含该Single的一个元素值
    • .error:用于包含错误
    public enum SingleEvent<Element> {
        case success(Element)
        case error(Swift.Error)
    }
    

    4,使用样例

    (1)创建 Single 和创建 Observable 非常相似。下面代码我们定义一个用于生成网络请求 Single 的函数:

    //获取豆瓣某频道下的歌曲信息
    func getPlaylist(_ channel: String) -> Single<[String: Any]> {
        return Single<[String: Any]>.create { single in
            let url = "https://douban.fm/j/mine/playlist?"
                + "type=n&channel=\(channel)&from=mainsite"
            let task = URLSession.shared.dataTask(with: URL(string: url)!) { data, _, error in
                if let error = error {
                    single(.error(error))
                    return
                }
                 
                guard let data = data,
                    let json = try? JSONSerialization.jsonObject(with: data,
                                                                 options: .mutableLeaves),
                    let result = json as? [String: Any] else {
                        single(.error(DataError.cantParseJSON))
                        return
                }
                 
                single(.success(result))
            }
             
            task.resume()
             
            return Disposables.create { task.cancel() }
        }
    }
     
    //与数据相关的错误类型
    enum DataError: Error {
        case cantParseJSON
    }
    

    (2)接着我们可以使用如下方式使用这个 Single

    import UIKit
    import RxSwift
    import RxCocoa
     
    class ViewController: UIViewController {
        let disposeBag = DisposeBag()
         
        override func viewDidLoad() {
            //获取第0个频道的歌曲信息
            getPlaylist("0")
                .subscribe { event in
                    switch event {
                    case .success(let json):
                        print("JSON结果: ", json)
                    case .error(let error):
                        print("发生错误: ", error)
                    }
                }
                .disposed(by: disposeBag)
        }
    }
    

    (3)也可以使用 subscribe(onSuccess:onError:)这种方式:

    import UIKit
    import RxSwift
    import RxCocoa
     
    class ViewController: UIViewController {
        let disposeBag = DisposeBag()
         
        override func viewDidLoad() {
            //获取第0个频道的歌曲信息
            getPlaylist("0")
                .subscribe(onSuccess: { json in
                    print("JSON结果: ", json)
                }, onError: { error in
                    print("发生错误: ", error)
                })
                .disposed(by: disposeBag)
        }
    }
    

    (4)运行结果如下:

    5,asSingle()

    (1)我们可以通过调用 Observable 序列的.asSingle()方法,将它转换为 Single

    let disposeBag = DisposeBag()
     
    Observable.of("1")
        .asSingle()
        .subscribe({ print($0) })
        .disposed(by: disposeBag)
    

    (2)运行结果如下:

    二、Completable

    1,基本介绍

    CompletableObservable 的另外一个版本。不像 Observable 可以发出多个元素,它要么只能产生一个 completed 事件,要么产生一个 error 事件。

    • 不会发出任何元素
    • 只会发出一个 completed 事件或者一个 error 事件
    • 不会共享状态变化

    2,应用场景

    CompletableObservable<Void> 有点类似。适用于那些只关心任务是否完成,而不需要在意任务返回值的情况。比如:在程序退出时将一些数据缓存到本地文件,供下次启动时加载。像这种情况我们只关心缓存是否成功。

    3,CompletableEvent

    为方便使用,RxSwiftCompletable 订阅提供了一个枚举(CompletableEvent):

    • .completed:用于产生完成事件
    • .error:用于产生一个错误
    public enum CompletableEvent {
        case error(Swift.Error)
        case completed
    }
    

    4,使用样例

    (1)创建 Completable 和创建 Observable 非常相似。下面代码我们使用 Completable 来模拟一个数据缓存本地的操作:

    //将数据缓存到本地
    func cacheLocally() -> Completable {
        return Completable.create { completable in
            //将数据缓存到本地(这里掠过具体的业务代码,随机成功或失败)
            let success = (arc4random() % 2 == 0)
             
            guard success else {
                completable(.error(CacheError.failedCaching))
                return Disposables.create {}
            }
             
            completable(.completed)
            return Disposables.create {}
        }
    }
     
    //与缓存相关的错误类型
    enum CacheError: Error {
        case failedCaching
    }
    

    (2)接着我们可以使用如下方式使用这个 Completable

    cacheLocally()
        .subscribe { completable in
            switch completable {
            case .completed:
                print("保存成功!")
            case .error(let error):
                print("保存失败: \(error.localizedDescription)")
            }
        }
        .disposed(by: disposeBag)
    

    (3)也可以使用 subscribe(onCompleted:onError:) 这种方式:

    cacheLocally()
        .subscribe(onCompleted: {
             print("保存成功!")
        }, onError: { error in
            print("保存失败: \(error.localizedDescription)")
        })
        .disposed(by: disposeBag)
    

    (4)运行结果如下(失败的情况):

    三、Maybe

    1,基本介绍

    Maybe 同样是 Observable 的另外一个版本。它介于 SingleCompletable 之间,它要么只能发出一个元素,要么产生一个 completed 事件,要么产生一个 error 事件。

    • 发出一个元素、或者一个 completed 事件、或者一个 error 事件
    • 不会共享状态变化

    2,应用场景

    Maybe 适合那种可能需要发出一个元素,又可能不需要发出的情况。

    3,MaybeEvent

    为方便使用,RxSwiftMaybe 订阅提供了一个枚举(MaybeEvent):

    • .success:里包含该 Maybe 的一个元素值
    • .completed:用于产生完成事件
    • .error:用于产生一个错误
    public enum MaybeEvent<Element> {
        case success(Element)
        case error(Swift.Error)
        case completed
    }
    

    4,使用样例

    (1)创建 Maybe 和创建 Observable 同样非常相似:

    func generateString() -> Maybe<String> {
        return Maybe<String>.create { maybe in
             
            //成功并发出一个元素
            maybe(.success("hangge.com"))
             
            //成功但不发出任何元素
            maybe(.completed)
             
            //失败
            //maybe(.error(StringError.failedGenerate))
             
            return Disposables.create {}
        }
    }
     
    //与缓存相关的错误类型
    enum StringError: Error {
        case failedGenerate
    }
    

    (2)接着我们可以使用如下方式使用这个 Maybe

    generateString()
        .subscribe { maybe in
            switch maybe {
            case .success(let element):
                print("执行完毕,并获得元素:\(element)")
            case .completed:
                print("执行完毕,且没有任何元素。")
            case .error(let error):
                print("执行失败: \(error.localizedDescription)")
       
            }
        }
        .disposed(by: disposeBag)
    

    (3)也可以使用 subscribe(onSuccess:onCompleted:onError:) 这种方式:

    generateString()
        .subscribe(onSuccess: { element in
            print("执行完毕,并获得元素:\(element)")
        },
                   onError: { error in
                    print("执行失败: \(error.localizedDescription)")
        },
                   onCompleted: {
                    print("执行完毕,且没有任何元素。")
        })
        .disposed(by: disposeBag)
    

    (4)运行结果如下:

    5,asMaybe()

    (1)我们可以通过调用 Observable 序列的 .asMaybe()方法,将它转换为 Maybe

    let disposeBag = DisposeBag()
     
    Observable.of("1")
        .asMaybe()
        .subscribe({ print($0) })
        .disposed(by: disposeBag)
    

    (2)运行结果如下:

    RxSwift使用详解系列
    原文出自:www.hangge.com转载请保留原文链接

    相关文章

      网友评论

        本文标题:Swift - RxSwift的使用详解17(特征序列1:Sin

        本文链接:https://www.haomeiwen.com/subject/lyhjfftx.html