Skip to content

Commit

Permalink
feat: Add visitorID context (#106)
Browse files Browse the repository at this point in the history
* feat: Add visitorID context

* refactor: visitorId in UserDefaults

* Update VisitorUtil key
  • Loading branch information
fabriziodemaria committed Apr 30, 2024
1 parent 0624dee commit 0ca65ea
Show file tree
Hide file tree
Showing 10 changed files with 101 additions and 22 deletions.
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import Foundation
import Common
import Confidence

public class DefaultStorage: Storage {
private let storageQueue = DispatchQueue(label: "com.confidence.storage")
private let resolverCacheBundleId = "com.confidence.cache"
private let filePath: String

init(filePath: String) {
public init(filePath: String) {
self.filePath = filePath
}

Expand Down Expand Up @@ -83,7 +81,7 @@ public class DefaultStorage: Storage {
}
}

func getConfigUrl() throws -> URL {
public func getConfigUrl() throws -> URL {
guard
let applicationSupportUrl: URL = FileManager.default.urls(
for: .applicationSupportDirectory,
Expand All @@ -101,17 +99,3 @@ public class DefaultStorage: Storage {
components: resolverCacheBundleId, "\(bundleIdentifier)", filePath)
}
}

extension DefaultStorage {
public static func resolverFlagsCache() -> DefaultStorage {
DefaultStorage(filePath: "resolver.flags.cache")
}

public static func resolverApplyCache() -> DefaultStorage {
DefaultStorage(filePath: "resolver.apply.cache")
}

public static func applierFlagsCache() -> DefaultStorage {
DefaultStorage(filePath: "applier.flags.cache")
}
}
File renamed without changes.
19 changes: 15 additions & 4 deletions Sources/Confidence/Confidence.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ import Foundation
import Combine

public class Confidence: ConfidenceEventSender {
private let parent: ConfidenceContextProvider?
public let clientSecret: String
public var timeout: TimeInterval
public var region: ConfidenceRegion
let eventSenderEngine: EventSenderEngine
public var initializationStrategy: InitializationStrategy
private let parent: ConfidenceContextProvider?
private let eventSenderEngine: EventSenderEngine
private let contextFlow = CurrentValueSubject<ConfidenceStruct, Never>([:])
private var removedContextKeys: Set<String> = Set()
private let confidenceQueue = DispatchQueue(label: "com.confidence.queue")
Expand All @@ -19,7 +19,8 @@ public class Confidence: ConfidenceEventSender {
eventSenderEngine: EventSenderEngine,
initializationStrategy: InitializationStrategy,
context: ConfidenceStruct = [:],
parent: ConfidenceEventSender? = nil
parent: ConfidenceEventSender? = nil,
visitorId: String? = nil
) {
self.eventSenderEngine = eventSenderEngine
self.clientSecret = clientSecret
Expand All @@ -28,6 +29,9 @@ public class Confidence: ConfidenceEventSender {
self.initializationStrategy = initializationStrategy
self.contextFlow.value = context
self.parent = parent
if let visitorId {
putContext(context: ["visitorId": ConfidenceValue.init(string: visitorId)])
}
}

public func contextChanges() -> AnyPublisher<ConfidenceStruct, Never> {
Expand Down Expand Up @@ -120,6 +124,7 @@ extension Confidence {
var region: ConfidenceRegion = .global
var initializationStrategy: InitializationStrategy = .fetchAndActivate
let eventStorage: EventStorage
var visitorId: String?

public init(clientSecret: String) {
self.clientSecret = clientSecret
Expand All @@ -146,6 +151,11 @@ extension Confidence {
return self
}

public func withVisitorId() -> Builder {
self.visitorId = VisitorUtil().getId()
return self
}

public func build() -> Confidence {
let uploader = RemoteConfidenceClient(
options: ConfidenceClientOptions(
Expand All @@ -168,7 +178,8 @@ extension Confidence {
eventSenderEngine: eventSenderEngine,
initializationStrategy: initializationStrategy,
context: [:],
parent: nil
parent: nil,
visitorId: visitorId
)
}
}
Expand Down
18 changes: 18 additions & 0 deletions Sources/Confidence/VisitorUtil.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import Foundation
import Common

class VisitorUtil {
let defaults = UserDefaults.standard
let userDefaultsKey = "confidence.visitor_id"
func getId() -> String {
let id = defaults.string(forKey: userDefaultsKey) ?? ""
if id.isEmpty {
let newId = UUID.init().uuidString
defaults.set(newId, forKey: userDefaultsKey)
defaults.synchronize()
return newId
} else {
return id
}
}
}
14 changes: 14 additions & 0 deletions Sources/ConfidenceProvider/ConfidenceFeatureProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -676,5 +676,19 @@ extension ConfidenceFeatureProvider {
}
}
}

extension DefaultStorage {
public static func resolverFlagsCache() -> DefaultStorage {
DefaultStorage(filePath: "resolver.flags.cache")
}

public static func resolverApplyCache() -> DefaultStorage {
DefaultStorage(filePath: "resolver.apply.cache")
}

public static func applierFlagsCache() -> DefaultStorage {
DefaultStorage(filePath: "applier.flags.cache")
}
}
// swiftlint:enable type_body_length
// swiftlint:enable file_length
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import Foundation
import Common
import OpenFeature
import XCTest

Expand Down
1 change: 1 addition & 0 deletions Tests/ConfidenceProviderTests/DefaultStorageTest.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import Foundation
import Common
import OpenFeature
import XCTest

Expand Down
1 change: 1 addition & 0 deletions Tests/ConfidenceProviderTests/Helpers/StorageMock.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import Foundation
import Common
import OpenFeature
import XCTest

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import Foundation
import Common
import OpenFeature
import XCTest

Expand Down
48 changes: 48 additions & 0 deletions Tests/ConfidenceTests/ConfidenceTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -197,4 +197,52 @@ final class ConfidenceTests: XCTestCase {
]
XCTAssertEqual(confidenceChild.getContext(), expected)
}

func testVisitorId() {
let confidence = Confidence.init(
clientSecret: "",
timeout: TimeInterval(),
region: .europe,
eventSenderEngine: EventSenderEngineMock(),
initializationStrategy: .activateAndFetchAsync,
context: ["k1": ConfidenceValue(string: "v1")],
visitorId: "uuid"
)
let expected = [
"k1": ConfidenceValue(string: "v1"),
"visitorId": ConfidenceValue(string: "uuid")
]
XCTAssertEqual(confidence.getContext(), expected)
}

func testWithVisitorId() throws {
let userDefaults = UserDefaults.standard
userDefaults.removeObject(forKey: "confidence.visitor_id")
let confidence = Confidence.Builder(clientSecret: "")
.withVisitorId()
.build()
let visitorId = try XCTUnwrap(confidence.getContext()["visitorId"]?.asString())
XCTAssertNotEqual(visitorId, "")
XCTAssertNotEqual(visitorId, "storage-error")
let newConfidence = Confidence.Builder(clientSecret: "")
.withVisitorId()
.build()
XCTAssertEqual(visitorId, try XCTUnwrap(newConfidence.getContext()["visitorId"]?.asString()))
userDefaults.removeObject(forKey: "confidence.visitor_id")
let veryNewConfidence = Confidence.Builder(clientSecret: "")
.withVisitorId()
.build()
let newVisitorId = try XCTUnwrap(veryNewConfidence.getContext()["visitorId"]?.asString())
XCTAssertNotEqual(newVisitorId, "")
XCTAssertNotEqual(newVisitorId, "storage-error")
XCTAssertNotEqual(newVisitorId, visitorId)
}

func testWithoutVisitorId() throws {
let userDefaults = UserDefaults.standard
userDefaults.removeObject(forKey: "confidence.visitor_id")
let confidence = Confidence.Builder(clientSecret: "")
.build()
XCTAssertNil(confidence.getContext()["visitorId"])
}
}

0 comments on commit 0ca65ea

Please sign in to comment.