会社の技術ブログでも似たような内容を投稿するのでこちらでは軽めに。
この土日で、Firebase RemoteConfigをSwiftで使うにあたって、より扱いやすくするライブラリ Shrimp を作成しました。
どんなライブラリなのか
通常、FIRRemoteConfigをそのまま使って、例えば"label_text"
というkeyを使ってRemoteConfigから値を取得したり、デフォルトの値をセットするとすると、こんな感じになります。
// Before
FIRRemoteConfig.remoteConfig.setDefaults(["label_text": NSString(string: "label_text")])
let text = FIRRemoteConfig.remoteConfig()["label_text"].stringValue ?? ""
これだと、デフォルト値をセットするのがやや面倒(一々StringやIntをNSString、NSNumberにしないといけない)だったり、
値を取得する時に、"label_text"
で取得できる値が String 型であると保証できない(型安全に欠ける)ので、
Swift側から使うとなると、やや違和感があったりします。
そこで、このライブラリを使うと、以下のような感じで置き換えることができるようになります。
extension ConfigKeys {
static let labelText = ConfigKey<String>("label_text")
}
// デフォルト値を設定する
Shrimp.shared.config[.labelText] = "Default Text"
Shrimp.shared.config[.labelText] = 123 // String型でないのでコンパイルエラー
// 値の取得をする時は、String型であることが保証される
let text = Shrimp.shared.config[.labelText] // text is `String`
ポイントとしては、 ConfigKey
これによって、デフォルト値をセットする、値を取得するときに、どんな型になるかを決定しています。
また、独自の型(enumとか)も、 ConfigKey の宣言と、 subscript の定義を追加してあげると、こんな感じで扱うことが出来ます。
enum SampleType: Int {
case a, b, none
}
extension ConfigKeys {
static let testType = ConfigKey<SampleType>("test_type")
}
extension RemoteConfig {
// subscriptを定義してあげる
subscript (key: ConfigKey<SampleType>) -> SampleType {
get {
return int(for: key).flatMap(SampleType.init) ?? .none
}
set {
set(key: key, value: newValue.rawValue)
}
}
}
// =================
Shrimp.shared.config[.testType] = .none
// 取得時は SampleType型が保証される
switch Shrimp.shared.config[.testType] {
case .a:
// ...
case .b:
// ...
case .none:
// ...
}
実は…
実装にあたっては、普段からお世話になっているSwiftyUserDefaultsの実装方法を参考にさせて頂きました。
あとまだ若干バグがあるのか、namespaceに絡んだ部分でうまく値が取得できなかったりしますが、そこもFirebaseにお問い合わせしつつ、自力でなんとかしています。笑
まだまだ作成したばかりでバグだったりイケてない場所もあるかもしれないですが、引き続き開発していけたらと思います。
(もしこの辺りSDK側でうまくやれるように吸収されたら存在意義なくなりそうでやや心配。)
Shrimpの名前の由来
「RemoteConfig、A/Bテストに向いているんじゃないか? 」
↓
A/Bテスト(えーびーテスト)
↓
海老
↓
LobsterかShrimpで迷って、小エビくらいのかわいさで良さそう。
↓
Shrimp
って具合です。本当に適当です。