【この記事で書くこと】
- Firebaseのサービス(今回はRemote Config)で何ができるのか
- iOS側ではどんなコードを書けば良いのか?
- ただし↑のコードはサンプルコードというより実際に使うために作ったコードなので、分かりにくいかもしれません。
今回はFirebaseの中でも一番シンプルなRemote Config
について書きたいと思います。
【書かないこと】
- Firebaseとは何かとかいう大きな話は書きません
- Firebase Consoleの説明は多く書きません(少なめにとどめる)
【環境】
let lang = Swift4.2
let env = XCode10
【何ができるのか】
Remote Config
は、簡単に言うと様々なアプリの設定情報をクラウドで持ち、iOSが(任意のタイミングで何度でも)それを読み込んで使えるというものです。
以下は自分が考えた用途です。
用途 | 詳細 | 注意点 |
---|---|---|
画面の配色 | UIView/UIViewControllerの背景色や枠色、文字の色情報をRemote Config に設定する。 |
変更するタイミングは起動時だけなのか、インタラクティブに行うのかを検討する。 |
画面上の文字 | タイトルや固定の説明文などをRemote Config に設定する。 |
文字を変更すると所定の領域に収まらないことがあるために要注意 |
メニュー | メニューの内容(文字列)などをRemote Config に設定する。 |
メニューがタップされてからの実際の画面遷移の制御はRemote Config ではできないので別途実装すること |
画面レイアウト | 配置情報をRemote Config に設定する。画面要素の配置などを変える時に使える(例えば画像と説明文の位置を入れ替えるとか) |
上記と同じく配置を変更する実装の難易度は高い(Remote Config の範囲外) |
A/Bテスト | 上記のRemote Config を使用して変更可能な全ての要素をA/Bテストできる |
今回は内容は書きません |
【Firebase Console】
Firebase Consoleでparams
というキーでJSONを設定します。
JSONでなくても構いませんが、その場合は後述のparser関数の内容を変えることになります。
こんなふうに編集することもできます。
【iOS側のコード】
iOS側のコードは【この記事で書くこと】で書いたように実際に使うために作ったコード
です。そのため、Remote Config
のサンプルとしては若干分かりにくいかもしれません。しかし、このような実装が適当であろうという現時点での自分の理解です。
iOS側のコードはCodableを使ってFirebase Consoleで作成した構造RemoteAppConfigurationを定義します。
FirebaseではRemote Config
に初期値を設定できますが 注1)、特に意味は無いので記述をシンプルに保つためにRemoteAppConfigurationに初期値を記述しておきます。注2)
注1)remoteConfig.setDefaults(fromPlist: "RemoteConfigDefaults") plistから設定できる(自分はまったくうれしくないので使いません)
注2)初期値を書かなければ各要素はOptionalになるのであまりお勧めできません。が、Firebase Console側で全ての要素を記述しなくてもiOSがクラッシュしないと言うメリットはあります(書き忘れの場合をテスト時に検出したい場合はデメリットか)
import Firebase
struct RemoteAppConfiguration: Codable
{
var one: String = ""
var two: Int = 0
var tree: String?
var four: String = ""
}
RemoteConfigをparseするprotocolを定義します。
このprotocolを実装したインスタンスをヘルパークラスに渡すことで、必要なRemoteAppConfigurationなどを取り出してもらいます。
public protocol RemoteConfigParsable
{
func parser(remoteConfig: RemoteConfig)
}
ヘルパークラスは下記のようなものです。
public final class RemoteConfigHelper
{
var remoteConfig: RemoteConfig!
}
public extension RemoteConfigHelper
{
func confugure(_ remoteConfigurables: [RemoteConfigParsable], expirationDuration: TimeInterval = 20)
{
remoteConfig = RemoteConfig.remoteConfig()
remoteConfig.fetch(withExpirationDuration: expirationDuration) { [weak self] (status, error) -> Void in
guard let _self = self else { return }
if status == .success {
_self.remoteConfig.activateFetched()
// 全てのRemoteConfigParsableのparser関数を実行する
for remoteConfigurable in remoteConfigurables
{
remoteConfigurable.parser(remoteConfig: _self.remoteConfig)
}
} else {
logger.error("RemoteConfig Error: \(error?.localizedDescription ?? "unknown")")
}
}
}
}
ヘルパークラスはRemoteConfigParsableを入力とする汎用のクラスになっています。
そしてRemoteConfigParsableの実装です。ここはなんでもいいのですが、parser関数の中で通知処理まで行うと言うちょっと強引な実装にしています。キモはJSONの場合は JSONDecoder().decode(ResponseType.self, from: data)
と書くこと。他にも文字列だけの場合は、let str = remoteConfig["key"].stringValue
で取り出したりすることで、ヘルパークラスはparserの内容を知る必要はありません。
var myConfig: RemoteAppConfiguration = RemoteAppConfiguration()
var myConfigObservable = BwObservable<RemoteAppConfiguration>() // 適当にNotification使うなりなんなりに変更してください
struct InfoConfig: RemoteConfigParsable
{
public typealias ResponseType = RemoteAppConfiguration
public let key: String = "params"
public func parser(remoteConfig: RemoteConfig)
{
let data = remoteConfig[key].dataValue
if let _config = try? JSONDecoder().decode(ResponseType.self, from: data)
{
myConfig = _config
myConfigObservable.publish(myConfig) // 適当にNotification使うなりなんなりに変更してください
//print(myConfig)
}
}
}
これで、RemoteConfigParsableの実体を定義するだけでFirebase Consoleで記述した内容をアプリに取り込むことができます。