@@ -48,7 +48,7 @@ extension OptimizelyClient {
48
48
return createUserContext ( userId: userId,
49
49
attributes: ( attributes ?? [ : ] ) as [ String : Any ] )
50
50
}
51
-
51
+
52
52
/// Create a user context to be used internally without sending an ODP identify event.
53
53
///
54
54
/// - Parameters:
@@ -62,6 +62,13 @@ extension OptimizelyClient {
62
62
identify: false )
63
63
}
64
64
65
+ /// Returns a decision result for a given flag key
66
+ ///
67
+ /// - Parameters:
68
+ /// - user: The user context for which the decision is being made
69
+ /// - key: The feature flag key to evaluate
70
+ /// - options: An array of options for decision-making.
71
+ /// - Returns: An OptimizelyDecision representing the flag decision
65
72
func decide( user: OptimizelyUserContext ,
66
73
key: String ,
67
74
options: [ OptimizelyDecideOption ] ? = nil ) -> OptimizelyDecision {
@@ -73,14 +80,22 @@ extension OptimizelyClient {
73
80
guard let _ = config. getFeatureFlag ( key: key) else {
74
81
return OptimizelyDecision . errorDecision ( key: key, user: user, error: . featureKeyInvalid( key) )
75
82
}
76
-
83
+
77
84
var allOptions = defaultDecideOptions + ( options ?? [ ] )
85
+ // Filtering out `enabledFlagsOnly` to ensure users always get a result.
78
86
allOptions. removeAll ( where: { $0 == . enabledFlagsOnly } )
79
87
80
- let decisionMap = decide ( user: user, keys: [ key] , options: allOptions, opType : . sync , ignoreDefaultOptions: true )
88
+ let decisionMap = decide ( user: user, keys: [ key] , options: allOptions, isAsync : false , ignoreDefaultOptions: true )
81
89
return decisionMap [ key] ?? OptimizelyDecision . errorDecision ( key: key, user: user, error: . generic)
82
90
}
83
91
92
+ /// Returns a decision result for a given key asynchronously
93
+ ///
94
+ /// - Parameters:
95
+ /// - user: The user context for which the decision is being made
96
+ /// - key: The feature flag key to evaluate
97
+ /// - options: An array of options for decision-making.
98
+ /// - completion: Handler will be called with a OptimizelyDecision
84
99
func decideAsync( user: OptimizelyUserContext ,
85
100
key: String ,
86
101
options: [ OptimizelyDecideOption ] ? = nil ,
@@ -99,53 +114,59 @@ extension OptimizelyClient {
99
114
}
100
115
101
116
var allOptions = self . defaultDecideOptions + ( options ?? [ ] )
117
+ // Filtering out `enabledFlagsOnly` to ensure users always get a result.
102
118
allOptions. removeAll ( where: { $0 == . enabledFlagsOnly } )
103
119
104
- let decisionMap = self . decide ( user: user, keys: [ key] , options: allOptions, opType : . async , ignoreDefaultOptions: true )
120
+ let decisionMap = self . decide ( user: user, keys: [ key] , options: allOptions, isAsync : true , ignoreDefaultOptions: true )
105
121
let decision = decisionMap [ key] ?? OptimizelyDecision . errorDecision ( key: key, user: user, error: . generic)
106
122
completion ( decision)
107
123
}
108
124
}
109
125
126
+ /// Returns a key-map of decision results for multiple flag keys
127
+ ///
128
+ /// - Parameters:
129
+ /// - user: The user context for which the decisions are being made
130
+ /// - keys: The feature flag keys to evaluate
131
+ /// - options: An array of options for decision-making.
132
+ /// - Returns: A dictionary of all decision results, mapped by flag keys.
110
133
func decide( user: OptimizelyUserContext ,
111
134
keys: [ String ] ,
112
135
options: [ OptimizelyDecideOption ] ? = nil ) -> [ String : OptimizelyDecision ] {
113
- return decide ( user: user, keys: keys, options: options, opType: . sync, ignoreDefaultOptions: false )
114
- }
115
-
116
- func decideAsync( user: OptimizelyUserContext ,
117
- keys: [ String ] ,
118
- options: [ OptimizelyDecideOption ] ? = nil ,
119
- completion: @escaping DecideForKeysCompletion ) {
120
- decisionQueue. async {
121
- let decisions = self . decide ( user: user, keys: keys, options: options, opType: . async, ignoreDefaultOptions: false )
122
- completion ( decisions)
123
- }
124
- }
125
-
126
- func decide( user: OptimizelyUserContext ,
127
- keys: [ String ] ,
128
- options: [ OptimizelyDecideOption ] ? = nil ,
129
- ignoreDefaultOptions: Bool ) -> [ String : OptimizelyDecision ] {
130
- return self . decide ( user: user, keys: keys, options: options, opType: . sync, ignoreDefaultOptions: ignoreDefaultOptions)
136
+ return decide ( user: user, keys: keys, options: options, isAsync: false )
131
137
}
132
138
139
+ /// Returns a decision result for a given key asynchronously
140
+ ///
141
+ /// - Parameters:
142
+ /// - user: The user context for which the decision is being made
143
+ /// - keys: The feature flag keys to evaluate
144
+ /// - options: An array of options for decision-making
145
+ /// - completion: Handler will be called with a dictionary mapping feature flag keys to OptimizelyDecision
133
146
func decideAsync( user: OptimizelyUserContext ,
134
147
keys: [ String ] ,
135
148
options: [ OptimizelyDecideOption ] ? = nil ,
136
- ignoreDefaultOptions: Bool ,
137
149
completion: @escaping DecideForKeysCompletion ) {
138
150
decisionQueue. async {
139
- let decisions = self . decide ( user: user, keys: keys, options: options, opType : . async , ignoreDefaultOptions : ignoreDefaultOptions )
151
+ let decisions = self . decide ( user: user, keys: keys, options: options, isAsync : true )
140
152
completion ( decisions)
141
153
}
142
154
}
143
155
156
+ /// Returns a key-map of decision results for multiple flag keys
157
+ ///
158
+ /// - Parameters:
159
+ /// - user: The user context for which to make the decision
160
+ /// - keys: Array of feature flag keys to decide upon
161
+ /// - options: Optional array of decision options that override default behavior
162
+ /// - isAsync: Boolean indicating whether the operation is asynchronous
163
+ /// - ignoreDefaultOptions: Boolean indicating whether to ignore default decide options
164
+ /// - Returns: A dictionary of all decision results, mapped by flag keys.
144
165
private func decide( user: OptimizelyUserContext ,
145
166
keys: [ String ] ,
146
167
options: [ OptimizelyDecideOption ] ? = nil ,
147
- opType : OPType ,
148
- ignoreDefaultOptions: Bool ) -> [ String : OptimizelyDecision ] {
168
+ isAsync : Bool ,
169
+ ignoreDefaultOptions: Bool = false ) -> [ String : OptimizelyDecision ] {
149
170
guard let config = self . config else {
150
171
logger. e ( OptimizelyError . sdkNotReady)
151
172
return [ : ]
@@ -187,7 +208,7 @@ extension OptimizelyClient {
187
208
}
188
209
}
189
210
190
- let decisionList = ( decisionService as? DefaultDecisionService ) ? . getVariationForFeatureList ( config: config, featureFlags: flagsWithoutForceDecision, user: user, opType : opType , options: allOptions)
211
+ let decisionList = ( decisionService as? DefaultDecisionService ) ? . getVariationForFeatureList ( config: config, featureFlags: flagsWithoutForceDecision, user: user, isAsync : isAsync , options: allOptions)
191
212
192
213
for index in 0 ..< flagsWithoutForceDecision. count {
193
214
if decisionList? . indices. contains ( index) ?? false {
@@ -221,6 +242,16 @@ extension OptimizelyClient {
221
242
return decisionMap
222
243
}
223
244
245
+ /// Returns a key-map of decision results for all flag keys
246
+ ///
247
+ /// This method evaluates all feature flags in the current configuration for the provided user.
248
+ /// It returns a dictionary mapping feature flag keys to their respective decisions.
249
+ ///
250
+ /// - Parameters:
251
+ /// - user: The user context for which decisions are made.
252
+ /// - options: Optional array of decision options that affect how decisions are made. Default is nil.
253
+ /// - Returns: A dictionary of all decision results, mapped by flag keys.
254
+ /// - Returns an empty dictionary if the SDK is not ready.
224
255
func decideAll( user: OptimizelyUserContext ,
225
256
options: [ OptimizelyDecideOption ] ? = nil ) -> [ String : OptimizelyDecision ] {
226
257
guard let config = self . config else {
@@ -231,6 +262,14 @@ extension OptimizelyClient {
231
262
return decide ( user: user, keys: config. featureFlagKeys, options: options)
232
263
}
233
264
265
+ /// Asynchronously evaluates all feature flags and returns the decisions.
266
+ ///
267
+ /// This method will return decisions for all feature flags in the project.
268
+ ///
269
+ /// - Parameters:
270
+ /// - user: The user context for which to evaluate the feature flags
271
+ /// - options: An array of options for decision-making. Default is nil.
272
+ /// - completion: Handler will be called with a dictionary mapping feature flag keys to OptimizelyDecision
234
273
func decideAllAsync( user: OptimizelyUserContext ,
235
274
options: [ OptimizelyDecideOption ] ? = nil ,
236
275
completion: @escaping DecideForKeysCompletion ) {
@@ -242,11 +281,11 @@ extension OptimizelyClient {
242
281
return
243
282
}
244
283
245
- let decision = self . decide ( user: user, keys: config. featureFlagKeys, options: options, opType : . async , ignoreDefaultOptions: false )
284
+ let decision = self . decide ( user: user, keys: config. featureFlagKeys, options: options, isAsync : true , ignoreDefaultOptions: false )
246
285
completion ( decision)
247
286
}
248
287
}
249
-
288
+
250
289
private func createOptimizelyDecision( flagKey: String ,
251
290
user: OptimizelyUserContext ,
252
291
flagDecision: FeatureDecision ? ,
@@ -358,16 +397,16 @@ extension OptimizelyClient {
358
397
359
398
if let valueType = Constants . VariableValueType ( rawValue: type) {
360
399
switch valueType {
361
- case . string:
362
- break
363
- case . integer:
364
- valueParsed = Int ( value)
365
- case . double:
366
- valueParsed = Double ( value)
367
- case . boolean:
368
- valueParsed = Bool ( value)
369
- case . json:
370
- valueParsed = OptimizelyJSON ( payload: value) ? . toMap ( )
400
+ case . string:
401
+ break
402
+ case . integer:
403
+ valueParsed = Int ( value)
404
+ case . double:
405
+ valueParsed = Double ( value)
406
+ case . boolean:
407
+ valueParsed = Bool ( value)
408
+ case . json:
409
+ valueParsed = OptimizelyJSON ( payload: value) ? . toMap ( )
371
410
}
372
411
}
373
412
0 commit comments