Skip to content

Commit 3c71668

Browse files
fix: WIP update types
1 parent 63a63b8 commit 3c71668

File tree

4 files changed

+216
-77
lines changed

4 files changed

+216
-77
lines changed

DevCycle/DVCVariable.swift

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,8 @@ public class DVCVariable<T> {
5555
let oldValue = self.value
5656
self.value = value
5757
self.isDefaulted = false
58-
if let handler = self.handler,
59-
!isEqual(oldValue, variable.value)
60-
{
58+
59+
if let handler = self.handler, !isEqual(oldValue, variable.value) {
6160
handler(value)
6261
}
6362
} else {
@@ -85,7 +84,11 @@ public class DVCVariable<T> {
8584
}
8685

8786
private func addNotificationObserver() {
88-
NotificationCenter.default.addObserver(self, selector: #selector(propertyChange(notification:)), name: Notification.Name(NotificationNames.NewUserConfig), object: nil)
87+
NotificationCenter.default.addObserver(
88+
self,
89+
selector: #selector(propertyChange(notification:)),
90+
name: Notification.Name(NotificationNames.NewUserConfig),
91+
object: nil)
8992
}
9093

9194
public func onUpdate(handler: @escaping VariableValueHandler<T>) -> DVCVariable {

DevCycle/DevCycleClient.swift

Lines changed: 59 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ public typealias IdentifyCompletedHandler = (Error?, [String: Variable]?) -> Voi
2828
public typealias FlushCompletedHandler = (Error?) -> Void
2929
public typealias CloseCompletedHandler = () -> Void
3030

31+
internal typealias VariableInstanceDic = [String: NSMapTable<AnyObject, AnyObject>]
32+
3133

3234
public class DevCycleClient {
3335
var sdkKey: String?
@@ -51,7 +53,7 @@ public class DevCycleClient {
5153
private var flushTimer: Timer?
5254
private var closed: Bool = false
5355
private var inactivityWorkItem: DispatchWorkItem?
54-
private var variableInstanceDictonary = [String: NSMapTable<AnyObject, AnyObject>]()
56+
private var variableInstanceDictonary = VariableInstanceDic()
5557
private var isConfigCached: Bool = false
5658
private var disableAutomaticEventLogging: Bool = false
5759
private var disableCustomEventLogging: Bool = false
@@ -154,21 +156,17 @@ public class DevCycleClient {
154156
if let config = config {
155157
Log.debug("Config: \(config)", tags: ["setup"])
156158
}
157-
self.config?.userConfig = config
158-
self.isConfigCached = false
159-
160-
self.cacheUser(user: user)
159+
self.setUserConfig(config)
160+
self.cacheUser(user)
161161

162-
if (self.checkIfEdgeDBEnabled(config: config!, enableEdgeDB: self.enableEdgeDB)) {
163-
if (!(user.isAnonymous ?? false)) {
164-
self.service?.saveEntity(user: user, completion: { data, response, error in
165-
if error != nil {
166-
Log.error("Error saving user entity for \(user). Error: \(String(describing: error))")
167-
} else {
168-
Log.info("Saved user entity")
169-
}
170-
})
171-
}
162+
if (self.checkIfEdgeDBEnabled(config: config!, enableEdgeDB: self.enableEdgeDB) && !(user.isAnonymous ?? false)) {
163+
self.service?.saveEntity(user: user, completion: { data, response, error in
164+
if error != nil {
165+
Log.error("Error saving user entity for \(user). Error: \(String(describing: error))")
166+
} else {
167+
Log.info("Saved user entity")
168+
}
169+
})
172170
}
173171
}
174172

@@ -216,17 +214,40 @@ public class DevCycleClient {
216214
let extraParams = RequestParams(sse: sse, lastModified: lastModified, etag: etag)
217215
self.service?.getConfig(user: lastIdentifiedUser, enableEdgeDB: self.enableEdgeDB, extraParams: extraParams, completion: { [weak self] config, error in
218216
guard let self = self else { return }
217+
219218
if let error = error {
220219
Log.error("Error getting config: \(error)", tags: ["refetchConfig"])
220+
self.eventEmitter.emit(EventEmitValues.error(error))
221221
} else {
222-
self.config?.userConfig = config
223-
self.isConfigCached = false
222+
self.setUserConfig(config)
224223
}
225224
})
226225
}
227226
}
227+
228+
private func setUserConfig(_ config: UserConfig?) {
229+
let oldConfig = self.config
230+
self.config?.userConfig = config
231+
self.isConfigCached = false
232+
233+
if let config = config {
234+
self.eventEmitter.emitFeatureUpdates(
235+
oldFeatures: oldConfig?.userConfig?.features,
236+
newFeatures: config.features
237+
)
238+
self.eventEmitter.emitVariableUpdates(
239+
oldVariables: oldConfig?.userConfig?.variables,
240+
newVariables: config.variables,
241+
variableInstanceDic: self.variableInstanceDictonary
242+
)
243+
244+
if oldConfig == nil || config.etag != oldConfig?.userConfig?.etag {
245+
self.eventEmitter.emit(EventEmitValues.configUpdated(config.variables))
246+
}
247+
}
248+
}
228249

229-
private func cacheUser(user: DevCycleUser) {
250+
private func cacheUser(_ user: DevCycleUser) {
230251
self.cacheService.save(user: user)
231252
if user.isAnonymous == true, let userId = user.userId {
232253
self.cacheService.setAnonUserId(anonUserId: userId)
@@ -274,9 +295,10 @@ public class DevCycleClient {
274295
return variable(key: key, defaultValue: defaultValue).value
275296
}
276297

298+
private let regex = try? NSRegularExpression(pattern: ".*[^a-z0-9(\\-)(_)].*")
299+
277300
public func variable<T>(key: String, defaultValue: T) -> DVCVariable<T> {
278-
let regex = try? NSRegularExpression(pattern: ".*[^a-z0-9(\\-)(_)].*")
279-
if (regex?.firstMatch(in: key, range: NSMakeRange(0, key.count)) != nil) {
301+
if (self.regex?.firstMatch(in: key, range: NSMakeRange(0, key.count)) != nil) {
280302
Log.error("The variable key \(key) is invalid. It must contain only lowercase letters, numbers, hyphens and underscores. The default value will always be returned for this call.")
281303
return DVCVariable(
282304
key: key,
@@ -292,6 +314,7 @@ public class DevCycleClient {
292314
if (self.variableInstanceDictonary[key] == nil) {
293315
self.variableInstanceDictonary[key] = NSMapTable<AnyObject, AnyObject>(valueOptions: .weakMemory)
294316
}
317+
295318
if let variableFromDictionary = self.variableInstanceDictonary[key]?.object(forKey: defaultValue as AnyObject) as? DVCVariable<T> {
296319
variable = variableFromDictionary
297320
} else {
@@ -307,15 +330,16 @@ public class DevCycleClient {
307330
evalReason: nil
308331
)
309332
}
310-
self.variableInstanceDictonary[key]?.setObject(variable, forKey: defaultValue as AnyObject)
333+
334+
self.variableInstanceDictonary[key]?.setObject(variable, forKey: defaultValue as AnyObject)
311335
}
312336

313-
if (!self.closed) {
314-
if(!self.disableAutomaticEventLogging){
315-
self.eventQueue.updateAggregateEvents(variableKey: variable.key, variableIsDefaulted: variable.isDefaulted)
316-
}
337+
if (!self.closed && !self.disableAutomaticEventLogging) {
338+
self.eventQueue.updateAggregateEvents(variableKey: variable.key, variableIsDefaulted: variable.isDefaulted)
317339
}
318340

341+
342+
self.eventEmitter.emit(EventEmitValues.variableEvaluated(variable.key, variable))
319343
return variable
320344
}
321345
}
@@ -336,18 +360,19 @@ public class DevCycleClient {
336360

337361
self.service?.getConfig(user: updateUser, enableEdgeDB: self.enableEdgeDB, extraParams: nil, completion: { [weak self] config, error in
338362
guard let self = self else { return }
363+
339364
if let error = error {
340365
Log.error("Error getting config: \(error)", tags: ["identify"])
341366
self.cache = self.cacheService.load()
367+
self.eventEmitter.emit(EventEmitValues.error(error))
342368
} else {
343369
if let config = config {
344370
Log.debug("Config: \(config)", tags: ["identify"])
345371
}
346-
self.config?.userConfig = config
347-
self.isConfigCached = false
372+
self.setUserConfig(config)
348373
}
349374
self.user = user
350-
self.cacheUser(user: user)
375+
self.cacheUser(user)
351376
callback?(error, config?.variables)
352377
})
353378
}
@@ -364,21 +389,23 @@ public class DevCycleClient {
364389

365390
self.service?.getConfig(user: anonUser, enableEdgeDB: self.enableEdgeDB, extraParams: nil, completion: { [weak self] config, error in
366391
guard let self = self else { return }
367-
guard error == nil else {
392+
393+
if let error = error {
368394
if let previousAnonUserId = cachedAnonUserId {
369395
self.cacheService.setAnonUserId(anonUserId: previousAnonUserId)
370396
}
397+
self.eventEmitter.emit(EventEmitValues.error(error))
371398
callback?(error, nil)
372399
return
373400
}
374401

375402
if let config = config {
376403
Log.debug("Config: \(config)", tags: ["reset"])
404+
self.eventEmitter.emit(EventEmitValues.configUpdated(config.variables))
377405
}
378-
self.config?.userConfig = config
379-
self.isConfigCached = false
406+
self.setUserConfig(config)
380407
self.user = anonUser
381-
self.cacheUser(user: anonUser)
408+
self.cacheUser(anonUser)
382409
callback?(error, config?.variables)
383410
})
384411
}

0 commit comments

Comments
 (0)