-
Notifications
You must be signed in to change notification settings - Fork 1.2k
/
OptimizelyFeatureFlagToolsViewModel.swift
133 lines (112 loc) · 5.02 KB
/
OptimizelyFeatureFlagToolsViewModel.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
import Foundation
import KsApi
import Prelude
import ReactiveSwift
public typealias OptimizelyFeatures = [(OptimizelyFeature, Bool)]
public protocol OptimizelyFeatureFlagToolsViewModelOutputs {
var reloadWithData: Signal<OptimizelyFeatures, Never> { get }
var updateUserDefaultsWithFeatures: Signal<OptimizelyFeatures, Never> { get }
}
public protocol OptimizelyFeatureFlagToolsViewModelInputs {
func didUpdateUserDefaults()
func setFeatureAtIndexEnabled(index: Int, isEnabled: Bool)
func viewDidLoad()
}
public protocol OptimizelyFeatureFlagToolsViewModelType {
var inputs: OptimizelyFeatureFlagToolsViewModelInputs { get }
var outputs: OptimizelyFeatureFlagToolsViewModelOutputs { get }
}
public final class OptimizelyFeatureFlagToolsViewModel: OptimizelyFeatureFlagToolsViewModelType,
OptimizelyFeatureFlagToolsViewModelInputs,
OptimizelyFeatureFlagToolsViewModelOutputs {
public init() {
let didUpdateUserDefaultsAndUI = self.didUpdateUserDefaultsProperty.signal
.ksr_debounce(.seconds(1), on: AppEnvironment.current.scheduler)
let features = Signal.merge(
self.viewDidLoadProperty.signal,
didUpdateUserDefaultsAndUI
)
.map { _ in AppEnvironment.current.optimizelyClient?.allFeatures() }
.skipNil()
let optimizelyFeatures = features
.map { features in
features.map { feature -> (OptimizelyFeature, Bool) in
let isEnabledFromServer = AppEnvironment.current.optimizelyClient?
.isFeatureEnabled(featureKey: feature.rawValue) ?? false
let isEnabledFromUserDefaults = getValueFromUserDefaults(for: feature)
return (feature, isEnabledFromUserDefaults ?? isEnabledFromServer)
}
}
self.reloadWithData = optimizelyFeatures
self.updateUserDefaultsWithFeatures = optimizelyFeatures
.takePairWhen(self.setFeatureEnabledAtIndexProperty.signal.skipNil())
.map(unpack)
.map { features, index, isEnabled -> OptimizelyFeatures? in
let (feature, _) = features[index]
var mutatedFeatures = features
setValueInUserDefaults(for: feature, and: isEnabled)
mutatedFeatures[index] = (feature, isEnabled)
return mutatedFeatures
}
.skipNil()
}
private let setFeatureEnabledAtIndexProperty = MutableProperty<(Int, Bool)?>(nil)
public func setFeatureAtIndexEnabled(index: Int, isEnabled: Bool) {
self.setFeatureEnabledAtIndexProperty.value = (index, isEnabled)
}
private let didUpdateUserDefaultsProperty = MutableProperty(())
public func didUpdateUserDefaults() {
self.didUpdateUserDefaultsProperty.value = ()
}
private let viewDidLoadProperty = MutableProperty(())
public func viewDidLoad() {
self.viewDidLoadProperty.value = ()
}
public let reloadWithData: Signal<OptimizelyFeatures, Never>
public let updateUserDefaultsWithFeatures: Signal<OptimizelyFeatures, Never>
public var inputs: OptimizelyFeatureFlagToolsViewModelInputs { return self }
public var outputs: OptimizelyFeatureFlagToolsViewModelOutputs { return self }
}
// MARK: - Private Helpers
/** Returns the value of the User Defaults key in the AppEnvironment.
*/
private func getValueFromUserDefaults(for feature: OptimizelyFeature) -> Bool? {
switch feature {
case .commentFlaggingEnabled:
return AppEnvironment.current.userDefaults
.optimizelyFeatureFlags[OptimizelyFeature.commentFlaggingEnabled.rawValue]
case .projectPageStoryTabEnabled:
return AppEnvironment.current.userDefaults
.optimizelyFeatureFlags[OptimizelyFeature.projectPageStoryTabEnabled.rawValue]
case .rewardLocalPickupEnabled:
return AppEnvironment.current.userDefaults
.optimizelyFeatureFlags[OptimizelyFeature.rewardLocalPickupEnabled.rawValue]
case .paymentSheetEnabled:
return AppEnvironment.current.userDefaults
.optimizelyFeatureFlags[OptimizelyFeature.paymentSheetEnabled.rawValue]
case .facebookLoginDeprecationEnabled:
return AppEnvironment.current.userDefaults
.optimizelyFeatureFlags[OptimizelyFeature.facebookLoginDeprecationEnabled.rawValue]
}
}
/** Sets the value for the UserDefaults key in the AppEnvironment.
*/
private func setValueInUserDefaults(for feature: OptimizelyFeature, and value: Bool) {
switch feature {
case .commentFlaggingEnabled:
AppEnvironment.current.userDefaults
.optimizelyFeatureFlags[OptimizelyFeature.commentFlaggingEnabled.rawValue] = value
case .projectPageStoryTabEnabled:
AppEnvironment.current.userDefaults
.optimizelyFeatureFlags[OptimizelyFeature.projectPageStoryTabEnabled.rawValue] = value
case .rewardLocalPickupEnabled:
return AppEnvironment.current.userDefaults
.optimizelyFeatureFlags[OptimizelyFeature.rewardLocalPickupEnabled.rawValue] = value
case .paymentSheetEnabled:
return AppEnvironment.current.userDefaults
.optimizelyFeatureFlags[OptimizelyFeature.paymentSheetEnabled.rawValue] = value
case .facebookLoginDeprecationEnabled:
return AppEnvironment.current.userDefaults
.optimizelyFeatureFlags[OptimizelyFeature.facebookLoginDeprecationEnabled.rawValue] = value
}
}