RxSwift Firebase RemoteConfig データ取得メモ
Firebase RemoteConfig のデータを取得するためのメモ
メモなので今後も追記予定
Jsonを保存しておいてパースして使う
protocol ViewModelInputs {
var fetchTrigger: PublishSubject<Void> { get }
}
protocol ViewModelOutputs {
var items: Observable<[Item]> { get }
var isLoading: Observable<Bool> { get }
var error: Observable<ActionError> { get }
}
protocol ViewModelType {
var inputs: ViewModelInputs { get }
var outputs: ViewModelOutputs { get }
}
class ViewModel: ViewModelInputs, ViewModelOutputs, ViewModelType {
var inputs: ViewModelInputs { return self }
var outputs: ViewModelOutputs { return self }
// MARK: - Inputs
let fetchTrigger = PublishSubject<Void>()
// MARK: - Outputs
let items: Observable<[Item]>
let isLoading: Observable<Bool>
let error: Observable<ActionError>
// 内部変数
private let status = BehaviorRelay<RemoteConfigFetchStatus>(value: .noFetchYet)
private let itemJson = RemoteConfig.remoteConfig().configValue(forKey: "xxx_json")
private let configAction: Action<(), RemoteConfigFetchStatus>
private let disposeBag = DisposeBag()
init() {
// Actionを定義
self.configAction = Action { _ in
return RemoteConfig.remoteConfig().rx
.fetch(withExpirationDuration: TimeInterval(180), activateFetched: true)
}
// 実行結果をbind
self.configAction.elements
.bind(to: status)
.disposed(by: disposeBag)
// 一時的な変数
let tmpItems = BehaviorRelay<[Item]>(value: [])
// Observableをoutputs変数へ
self.items = tmpItems.asObservable()
self.status
.filter { $0 == RemoteConfigFetchStatus.success } // 接続成功時のみ
.withLatestFrom(Observable.of(itemJson.stringValue)) // データ取得
.filterNil()
.compactMap { $0.data(using: .utf8) }
.compactMap { data in
// Jsonを解析して配列を生成
do {
return try (JSONSerialization.jsonObject(with: data, options: []) as? [[String : Any]])?.compactMap { Item(json: JSON($0)) }
} catch {
return []
}
}
.bind(to: tmpItems)
.disposed(by: disposeBag)
// ローディング 初期値はfalse
self.isLoading = self.configAction.executing.startWith(false)
// エラー
self.error = self.configAction.errors
// 開始
self.fetchTrigger
.bind(to: self.configAction.inputs)
.disposed(by: disposeBag)
}
}
こんなふうにして使う
self.viewModel = ViewModel()
// Firebase Remote Config へ接続
self.viewModel.inputs.fetchTrigger.onNext(())
// FireBase から データを取得してテーブルに表示
self.viewModel.outputs.items.asObservable()
.subscribe(onNext:{ [unowned self] items in
self.items = items
self.tableView.reloadData() // DataSourceもRxにするとさらに楽
}).disposed(by: rx.disposeBag)
// ローディング
self.viewModel.isLoading.asDriver(onErrorJustReturn: false)
.drive(SVProgressHUD.rx.isAnimating())
.disposed(by: rx.disposeBag)
// エラー表示
self.viewModel.outputs.error
.subscribe(onNext: { [unowned self] error in
// アラートとかで表示する
print(error.localizedDescription)
}).disposed(by: rx.disposeBag)
ついでにこんなのを作ってローディング中に表示する
trueで表示、falseで非表示
Actionのexecutingが実行中にtrueを流すのでそのまま表示
import UIKit
import SVProgressHUD
import RxSwift
import RxCocoa
extension Reactive where Base: SVProgressHUD {
static func isAnimating() -> AnyObserver<Bool> {
return AnyObserver { event in
MainScheduler.ensureExecutingOnScheduler()
switch event {
case .next(let value):
if value {
SVProgressHUD.show()
} else {
SVProgressHUD.dismiss()
}
default:
break
}
}
}
}
Author And Source
この問題について(RxSwift Firebase RemoteConfig データ取得メモ), 我々は、より多くの情報をここで見つけました https://qiita.com/katafuchix/items/1abf3205dd4233003dce著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .