給 iOS 開發者的 RxSwift(一)

2021-03-02 Cocoa開發者社區

RxSwift 或許我們都聽說過,但或許只知道 RxSwift 這個單詞,長篇大論關於 RxSwift 的介紹往往使讀者迷失在各種概念當中,卻不知如何讓它大展伸手。或許我們可以換一種姿勢,一些應用場景會讓我們產生共鳴,解決問題的方式由很多,為什麼不找一種最優的呢?RxSwift也許會幫到你。

什麼是 ReactiveX(Reactive Extensions)

An API for asynchronous programming

with observable streams

通過可觀察的流實現異步編程的一種API(不明白?嗯,看完所有的例子再讀一篇)

ReactiveX is more than an API, it's an idea and a breakthrough in programming. It has inspired several other APIs, frameworks, and even programming languages.

ReactiveX 不僅僅是一種 API 那麼簡單,它更是一種編程思想的突破。它已經影響了其他 API,frameworks,以及程式語言。

它無處不在

它是跨平臺的(RxJS,RxJava,RxNET),也就是說掌握 RxSwift 這種思想,學習其他的 Rx 系列的將非常簡單。

先來個總結?還沒開始就總結!

ReactiveX(Reactive Extensions)是通過可觀察的流實現異步編程的一種API,它結合了觀察者模式、迭代器模式和函數式編程的精華。RxSwift 是 ReactiveX 編程思想的一種實現,幾乎每一種語言都會有那麼一個 Rx[xxxx] 框架,比如 RxJava,RxJS 等。Rx 可以概括為:

觀察者模式 Observable:對某些數據流(很廣,可以是一些事件等)進行處理,使其變成可觀察對象(Observable)序列,這樣觀察者(observer)就可以訂閱這些序列;

操作符 Operators:然而對於訂閱者來說(observer)某些選項(items)並不是自己需要的(需要過濾),某些選項(items)需要轉換才能達到自己的目的;

迭代模式 Iterator:這樣集合或者序列中的值就可以進行遍歷了。

調度器 Scheduler:為了提升用戶體驗,或其它目的,有些操作需要放到特定的線程去執行,比如 UI 操作需要放到主線程,這就涉及到了調度器。

所以 Rx 可以這樣概括,Rx = Observables + LINQ + Schedulers,其中 LINQ(Language Integrated Query)語言集成查詢,比如那些操作符號。

先來看個例子:修改用戶暱稱

用戶暱稱必須由3-10個字符組成,用戶名不合法時顯示提示(暱稱由3-10個字符組成),且修改按鈕不可點擊。

func registerRx() {

    let nickNameValid = nickNameTextField.rx.text.orEmpty

        .map { (text) -> Bool in

        let tLength = text.characters.count

        return tLength >= 3 && tLength <= 10

        }

        .share(replay: 1)

    

    nickNameValid

        .bind(to: alertLabel.rx.isHidden)

        .disposed(by: disposeBag)

    

    nickNameValid

        .bind(to: changeButton.rx.isEnabled)

        .disposed(by: disposeBag)

    changeButton.rx.tap

        .subscribe { (next) in

         print("修改暱稱成功!")

        }

        .disposed(by: disposeBag)

}

圖片發自簡書App

知識點說明

安裝 RxSwift 時會安裝 RxSwift(對ReactiveX的實現) 和 RxCocoa(對iOS cocoa 層的實現);

orEmpty:主要使 String? 類型變為 String類型;

map:它屬於 Rx 變換操作中的一種,主要對 Observable 發射的數據應用一個函數,執行某種操作,返回經過函數處理過的 Observable。Observable 可觀察的對象,用來被觀察者(observer)訂閱,這樣observe可以監聽Observable發出的事件;

share(replay: 1):只允許監聽一次;

到這裡,還不了解基本概念?

Observable

Observable 直譯為可觀察的,它在 RxSwift 起到了舉足輕重的作用,在整個 RxSwift 的使用過程中你會經常與它打交道。如果你使用過 RAC ,它如同 Signal 一樣。RxSwift 中關鍵點就是在於如何把普通的數據或者事件變成可觀察的,這樣當某些數據或事件有變化的時候就會通知它的訂閱者。

那如何能夠讓某些數據或事件成為 Observable 呢?

RxSwift 中提供很多種創建 Observable 創建方法。比如:From、never、empty 和 create 等,更多創建方法。訂閱者可以收到 3 個事件,onNext、onError 和 onCompleted,每個 Observable 都應該至少有一個 onError 或 onCompleted 事件,onNext 表示它傳給下一個接收者時的數據流。

func create() {

       let observable = Observable<String>.create { (observer) -> Disposable in

        observer.onNext("Hello Lefe_x, I am here!")

        observer.onCompleted()

            return Disposables.create()

        }

        

        observable.subscribe(onNext: { (text) in

            print(text)

        }, onError: nil, onCompleted: {

            print("complete!")

        }, onDisposed: nil).disposed(by: disposeBag)

    }

Lefe_x 經常刷微博,剛開始時他並不刷微博,別人也不會看到他發的內容(這時他是不可訂閱的)。某天,Lefe_x 想讓自己學到的知識能幫助更多的同學,他就註冊了微博,開始了刷微博之旅(變成了可訂閱的 Observable),這樣別人就可以關注他(訂閱)。慢慢地,越來越多的人開始關注他,這樣當他發微博(事件流)的時候,它的粉絲就可以被提醒(通知訂閱者),這些提醒有不同功能,比如有的是提醒 Lefe_x 發布了新微博,有的提醒微博被轉發了(相當於 onNext、onError 和 onCompleted 事件)。

Operators 操作符

Observable 創建後,可能為了滿足某些需求需要修改它,這時就需要用到操作符。RxSwift 提供了非常多的操作符,當然不必要一一掌握這些操作符,使用的時候查一下即可,當然常見的操作符必須要掌握,比如 map、flatMap 、create 、filter 等。這裡查看更多

再來個例子放鬆下:

這個例子主要把查找數組中的字符串 Lefe_x,並顯示到 Label 上。

override func viewDidLoad() {

    super.viewDidLoad()

    DispatchQueue.global().async {

        self.from()

    }

}

    

func from() {

    Observable.from(["Lefe", "Lefe_x", "lefex", "wsy", "Rx"])

        .subscribeOn(MainScheduler.instance)

        .filter({ (text) -> Bool in

            return text == "Lefe_x"

        })

        .map({ (text) -> String in

            return "我的新浪微博是: " + text

        })

        .subscribe(onNext: { [weak self] (text) in

            self?.nickNameLabel.text = text

        })

        .disposed(by: disposeBag)

}

運行結果為:

呀,這不是前幾天有人寫過的嗎?沒錯,那是前幾天發的一個 #iOS知識小集# ,不過哪裡只是一個總結,沒有詳細的說明。這裡主要說一下調度器 (Scheduler)。

Scheduler 調度器

如果你想給 Observable 操作符鏈添加多線程功能,你可以指定操作符(或者特定的Observable)在特定的調度器(Scheduler)上執行。對於 ReactiveX 中可觀察對象操作符來說,它有時會攜帶一個調度器作為參數,這樣可以指定可觀察對象在哪一個線程中執行。而默認的情況下,某些可觀察對象是在訂閱者訂閱時的那個線程中執行。SubscribeOn 可以改變可觀察對象該在那個調度器中執行。ObserveOn 用來改變給訂閱者發送通知時所在的調度器。這樣就可以使可觀察對象想在那個調度器中執行就在那個調度器中執行,不受約束,而這些細節是不被調用者所關心的。猶如 GCD 一樣,你只管使用,底層線程是咋麼創建的,你不必關心。

參考

相關焦點

  • RxSwift 實戰教程-核心用法
    override func viewDidLoad() {        super.viewDidLoad()    }}另外建立一個RegisterViewModel.swift文件,一個Protocol.swift文件,一個Service.swift文件我們先寫那個比較好呢?
  • TimLiu總結的iOS、mac開源項目及庫 — Edit
    --swiftsoon - 一款倒計時 WatchKit 示例應用。作者從架構的角度,思考如何設計一款完整、通訊高效且性能又好的 WatchKit 擴展應用。該示例學習性非常強。--swiftwatchOS-2-Sampler - 基於 watchOS 2 若干新特性,寫了相應的示例代碼供大家學習、參考。
  • 13歲iOS開發者:Swift開發Sprite Kit遊戲實踐
    本文作者Ajay Venkat是一名年僅13歲的iOS開發者,他非常喜歡用蘋果的Sprite Kit 2D遊戲框架來開發iOS遊戲,在了解到很多同齡孩子也對學習如何使用Sprite Kit來開發iOS遊戲非常感興趣之後,他以自己用Swift語言所開發的一款名為「Space Monkey」的遊戲為例,在Ray Wenderlich上寫下了這篇指南,以下為譯文:
  • [Swift基礎] 麥子學院iOS開發視頻教程從入門到精通
    第一階段:語言基礎和iOS入門1、秒學Swift開發語言,坐標系計算機語言學法2、初始Objective-C3、iOS8 App開發快速入門4、iOS開發語言 swift 2.2基礎第二階段:玩轉界面1、swift2.0-iOS玩轉UIKit2、IOS動畫編程3、IOS多點觸控與手勢識別
  • 盤點開發者最喜愛的Swift技巧
    屈指算來,Swift語言才發布半年左右,卻已深得眾多開發者的青睞,也有了許許多多的學習資源、項目和工具。在本文中,來自objc.io、LinkedIn等各個公司的軟體工程師及資深開發者總結了自己在接觸Swift過程中最喜愛的貼士與技巧,有些技巧即使是很早就入坑Swift的開發者都不知道,不妨一起來了解一下吧。
  • iOS入門基礎
    iOS框架層次 一、從底層到應用層 (一)core os -> core services -> media ->cocoa touch 核心系統->核心服務->媒體服務層->可觸摸層
  • RxSwift 入坑解讀-那些難以理解的細節
    }    .addDisposableTo(disposeBag)所有動作都發生在當前的默認線程observeOn轉換線程到主線程,下面所有的操作都是在主線程中subscribeOn規定動作一開始不是發生在默認線程了,而是在OtherScheduler了。
  • RxSwift的第一印象
    在學習的過程中,我寫了一系列關於我學習響應式編程的經歷的文章,所以經常會被讀者問到一些關於 RxSwift 的問題。慚愧地說,我還從沒有使用RxSwift來編寫一個項目。實際上我還從來沒用過任何語言的 Rx 框架,所以我一直認為,對於那些曾在別的開發環境中有使用Rx經歷的人來說,理解RxSwift是非常容易的。既然如此,我也是時候來嘗試一把了。
  • Apple 在 iOS 13.1 中使用 Swift 開發的應用程式
    /usr/lib/swift/libswiftMetalKit.dylib/usr/lib/swift/libswiftCoreImage.dylib/usr/lib/swift/libswiftObjectiveC.dylib/usr/lib/swift/libswiftVision.dylib/usr/lib/swift/libswiftSpeech.dylib
  • swift語言是什麼?蘋果最新編程swift語言資料
    swift語言是什麼?蘋果最新編程swift語言資料    Swift是Apple在WWDC2014所發布的一門程式語言,用來撰寫OS X和iOS應用程式。在設計Swift時.就有意和Objective-C共存,Objective-C是Apple作業系統在導入Swift前使用的程式語言。
  • 21個高質量的Swift開源iOS App
    在這篇文章中,基於對代碼質量和排名的考量標準,Mybridge AI從900個用Swift編寫的開源APP中甄選了21個項目推薦給開發者(不包括開源庫)。No.20Youtube iOS app clone written in swift 3 (Github Stars: 372 ).
  • 從Java到Swift
    (文中的示例代碼均來自The Swift Programming Language:https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/index.html?
  • 深入理解RxSwift
    nameTextField.rx.text.orEmpty.bind(to: nameSubject).disposed(by: disposeBag)passwordTextField.rx.text.orEmpty.bind(to: passwordSubject).disposed(by: disposeBag)Observable<Bool>.combineLatest
  • iOS 開發者帳號總結
    》的文章,主要總結了不同開發者帳號之間的區別,以及一些帳號管理和選擇上的建議。簡述iOS開發在國內已經發展好幾年了,在進行iOS開發之前必不可少的一件事,就是申請開發者帳號。申請開發者帳號後,就可以進入開發者中心下載Xcode編譯器,並且配置開發者證書進行真機測試來調試項目。在程序開發完成後,就可以進行項目打包並發布上線到AppStore了,而這些步驟都是需要開發者帳號的。
  • iOS面試題-Swift篇
    ("didSet", oldValue, title) }}swift 為什麼將 String,Array,Dictionary設計為值類型?swift 的初始化方法,更加嚴格和準確, swift初始化方法需要保證所有的非optional的成員變量都完成初始化, 同時 swfit 新增了convenience和 required兩個修飾初始化器的關鍵字比較 Swift和OC中的 protocol 有什麼不同?
  • iOS代碼掃描從放棄到入門
    imageinfer + sonar-swift基於上面失敗方案一度想放棄,但是無意中在社區中,看到了好未來開源的iOS代碼掃描的帖子"我們開源了一款SonarQube iOS代碼掃描插件github地址:https://github.com/tal-tech/sonar-swift簡單看了一下需要工具,需要infer、xcpretty、sonar、sonar-swift插件.
  • Swift語言入門視頻教程:簡介及開發環境搭建
    蘋果公司在今年的WWDC大會上發布了全新程式語言Swift,Swift語言的發布對於開發者們,尤其是iOS開發者們來說確實是蘋果開發者大會的一大亮點。我們可以預想到未來的iOS開發招聘信息很可能會變成「招聘iOS程式設計師,要求擁有5年的Swift語言開發經驗」。
  • 淺談 swiftinterface 文件
    interface 文件介紹上一節說到,打開 Build Libraries for Distribution 這個選項本質上是增加兩個 swiftc 的編譯參數:-enable-library-evolution 和 -emit-module-interface-path。
  • ios越獄已成過去式,ios籤名將迎來新轉機
    ios越獄已成過去式,ios籤名將迎來新轉機 作為一個ios系統的資深玩家,能夠通過越獄的方式對自己的機器自由定製是無可厚非的,相信必然也有一定的防禦手段去避免被惡意程序攻擊。但這畢竟是非常小的一部分人,對於絕大部分的人來說,本身就缺乏對程序的編寫以及必要的安全意識,越獄的事情幾乎是不可能的。