1717#import " AppDelegate.h"
1818#import " VariationViewController.h"
1919#import " FailureViewController.h"
20+ #import " CustomLogger.h"
2021
2122@import Optimizely;
2223#if TARGET_OS_IOS
23- @import Amplitude_iOS;
24+ @import Amplitude_iOS;
2425#endif
2526
27+
28+ static NSString * const kOptimizelySdkKey = @" FCnSegiEkRry9rhVMroit4" ;
2629static NSString * const kOptimizelyDatafileName = @" demoTestDatafile" ;
2730static NSString * const kOptimizelyExperimentKey = @" background_experiment" ;
2831static NSString * const kOptimizelyEventKey = @" sample_conversion" ;
29- static NSString * const kOptimizelySdkKey = @" AqLkkcss3wRGUbftnKNgh2" ;
3032
3133@interface AppDelegate ()
3234@property (nonnull , strong , nonatomic ) NSString *userId;
3335@property (nonnull , strong , nonatomic ) NSDictionary *attributes;
34- @property (nullable , strong , nonatomic ) OptimizelyManager *optimizely;
36+ @property (nullable , strong , nonatomic ) OptimizelyClient *optimizely;
3537@end
3638
3739@implementation AppDelegate
3840
39-
4041- (BOOL )application : (UIApplication *)application didFinishLaunchingWithOptions : (NSDictionary *)launchOptions {
4142
42- self. userId = [ NSString stringWithFormat: @" %d " , arc4random_uniform ( 300000 )];
43- self. attributes = @{ @" browser_type " : @" safari " };
43+ // most of the third-party integrations only support iOS, so the sample code is only targeted for iOS builds
44+ # if TARGET_OS_IOS
4445
46+ #endif
4547
48+ self.userId = [NSString stringWithFormat: @" %d " , arc4random_uniform (300000 )];
49+ self.attributes = @{ @" browser_type" : @" safari" };
50+
4651 // initialize SDK in one of these two ways:
4752 // (1) asynchronous SDK initialization (RECOMMENDED)
4853 // - fetch a JSON datafile from the server
4954 // - network delay, but the local configuration is in sync with the server experiment settings
5055 // (2) synchronous SDK initialization
5156 // - initialize immediately with the given JSON datafile or its cached copy
5257 // - no network delay, but the local copy is not guaranteed to be in sync with the server experiment settings
53-
58+
5459 [self initializeOptimizelySDKAsynchronous ];
55- // [self initializeOptimizelySDKSynchronous];
56-
5760 return YES ;
5861}
5962
60- -(void )initializeOptimizelySDKAsynchronous {
61- self.optimizely = [[OptimizelyManager alloc ] initWithSdkKey: kOptimizelySdkKey ];
63+ // MARK: - Initialization Examples
6264
63- [self .optimizely initializeSDKWithCompletion: ^(NSData * _Nullable data, NSError * _Nullable error) {
65+ -(void )initializeOptimizelySDKAsynchronous {
66+ self.optimizely = [[OptimizelyClient alloc ] initWithSdkKey: kOptimizelySdkKey ];
67+
68+ [self .optimizely startWithCompletion: ^(NSData *data, NSError *error) {
6469 if (error == nil ) {
6570 NSLog (@" Optimizely SDK initialized successfully!" );
6671 } else {
6772 NSLog (@" Optimizely SDK initiliazation failed: %@ " , error.localizedDescription );
6873 self.optimizely = nil ;
6974 }
7075
71- [self .optimizely.notificationCenter addActivateNotificationListenerWithActivateListener: ^(NSDictionary <NSString *,id > * _Nonnull experiment, NSString * _Nonnull userId, NSDictionary <NSString *,id > * _Nullable attributes, NSDictionary <NSString *,id > * _Nonnull variation, NSDictionary <NSString *,id > * _Nonnull event) {
72- NSLog (@" got activate with experiment" );
73- NSLog (@" %@ " , experiment[@" key" ]);
74- }];
75- [self startAppWithExperimentActivated ];
76+ [self startWithRootViewController ];
7677 }];
7778}
7879
7980-(void )initializeOptimizelySDKSynchronous {
80- NSString *localDatafilePath = [[NSBundle bundleForClass: self .classForCoder ] pathForResource: kOptimizelyDatafileName ofType: @" json" ];
81+ NSString *localDatafilePath = [[NSBundle mainBundle ] pathForResource: kOptimizelyDatafileName ofType: @" json" ];
8182 if (localDatafilePath == nil ) {
8283 NSAssert (false , @" Local datafile cannot be found" );
8384 self.optimizely = nil ;
8485 return ;
8586 }
8687
87- self.optimizely = [[OptimizelyManager alloc ] initWithSdkKey: kOptimizelySdkKey ];
88-
89- // customization example (optional)
90- // TODO: add cutomization for ObjC
88+ self.optimizely = [[OptimizelyClient alloc ] initWithSdkKey: kOptimizelySdkKey ];
9189
9290 NSString *datafileJSON = [NSString stringWithContentsOfFile: localDatafilePath encoding: NSUTF8StringEncoding error: nil ];
93-
91+
9492 if (datafileJSON == nil ) {
9593 NSLog (@" Invalid JSON format" );
9694 self.optimizely = nil ;
9795 } else {
9896 NSError *error;
99- BOOL status = [self .optimizely initializeSDKWithDatafile : datafileJSON error: &error];
97+ BOOL status = [self .optimizely startWithDatafile : datafileJSON error: &error];
10098 if (status) {
10199 NSLog (@" Optimizely SDK initialized successfully!" );
102100 } else {
@@ -105,72 +103,117 @@ -(void)initializeOptimizelySDKSynchronous {
105103 }
106104 }
107105
108- [self startAppWithExperimentActivated ];
109- }
110-
111- -(void )startAppWithExperimentActivated {
112- NSError *error;
113- NSString *variationKey = [self .optimizely activateWithExperimentKey: kOptimizelyExperimentKey
114- userId: self .userId
115- attributes: self .attributes
116- error: &error];
117-
118- if (variationKey == nil ) {
119- NSLog (@" Optimizely SDK activation failed: %@ " , error.localizedDescription );
120- self.optimizely = nil ;
121- }
122-
123-
124- [self setRootViewControllerWithOtimizelyManager: self .optimizely bucketedVariation: variationKey];
106+ [self startWithRootViewController ];
125107}
126108
127- -(void )setRootViewControllerWithOtimizelyManager : (OptimizelyManager*)manager bucketedVariation : (NSString *)variationKey {
128- dispatch_async (dispatch_get_main_queue (), ^{
109+ -(void )initializeOptimizelySDKWithCustomization {
110+ // customization example (optional)
111+
112+ CustomLogger *customLogger = [[CustomLogger alloc ] init ];
113+ // 30 sec interval may be too frequent. This is for demo purpose.
114+ // This should be should be much larger (default = 10 mins).
115+ NSNumber *customDownloadIntervalInSecs = @(30 );
116+
117+ self.optimizely = [[OptimizelyClient alloc ] initWithSdkKey: kOptimizelySdkKey
118+ logger: customLogger
119+ eventDispatcher: nil
120+ userProfileService: nil
121+ periodicDownloadInterval: customDownloadIntervalInSecs
122+ defaultLogLevel: OptimizelyLogLevelInfo];
123+
124+ NSNumber *notifId;
125+ notifId = [self .optimizely.notificationCenter addDecisionNotificationListenerWithDecisionListener: ^(NSString *type,
126+ NSString *userId,
127+ NSDictionary <NSString *,id > *attributes,
128+ NSDictionary <NSString *,id > *decisionInfo) {
129+ NSLog (@" Received decision notification: %@ %@ %@ %@ " , type, userId, attributes, decisionInfo);
130+ }];
131+
132+ notifId = [self .optimizely.notificationCenter addTrackNotificationListenerWithTrackListener: ^(NSString *eventKey,
133+ NSString *userId,
134+ NSDictionary <NSString *,id > *attributes, NSDictionary <NSString *,id > *eventTags, NSDictionary <NSString *,id > *event) {
135+ NSLog (@" Received track notification: %@ %@ %@ %@ %@ " , eventKey, userId, attributes, eventTags, event);
129136
130137#if TARGET_OS_IOS
131- UIStoryboard *storyboard = [UIStoryboard storyboardWithName: @" iOSMain" bundle: nil ];
132- #else
133- UIStoryboard *storyboard = [UIStoryboard storyboardWithName: @" tvOSMain" bundle: nil ];
138+ // Amplitude example
139+ NSString *propertyKey = [NSString stringWithFormat: @" [Optimizely] %@ " , eventKey];
140+ AMPIdentify *identify = [[AMPIdentify alloc ] init ];
141+ [identify set: propertyKey value: userId];
142+ // Track event (optional)
143+ NSString *eventIdentifier = [NSString stringWithFormat: @" [Optimizely] %@ - %@ " , eventKey, userId];
144+ [Amplitude.instance logEvent: eventIdentifier];
134145#endif
135- UIViewController *rootViewController;
146+ }];
147+
148+ [self .optimizely startWithCompletion: ^(NSData *data, NSError *error) {
149+ if (error == nil ) {
150+ NSLog (@" Optimizely SDK initialized successfully!" );
151+ } else {
152+ NSLog (@" Optimizely SDK initiliazation failed: %@ " , error.localizedDescription );
153+ self.optimizely = nil ;
154+ }
155+
156+ [self startWithRootViewController ];
157+ }];
158+ }
159+
160+ // MARK: - ViewControl
161+
162+ -(void )startWithRootViewController {
163+ dispatch_async (dispatch_get_main_queue (), ^{
164+ NSError *error;
165+ NSString *variationKey = [self .optimizely activateWithExperimentKey: kOptimizelyExperimentKey
166+ userId: self .userId
167+ attributes: self .attributes
168+ error: &error];
136169
137- if ((manager != nil ) && (variationKey != nil )) {
138- VariationViewController *vc = [storyboard instantiateViewControllerWithIdentifier: @" VariationViewController" ];
139-
140- vc.eventKey = kOptimizelyEventKey ;
141- vc.optimizely = manager;
142- vc.userId = self.userId ;
143- vc.variationKey = variationKey;
144-
145- rootViewController = vc;
170+ if (variationKey != nil ) {
171+ [self openVariationViewWithVariationKey: variationKey];
146172 } else {
147- rootViewController = [storyboard instantiateViewControllerWithIdentifier: @" FailureViewController" ];
173+ NSLog (@" Optimizely SDK activation failed: %@ " , error.localizedDescription );
174+ [self openFailureView ];
148175 }
149-
150- self.window .rootViewController = rootViewController;
151176 });
152177}
153178
179+ -(void )openVariationViewWithVariationKey : (nullable NSString *)variationKey {
180+ VariationViewController *variationViewController = [self .storyboard instantiateViewControllerWithIdentifier: @" VariationViewController" ];
181+
182+ variationViewController.optimizely = self.optimizely ;
183+ variationViewController.userId = self.userId ;
184+ variationViewController.variationKey = variationKey;
185+ variationViewController.eventKey = kOptimizelyEventKey ;
186+
187+ self.window .rootViewController = variationViewController;
188+ }
154189
190+ -(void )openFailureView {
191+ self.window .rootViewController = [self .storyboard instantiateViewControllerWithIdentifier: @" FailureViewController" ];
192+ }
155193
156- - (void )applicationWillResignActive : (UIApplication *)application {
194+ -(UIStoryboard*)storyboard {
195+ #if TARGET_OS_IOS
196+ return [UIStoryboard storyboardWithName: @" iOSMain" bundle: nil ];
197+ #else
198+ return [UIStoryboard storyboardWithName: @" tvOSMain" bundle: nil ];
199+ #endif
157200}
158201
202+ // MARK: - AppDelegate
159203
160- - (void )applicationDidEnterBackground : (UIApplication *)application {
204+ - (void )applicationWillResignActive : (UIApplication *)application {
161205}
162206
207+ - (void )applicationDidEnterBackground : (UIApplication *)application {
208+ }
163209
164210- (void )applicationWillEnterForeground : (UIApplication *)application {
165211}
166212
167-
168213- (void )applicationDidBecomeActive : (UIApplication *)application {
169214}
170215
171-
172216- (void )applicationWillTerminate : (UIApplication *)application {
173217}
174218
175-
176219@end
0 commit comments