Firebase Remote Configの機能を共通化した構造体を作ってみた(Swift)
Firebase Remote Configとは
WebでいうGoogleAnalyticsのモバイル版がFirebaseという感じです。GoogleAnalyticsほどさまざまな分析は現状まだできませんが、分析の他にもプッシュ通知(Notification)や、モバイル端末で持っているプロパティをリモートで操作する(RemoteConfig)ことが可能です。表示している色などをクライアントによってランダムに変更するというのもRemoteConfigを利用すると簡単にできます(ABテストですね)。
やりたいこと
ユーザによって表示するコンテンツを変えたい。最新バージョンの人とそうでない人とでコンテンツを変えてみます。
環境
Xcode7.3, Swift2.2
実際にRemote Configを使ってみた
1, コンソールでの設定
まずFirebaseのコンソール画面に行き、Remote Configの設定をしていきます。パラメータを追加をクリックして必要なパラメータを作成します。ここでは最新バージョンをいれているユーザに違う値を渡すようにするため、latestVersionという条件を作成しています。
2, 実装
Podfileに pod 'Firebase/RemoteConfig'
と記入して pod install
とターミナルで実行してFirebaseRemoteConfigをインストールします。
AppDelegate.swift
は最低限以下のようになります。(githubより抜粋)
import UIKit
import Firebase
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// [START configure_firebase]
FIRApp.configure()
// [END configure_firebase]
return true
}
}
ViewController.swift
は以下のようになります。
import UIKit
import Firebase
import FirebaseRemoteConfig
class ViewController: UIViewController {
var remoteConfig: FIRRemoteConfig!
var tabTitles: [String] = ["ヘアアレンジ", "メイク", "スキンケア"]
var tabTitlesEn: [String] = ["hair_arrange", "make", "skin_care"]
override func viewDidLoad() {
super.viewDidLoad()
setTabWithRemoteConfig()
}
...
func setTabWithRemoteConfig() {
// RemoteConfigのシングルトンインスタンス取得
remoteConfig = FIRRemoteConfig.remoteConfig()
// デバッグモードの設定
let remoteConfigSettings = FIRRemoteConfigSettings(developerModeEnabled: true)
remoteConfig.configSettings = remoteConfigSettings!
// 下でデフォルト値を設定しているからこれはなくても問題ない.
// remoteConfig.setDefaults(["tabTitles": "アイテム"])
// remoteConfig.setDefaults(["tabTitlesEn": "item"])
// キャッシュの有効期間
let expirationDuration = remoteConfig.configSettings.isDeveloperModeEnabled ? 0 : 3600
// Firebaseのコンソール画面で設定した値を持ってくる非同期処理
remoteConfig.fetchWithExpirationDuration(NSTimeInterval(expirationDuration)) { [weak self] (status, error) -> Void in
if (status == FIRRemoteConfigFetchStatus.Success) {
self?.remoteConfig.activateFetched()
} else {
print("Config not fetched")
print("Error \(error!.localizedDescription)")
}
// 値を取り出す. ここでデフォルト値も設定.
self?.tabTitles.append(self?.remoteConfig["tabTitles"].stringValue ?? "アイテム")
self?.tabTitlesEn.append(self?.remoteConfig["tabTitlesEn"].stringValue ?? "item")
// tableViewを扱っている時はここでreloadDataをする.
// 値をRemote Configで取得した後の処理を実装する.
}
}
...
}
この処理をどこかにまとめたい
Remote Configを利用する時に、毎回これを書くと同じコードが増えるので、FirebaseRemoteConfigManagerを作って同じコードになりうるところは一箇所にまとめようと思います。
FirebaseRemoteConfigManager.swiftの作成
BrightFuturesを使って非同期処理を実装していきます。Carthage等でBrightFuturesをインストールしておきます。以下はFirebaseRemoteConfigManager.swift
の中身です。
import Foundation
import Firebase
import FirebaseRemoteConfig
import BrightFutures
struct FirebaseRemoteConfigManager {
private let remoteConfig: FIRRemoteConfig
private let expirationDuration: Int
init() {
// さっきfunctionの中で設定していたものをイニシャライザにまとめる.
self.remoteConfig = FIRRemoteConfig.remoteConfig()
let remoteConfigSettings = FIRRemoteConfigSettings(developerModeEnabled: true)
self.remoteConfig.configSettings = remoteConfigSettings!
self.expirationDuration = remoteConfig.configSettings.isDeveloperModeEnabled ? 0 : 3600
}
// 返り値はFutureでラップする.
func fetchRemoteConfig() -> Future<FIRRemoteConfig, NSError> {
let promise = Promise<FIRRemoteConfig, NSError>()
remoteConfig.fetchWithExpirationDuration(NSTimeInterval(expirationDuration)) { (status, error) -> Void in
if let error = error {
promise.failure(error)
// 処理に失敗したから早めにreturnさせる.
return
}
if status != FIRRemoteConfigFetchStatus.Success {
let error = NSError(domain: "hogehoge", code: 0, userInfo: [NSLocalizedDescriptionKey: "status is failed"])
promise.failure(error)
// 処理に失敗したから早めにreturnさせる.
return
}
self.remoteConfig.activateFetched()
// 通信が問題なく完了した時のみSuccessになる.
promise.success(self.remoteConfig)
}
return promise.future
}
}
ViewControllerの実装
import UIKit
import Firebase
import FirebaseRemoteConfig
class ViewController: UIViewController {
var tabTitles: [String] = ["ヘアアレンジ", "メイク", "スキンケア"]
var tabTitlesEn: [String] = ["hair_arrange", "make", "skin_care"]
// FirebaseRemoteConfigManagerをインスタンス化する.
private let remoteConfigManager = FirebaseRemoteConfigManager()
override func viewDidLoad() {
super.viewDidLoad()
setTabNameFromRemoteConfig()
}
...
private func setTabNameFromRemoteConfig() {
// .onSuccessに、非同期通信がうまく行った時の(Remote Configで設定した値を利用する)処理を書く.
// .onFailureに、非同期通信が失敗した時の処理を書く.
remoteConfigManager.fetchRemoteConfig()
.onSuccess { result in
print("Fetch succeeded.")
// ["key名"].stringValueで値を取り出せる.
self.tabTitles.append(result["tabTitles"].stringValue ?? "アイテム")
self.tabTitlesEn.append(result["tabTitlesEn"].stringValue ?? "item")
// tableViewを扱っている時はここでreloadDataをする.
// 値をRemote Configで取得した後の処理を実装する.
}
.onFailure { error in
print(error.localizedDescription)
}
}
...
}
ViewControllerの記述量が減った上、コールバックで書くと深いネストになる問題点も回避できます。Remote Configを使いたいところで、private let remoteConfigManager = FirebaseRemoteConfigManager()
を記述して、以下のコードをfuncの中などにいれてあげれば良いです。
remoteConfigManager.fetchRemoteConfig()
.onSuccess { result in
// ["key名"].stringValueで値を取り出せる.
// result["key名"].stringValue ?? "デフォルト値など"を使った処理
// tableViewを扱っている時はここでreloadDataをする.
}
.onFailure { error in
print(error.localizedDescription)
}
Author And Source
この問題について(Firebase Remote Configの機能を共通化した構造体を作ってみた(Swift)), 我々は、より多くの情報をここで見つけました https://qiita.com/ngo275/items/2a27932c4e54e062de21著者帰属:元の著者の情報は、元の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 .