Skip to content

Commit 2332741

Browse files
Feature flag & rollout bucket decision (#206)
* Feature flag & rollout parsing * New Models added * variation variable usage mapping * Feature variable and its usage parsing * demoTestDatafile version upgraded to 4 and maintain compatibility to v3 * Test cases added for new models * get back to Asynchronous Initialization of OPTLYManager * CR updated * Feature flag & rollout bucketing decision * Decision Service Logic added * Test cases for getVariationForFeatureExperiment * Test cases for getVariationForFeatureRollout * CR updated * fix - file references * replaced experimentId & variationId with their objects in FeatureDecision * Removed xcode analyze warnings * copyright years changed * Increase code coverage for Optimizely * replaced macros with categories and static methods * getVariationForFeature revamped for mutex group * increase code coverage for Optimizely * Categories replaced with private static methods * categories replaced with private static methods * fix - OPTLYMacros.h reference in OptimizelySDKUniversal * fix - CI Checks failure * OPTLYFeatureFlag.m+h property "Key" changed to "key" * OPTLYFeatureFlag.m+h property "Key" changed to "key" * method name changed
1 parent 0307293 commit 2332741

33 files changed

+1610
-120
lines changed

OptimizelyDemoApp/AppDelegate.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/****************************************************************************
2-
* Copyright 2016-2017, Optimizely, Inc. and contributors *
2+
* Copyright 2017, Optimizely, Inc. and contributors *
33
* *
44
* Licensed under the Apache License, Version 2.0 (the "License"); *
55
* you may not use this file except in compliance with the License. *

OptimizelySDKCore/OptimizelySDKCore.xcodeproj/project.pbxproj

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,10 @@
7474
3E35DCCA1F47AD3D00018732 /* withoutOptProp.json in Resources */ = {isa = PBXBuildFile; fileRef = 3E35DCBB1F47AD3D00018732 /* withoutOptProp.json */; };
7575
3E35DCE61F47B42E00018732 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3E35DCE51F47B42E00018732 /* UIKit.framework */; };
7676
3E35DCE81F47B44900018732 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3E35DCE71F47B44900018732 /* CoreGraphics.framework */; };
77+
3E44F64A1FEAA2340044C005 /* OPTLYFeatureDecision.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E44F6471FEAA22F0044C005 /* OPTLYFeatureDecision.h */; settings = {ATTRIBUTES = (Public, ); }; };
78+
3E44F64B1FEAA2340044C005 /* OPTLYFeatureDecision.m in Sources */ = {isa = PBXBuildFile; fileRef = 3E44F6481FEAA22F0044C005 /* OPTLYFeatureDecision.m */; };
79+
3E44F64C1FEAA2340044C005 /* OPTLYFeatureDecision.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E44F6471FEAA22F0044C005 /* OPTLYFeatureDecision.h */; settings = {ATTRIBUTES = (Public, ); }; };
80+
3E44F64D1FEAA2340044C005 /* OPTLYFeatureDecision.m in Sources */ = {isa = PBXBuildFile; fileRef = 3E44F6481FEAA22F0044C005 /* OPTLYFeatureDecision.m */; };
7781
3E858C601F42277B00D53856 /* LICENSE in Resources */ = {isa = PBXBuildFile; fileRef = 3E858C5E1F42277B00D53856 /* LICENSE */; };
7882
3E858C661F4227BA00D53856 /* OPTLYJSONModelLib.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E858C651F4227BA00D53856 /* OPTLYJSONModelLib.h */; settings = {ATTRIBUTES = (Public, ); }; };
7983
3E858C6D1F4227CD00D53856 /* OPTLYJSONModel.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E858C671F4227CD00D53856 /* OPTLYJSONModel.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -277,8 +281,6 @@
277281
EA2FAB591DC6F5BE00B1D81B /* OPTLYLoggerMessages.h in Headers */ = {isa = PBXBuildFile; fileRef = EA2FAB4F1DC6F5BE00B1D81B /* OPTLYLoggerMessages.h */; settings = {ATTRIBUTES = (Public, ); }; };
278282
EA2FAB731DC6F5F400B1D81B /* OPTLYLog.h in Headers */ = {isa = PBXBuildFile; fileRef = EA2FAB6D1DC6F5F400B1D81B /* OPTLYLog.h */; settings = {ATTRIBUTES = (Public, ); }; };
279283
EA2FAB741DC6F5F400B1D81B /* OPTLYLog.h in Headers */ = {isa = PBXBuildFile; fileRef = EA2FAB6D1DC6F5F400B1D81B /* OPTLYLog.h */; settings = {ATTRIBUTES = (Public, ); }; };
280-
EA2FAB791DC6F5F400B1D81B /* OPTLYMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = EA2FAB6F1DC6F5F400B1D81B /* OPTLYMacros.h */; settings = {ATTRIBUTES = (Private, ); }; };
281-
EA2FAB7A1DC6F5F400B1D81B /* OPTLYMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = EA2FAB6F1DC6F5F400B1D81B /* OPTLYMacros.h */; settings = {ATTRIBUTES = (Private, ); }; };
282284
EA2FAB821DC6FA7D00B1D81B /* OptimizelySDKCore.h in Headers */ = {isa = PBXBuildFile; fileRef = EA3C68081DC1E66C00C578CA /* OptimizelySDKCore.h */; settings = {ATTRIBUTES = (Public, ); }; };
283285
EA2FAB831DC6FCD300B1D81B /* OptimizelySDKCore.h in Headers */ = {isa = PBXBuildFile; fileRef = EA3C68081DC1E66C00C578CA /* OptimizelySDKCore.h */; settings = {ATTRIBUTES = (Public, ); }; };
284286
EA2FAB9C1DC6FDFA00B1D81B /* OptimizelySDKCoreTests.m in Sources */ = {isa = PBXBuildFile; fileRef = EA2FAB841DC6FDFA00B1D81B /* OptimizelySDKCoreTests.m */; };
@@ -533,6 +535,8 @@
533535
3E35DCBB1F47AD3D00018732 /* withoutOptProp.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = withoutOptProp.json; path = Data/withoutOptProp.json; sourceTree = "<group>"; };
534536
3E35DCE51F47B42E00018732 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
535537
3E35DCE71F47B44900018732 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
538+
3E44F6471FEAA22F0044C005 /* OPTLYFeatureDecision.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OPTLYFeatureDecision.h; path = OptimizelySDKCore/OPTLYFeatureDecision.h; sourceTree = "<group>"; };
539+
3E44F6481FEAA22F0044C005 /* OPTLYFeatureDecision.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OPTLYFeatureDecision.m; path = OptimizelySDKCore/OPTLYFeatureDecision.m; sourceTree = "<group>"; };
536540
3E858C5E1F42277B00D53856 /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = LICENSE; path = OPTLYJSONModel/LICENSE; sourceTree = "<group>"; };
537541
3E858C5F1F42277B00D53856 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = OPTLYJSONModel/README.md; sourceTree = "<group>"; };
538542
3E858C651F4227BA00D53856 /* OPTLYJSONModelLib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OPTLYJSONModelLib.h; path = OPTLYJSONModel/OPTLYJSONModel/OPTLYJSONModelLib.h; sourceTree = "<group>"; };
@@ -654,7 +658,6 @@
654658
EA2FAB501DC6F5BE00B1D81B /* OPTLYLoggerMessages.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OPTLYLoggerMessages.m; sourceTree = "<group>"; };
655659
EA2FAB6D1DC6F5F400B1D81B /* OPTLYLog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OPTLYLog.h; sourceTree = "<group>"; };
656660
EA2FAB6E1DC6F5F400B1D81B /* OPTLYLog.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OPTLYLog.m; sourceTree = "<group>"; };
657-
EA2FAB6F1DC6F5F400B1D81B /* OPTLYMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OPTLYMacros.h; sourceTree = "<group>"; };
658661
EA2FAB841DC6FDFA00B1D81B /* OptimizelySDKCoreTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OptimizelySDKCoreTests.m; sourceTree = "<group>"; };
659662
EA2FAB861DC6FDFA00B1D81B /* OptimizelyTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OptimizelyTest.m; sourceTree = "<group>"; };
660663
EA2FAB871DC6FDFA00B1D81B /* OPTLYAudienceTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OPTLYAudienceTest.m; sourceTree = "<group>"; };
@@ -942,7 +945,6 @@
942945
children = (
943946
EA2FAB6D1DC6F5F400B1D81B /* OPTLYLog.h */,
944947
EA2FAB6E1DC6F5F400B1D81B /* OPTLYLog.m */,
945-
EA2FAB6F1DC6F5F400B1D81B /* OPTLYMacros.h */,
946948
EA064BC51DD3FC8800DF7537 /* OPTLYQueue.h */,
947949
EA064BC61DD3FC8800DF7537 /* OPTLYQueue.m */,
948950
);
@@ -1195,6 +1197,8 @@
11951197
children = (
11961198
EA16D9401ECCC5C600C4C998 /* OPTLYDecisionService.h */,
11971199
EA16D9411ECCC5C600C4C998 /* OPTLYDecisionService.m */,
1200+
3E44F6471FEAA22F0044C005 /* OPTLYFeatureDecision.h */,
1201+
3E44F6481FEAA22F0044C005 /* OPTLYFeatureDecision.m */,
11981202
EAC5F3511E7B7EEF00C087B8 /* OPTLYUserProfileServiceBasic.h */,
11991203
EAC5F3521E7B7EEF00C087B8 /* OPTLYUserProfileServiceBasic.m */,
12001204
);
@@ -1223,6 +1227,7 @@
12231227
EA16D9421ECCC5C600C4C998 /* OPTLYDecisionService.h in Headers */,
12241228
3E858C6F1F4227CD00D53856 /* OPTLYJSONModelClassProperty.h in Headers */,
12251229
3E858C851F4227E300D53856 /* OPTLYJSONValueTransformer.h in Headers */,
1230+
3E44F64A1FEAA2340044C005 /* OPTLYFeatureDecision.h in Headers */,
12261231
3E858C831F4227E300D53856 /* OPTLYJSONKeyMapper.h in Headers */,
12271232
3E858C711F4227CD00D53856 /* OPTLYJSONModelError.h in Headers */,
12281233
3ECB81FE1FD926FE006505E6 /* OPTLYVariableUsage.h in Headers */,
@@ -1271,7 +1276,6 @@
12711276
EA16D9361ECBA9B200C4C998 /* OPTLYUserProfile.h in Headers */,
12721277
EA16D93C1ECBD90E00C4C998 /* OPTLYExperimentBucketMapEntity.h in Headers */,
12731278
EA8FD0DF1DE9798E00D950AD /* OPTLYNetworkService.h in Headers */,
1274-
EA2FAB791DC6F5F400B1D81B /* OPTLYMacros.h in Headers */,
12751279
EA2FA9771DC6F3CF00B1D81B /* murmur3.h in Headers */,
12761280
);
12771281
runOnlyForDeploymentPostprocessing = 0;
@@ -1283,6 +1287,7 @@
12831287
EA16D9431ECCC5C600C4C998 /* OPTLYDecisionService.h in Headers */,
12841288
3E858C871F4227ED00D53856 /* OPTLYJSONModel.h in Headers */,
12851289
3E858C8B1F4227F900D53856 /* OPTLYJSONModelError.h in Headers */,
1290+
3E44F64C1FEAA2340044C005 /* OPTLYFeatureDecision.h in Headers */,
12861291
3E858C931F42280500D53856 /* OPTLYJSONModelLib.h in Headers */,
12871292
3E858C961F42280900D53856 /* OPTLYJSONValueTransformer.h in Headers */,
12881293
3ECB81FF1FD926FE006505E6 /* OPTLYVariableUsage.h in Headers */,
@@ -1331,7 +1336,6 @@
13311336
EA16D93D1ECBD90E00C4C998 /* OPTLYExperimentBucketMapEntity.h in Headers */,
13321337
EAC5F3541E7B7EEF00C087B8 /* OPTLYUserProfileServiceBasic.h in Headers */,
13331338
EA2FAAA71DC6F57200B1D81B /* OPTLYDecisionEventTicket.h in Headers */,
1334-
EA2FAB7A1DC6F5F400B1D81B /* OPTLYMacros.h in Headers */,
13351339
EA2FAC7B1DC70EBC00B1D81B /* murmur3.h in Headers */,
13361340
);
13371341
runOnlyForDeploymentPostprocessing = 0;
@@ -1876,6 +1880,7 @@
18761880
3E858C861F4227E300D53856 /* OPTLYJSONValueTransformer.m in Sources */,
18771881
3E858C701F4227CD00D53856 /* OPTLYJSONModelClassProperty.m in Sources */,
18781882
EA2FAC261DC6FFC600B1D81B /* OPTLYLoggerMessages.m in Sources */,
1883+
3E44F64B1FEAA2340044C005 /* OPTLYFeatureDecision.m in Sources */,
18791884
3E9CADFF1FD90E6200EBC49A /* OPTLYFeatureFlag.m in Sources */,
18801885
3E858C6E1F4227CD00D53856 /* OPTLYJSONModel.m in Sources */,
18811886
EA2FAC291DC6FFC600B1D81B /* OPTLYLog.m in Sources */,
@@ -1956,6 +1961,7 @@
19561961
3E858C8A1F4227F900D53856 /* OPTLYJSONModelClassProperty.m in Sources */,
19571962
EA2FAC001DC6FFA100B1D81B /* OPTLYLogger.m in Sources */,
19581963
3E858C951F42280900D53856 /* OPTLYJSONKeyMapper.m in Sources */,
1964+
3E44F64D1FEAA2340044C005 /* OPTLYFeatureDecision.m in Sources */,
19591965
3E9CAE011FD90E6200EBC49A /* OPTLYFeatureFlag.m in Sources */,
19601966
EA2FAC011DC6FFA100B1D81B /* OPTLYLoggerMessages.m in Sources */,
19611967
EA2FAC041DC6FFA100B1D81B /* OPTLYLog.m in Sources */,

OptimizelySDKCore/OptimizelySDKCore/OPTLYBucketer.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
@class OPTLYVariation;
2020
@class OPTLYExperiment;
21-
@class OPTLYProjectConfig;
21+
@class OPTLYProjectConfig, OPTLYGroup;
2222

2323
NS_ASSUME_NONNULL_BEGIN
2424
extern NSString *const OPTLYBucketerMutexPolicy;
@@ -54,6 +54,14 @@ NS_ASSUME_NONNULL_END
5454
*/
5555
- (nullable instancetype)initWithConfig:(nonnull OPTLYProjectConfig *)config;
5656

57+
/**
58+
* Bucket experiment based on bucket value and traffic allocations.
59+
* @param group representing OPTLYGroup from which experiment belongs to.
60+
* @param bucketingId Id to be used for bucketing the user.
61+
* @return experiment which represent OPTLYExperiment.
62+
*/
63+
- (nullable OPTLYExperiment *)bucketToExperiment:(nonnull OPTLYGroup *)group withBucketingId:(nonnull NSString *)bucketingId;
64+
5765
/**
5866
* Hash the bucketing ID and map it to the range [0, 10000).
5967
* @param bucketingId The ID for which to generate the hash and bucket values.

OptimizelySDKCore/OptimizelySDKCore/OPTLYDatafileKeys.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/****************************************************************************
2-
* Copyright 2016, Optimizely, Inc. and contributors *
2+
* Copyright 2017, Optimizely, Inc. and contributors *
33
* *
44
* Licensed under the Apache License, Version 2.0 (the "License"); *
55
* you may not use this file except in compliance with the License. *

OptimizelySDKCore/OptimizelySDKCore/OPTLYDatafileKeys.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/****************************************************************************
2-
* Copyright 2016, Optimizely, Inc. and contributors *
2+
* Copyright 2017, Optimizely, Inc. and contributors *
33
* *
44
* Licensed under the Apache License, Version 2.0 (the "License"); *
55
* you may not use this file except in compliance with the License. *

OptimizelySDKCore/OptimizelySDKCore/OPTLYDecisionService.h

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/****************************************************************************
2-
* Copyright 2017, Optimizely, Inc. and contributors *
2+
* Copyright 2017-2018, Optimizely, Inc. and contributors *
33
* *
44
* Licensed under the Apache License, Version 2.0 (the "License"); *
55
* you may not use this file except in compliance with the License. *
@@ -31,7 +31,7 @@
3131
// of user IDs that all map to the same experiment variation.
3232
extern NSString * _Nonnull const OptimizelyBucketId;
3333

34-
@class OPTLYExperiment, OPTLYVariation;
34+
@class OPTLYExperiment, OPTLYVariation, OPTLYFeatureFlag, OPTLYFeatureDecision;
3535

3636
@interface OPTLYDecisionService : OPTLYJSONModel
3737

@@ -66,5 +66,16 @@ extern NSString * _Nonnull const OptimizelyBucketId;
6666
- (nullable OPTLYVariation *)getVariation:(nonnull NSString *)userId
6767
experiment:(nonnull OPTLYExperiment *)experiment
6868
attributes:(nullable NSDictionary *)attributes;
69-
69+
70+
/**
71+
* Get a variation the user is bucketed into for the given FeatureFlag
72+
* @param featureFlag The feature flag the user wants to access.
73+
* @param userId The ID of the user.
74+
* @param attributes User attributes
75+
* @return The variation assigned to the specified user ID for a feature flag.
76+
*/
77+
- (nullable OPTLYFeatureDecision *)getVariationForFeature:(nonnull OPTLYFeatureFlag *)featureFlag
78+
userId:(nonnull NSString *)userId
79+
attributes:(nullable NSDictionary *)attributes;
80+
7081
@end

0 commit comments

Comments
 (0)