17
17
#import " AppDelegate.h"
18
18
#import " VariationViewController.h"
19
19
#import " FailureViewController.h"
20
+ #import " CustomLogger.h"
20
21
21
22
@import Optimizely;
22
23
#if TARGET_OS_IOS
23
- @import Amplitude_iOS;
24
+ @import Amplitude_iOS;
24
25
#endif
25
26
27
+
28
+ static NSString * const kOptimizelySdkKey = @" FCnSegiEkRry9rhVMroit4" ;
26
29
static NSString * const kOptimizelyDatafileName = @" demoTestDatafile" ;
27
30
static NSString * const kOptimizelyExperimentKey = @" background_experiment" ;
28
31
static NSString * const kOptimizelyEventKey = @" sample_conversion" ;
29
- static NSString * const kOptimizelySdkKey = @" AqLkkcss3wRGUbftnKNgh2" ;
30
32
31
33
@interface AppDelegate ()
32
34
@property (nonnull , strong , nonatomic ) NSString *userId;
33
35
@property (nonnull , strong , nonatomic ) NSDictionary *attributes;
34
- @property (nullable , strong , nonatomic ) OptimizelyManager *optimizely;
36
+ @property (nullable , strong , nonatomic ) OptimizelyClient *optimizely;
35
37
@end
36
38
37
39
@implementation AppDelegate
38
40
39
-
40
41
- (BOOL )application : (UIApplication *)application didFinishLaunchingWithOptions : (NSDictionary *)launchOptions {
41
42
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
44
45
46
+ #endif
45
47
48
+ self.userId = [NSString stringWithFormat: @" %d " , arc4random_uniform (300000 )];
49
+ self.attributes = @{ @" browser_type" : @" safari" };
50
+
46
51
// initialize SDK in one of these two ways:
47
52
// (1) asynchronous SDK initialization (RECOMMENDED)
48
53
// - fetch a JSON datafile from the server
49
54
// - network delay, but the local configuration is in sync with the server experiment settings
50
55
// (2) synchronous SDK initialization
51
56
// - initialize immediately with the given JSON datafile or its cached copy
52
57
// - no network delay, but the local copy is not guaranteed to be in sync with the server experiment settings
53
-
58
+
54
59
[self initializeOptimizelySDKAsynchronous ];
55
- // [self initializeOptimizelySDKSynchronous];
56
-
57
60
return YES ;
58
61
}
59
62
60
- -(void )initializeOptimizelySDKAsynchronous {
61
- self.optimizely = [[OptimizelyManager alloc ] initWithSdkKey: kOptimizelySdkKey ];
63
+ // MARK: - Initialization Examples
62
64
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) {
64
69
if (error == nil ) {
65
70
NSLog (@" Optimizely SDK initialized successfully!" );
66
71
} else {
67
72
NSLog (@" Optimizely SDK initiliazation failed: %@ " , error.localizedDescription );
68
73
self.optimizely = nil ;
69
74
}
70
75
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 ];
76
77
}];
77
78
}
78
79
79
80
-(void )initializeOptimizelySDKSynchronous {
80
- NSString *localDatafilePath = [[NSBundle bundleForClass: self .classForCoder ] pathForResource: kOptimizelyDatafileName ofType: @" json" ];
81
+ NSString *localDatafilePath = [[NSBundle mainBundle ] pathForResource: kOptimizelyDatafileName ofType: @" json" ];
81
82
if (localDatafilePath == nil ) {
82
83
NSAssert (false , @" Local datafile cannot be found" );
83
84
self.optimizely = nil ;
84
85
return ;
85
86
}
86
87
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 ];
91
89
92
90
NSString *datafileJSON = [NSString stringWithContentsOfFile: localDatafilePath encoding: NSUTF8StringEncoding error: nil ];
93
-
91
+
94
92
if (datafileJSON == nil ) {
95
93
NSLog (@" Invalid JSON format" );
96
94
self.optimizely = nil ;
97
95
} else {
98
96
NSError *error;
99
- BOOL status = [self .optimizely initializeSDKWithDatafile : datafileJSON error: &error];
97
+ BOOL status = [self .optimizely startWithDatafile : datafileJSON error: &error];
100
98
if (status) {
101
99
NSLog (@" Optimizely SDK initialized successfully!" );
102
100
} else {
@@ -105,72 +103,117 @@ -(void)initializeOptimizelySDKSynchronous {
105
103
}
106
104
}
107
105
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 ];
125
107
}
126
108
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);
129
136
130
137
#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];
134
145
#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];
136
169
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];
146
172
} else {
147
- rootViewController = [storyboard instantiateViewControllerWithIdentifier: @" FailureViewController" ];
173
+ NSLog (@" Optimizely SDK activation failed: %@ " , error.localizedDescription );
174
+ [self openFailureView ];
148
175
}
149
-
150
- self.window .rootViewController = rootViewController;
151
176
});
152
177
}
153
178
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
+ }
154
189
190
+ -(void )openFailureView {
191
+ self.window .rootViewController = [self .storyboard instantiateViewControllerWithIdentifier: @" FailureViewController" ];
192
+ }
155
193
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
157
200
}
158
201
202
+ // MARK: - AppDelegate
159
203
160
- - (void )applicationDidEnterBackground : (UIApplication *)application {
204
+ - (void )applicationWillResignActive : (UIApplication *)application {
161
205
}
162
206
207
+ - (void )applicationDidEnterBackground : (UIApplication *)application {
208
+ }
163
209
164
210
- (void )applicationWillEnterForeground : (UIApplication *)application {
165
211
}
166
212
167
-
168
213
- (void )applicationDidBecomeActive : (UIApplication *)application {
169
214
}
170
215
171
-
172
216
- (void )applicationWillTerminate : (UIApplication *)application {
173
217
}
174
218
175
-
176
219
@end
0 commit comments