Skip to content

Commit 4466da0

Browse files
fix: some crashes have come up because of logger injection. the reason seems to be the the binder is being updated every inject (#387)
1 parent f1995d5 commit 4466da0

13 files changed

+90
-76
lines changed

DemoSwiftApp/AppDelegate.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,18 @@
1717
import UIKit
1818
import Optimizely
1919

20+
private final class CustomLogger: OPTLogger {
21+
public static var logLevel: OptimizelyLogLevel = .info
22+
23+
required init() {
24+
}
25+
26+
public func log(level: OptimizelyLogLevel, message: String) {
27+
if level.rawValue <= CustomLogger.logLevel.rawValue {
28+
print("🐱 - [\(level.name)] Kitty - \(message)")
29+
}
30+
}
31+
}
2032
@UIApplicationMain
2133
class AppDelegate: UIResponder, UIApplicationDelegate {
2234
let logLevel = OptimizelyLogLevel.debug

DemoSwiftApp/Customization/CustomLogger.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import Foundation
1010
import Optimizely
1111

12-
class CustomLogger: OPTLogger {
12+
private final class CustomLogger: OPTLogger {
1313
public static var logLevel: OptimizelyLogLevel = .info
1414

1515
required init() {

Podfile.lock

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
PODS:
22
- OCMock (3.7.1)
3-
- SwiftLint (0.40.3)
3+
- SwiftLint (0.42.0)
44

55
DEPENDENCIES:
66
- OCMock (= 3.7.1)
@@ -13,8 +13,8 @@ SPEC REPOS:
1313

1414
SPEC CHECKSUMS:
1515
OCMock: 75fbeaa46a9b11f8c182bbb1d1f7e9a35ccc9955
16-
SwiftLint: dfd554ff0dff17288ee574814ccdd5cea85d76f7
16+
SwiftLint: 4fa9579c63416865179bc416f0a92d55f009600d
1717

1818
PODFILE CHECKSUM: 0195918f4c7b47425ae284153b642617e2ef6781
1919

20-
COCOAPODS: 1.9.3
20+
COCOAPODS: 1.9.2

Sources/Extensions/OptimizelyClient+Extension.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,24 +25,24 @@ extension OptimizelyClient {
2525
notificationCenter: OPTNotificationCenter) {
2626
// bind it as a non-singleton. so, we will create an instance anytime injected.
2727
// we don't associate the logger with a sdkKey at this time because not all components are sdkKey specific.
28-
let binder: Binder = Binder<OPTLogger>(service: OPTLogger.self).to(factory: type(of: logger).init)
28+
var binder: Binder = Binder<OPTLogger>(service: OPTLogger.self, factory: type(of: logger).init)
29+
2930
//Register my logger service.
3031
HandlerRegistryService.shared.registerBinding(binder: binder)
3132

3233
// this is bound a reusable singleton. so, if we re-initalize, we will keep this.
33-
HandlerRegistryService.shared.registerBinding(binder: Binder<OPTNotificationCenter>(service: OPTNotificationCenter.self).singetlon().reInitializeStrategy(strategy: .reUse).using(instance: notificationCenter).sdkKey(key: sdkKey))
34-
34+
HandlerRegistryService.shared.registerBinding(binder: Binder<OPTNotificationCenter>(sdkKey: sdkKey, service: OPTNotificationCenter.self, strategy: .reUse, isSingleton: true, inst: notificationCenter))
3535
// the decision service is also a singleton that will reCreate on re-initalize
36-
HandlerRegistryService.shared.registerBinding(binder: Binder<OPTDecisionService>(service: OPTDecisionService.self).singetlon().using(instance: decisionService).reInitializeStrategy(strategy: .reUse).sdkKey(key: sdkKey))
36+
HandlerRegistryService.shared.registerBinding(binder: Binder<OPTDecisionService>(sdkKey: sdkKey, service: OPTDecisionService.self, strategy: .reUse, isSingleton: true, inst: decisionService))
3737

3838
// An event dispatcher. We use a singleton and use the same Event dispatcher for all
3939
// projects. If you change the event dispatcher, you can potentially lose data if you
4040
// don't use the same backingstore.
41-
HandlerRegistryService.shared.registerBinding(binder: Binder<OPTEventDispatcher>(service: OPTEventDispatcher.self).singetlon().reInitializeStrategy(strategy: .reUse).using(instance: eventDispatcher).sdkKey(key: sdkKey))
41+
HandlerRegistryService.shared.registerBinding(binder: Binder<OPTEventDispatcher>(sdkKey: sdkKey, service: OPTEventDispatcher.self, strategy: .reUse, isSingleton: true, inst: eventDispatcher))
4242

4343
// This is a singleton and might be a good candidate for reuse. The handler supports mulitple
4444
// sdk keys without having to be created for every key.
45-
HandlerRegistryService.shared.registerBinding(binder: Binder<OPTDatafileHandler>(service: OPTDatafileHandler.self).singetlon().reInitializeStrategy(strategy: .reUse).to(factory: type(of: datafileHandler).init).using(instance: datafileHandler).sdkKey(key: sdkKey))
45+
HandlerRegistryService.shared.registerBinding(binder: Binder<OPTDatafileHandler>(sdkKey: sdkKey, service: OPTDatafileHandler.self, strategy: .reUse, isSingleton: true, inst: datafileHandler))
4646
}
4747

4848
/// OptimizelyClient init

Sources/Utils/HandlerRegistryService.swift

Lines changed: 18 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -52,16 +52,29 @@ class HandlerRegistryService {
5252

5353
let binderToUse = binders.property?[skLocal] ?? binders.property?[skGlobal]
5454

55+
func updateBinder(b : BinderProtocol) {
56+
if binders.property?[skLocal] != nil {
57+
binders.property?[skLocal] = b
58+
} else {
59+
binders.property?[skGlobal] = b
60+
}
61+
}
62+
5563
if var binder = binderToUse {
5664
if isReintialize && binder.strategy == .reCreate {
5765
binder.instance = binder.factory()
5866
result = binder.instance
67+
updateBinder(b: binder)
5968
} else if let inst = binder.instance, binder.isSingleton {
6069
result = inst
6170
} else {
71+
if !binder.isSingleton {
72+
return binder.factory()
73+
}
6274
let inst = binder.factory()
6375
binder.instance = inst
6476
result = inst
77+
updateBinder(b: binder)
6578
}
6679
}
6780
return result
@@ -97,7 +110,7 @@ protocol BinderProtocol {
97110
var instance: Any? { get set }
98111

99112
}
100-
class Binder<T>: BinderProtocol {
113+
struct Binder<T>: BinderProtocol {
101114
var sdkKey: String?
102115
var service: Any
103116
var strategy: ReInitializeStrategy = .reCreate
@@ -117,34 +130,13 @@ class Binder<T>: BinderProtocol {
117130
}
118131
}
119132

120-
init(service: Any) {
133+
init(sdkKey: String? = nil, service: Any, strategy: ReInitializeStrategy = .reCreate, factory: @escaping (() -> Any?) = { ()->Any? in { return nil as Any? }}, isSingleton: Bool = false, inst: T? = nil) {
134+
self.sdkKey = sdkKey
121135
self.service = service
122-
}
123-
124-
func sdkKey(key: String) -> Binder {
125-
self.sdkKey = key
126-
return self
127-
}
128-
129-
func singetlon() -> Binder {
130-
isSingleton = true
131-
return self
132-
}
133-
134-
func reInitializeStrategy(strategy: ReInitializeStrategy) -> Binder {
135136
self.strategy = strategy
136-
137-
return self
138-
}
139-
140-
func using(instance: T) -> Binder {
141-
self.inst = instance
142-
return self
143-
}
144-
145-
func to(factory:@escaping () -> T?) -> Binder {
146137
self.factory = factory
147-
return self
138+
self.isSingleton = isSingleton
139+
self.inst = inst
148140
}
149141
}
150142

Tests/OptimizelyTests-APIs/OptimizelyClientTests_DatafileHandler.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ class OptimizelyClientTests_DatafileHandler: XCTestCase {
6464
// set the url to use as our datafile download url
6565
handler.localFileUrl = fileUrl
6666

67-
HandlerRegistryService.shared.registerBinding(binder: Binder<OPTDatafileHandler>(service: OPTDatafileHandler.self).using(instance: handler).singetlon().sdkKey(key: sdkKey).reInitializeStrategy(strategy: .reUse))
67+
HandlerRegistryService.shared.registerBinding(binder: Binder<OPTDatafileHandler>(sdkKey: sdkKey, service: OPTDatafileHandler.self, strategy: .reUse, isSingleton: true, inst: handler))
6868

6969
let client = OptimizelyClient(sdkKey: sdkKey)
7070

Tests/OptimizelyTests-APIs/OptimizelyClientTests_Init_Async.swift

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,9 @@ class OptimizelyClientTests_Init_Async: XCTestCase {
5656
let testSdkKey = OTUtils.randomSdkKey // unique but consistent with registry + start
5757

5858
let handler = FakeDatafileHandler(mode: .successWithData)
59-
HandlerRegistryService.shared.registerBinding(binder: Binder(service: OPTDatafileHandler.self).sdkKey(key: testSdkKey).using(instance: handler).to(factory: FakeDatafileHandler.init).reInitializeStrategy(strategy: .reUse).singetlon())
59+
60+
HandlerRegistryService.shared.registerBinding(binder: Binder(sdkKey: testSdkKey, service: OPTDatafileHandler.self, strategy: .reUse, factory: FakeDatafileHandler.init, isSingleton: true, inst: handler))
61+
6062

6163
let optimizely = OptimizelyClient(sdkKey: testSdkKey)
6264

@@ -74,7 +76,7 @@ class OptimizelyClientTests_Init_Async: XCTestCase {
7476
let testSdkKey = OTUtils.randomSdkKey // unique but consistent with registry + start
7577

7678
let handler = FakeDatafileHandler(mode: .failure)
77-
HandlerRegistryService.shared.registerBinding(binder: Binder(service: OPTDatafileHandler.self).sdkKey(key: testSdkKey).using(instance: handler).to(factory: FakeDatafileHandler.init).reInitializeStrategy(strategy: .reUse).singetlon())
79+
HandlerRegistryService.shared.registerBinding(binder: Binder(sdkKey: testSdkKey, service: OPTDatafileHandler.self, strategy: .reUse, factory: FakeDatafileHandler.init, isSingleton: true, inst: handler))
7880

7981
let optimizely = OptimizelyClient(sdkKey: testSdkKey)
8082

@@ -95,8 +97,8 @@ class OptimizelyClientTests_Init_Async: XCTestCase {
9597
let testSdkKey = OTUtils.randomSdkKey // unique but consistent with registry + start
9698

9799
let handler = FakeDatafileHandler(mode: .failedToLoadFromCache)
98-
HandlerRegistryService.shared.registerBinding(binder: Binder(service: OPTDatafileHandler.self).sdkKey(key: testSdkKey).using(instance: handler).to(factory: FakeDatafileHandler.init).reInitializeStrategy(strategy: .reUse).singetlon())
99-
100+
HandlerRegistryService.shared.registerBinding(binder: Binder(sdkKey: testSdkKey, service: OPTDatafileHandler.self, strategy: .reUse, factory: FakeDatafileHandler.init, isSingleton: true, inst: handler))
101+
100102
let optimizely = OptimizelyClient(sdkKey: testSdkKey)
101103

102104
let exp = expectation(description: "x")
@@ -116,7 +118,7 @@ class OptimizelyClientTests_Init_Async: XCTestCase {
116118
let testSdkKey = OTUtils.randomSdkKey // unique but consistent with registry + start
117119

118120
let handler = FakeDatafileHandler(mode: .successWithData)
119-
HandlerRegistryService.shared.registerBinding(binder: Binder(service: OPTDatafileHandler.self).sdkKey(key: testSdkKey).using(instance: handler).to(factory: FakeDatafileHandler.init).reInitializeStrategy(strategy: .reUse).singetlon())
121+
HandlerRegistryService.shared.registerBinding(binder: Binder(sdkKey: testSdkKey, service: OPTDatafileHandler.self, strategy: .reUse, factory: FakeDatafileHandler.init, isSingleton: true, inst: handler))
120122

121123
let optimizely = OptimizelyClient(sdkKey: testSdkKey,
122124
periodicDownloadInterval: 1)

Tests/OptimizelyTests-APIs/OptimizelyClientTests_Init_Sync.swift

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ class OptimizelyClientTests_Init_Sync: XCTestCase {
7070
let testSdkKey = OTUtils.randomSdkKey // unique but consistent with registry + start
7171

7272
let handler = FakeDatafileHandler(mode: .successWithData)
73-
HandlerRegistryService.shared.registerBinding(binder: Binder(service: OPTDatafileHandler.self).sdkKey(key: testSdkKey).using(instance: handler).to(factory: FakeDatafileHandler.init).reInitializeStrategy(strategy: .reUse).singetlon())
73+
HandlerRegistryService.shared.registerBinding(binder: Binder(sdkKey: testSdkKey, service: OPTDatafileHandler.self, strategy: .reUse, factory: FakeDatafileHandler.init, isSingleton: true, inst: handler))
7474

7575
let optimizely = OptimizelyClient(sdkKey: testSdkKey)
7676

@@ -85,7 +85,7 @@ class OptimizelyClientTests_Init_Sync: XCTestCase {
8585
let testSdkKey = OTUtils.randomSdkKey // unique but consistent with registry + start
8686

8787
let handler = FakeDatafileHandler(mode: .successWithNil)
88-
HandlerRegistryService.shared.registerBinding(binder: Binder(service: OPTDatafileHandler.self).sdkKey(key: testSdkKey).using(instance: handler).to(factory: FakeDatafileHandler.init).reInitializeStrategy(strategy: .reUse).singetlon())
88+
HandlerRegistryService.shared.registerBinding(binder: Binder(sdkKey: testSdkKey, service: OPTDatafileHandler.self, strategy: .reUse, factory: FakeDatafileHandler.init, isSingleton: true, inst: handler))
8989

9090
let optimizely = OptimizelyClient(sdkKey: testSdkKey)
9191

@@ -100,7 +100,7 @@ class OptimizelyClientTests_Init_Sync: XCTestCase {
100100
let testSdkKey = OTUtils.randomSdkKey // unique but consistent with registry + start
101101

102102
let handler = FakeDatafileHandler(mode: .failure)
103-
HandlerRegistryService.shared.registerBinding(binder: Binder(service: OPTDatafileHandler.self).sdkKey(key: testSdkKey).using(instance: handler).to(factory: FakeDatafileHandler.init).reInitializeStrategy(strategy: .reUse).singetlon())
103+
HandlerRegistryService.shared.registerBinding(binder: Binder(sdkKey: testSdkKey, service: OPTDatafileHandler.self, strategy: .reUse, factory: FakeDatafileHandler.init, isSingleton: true, inst: handler))
104104

105105
let optimizely = OptimizelyClient(sdkKey: testSdkKey)
106106

@@ -115,7 +115,7 @@ class OptimizelyClientTests_Init_Sync: XCTestCase {
115115
let testSdkKey = OTUtils.randomSdkKey // unique but consistent with registry + start
116116

117117
let handler = FakeDatafileHandler(mode: .successWithData)
118-
HandlerRegistryService.shared.registerBinding(binder: Binder(service: OPTDatafileHandler.self).sdkKey(key: testSdkKey).using(instance: handler).to(factory: FakeDatafileHandler.init).reInitializeStrategy(strategy: .reUse).singetlon())
118+
HandlerRegistryService.shared.registerBinding(binder: Binder(sdkKey: testSdkKey, service: OPTDatafileHandler.self, strategy: .reUse, factory: FakeDatafileHandler.init, isSingleton: true, inst: handler))
119119

120120
let optimizely = OptimizelyClient(sdkKey: testSdkKey)
121121

@@ -130,7 +130,7 @@ class OptimizelyClientTests_Init_Sync: XCTestCase {
130130
let testSdkKey = OTUtils.randomSdkKey // unique but consistent with registry + start
131131

132132
let handler = FakeDatafileHandler(mode: .successWithData)
133-
HandlerRegistryService.shared.registerBinding(binder: Binder(service: OPTDatafileHandler.self).sdkKey(key: testSdkKey).using(instance: handler).to(factory: FakeDatafileHandler.init).reInitializeStrategy(strategy: .reUse).singetlon())
133+
HandlerRegistryService.shared.registerBinding(binder: Binder(sdkKey: testSdkKey, service: OPTDatafileHandler.self, strategy: .reUse, factory: FakeDatafileHandler.init, isSingleton: true, inst: handler))
134134

135135
let optimizely = OptimizelyClient(sdkKey: testSdkKey)
136136

@@ -147,7 +147,7 @@ class OptimizelyClientTests_Init_Sync: XCTestCase {
147147
let testSdkKey = OTUtils.randomSdkKey // unique but consistent with registry + start
148148

149149
let handler = FakeDatafileHandler(mode: .successWithData)
150-
HandlerRegistryService.shared.registerBinding(binder: Binder(service: OPTDatafileHandler.self).sdkKey(key: testSdkKey).using(instance: handler).to(factory: FakeDatafileHandler.init).reInitializeStrategy(strategy: .reUse).singetlon())
150+
HandlerRegistryService.shared.registerBinding(binder: Binder(sdkKey: testSdkKey, service: OPTDatafileHandler.self, strategy: .reUse, factory: FakeDatafileHandler.init, isSingleton: true, inst: handler))
151151

152152
let optimizely = OptimizelyClient(sdkKey: testSdkKey,
153153
periodicDownloadInterval: 10)
@@ -163,7 +163,7 @@ class OptimizelyClientTests_Init_Sync: XCTestCase {
163163
let testSdkKey = OTUtils.randomSdkKey // unique but consistent with registry + start
164164

165165
let handler = FakeDatafileHandler(mode: .successWithData)
166-
HandlerRegistryService.shared.registerBinding(binder: Binder(service: OPTDatafileHandler.self).sdkKey(key: testSdkKey).using(instance: handler).to(factory: FakeDatafileHandler.init).reInitializeStrategy(strategy: .reUse).singetlon())
166+
HandlerRegistryService.shared.registerBinding(binder: Binder(sdkKey: testSdkKey, service: OPTDatafileHandler.self, strategy: .reUse, factory: FakeDatafileHandler.init, isSingleton: true, inst: handler))
167167

168168
let optimizely = OptimizelyClient(sdkKey: testSdkKey,
169169
periodicDownloadInterval: 10)
@@ -185,7 +185,7 @@ class OptimizelyClientTests_Init_Sync: XCTestCase {
185185
let testSdkKey = OTUtils.randomSdkKey // unique but consistent with registry + start
186186

187187
let handler = FakeDatafileHandler(mode: .successWithData)
188-
HandlerRegistryService.shared.registerBinding(binder: Binder(service: OPTDatafileHandler.self).sdkKey(key: testSdkKey).using(instance: handler).to(factory: FakeDatafileHandler.init).reInitializeStrategy(strategy: .reUse).singetlon())
188+
HandlerRegistryService.shared.registerBinding(binder: Binder(sdkKey: testSdkKey, service: OPTDatafileHandler.self, strategy: .reUse, factory: FakeDatafileHandler.init, isSingleton: true, inst: handler))
189189

190190
let optimizely = OptimizelyClient(sdkKey: testSdkKey,
191191
periodicDownloadInterval: 10)

Tests/OptimizelyTests-APIs/OptimizelyClientTests_OptimizelyConfig.swift

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -73,12 +73,7 @@ class OptimizelyClientTests_OptimizelyConfig: XCTestCase {
7373

7474
let badUniqueSdkKey = "badUniqueSdkKey"
7575

76-
HandlerRegistryService.shared.registerBinding(binder: Binder(service: OPTDatafileHandler.self)
77-
.sdkKey(key: badUniqueSdkKey)
78-
.using(instance: FakeDatafileHandler())
79-
.to(factory: FakeDatafileHandler.init)
80-
.reInitializeStrategy(strategy: .reUse)
81-
.singetlon())
76+
HandlerRegistryService.shared.registerBinding(binder: Binder(sdkKey: badUniqueSdkKey, service: OPTDatafileHandler.self, strategy: .reUse, factory: FakeDatafileHandler.init, isSingleton: true, inst: FakeDatafileHandler()))
8277

8378
var optimizelyConfig: OptimizelyConfig?
8479
let optimizely = OptimizelyClient(sdkKey: badUniqueSdkKey, periodicDownloadInterval: 1)

0 commit comments

Comments
 (0)