@@ -48,7 +48,7 @@ extension OptimizelyClient {
4848 return createUserContext ( userId: userId,
4949 attributes: ( attributes ?? [ : ] ) as [ String : Any ] )
5050 }
51-
51+
5252 /// Create a user context to be used internally without sending an ODP identify event.
5353 ///
5454 /// - Parameters:
@@ -62,6 +62,13 @@ extension OptimizelyClient {
6262 identify: false )
6363 }
6464
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
6572 func decide( user: OptimizelyUserContext ,
6673 key: String ,
6774 options: [ OptimizelyDecideOption ] ? = nil ) -> OptimizelyDecision {
@@ -73,14 +80,22 @@ extension OptimizelyClient {
7380 guard let _ = config. getFeatureFlag ( key: key) else {
7481 return OptimizelyDecision . errorDecision ( key: key, user: user, error: . featureKeyInvalid( key) )
7582 }
76-
83+
7784 var allOptions = defaultDecideOptions + ( options ?? [ ] )
85+ // Filtering out `enabledFlagsOnly` to ensure users always get a result.
7886 allOptions. removeAll ( where: { $0 == . enabledFlagsOnly } )
7987
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 )
8189 return decisionMap [ key] ?? OptimizelyDecision . errorDecision ( key: key, user: user, error: . generic)
8290 }
8391
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
8499 func decideAsync( user: OptimizelyUserContext ,
85100 key: String ,
86101 options: [ OptimizelyDecideOption ] ? = nil ,
@@ -99,53 +114,59 @@ extension OptimizelyClient {
99114 }
100115
101116 var allOptions = self . defaultDecideOptions + ( options ?? [ ] )
117+ // Filtering out `enabledFlagsOnly` to ensure users always get a result.
102118 allOptions. removeAll ( where: { $0 == . enabledFlagsOnly } )
103119
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 )
105121 let decision = decisionMap [ key] ?? OptimizelyDecision . errorDecision ( key: key, user: user, error: . generic)
106122 completion ( decision)
107123 }
108124 }
109125
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.
110133 func decide( user: OptimizelyUserContext ,
111134 keys: [ String ] ,
112135 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 )
131137 }
132138
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
133146 func decideAsync( user: OptimizelyUserContext ,
134147 keys: [ String ] ,
135148 options: [ OptimizelyDecideOption ] ? = nil ,
136- ignoreDefaultOptions: Bool ,
137149 completion: @escaping DecideForKeysCompletion ) {
138150 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 )
140152 completion ( decisions)
141153 }
142154 }
143155
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.
144165 private func decide( user: OptimizelyUserContext ,
145166 keys: [ String ] ,
146167 options: [ OptimizelyDecideOption ] ? = nil ,
147- opType : OPType ,
148- ignoreDefaultOptions: Bool ) -> [ String : OptimizelyDecision ] {
168+ isAsync : Bool ,
169+ ignoreDefaultOptions: Bool = false ) -> [ String : OptimizelyDecision ] {
149170 guard let config = self . config else {
150171 logger. e ( OptimizelyError . sdkNotReady)
151172 return [ : ]
@@ -187,7 +208,7 @@ extension OptimizelyClient {
187208 }
188209 }
189210
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)
191212
192213 for index in 0 ..< flagsWithoutForceDecision. count {
193214 if decisionList? . indices. contains ( index) ?? false {
@@ -221,6 +242,16 @@ extension OptimizelyClient {
221242 return decisionMap
222243 }
223244
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.
224255 func decideAll( user: OptimizelyUserContext ,
225256 options: [ OptimizelyDecideOption ] ? = nil ) -> [ String : OptimizelyDecision ] {
226257 guard let config = self . config else {
@@ -231,6 +262,14 @@ extension OptimizelyClient {
231262 return decide ( user: user, keys: config. featureFlagKeys, options: options)
232263 }
233264
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
234273 func decideAllAsync( user: OptimizelyUserContext ,
235274 options: [ OptimizelyDecideOption ] ? = nil ,
236275 completion: @escaping DecideForKeysCompletion ) {
@@ -242,11 +281,11 @@ extension OptimizelyClient {
242281 return
243282 }
244283
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 )
246285 completion ( decision)
247286 }
248287 }
249-
288+
250289 private func createOptimizelyDecision( flagKey: String ,
251290 user: OptimizelyUserContext ,
252291 flagDecision: FeatureDecision ? ,
@@ -358,16 +397,16 @@ extension OptimizelyClient {
358397
359398 if let valueType = Constants . VariableValueType ( rawValue: type) {
360399 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 ( )
371410 }
372411 }
373412
0 commit comments