17
17
import Foundation
18
18
19
19
class DefaultDecisionService : OPTDecisionService {
20
- var config : ProjectConfig !
21
- var bucketer : OPTBucketer !
22
- var userProfileService : OPTUserProfileService !
23
-
24
- internal required init ( config: ProjectConfig , bucketer: OPTBucketer , userProfileService: OPTUserProfileService ) {
25
- self . config = config
26
- self . bucketer = bucketer
27
- self . userProfileService = userProfileService
28
- }
29
20
30
- // [Jae]: let be configured after initialized (with custom DecisionHandler set up on OPTManger initialization)
31
- init ( ) { }
21
+ let bucketer : OPTBucketer
22
+ let userProfileService : OPTUserProfileService
32
23
33
- func initialize( config: ProjectConfig , bucketer: OPTBucketer , userProfileService: OPTUserProfileService ) {
34
- self . config = config
35
- self . bucketer = bucketer
24
+ init ( userProfileService: OPTUserProfileService ) {
25
+ self . bucketer = DefaultBucketer ( )
36
26
self . userProfileService = userProfileService
37
27
}
38
-
39
- func getVariation( userId: String , experiment: Experiment , attributes: OptimizelyAttributes ) -> Variation ? {
28
+
29
+ func getVariation( config : ProjectConfig , userId: String , experiment: Experiment , attributes: OptimizelyAttributes ) -> Variation ? {
40
30
let experimentId = experiment. id;
41
31
42
32
// Acquire bucketingId .
@@ -68,12 +58,13 @@ class DefaultDecisionService : OPTDecisionService {
68
58
var bucketedVariation : Variation ?
69
59
// ---- check if the user passes audience targeting before bucketing ----
70
60
if let result = isInExperiment (
61
+ config: config,
71
62
experiment: experiment,
72
63
userId: userId,
73
64
attributes: attributes) , result == true {
74
65
75
66
// bucket user into a variation
76
- bucketedVariation = bucketer. bucketExperiment ( experiment: experiment, bucketingId: bucketingId)
67
+ bucketedVariation = bucketer. bucketExperiment ( config : config , experiment: experiment, bucketingId: bucketingId)
77
68
78
69
if let bucketedVariation = bucketedVariation {
79
70
// save to user profile
@@ -85,7 +76,7 @@ class DefaultDecisionService : OPTDecisionService {
85
76
86
77
}
87
78
88
- func isInExperiment( experiment: Experiment , userId: String , attributes: OptimizelyAttributes ) -> Bool ? {
79
+ func isInExperiment( config : ProjectConfig , experiment: Experiment , userId: String , attributes: OptimizelyAttributes ) -> Bool ? {
89
80
90
81
if let conditions = experiment. audienceConditions {
91
82
switch conditions {
@@ -119,45 +110,46 @@ class DefaultDecisionService : OPTDecisionService {
119
110
return true
120
111
}
121
112
122
- func getExperimentInGroup( group: Group , bucketingId: String ) -> Experiment ? {
123
- let experiment = bucketer. bucketToExperiment ( group: group, bucketingId: bucketingId)
113
+ func getExperimentInGroup( config : ProjectConfig , group: Group , bucketingId: String ) -> Experiment ? {
114
+ let experiment = bucketer. bucketToExperiment ( config : config , group: group, bucketingId: bucketingId)
124
115
if let _ = experiment {
125
116
// log
126
117
}
127
118
128
119
return experiment;
129
120
}
130
121
131
- func getVariationForFeature( featureFlag: FeatureFlag , userId: String , attributes: OptimizelyAttributes ) -> ( experiment: Experiment ? , variation: Variation ? ) ? {
122
+ func getVariationForFeature( config : ProjectConfig , featureFlag: FeatureFlag , userId: String , attributes: OptimizelyAttributes ) -> ( experiment: Experiment ? , variation: Variation ? ) ? {
132
123
//Evaluate in this order:
133
124
134
125
//1. Attempt to bucket user into experiment using feature flag.
135
126
// Check if the feature flag is under an experiment and the the user is bucketed into one of these experiments
136
- if let variation = getVariationForFeatureExperiment ( featureFlag: featureFlag, userId: userId, attributes: attributes) {
127
+ if let variation = getVariationForFeatureExperiment ( config : config , featureFlag: featureFlag, userId: userId, attributes: attributes) {
137
128
return variation
138
129
}
139
130
140
131
//2. Attempt to bucket user into rollout using the feature flag.
141
132
// Check if the feature flag has rollout and the user is bucketed into one of it's rules
142
- if let variation = getVariationForFeatureRollout ( featureFlag: featureFlag, userId: userId, attributes: attributes) {
133
+ if let variation = getVariationForFeatureRollout ( config : config , featureFlag: featureFlag, userId: userId, attributes: attributes) {
143
134
return ( nil , variation)
144
135
}
145
136
146
137
return nil ;
147
138
148
139
}
149
140
150
- func getVariationForFeatureGroup( featureFlag: FeatureFlag ,
141
+ func getVariationForFeatureGroup( config: ProjectConfig ,
142
+ featureFlag: FeatureFlag ,
151
143
groupId: String ,
152
144
userId: String ,
153
145
attributes: OptimizelyAttributes ) -> ( experiment: Experiment ? , variation: Variation ? ) ? {
154
146
155
147
let bucketing_id = getBucketingId ( userId: userId, attributes: attributes)
156
148
if let group = config. project. groups. filter ( { $0. id == groupId} ) . first {
157
149
158
- if let experiment = getExperimentInGroup ( group: group, bucketingId: bucketing_id) ,
150
+ if let experiment = getExperimentInGroup ( config : config , group: group, bucketingId: bucketing_id) ,
159
151
featureFlag. experimentIds. contains ( experiment. id) ,
160
- let variation = getVariation ( userId: userId, experiment: experiment, attributes: attributes) {
152
+ let variation = getVariation ( config : config , userId: userId, experiment: experiment, attributes: attributes) {
161
153
// log
162
154
return ( experiment, variation)
163
155
}
@@ -169,7 +161,8 @@ class DefaultDecisionService : OPTDecisionService {
169
161
return nil
170
162
}
171
163
172
- func getVariationForFeatureExperiment( featureFlag: FeatureFlag ,
164
+ func getVariationForFeatureExperiment( config: ProjectConfig ,
165
+ featureFlag: FeatureFlag ,
173
166
userId: String ,
174
167
attributes: OptimizelyAttributes ) -> ( experiment: Experiment ? , variation: Variation ? ) ? {
175
168
@@ -178,14 +171,15 @@ class DefaultDecisionService : OPTDecisionService {
178
171
// Evaluate each experiment ID and return the first bucketed experiment variation
179
172
for experimentId in experimentIds {
180
173
if let experiment = config. getExperiment ( id: experimentId) ,
181
- let variation = getVariation ( userId: userId, experiment: experiment, attributes: attributes) {
174
+ let variation = getVariation ( config : config , userId: userId, experiment: experiment, attributes: attributes) {
182
175
return ( experiment, variation)
183
176
}
184
177
}
185
178
return nil ;
186
179
}
187
180
188
- func getVariationForFeatureRollout( featureFlag: FeatureFlag ,
181
+ func getVariationForFeatureRollout( config: ProjectConfig ,
182
+ featureFlag: FeatureFlag ,
189
183
userId: String ,
190
184
attributes: OptimizelyAttributes ) -> Variation ? {
191
185
@@ -200,16 +194,16 @@ class DefaultDecisionService : OPTDecisionService {
200
194
let rolloutRules = rollout. experiments
201
195
// Evaluate all rollout rules except for last one
202
196
for experiment in rolloutRules [ 0 ..< rolloutRules. count. advanced ( by: - 1 ) ] {
203
- if isInExperiment ( experiment: experiment, userId: userId, attributes: attributes) ?? false {
204
- if let variation = bucketer. bucketExperiment ( experiment: experiment, bucketingId: bucketingId) {
197
+ if isInExperiment ( config : config , experiment: experiment, userId: userId, attributes: attributes) ?? false {
198
+ if let variation = bucketer. bucketExperiment ( config : config , experiment: experiment, bucketingId: bucketingId) {
205
199
return variation
206
200
}
207
201
}
208
202
}
209
203
// Evaluate fall back rule / last rule now
210
204
let experiment = rolloutRules [ rolloutRules. count - 1 ] ;
211
- if isInExperiment ( experiment: experiment, userId: userId, attributes: attributes) ?? false {
212
- return bucketer. bucketExperiment ( experiment: experiment, bucketingId: bucketingId)
205
+ if isInExperiment ( config : config , experiment: experiment, userId: userId, attributes: attributes) ?? false {
206
+ return bucketer. bucketExperiment ( config : config , experiment: experiment, bucketingId: bucketingId)
213
207
}
214
208
215
209
return nil
0 commit comments