Skip to content

Commit 4d26821

Browse files
authored
feat(event processor): Add LogEvent notification support (#263)
* fix existing tests for ep batch changes * add support for maxQueueSize - configurable * add LogEvent notification to event processor
1 parent fdc843f commit 4d26821

File tree

12 files changed

+266
-107
lines changed

12 files changed

+266
-107
lines changed

.travis.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@ jobs:
5353
branches:
5454
only:
5555
- master
56-
env: SCHEME=OptimizelySwiftSDK-iOS TEST_SDK=iphonesimulator PLATFORM='iOS Simulator' OS=9.3 NAME='iPad Air'
57-
name: PLATFORM='iOS Simulator' OS=9.3 NAME='iPad Air'
56+
env: SCHEME=OptimizelySwiftSDK-iOS TEST_SDK=iphonesimulator PLATFORM='iOS Simulator' OS=12.1 NAME='iPhone 7'
57+
name: PLATFORM='iOS Simulator' OS=12.1 NAME='iPhone 7'
5858
install:
5959
- gem install slather --no-document --quiet
6060
- gem install cocoapods -v '1.6.1'
@@ -80,8 +80,8 @@ jobs:
8080
env: SCHEME=OptimizelySwiftSDK-iOS TEST_SDK=iphonesimulator PLATFORM='iOS Simulator' OS=11.4 NAME='iPhone 7 Plus'
8181
name: PLATFORM='iOS Simulator' OS=11.4 NAME='iPhone 7 Plus'
8282
- <<: *unittests
83-
env: SCHEME=OptimizelySwiftSDK-iOS TEST_SDK=iphonesimulator PLATFORM='iOS Simulator' OS=12.1 NAME='iPhone 7'
84-
name: PLATFORM='iOS Simulator' OS=12.1 NAME='iPhone 7'
83+
env: SCHEME=OptimizelySwiftSDK-iOS TEST_SDK=iphonesimulator PLATFORM='iOS Simulator' OS=9.3 NAME='iPad Air'
84+
name: PLATFORM='iOS Simulator' OS=9.3 NAME='iPad Air'
8585
- <<: *unittests
8686
env: SCHEME=OptimizelySwiftSDK-tvOS TEST_SDK=appletvsimulator PLATFORM='tvOS Simulator' OS=12.1 NAME='Apple TV 4K'
8787
name: PLATFORM='tvOS Simulator' OS=12.1 NAME='Apple TV 4K'

DemoObjCApp/AppDelegate.m

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,14 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(
5555
// MARK: - Initialization Examples
5656

5757
-(void)initializeOptimizelySDKAsynchronous {
58-
DefaultEventDispatcher *eventDispacher = [[DefaultEventDispatcher alloc] initWithTimerInterval:1];
58+
DefaultEventDispatcher *eventDispacher = [[DefaultEventDispatcher alloc] initWithBatchSize:10 timerInterval:1 maxQueueSize:1000];
5959

60-
self.optimizely = [[OptimizelyClient alloc] initWithSdkKey:kOptimizelySdkKey logger:nil eventDispatcher:eventDispacher userProfileService:nil periodicDownloadInterval:@(5) defaultLogLevel:OptimizelyLogLevelDebug];
60+
self.optimizely = [[OptimizelyClient alloc] initWithSdkKey:kOptimizelySdkKey
61+
logger:nil
62+
eventDispatcher:eventDispacher
63+
userProfileService:nil
64+
periodicDownloadInterval:@(5)
65+
defaultLogLevel:OptimizelyLogLevelDebug];
6166

6267
[self.optimizely startWithCompletion:^(NSData *data, NSError *error) {
6368
if (error == nil) {
@@ -126,6 +131,11 @@ -(void)initializeOptimizelySDKWithCustomization {
126131

127132
}];
128133

134+
notifId = [self.optimizely.notificationCenter addLogEventNotificationListenerWithLogEventListener:^(NSString *url,
135+
NSDictionary<NSString *,id> *event) {
136+
NSLog(@"Received logEvent notification: %@ %@", url, event);
137+
}];
138+
129139
[self.optimizely startWithCompletion:^(NSData *data, NSError *error) {
130140
if (error == nil) {
131141
NSLog(@"Optimizely SDK initialized successfully!");

DemoSwiftApp/AppDelegate.swift

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
8282

8383
do {
8484
let datafileJSON = try String(contentsOfFile: localDatafilePath, encoding: .utf8)
85-
try optimizely!.start(datafile: datafileJSON)
85+
try optimizely.start(datafile: datafileJSON)
8686

8787
print("Optimizely SDK initialized successfully!")
8888
} catch {
@@ -108,7 +108,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
108108
addListeners()
109109

110110
// initialize SDK
111-
optimizely!.start { result in
111+
optimizely.start { result in
112112
switch result {
113113
case .failure(let error):
114114
print("Optimizely SDK initiliazation failed: \(error)")
@@ -151,7 +151,10 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
151151
}
152152
}
153153
})
154-
154+
155+
_ = optimizely.notificationCenter.addLogEventNotificationListener(logEventListener: { (url, event) in
156+
print("Received logEvent notification: \(url) \(event)")
157+
})
155158
}
156159

157160
// MARK: - ViewControl

OptimizelySwiftSDK.xcodeproj/xcshareddata/xcschemes/OptimizelySwiftSDK-tvOS.xcscheme

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
buildConfiguration = "Debug"
2727
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
2828
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
29-
codeCoverageEnabled = "YES"
3029
shouldUseLaunchSchemeArgsEnv = "YES">
3130
<Testables>
3231
<TestableReference

Sources/Customization/DefaultEventDispatcher.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,6 @@ open class DefaultEventDispatcher: BackgroundingCallbacks, OPTEventDispatcher {
8080
dataStore: DataStoreUserDefaults())
8181
}
8282

83-
8483
if self.maxQueueSize < self.batchSize {
8584
self.logger.e(.eventDispatcherConfigError("batchSize cannot be bigger than maxQueueSize"))
8685
self.maxQueueSize = self.batchSize
@@ -93,7 +92,7 @@ open class DefaultEventDispatcher: BackgroundingCallbacks, OPTEventDispatcher {
9392

9493
deinit {
9594
stopTimer()
96-
95+
9796
removeProjectChangeNotificationObservers()
9897

9998
unsubscribe()
@@ -189,6 +188,9 @@ open class DefaultEventDispatcher: BackgroundingCallbacks, OPTEventDispatcher {
189188
request.httpBody = event.body
190189
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
191190

191+
// send notification BEFORE sending event to the server
192+
NotificationCenter.default.post(name: .willSendOptimizelyEvents, object: event)
193+
192194
let task = session.uploadTask(with: request, from: event.body) { (_, response, error) in
193195
self.logger.d(response.debugDescription)
194196

Sources/Implementation/DefaultNotificationCenter.swift

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,14 @@ public class DefaultNotificationCenter: OPTNotificationCenter {
2020
public var notificationId: Int = 1
2121
var notificationListeners = [Int: (Int, GenericListener)]()
2222

23+
var observerLogEvent: NSObjectProtocol?
24+
2325
required public init() {
24-
26+
addInternalNotificationListners()
27+
}
28+
29+
deinit {
30+
removeInternalNotificationListners()
2531
}
2632

2733
internal func incrementNotificationId() -> Int {
@@ -116,6 +122,23 @@ public class DefaultNotificationCenter: OPTNotificationCenter {
116122
return incrementNotificationId()
117123
}
118124

125+
public func addLogEventNotificationListener(logEventListener: @escaping LogEventListener) -> Int? {
126+
notificationListeners[notificationId] = (NotificationType.logEvent.rawValue, { (args: Any...) in
127+
guard let myArgs = args[0] as? [Any?] else {
128+
return
129+
}
130+
if myArgs.count < 2 {
131+
return
132+
}
133+
if let url = myArgs[0] as? String,
134+
let event = myArgs[1] as? [String: Any] {
135+
logEventListener(url, event)
136+
}
137+
})
138+
139+
return incrementNotificationId()
140+
}
141+
119142
public func removeNotificationListener(notificationId: Int) {
120143
self.notificationListeners.removeValue(forKey: notificationId)
121144
}
@@ -135,3 +158,31 @@ public class DefaultNotificationCenter: OPTNotificationCenter {
135158
}
136159

137160
}
161+
162+
// MARK: Notification Translation
163+
164+
extension DefaultNotificationCenter {
165+
166+
func addInternalNotificationListners() {
167+
observerLogEvent = NotificationCenter.default.addObserver(forName: .willSendOptimizelyEvents, object: nil, queue: nil) { (notif) in
168+
guard let eventForDispatch = notif.object as? EventForDispatch else { return }
169+
170+
let url = eventForDispatch.url.absoluteString
171+
let eventData = eventForDispatch.body
172+
173+
if let event = try? JSONSerialization.jsonObject(with: eventData, options: []) as? [String: Any] {
174+
let args: [Any] = [url, event]
175+
self.sendNotifications(type: NotificationType.logEvent.rawValue, args: args)
176+
} else {
177+
print("LogEvent notification discarded due to invalid event")
178+
}
179+
}
180+
}
181+
182+
func removeInternalNotificationListners() {
183+
if let observer = observerLogEvent {
184+
NotificationCenter.default.removeObserver(observer, name: .willSendOptimizelyEvents, object: nil)
185+
}
186+
}
187+
188+
}

Sources/Optimizely/OptimizelyClient+ObjC.swift

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,14 @@ extension OptimizelyClient {
410410
return returnVal(num: num)
411411
}
412412

413+
func addLogEventNotificationListener(logEventListener: @escaping (String, [String: Any]) -> Void) -> NSNumber? {
414+
let num = notifications.addLogEventNotificationListener { (url, event) in
415+
logEventListener(url, event)
416+
}
417+
418+
return returnVal(num: num)
419+
}
420+
413421
func removeNotificationListener(notificationId: Int) {
414422
notifications.removeNotificationListener(notificationId: notificationId)
415423
}
@@ -441,8 +449,10 @@ extension OptimizelyClient {
441449

442450
let innerEventDispatcher: DefaultEventDispatcher
443451

444-
@objc public init(timerInterval: TimeInterval) {
445-
innerEventDispatcher = DefaultEventDispatcher(timerInterval: timerInterval)
452+
@objc public init(batchSize: Int = DefaultEventDispatcher.DefaultValues.batchSize,
453+
timerInterval: TimeInterval = DefaultEventDispatcher.DefaultValues.timeInterval,
454+
maxQueueSize: Int = DefaultEventDispatcher.DefaultValues.maxQueueSize) {
455+
innerEventDispatcher = DefaultEventDispatcher(batchSize: batchSize, timerInterval: timerInterval, maxQueueSize: maxQueueSize)
446456
}
447457

448458
public func dispatchEvent(event: EventForDispatch, completionHandler: ((Data?, NSError?) -> Void)?) {

0 commit comments

Comments
 (0)