初探RxSwift

demo鏈接

根據(jù)自己對RxSwift的理解寫了一個登陸以及驗證碼倒計時

Observer

一個可以被觀察的對象被觀察者監(jiān)聽

Observerable

觀察者 產(chǎn)生信號推送給訂閱者

/// A type-erased `ObservableType`. 
///
/// It represents a push style sequence.
public class Observable<Element> : ObservableType {

登陸業(yè)務(wù)的整體處理邏輯為

整個業(yè)務(wù)處理流程為 創(chuàng)建 (賬號密碼輸入框文字改變)的觀察者 ---》 發(fā)送響應(yīng)信號 ---》 篩選并合并響應(yīng)信號 ===》 訂閱收到相應(yīng)信號并處理

首先創(chuàng)建賬號文字改變和密碼文字改變的觀察者 然后通過這個序列得到一個新的賬號密碼是否符合規(guī)范的序列輸入框改變后通知accontobseque響應(yīng) 最后將兩個序列信號合并條件符合后再通知loginobserver(Observer)進行響應(yīng)的ui處理

  ///
        let inputaccontObserVerable = accontTextField.rx.text
        let inputpasswordObserVerable = passwordTextField.rx.text
 /**
         Returns an observable sequence that **shares a single subscription to the underlying sequence**, and immediately upon subscription replays  elements in buffer.

         This operator is equivalent to:
         * `.whileConnected`
         ```
         // Each connection will have it's own subject instance to store replay events.
         // Connections will be isolated from each another.
         source.multicast(makeSubject: { Replay.create(bufferSize: replay) }).refCount()
         ```
         * `.forever`
         ```
         // One subject will store replay events for all connections to source.
         // Connections won't be isolated from each another.
         source.multicast(Replay.create(bufferSize: replay)).refCount()
         ```

         It uses optimized versions of the operators for most common operations.

         - parameter replay: Maximum element count of the replay buffer.
         - parameter scope: Lifetime scope of sharing subject. For more information see `SubjectLifetimeScope` enum.

         - seealso: [shareReplay operator on reactivex.io](http://reactivex.io/documentation/operators/replay.html)

         - returns: An observable sequence that contains the elements of a sequence produced by multicasting the source sequence.
         */

//        shareReplay 會返回一個新的事件序列藤肢,它監(jiān)聽底層序列的事件饮潦,并且通知自己的訂閱者們。
//        解決有多個訂閱者的情況下,map會被執(zhí)行多次的問題轧粟。

          // 返回一個可觀察序列遭庶,該序列**共享對基礎(chǔ)序列**的單個訂閱蟆技,并在訂閱后立即在緩沖區(qū)中重播元素加缘。

          //參數(shù)replay:重放緩沖區(qū)的最大元素計數(shù)。
      //  public func share(replay: Int = default, scope: RxSwift.SubjectLifetimeScope = default) -> RxSwift.Observable<Self.E>
        let accontobseque = inputaccontObserVerable.share(replay: 1).map {
            return $0!.count == 11
        }

        /// 返回一個可觀察的序列 比如 輸入的信號為 1霹娄,12能犯,123 那么將這個信號轉(zhuǎn)換為 false,false犬耻,false踩晶,具體可以根據(jù)業(yè)務(wù)需求來
        let passwordseque = inputpasswordObserVerable.share(replay: 1).map {
            return $0!.count == 6
        }

  //返回username和password組合后的流
        let _ = Observable.combineLatest(accont.asObservable(), password.asObservable()) {
            return ($0, $1)
            }.bind(to: loginobserver)

extension LoginViewController {

    /// 被觀察者 loginobserver
    private var loginobserver: AnyObserver<Bool> {
        return AnyObserver.init(eventHandler: { [weak self] (event) in
            if let canlogin = event.element {
                self?.loginBtn.backgroundColor = canlogin ?  UIColor.red:UIColor.gray
            }
        }).asObserver()
    }

ui邏輯整理好后處理業(yè)務(wù)邏輯新建一個LoginViewmodel

初始化方法為

 convenience  init(vc: LoginViewController) {
        self.init()
        self.ctr = vc
        setUpBindSignal()
    }

實現(xiàn)業(yè)務(wù)與界面的雙向綁定

    var accont: Driver<String?>!
    var password: Driver<String?>!
    var msmcode: Driver<String>!
    let msmhaviorsubject = BehaviorSubject<String>.init(value: "")
    
    private func setUpBindSignal() {
        accont = (ctr.accontTextField.rx.text).asDriver()
        password = (ctr.passwordTextField.rx.text).asDriver()
        let _ = msmhaviorsubject.asDriver(onErrorJustReturn: "").drive(ctr.msmlab.rx.text) 
    }

當點擊登錄方法后合并賬號和密碼信息通過flatmaplatest返回一個觀察者對象等到完成后通知綁定的業(yè)務(wù)邏輯進行登錄處理

 //返回username和password組合后的流
        let _ = Observable.combineLatest(accont.asObservable(), password.asObservable()) {
            return ($0, $1)
            }.flatMapLatest { (arg0) -> Observable<Loginmodel> in
                let (user, pass) = arg0
                debugPrint("用戶名:\(user!) 密碼:\(pass!)")
                return self.client.login(accont: user!, password: pass!)
            }.bind(to: ctr.finishbserver)

extension LoginViewController {
    var finishbserver: AnyObserver<Loginmodel> {
        return AnyObserver.init(eventHandler: { [weak self] (event) in
            if let loginmodel = event.element {
                self?.loginstatusLab.text = loginmodel.username
            }
        }).asObserver()
    }
}

網(wǎng)絡(luò)請求層處理到此一個完整的登錄和結(jié)果展示就成功了還有一個短信驗證碼倒計時實現(xiàn)了與界面的綁定。

class NetClient: NSObject {

    func login(accont: String,password: String) -> Observable<Loginmodel> {
        return Observable<Loginmodel>.create({ (event) -> Disposable in
             sleep(2)

            let loginmodel = Loginmodel()
            loginmodel.status = "登錄成功"
            loginmodel.username = "紅鯉魚與綠鯉魚與驢"

            /// 直接向訂閱者發(fā)送信號
            event.on(Event.next(loginmodel))
            event.on(Event.completed)

            //event.onNext(<#T##element: Loginmodel##Loginmodel#>)
            //event.onError(<#T##error: Error##Error#>)
            //event.onCompleted()
            /// 訂閱next信號 和 err信號 還有完成信號 并進行不同的處理
            ///訂閱方法為 subsrcir(onnext...,onerror:....,oncomplete:...,ondisponse:.... )

            ///subscribe(onNext: <#T##((Loginmodel) -> Void)?##((Loginmodel) -> Void)?##(Loginmodel) -> Void#>, onError: <#T##((Error) -> Void)?##((Error) -> Void)?##(Error) -> Void#>, onCompleted: <#T##(() -> Void)?##(() -> Void)?##() -> Void#>, onDisposed: <#T##(() -> Void)?##(() -> Void)?##() -> Void#>)
            return Disposables.create {

            }
        })
    }
}

map

這個方法跟數(shù)組自帶的api一樣map遍歷一個數(shù)組通過transform處理這個數(shù)組并得到一個期望返回值的數(shù)組例如
var arr = [1,2,3,4]
let newer = arr.map<Bool>.map {
    /// 處理
}
那么newarr就是一個bool類型的數(shù)組
同理 遍歷這個
public func map<R>(_ transform: @escaping (Self.E) throws -> R) -> RxSwift.Observable<R>

flatmap

flatMap, flatMapLatest 讓觀察者觀察的東西變成動態(tài)的了. 后者是只觀察最后一個值.

   let _ = Observable.combineLatest(accont.asObservable(), password.asObservable()) {
            return ($0, $1)
            }.flatMapLatest { (arg0) -> Observable<Loginmodel> in
                let (user, pass) = arg0
                debugPrint("用戶名:\(user!) 密碼:\(pass!)")
                return self.client.login(accont: user!, password: pass!)
            }.bind(to: ctr.finishbserver)

上述代碼段將用戶名和密碼最后一個值進行和處理生成了一組新的observerable

Driver

driver與observerable在功能上它類似被觀察者(Observable)枕磁,而它本身也可以與轉(zhuǎn)換成被觀察者(Observable: asDriver, Driver: asObservable)渡蜻,他不可以發(fā)送err事件 所以一旦發(fā)生錯誤會有容錯處理(onErrorJustReturn: "")
Driver序列不允許發(fā)出error,
Driver序列的監(jiān)聽只會在主線程中透典。
所以Driver是專為UI綁定量身打造的東西。
以下情況你可以使用Driver替換BindTo:
不能發(fā)出error;
在主線程中監(jiān)聽;
共享事件流;

BehaviorSubject

/// Represents a value that changes over time.
///
/// Observers can subscribe to the subject to receive the last (or initial) value and all subsequent notifications.

他既可以當做觀察者也可以當做被觀察者

具體可以參考Rxswift的subject

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末顿苇,一起剝皮案震驚了整個濱河市峭咒,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌纪岁,老刑警劉巖凑队,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異幔翰,居然都是意外死亡漩氨,警方通過查閱死者的電腦和手機夜牡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進店門铡俐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人似舵,你說我怎么就攤上這事做修』粽” “怎么了?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵饰及,是天一觀的道長蔗坯。 經(jīng)常有香客問我,道長燎含,這世上最難降的妖魔是什么宾濒? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮屏箍,結(jié)果婚禮上绘梦,老公的妹妹穿的比我還像新娘橘忱。我一直安慰自己,他們只是感情好谚咬,可當我...
    茶點故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布鹦付。 她就那樣靜靜地躺著,像睡著了一般择卦。 火紅的嫁衣襯著肌膚如雪敲长。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天秉继,我揣著相機與錄音祈噪,去河邊找鬼。 笑死尚辑,一個胖子當著我的面吹牛辑鲤,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播杠茬,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼月褥,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了瓢喉?” 一聲冷哼從身側(cè)響起宁赤,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎栓票,沒想到半個月后决左,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡走贪,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年佛猛,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片坠狡。...
    茶點故事閱讀 39,834評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡继找,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出逃沿,到底是詐尸還是另有隱情码荔,我是刑警寧澤,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布感挥,位于F島的核電站缩搅,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏触幼。R本人自食惡果不足惜硼瓣,卻給世界環(huán)境...
    茶點故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧堂鲤,春花似錦亿傅、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至半哟,卻和暖如春酬滤,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背寓涨。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工盯串, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人戒良。 一個月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓体捏,卻偏偏與公主長得像,于是被迫代替她去往敵國和親糯崎。 傳聞我的和親對象是個殘疾皇子几缭,可洞房花燭夜當晚...
    茶點故事閱讀 44,779評論 2 354

推薦閱讀更多精彩內(nèi)容