#概要
最近RxSwiftを勉強し始めて現在理解していることを備忘録として残せたらいいなと思い記事にします。
そもそもRxSwiftのRxとは
Rx(Reactive X)とは、「オブザーバパターン」「イテレータパターン」「関数型プログラミング」の概念を実装している拡張ライブラリです。
Rxを導入するメリットは、「値の変化を検知できる」「非同期の処理を簡潔に書ける」ということに尽きると思います。 値の変化というのは変数値の変化やUIの変化も含まれます。 例えばボタンをタッチする、という動作もボタンのステータスが変わったと捉えることができRxを使って記述することができます。
とのことです。
詳しくは以下のサイトを参照してください。
入門!RxSwift
RxSwiftについてようやく理解できてきたのでまとめることにした(1)
###今回使用するライブラリ
RxSwift pod 'RxSwift'
--- ObservableなどのRx系の本領的なものを使うのに必要
RxCocoa pod 'RxCocoa'
--- UIKitでRxを使うのに必要
RxDataSources pod 'RxDataSources'
--- tableViewなどのdatasourceの扱いを楽にしてくれる
Firestore pod 'Firebase/Firestore'
--- todoの保存をするのに必要
以上のライブラリを使用していきます。
認証機能は?と思われたかもしれないですが今回は省かせていただきます。
また、今回の記事はfirebaseやpodは導入済みのものとして話を進めさせていただきます。
#StoreManager
まずはこのアプリのもっとも重要なTodoの追加や取得の処理を書いていきます。
StoreManager
という名前のファイルを作ってください。
import Foundation
import FirebaseFirestore
import RxSwift
class StoreManager {
static let shared = StoreManager()
private let store = Firestore.firestore()
}
こんな感じで定義してください。
ここは説明するまでもないと思うので説明を省略します。
次にTodo
を保存する関数を作ります。
extension
で拡張すると可読性が上がるので拡張します。
extension StoreManager {
// firestore にtodoのデータを保存
func insertTodoToFireStore(title: String, detail: String) {
let data: [String: Any] = [
"title": title,
"detail": detail,
"createdAt": Timestamp()
]
store.collection("todos").addDocument(data: data)
}
}
ここも特に説明はいらないと思いますは簡単に説明しておきます。
title
,detail
を受け取り[String: Any]
型のDictionary
にして各値を格納します。そして、todos
というコレクション名のコレクションにデータを保存します。
次にデータを取得する関数を作ります。
// firestore からtodosのデータ取得
func fetchTodosFromFirestore() -> Single<[TodoModel]> {
Single.create { [weak self](single) -> Disposable in
self?.store.collection("todos").getDocuments { (snapshots, error) in
guard let docs = snapshots?.documents, error == nil else {
single(.failure(CustomError.error(message: "Failed To Fetch Todos From Firestore")))
return
}
let todos = docs.map { TodoModel(data: $0.data()) }
single(.success(todos))
}
return Disposables.create()
}
}
ここがこのクラスのキモですね。
戻り値にSingle<[TodoModel]>
とありますね。
Single
はRxSwiftをインポートしていないと使えないので忘れないでください。
また、現時点ではTodoModel
というものが定義されていないのでエラーになると思いますが気になる人はとりあえずTodoModelを定義しておいてください。
Single
について説明していきます。
Single
はSuccessとErrorを流し、Completedを流さないものになります。
successとはnextを一回だけ流れるものでerrorはそのままですね。
ほーという感じだと思いますがcomplete処理がいらなかったらSingleを使うという感じでいいんじゃないでしょうか。
Singleの他にもMaybe、Completableがあります。
詳しいことは以下の記事を参照してください。
RxSwift 3.3.0で追加された3つのUnit(Single, Maybe, Completable)
次にguard let文
の中でエラー処理を書いています。
ここは説明なしでもわかると思います。
そして、取得した値をTodoModel
に加工してsuccess
で流してあげます。
最後にDisposables.create()
ですが、これはストリームのライフサイクルを管理するためのものです。
disposeされたときに、ここに書いた処理が実行されます。
Disposable
について
#TodoModel
先ほど飛ばしたTodoModel
はこんな感じで書きます。
import Foundation
import FirebaseFirestore
struct TodoModel {
let title: String
let detail: String
let createdAt: Timestamp
init(data: [String: Any]) {
title = data["title"] as? String ?? ""
detail = data["detail"] as? String ?? ""
createdAt = data["createdAt"] as? Timestamp ?? Timestamp()
}
}
#最後に
part1はここまでになります。
正直まだ理解しきれていないこともあり、調べながらになりますが理解できているところとあまり理解できていないとこがわかってoutputって大切だなと思いました。
また、あまり理解できずに書いてしまっているところや誤解釈してしまっているところがありましたらご指摘の方お願いいたします。
[part2]はViewModelの作成をしていきます。
TodoAPPでRxSwift入門[part2]