Skip to content

Commit

Permalink
integrate statsig with featureflag protocol
Browse files Browse the repository at this point in the history
  • Loading branch information
mike-dydx committed Jul 26, 2024
1 parent e4e0daf commit 0d1593f
Show file tree
Hide file tree
Showing 52 changed files with 12,261 additions and 11,086 deletions.
2 changes: 1 addition & 1 deletion JedioKit/JedioKit/_Field/FieldDefinition.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import Utilities
}

override open var parser: Parser {
return Parser.featureFlagged
return Parser.standard
}
}

Expand Down
2 changes: 1 addition & 1 deletion JedioKit/JedioKit/_Field/FieldDefinitionGroup.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import Utilities

@objc open class FieldDefinitionGroup: DictionaryEntity {
override open var parser: Parser {
return Parser.featureFlagged
return Parser.standard
}

public var input: Bool {
Expand Down
2 changes: 1 addition & 1 deletion JedioKit/JedioKit/_Field/FieldLoader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,6 @@ import Utilities
}

override open var parser: Parser {
return Parser.featureFlagged
return Parser.standard
}
}
48 changes: 24 additions & 24 deletions ParticlesKit/ParticlesKit/_Cache/_Features/FeaturesConfig.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,27 @@
// Copyright © 2021 dYdX Trading Inc. All rights reserved.
//

import Utilities

open class FeaturesConfig: NSObject, IOProtocol {
@objc public dynamic var isLoading: Bool = false

public var priority: Int = 0

public func load(path: String, params: [String: Any]?, completion: @escaping IOReadCompletionHandler) {
isLoading = true
let path = path.lastPathComponent
let data = FeatureService.shared?.flag(feature: path)
isLoading = false
completion(data, nil, priority, nil)
}

public func save(path: String, params: [String: Any]?, data: Any?, completion: IOWriteCompletionHandler?) {
}

public func modify(path: String, params: [String: Any]?, data: Any?, completion: IOWriteCompletionHandler?) {
}

public func delete(path: String, params: [String: Any]?, completion: IODeleteCompletionHandler?) {
}
}
//import Utilities
//
//open class FeaturesConfig: NSObject, IOProtocol {
// @objc public dynamic var isLoading: Bool = false
//
// public var priority: Int = 0
//
// public func load(path: String, params: [String: Any]?, completion: @escaping IOReadCompletionHandler) {
// isLoading = true
// let path = path.lastPathComponent
// let data = FeatureService.shared?.flag(feature: path)
// isLoading = false
// completion(data, nil, priority, nil)
// }
//
// public func save(path: String, params: [String: Any]?, data: Any?, completion: IOWriteCompletionHandler?) {
// }
//
// public func modify(path: String, params: [String: Any]?, data: Any?, completion: IOWriteCompletionHandler?) {
// }
//
// public func delete(path: String, params: [String: Any]?, completion: IODeleteCompletionHandler?) {
// }
//}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ open class JsonCredentialsProvider: NSObject {

private var entity: DictionaryEntity?

public func key(for lookupKey: String) -> String? {
public func credential(for lookupKey: String) -> String? {
let content = entity?.data?[lookupKey]
if let contentDict = parser.asDictionary(content) {
let value = parser.asString(contentDict["value"])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,24 @@ import Utilities
completion()
}

public func flag(feature: String?) -> Any? {
public func isOn(feature: String) -> Bool? {
featureFlags?[feature] as? Bool
}

public func value(feature: String) -> String? {
if let value = featureFlags?[feature] as? String {
return value
}
return nil
}

public func flag<T>(feature: String?) -> T? {
if let feature = feature {
if let value = featureFlags?[feature] {
if (value as? String) == "<null>" {
return nil
}
return value
return value as? T
}
}
return nil
Expand Down
5 changes: 2 additions & 3 deletions ParticlesKit/ParticlesKit/_Shared/ParticlesInjection.swift
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,8 @@ open class ParticlesInjection: NSObject, InjectionProtocol {

open func injectParsers() {
Console.shared.log("injectParsers")
// Router and Xib loader supports Feature flagging
MappedRouter.parserOverwrite = Parser.featureFlagged
XibJsonFile.parserOverwrite = Parser.featureFlagged
MappedRouter.parserOverwrite = Parser.standard
XibJsonFile.parserOverwrite = Parser.standard
JsonEndpointResolver.parserOverwrite = Parser.debug
JsonCredentialsProvider.parserOverwrite = Parser.debug
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ open class ParticlesPlatformInjection: ParticlesInjection {

HapticFeedback.shared = MotionHapticFeedback()
SDImageCodersManager.shared.addCoder(SDImageSVGCoder.shared)
RoutingTabBarController.parserOverwrite = Parser.featureFlagged
RoutingTabBarController.parserOverwrite = Parser.standard
PrompterFactory.shared = UIKitPrompterFactory()
}
}
43 changes: 24 additions & 19 deletions Shared/CommonAppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import FirebaseStaticInjections
import dydxStateManager
import dydxViews
import dydxAnalytics
import Statsig
import StatsigInjections

open class CommonAppDelegate: ParticlesAppDelegate {
open var notificationTag: String {
Expand Down Expand Up @@ -49,15 +49,15 @@ open class CommonAppDelegate: ParticlesAppDelegate {
// these three injections need to happen before app start
injectFirebase()
injectRating()
injectStatsig()
injectStatsigApiKey()
let compositeFeatureFlags = CompositeFeatureFlagsProvider()
switch Installation.source {
case .debug, .testFlight:
compositeFeatureFlags.local = FeatureFlagsStore.shared
case .appStore, .jailBroken:
break
}
// compositeFeatureFlags.remote = FirebaseRunner.shared.enabled ? FirebaseFeatureFlagsProvider() : nil
compositeFeatureFlags.remote = StatsigFeatureFlagsProvider.shared
FeatureService.shared = compositeFeatureFlags
FeatureService.shared?.activate { /* [weak self] in */
Injection.shared?.injectFeatured(completion: completion)
Expand Down Expand Up @@ -104,36 +104,41 @@ open class CommonAppDelegate: ParticlesAppDelegate {
}
}

open func injectStatsig() {
Console.shared.log("injectStatsig")
if let apiKey = CredientialConfig.shared.key(for: "statsigApiKey"), apiKey.isNotEmpty {
#if DEBUG
Statsig.start(sdkKey: apiKey, user: StatsigUser(userID: "test-id"))
#else
Statsig.start(sdkKey: apiKey, user: StatsigUser(userID: Statsig.getStableID()))
#endif
}
}

open func injectAmplitude() {
Console.shared.log("injectAmplitude")
let apiKey: String?
switch Installation.source {
case .jailBroken, .debug, .testFlight:
apiKey = CredientialConfig.shared.key(for: "amplitudeStagingApiKey")
apiKey = CredientialConfig.shared.credential(for: "amplitudeStagingApiKey")
case .appStore:
apiKey = CredientialConfig.shared.key(for: "amplitudeApiKey")
apiKey = CredientialConfig.shared.credential(for: "amplitudeApiKey")
}
if let apiKey = apiKey, apiKey.isNotEmpty {
AmplitudeRunner.shared.apiKey = apiKey
add(tracking: dydxAmplitudeTracking())
}
}

open func injectStatsigApiKey() {
Console.shared.log("injectStatsig")
let environment: StatsigFeatureFlagsProvider.Environment
switch Installation.source {
case .debug, .testFlight:
environment = .development
case .appStore, .jailBroken:
environment = .production
}
guard let apiKey = CredientialConfig.shared.credential(for: "statsigApiKey") else {
assertionFailure("Statsig API key is missing")
return
}
StatsigFeatureFlagsProvider.shared = StatsigFeatureFlagsProvider(apiKey: apiKey, environment: environment)
}

open func injectAttribution() {
Console.shared.log("injectAttribution")
if let devKey = CredientialConfig.shared.key(for: "appsFlyerDevKey"), devKey.isNotEmpty,
let appId = CredientialConfig.shared.key(for: "appsFlyerAppId"), appId.isNotEmpty {
if let devKey = CredientialConfig.shared.credential(for: "appsFlyerDevKey"), devKey.isNotEmpty,
let appId = CredientialConfig.shared.credential(for: "appsFlyerAppId"), appId.isNotEmpty {
AppsFlyerRunner.shared.devKey = devKey
AppsFlyerRunner.shared.appId = appId
Attributer.shared = AppsFlyerAttributor()
Expand Down Expand Up @@ -168,7 +173,7 @@ open class CommonAppDelegate: ParticlesAppDelegate {
}

open func injectWebview() {
ParticlesWebView.setup(urlString: CredientialConfig.shared.key(for: "webAppUrl"))
ParticlesWebView.setup(urlString: CredientialConfig.shared.credential(for: "webAppUrl"))
}

override open func startup(completion: @escaping () -> Void) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ import Combine
urlSession: nil)) {[weak self] error in
Console.shared.log("Statsig feature flags initialized")
if let error {
// assertionFailure("Statsig failed to initialize: \(error)")
assertionFailure("Statsig failed to initialize: \(error)")
}
self?.newValuesSubject.send()
completion()
Expand Down
8 changes: 0 additions & 8 deletions Utilities/Utilities.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,6 @@
314B645423DCCF0200139EB3 /* DebugParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 314B63AD23DCCF0100139EB3 /* DebugParser.swift */; };
314B645523DCCF0200139EB3 /* DebugParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 314B63AD23DCCF0100139EB3 /* DebugParser.swift */; };
314B645623DCCF0200139EB3 /* DebugParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 314B63AD23DCCF0100139EB3 /* DebugParser.swift */; };
314B645823DCCF0200139EB3 /* FeatureFlaggedParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 314B63AE23DCCF0100139EB3 /* FeatureFlaggedParser.swift */; };
314B645923DCCF0200139EB3 /* FeatureFlaggedParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 314B63AE23DCCF0100139EB3 /* FeatureFlaggedParser.swift */; };
314B645A23DCCF0200139EB3 /* FeatureFlaggedParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 314B63AE23DCCF0100139EB3 /* FeatureFlaggedParser.swift */; };
314B645C23DCCF0200139EB3 /* Debouncer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 314B63AF23DCCF0100139EB3 /* Debouncer.swift */; };
314B645D23DCCF0200139EB3 /* Debouncer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 314B63AF23DCCF0100139EB3 /* Debouncer.swift */; };
314B645E23DCCF0200139EB3 /* Debouncer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 314B63AF23DCCF0100139EB3 /* Debouncer.swift */; };
Expand Down Expand Up @@ -339,7 +336,6 @@
314B63A923DCCF0100139EB3 /* NotificationToken.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NotificationToken.swift; sourceTree = "<group>"; };
314B63AC23DCCF0100139EB3 /* Parser.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Parser.swift; sourceTree = "<group>"; };
314B63AD23DCCF0100139EB3 /* DebugParser.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DebugParser.swift; sourceTree = "<group>"; };
314B63AE23DCCF0100139EB3 /* FeatureFlaggedParser.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FeatureFlaggedParser.swift; sourceTree = "<group>"; };
314B63AF23DCCF0100139EB3 /* Debouncer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Debouncer.swift; sourceTree = "<group>"; };
314B63B023DCCF0100139EB3 /* JsonWriter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JsonWriter.swift; sourceTree = "<group>"; };
314B63B123DCCF0100139EB3 /* Installation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Installation.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -674,7 +670,6 @@
children = (
319BB727242928D700DC9E97 /* ConditionalParser.swift */,
314B63AD23DCCF0100139EB3 /* DebugParser.swift */,
314B63AE23DCCF0100139EB3 /* FeatureFlaggedParser.swift */,
314B63AC23DCCF0100139EB3 /* Parser.swift */,
317F16CD2572CE2800D178B8 /* AppConfiguration.swift */,
);
Expand Down Expand Up @@ -1198,7 +1193,6 @@
314B64B223DCCF0200139EB3 /* NSObject+Class.m in Sources */,
314B645E23DCCF0200139EB3 /* Debouncer.swift in Sources */,
317F16D92572CEC500D178B8 /* ImageUploaderProtocol.swift in Sources */,
314B645A23DCCF0200139EB3 /* FeatureFlaggedParser.swift in Sources */,
31471F7224BA2F1E00057221 /* UserAgent.swift in Sources */,
314B64E223DCCF0200139EB3 /* DebugTracking.swift in Sources */,
317F16D02572CE2800D178B8 /* AppConfiguration.swift in Sources */,
Expand Down Expand Up @@ -1276,7 +1270,6 @@
files = (
314B64B123DCCF0200139EB3 /* NSObject+Class.m in Sources */,
314B645D23DCCF0200139EB3 /* Debouncer.swift in Sources */,
314B645923DCCF0200139EB3 /* FeatureFlaggedParser.swift in Sources */,
314B64E123DCCF0200139EB3 /* DebugTracking.swift in Sources */,
31471F7124BA2F1E00057221 /* UserAgent.swift in Sources */,
317F16D82572CEC500D178B8 /* ImageUploaderProtocol.swift in Sources */,
Expand Down Expand Up @@ -1350,7 +1343,6 @@
314B64D023DCCF0200139EB3 /* TimeCounter.swift in Sources */,
314B64B023DCCF0200139EB3 /* NSObject+Class.m in Sources */,
314B645C23DCCF0200139EB3 /* Debouncer.swift in Sources */,
314B645823DCCF0200139EB3 /* FeatureFlaggedParser.swift in Sources */,
314B64E023DCCF0200139EB3 /* DebugTracking.swift in Sources */,
314B643423DCCF0200139EB3 /* JsonLoader.swift in Sources */,
314B648423DCCF0200139EB3 /* TimeIntervale+String.swift in Sources */,
Expand Down
18 changes: 10 additions & 8 deletions Utilities/Utilities/_Store/FeatureFlagsStore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,16 @@ public class FeatureFlagsStore: UserDefaultsStore, FeatureFlagsProtocol {
completion()
}

public func flag(feature: String?) -> Any? {
if let feature = feature {
if let value = featureFlags?[feature] {
if (value as? String) == "<null>" {
return nil
}
return value
}
public func isOn(feature: String) -> Bool? {
if let value = featureFlags?[feature] as? Bool {
return value
}
return nil
}

public func value(feature: String) -> String? {
if let value = featureFlags?[feature] as? String {
return value
}
return nil
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,16 @@
//

import Foundation
import Combine

public class CompositeFeatureFlagsProvider: NSObject & FeatureFlagsProtocol {
public var local: FeatureFlagsProtocol?
public var remote: FeatureFlagsProtocol?

public var featureFlags: [String: Any]? {
let localFlags = local?.featureFlags
let remoteFlags = remote?.featureFlags
if let localFlags = localFlags {
if let remoteFlags = remoteFlags {
return remoteFlags.merging(localFlags) { (_, local) -> Any in
local
}
} else {
return localFlags
}
} else {
return remoteFlags
}

public var newValuesAvailablePublisher: AnyPublisher<Void, Never> {
Publishers.Merge(local?.newValuesAvailablePublisher ?? Just(()).eraseToAnyPublisher(),
remote?.newValuesAvailablePublisher ?? Just(()).eraseToAnyPublisher())
.eraseToAnyPublisher()
}

public func refresh(completion: @escaping () -> Void) {
Expand Down Expand Up @@ -56,18 +47,27 @@ public class CompositeFeatureFlagsProvider: NSObject & FeatureFlagsProtocol {
}
}

public func flag(feature: String?) -> Any? {
public func value(feature: String) -> String? {
switch Installation.source {
case .appStore, .jailBroken:
return remote?.flag(feature: feature)
return remote?.value(feature: feature)
case .debug, .testFlight:
if let localFlag = local?.flag(feature: feature) {
if let localFlag = local?.value(feature: feature) {
return localFlag
} else {
return remote?.flag(feature: feature)
return remote?.value(feature: feature)
}
}
}

public func isOn(feature: String) -> Bool? {
switch Installation.source {
case .appStore, .jailBroken:
return remote?.isOn(feature: feature) == true
case .debug, .testFlight:
return local?.isOn(feature: feature) ?? remote?.isOn(feature: feature) ?? false
}
}

public func customized() -> Bool {
return local?.customized() ?? false
Expand Down
Loading

0 comments on commit 0d1593f

Please sign in to comment.