Last active
February 18, 2021 06:36
-
-
Save imaizume/3e6dd078e2551cda53c611a91e5da2ac to your computer and use it in GitHub Desktop.
How to manage parameters for Firebase Remote Config in Swift easily.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// MARK:- definition | |
/// Constraint for Parameter Type Definition. | |
protocol ParameterProtocol { | |
/// Parameter name in Firebase console. e.g. "beta_test_1" | |
var name: String { get } | |
/// Default value to be set to Remote Config object. | |
var defaultValue: [String: NSObject] { get } | |
} | |
/// Parameters return bool value. | |
enum BoolParameter: String { | |
case betaTest1 | |
case betaTest2 | |
} | |
extension BoolParameter: ParameterProtocol { | |
var name: String { return self.rawValue } | |
var defaultValue: [String: NSObject] { | |
switch self { | |
case .betaTest1: // default false | |
return [self.rawValue: false as NSObject] | |
case .betaTest2: // default true | |
return [self.rawValue: true as NSObject] | |
} | |
} | |
} | |
/// Parameters return string value. | |
enum StringParameter: String { | |
case betaTestA | |
case betaTestB | |
} | |
extension StringParameter: ParameterProtocol { | |
var name: String { return self.rawValue } | |
var defaultValue: [String: NSObject] { | |
switch self { | |
case .betaTestA: // default "" | |
return [self.rawValue: "" as NSObject] | |
case .betaTestB: // default "test" | |
return [self.rawValue: "test" as NSObject] | |
} | |
} | |
} | |
/// Interface required to store object which returns bool value. | |
protocol BoolStoreProtocol { | |
func boolValue(for key: BoolParameter) -> Bool | |
} | |
/// Stub object which returns bool value. | |
class BoolStoreStub: BoolStoreProtocol { | |
func boolValue(for key: BoolParameter) -> Bool { | |
return false | |
} | |
} | |
/// Interface required to store object which returns string value. | |
protocol StringStoreProtocol { | |
func stringValue(for key: StringParameter) -> String? | |
} | |
/// Stub object which returns string value. | |
class StringStoreStub: StringStoreProtocol { | |
func stringValue(for key: StringParameter) -> String? { | |
return "" | |
} | |
} | |
/// Store object which returns value fetched from Firebase. | |
class FirebaseStore {} | |
extension FirebaseStore: BoolStoreProtocol { | |
func boolValue(for key: BoolParameter) -> Bool { | |
let remoteConfig = RemoteConfig.remoteConfig() | |
remoteConfig.setDefaults(key.defaultValue) | |
return remoteConfig[key.name].boolValue | |
} | |
} | |
extension FirebaseStore: StringStoreProtocol { | |
func stringValue(for key: StringParameter) -> String? { | |
let remoteConfig = RemoteConfig.remoteConfig() | |
remoteConfig.setDefaults(key.defaultValue) | |
return remoteConfig[key.name].stringValue | |
} | |
} | |
// MARK:- example | |
let boolStore: BoolStoreProtocol = FirebaseStore() | |
let boolStub: BoolStoreProtocol = BoolStoreStub() | |
let realBoolValue: Bool = boolStore.boolValue(for: .betaTest1) | |
let stubBoolValue: Bool = boolStub.boolValue(for: .betaTest1) | |
let stringStore: StringStoreProtocol = FirebaseStore() | |
let stringStub: StringStoreProtocol = StringStoreStub() | |
let realStringValue: String? = stringStore.stringValue(for: .betaTestA) | |
let stubStringValue: String? = stringStub.stringValue(for: .betaTestA) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// Constraint for Parameter Type Definition. | |
protocol ParameterProtocol { | |
/// Type of value which parameter returns | |
associatedtype ValueType | |
/// Parameter name in Firebase console. e.g. "beta_test_1" | |
var name: String { get } | |
/// Default value to be set to Remote Config object. | |
func defaultValue() -> ValueType | |
} | |
enum BoolParameter: String { | |
case betaTest1 | |
case betaTest2 | |
} | |
extension BoolParameter: ParameterProtocol { | |
typealias ValueType = Bool | |
var name: String { return self.rawValue } | |
func defaultValue() -> Bool { | |
switch self { | |
case .betaTest1: | |
return false | |
case .betaTest2: | |
return true | |
} | |
} | |
} | |
enum StringParameter: String { | |
case betaTestA | |
case betaTestB | |
} | |
extension StringParameter: ParameterProtocol { | |
typealias ValueType = String | |
var name: String { return self.rawValue } | |
func defaultValue() -> String { | |
switch self { | |
case .betaTestA: | |
return "" | |
case .betaTestB: | |
return "test" | |
} | |
} | |
} | |
class AnyKindOfParameter<ValueType>: ParameterProtocol { | |
init<X: ParameterProtocol>(_ base: X) where X.ValueType == ValueType { | |
self.name = base.name | |
self._defaultValue = { base.defaultValue() } | |
} | |
private(set) var name: String | |
func defaultValue() -> ValueType { | |
return self._defaultValue() | |
} | |
private let _defaultValue: () -> ValueType | |
} | |
extension AnyKindOfParameter where ValueType == Bool { | |
convenience init(_ base: BoolParameter) { self.init(base) } | |
} | |
extension AnyKindOfParameter where ValueType == String { | |
convenience init(_ base: StringParameter) { self.init(base) } | |
} | |
protocol StoreProtocol { | |
associatedtype ValueType | |
func getValue(for parameter: AnyKindOfParameter<ValueType>) -> ValueType | |
} | |
protocol BoolStoreProtocol { | |
func getValue(for parameter: AnyKindOfParameter<Bool>) -> Bool | |
} | |
protocol StringStoreProtocol { | |
func getValue(for parameter: AnyKindOfParameter<String>) -> String | |
} | |
class BoolStore {} | |
extension BoolStore: StoreProtocol, BoolStoreProtocol { | |
typealias ValueType = Bool | |
func getValue(for parameter: AnyKindOfParameter<Bool>) -> Bool { | |
let remoteConfig = RemoteConfig.remoteConfig() | |
remoteConfig.setDefaults([parameter.name: parameter.defaultValue() as NSObject]) | |
return remoteConfig[parameter.name].boolValue | |
} | |
} | |
class BoolStub {} | |
extension BoolStub: StoreProtocol, BoolStoreProtocol { | |
func getValue(for parameter: AnyKindOfParameter<Bool>) -> Bool { | |
guard let param = parameter as? BoolParameter else { return false } | |
switch param { | |
case .betaTest1: | |
return true | |
case .betaTest2: | |
return false | |
} | |
} | |
} | |
let x: BoolStoreProtocol = BoolStore() | |
let y: BoolStoreProtocol = BoolStub() | |
let a: Bool = x.getValue(for: .init(.betaTest1)) | |
let b: Bool = y.getValue(for: .init(.betaTest1)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment