diff --git a/Split/Api/DefaultSplitClient.swift b/Split/Api/DefaultSplitClient.swift index 87a8949ba..103ee73d5 100644 --- a/Split/Api/DefaultSplitClient.swift +++ b/Split/Api/DefaultSplitClient.swift @@ -16,7 +16,7 @@ public final class DefaultSplitClient: NSObject, SplitClient, TelemetrySplitClie private let anyValueValidator: AnyValueValidator private var isClientDestroyed = false private let eventsTracker: EventsTracker - private weak var clientManager: SplitClientManager? + private let clientManager: SplitClientManager @objc public var listener: SplitEventListener? var initStopwatch: Stopwatch? @@ -66,14 +66,8 @@ extension DefaultSplitClient { } private func on(event: SplitEvent, runInBackground: Bool, queue: DispatchQueue?, execute action: @escaping SplitAction) { - - guard let factory = clientManager?.splitFactory else { - return - } - let task = SplitEventActionTask(action: action, event: event, runInBackground: runInBackground, - factory: factory, queue: queue) task.event = event on(event: event, executeTask: task) @@ -105,8 +99,7 @@ extension DefaultSplitClient { } private func registerEvent(_ event: SplitEvent, action: @Sendable @escaping (T) -> Void) { - guard let factory = clientManager?.splitFactory else { return } - let task = SplitEventActionTask(action: action, event: event, runInBackground: true, factory: factory, queue: nil) + let task = SplitEventActionTask(action: action, event: event, runInBackground: true, queue: nil) eventsManager.register(event: event, task: task) } } @@ -301,9 +294,7 @@ extension DefaultSplitClient { extension DefaultSplitClient { private func syncFlush() { - if let clientManager = clientManager { - clientManager.flush() - } + clientManager.flush() } public func flush() { @@ -324,10 +315,8 @@ extension DefaultSplitClient { DispatchQueue.global().async { [weak self, sendableCompletion] in guard let self = self else { return } - if let clientManager = self.clientManager { - clientManager.destroy(forKey: self.key) - sendableCompletion.completion?() - } + self.clientManager.destroy(forKey: self.key) + sendableCompletion.completion?() } } } diff --git a/Split/Api/DefaultSplitFactory.swift b/Split/Api/DefaultSplitFactory.swift index 3c593cb30..6de88e376 100644 --- a/Split/Api/DefaultSplitFactory.swift +++ b/Split/Api/DefaultSplitFactory.swift @@ -113,8 +113,7 @@ public class DefaultSplitFactory: NSObject, SplitFactory, @unchecked Sendable { eventsManagerCoordinator: eventsManager, mySegmentsSyncWorkerFactory: mySegmentsSyncWorkerFactory, telemetryStopwatch: params.initStopwatch, - propertyValidator: components.getPropertyValidator(), - factory: self) + propertyValidator: components.getPropertyValidator()) components.destroy() diff --git a/Split/Api/LocalhostSplitClient.swift b/Split/Api/LocalhostSplitClient.swift index a5bf65f9f..6c6087f81 100644 --- a/Split/Api/LocalhostSplitClient.swift +++ b/Split/Api/LocalhostSplitClient.swift @@ -48,14 +48,12 @@ public final class LocalhostSplitClient: NSObject, SplitClient { private let eventsManager: SplitEventsManager? private var evaluator: Evaluator private let key: Key - weak var clientManager: SplitClientManager? @objc public var listener: SplitEventListener? - init(key: Key, splitsStorage: SplitsStorage, clientManager: SplitClientManager?, eventsManager: SplitEventsManager? = nil, evaluator: Evaluator) { + init(key: Key, splitsStorage: SplitsStorage, eventsManager: SplitEventsManager? = nil, evaluator: Evaluator) { self.eventsManager = eventsManager self.key = key self.splitsStorage = splitsStorage - self.clientManager = clientManager self.evaluator = evaluator super.init() @@ -132,12 +130,9 @@ public final class LocalhostSplitClient: NSObject, SplitClient { } private func on(event: SplitEvent, runInBackground: Bool, queue: DispatchQueue?, execute action: @escaping SplitAction) { - - guard let factory = clientManager?.splitFactory else { return } if let eventsManager = self.eventsManager { let task = SplitEventActionTask(action: action, event: event, runInBackground: runInBackground, - factory: factory, queue: queue) eventsManager.register(event: event, task: task) } @@ -159,8 +154,7 @@ public final class LocalhostSplitClient: NSObject, SplitClient { } private func registerEvent(_ event: SplitEvent, action: @Sendable @escaping (T) -> Void) { - guard let factory = clientManager?.splitFactory else { return } - let task = SplitEventActionTask(action: action, event: event, runInBackground: true, factory: factory, queue: nil) + let task = SplitEventActionTask(action: action, event: event, runInBackground: true, queue: nil) eventsManager?.register(event: event, task: task) } diff --git a/Split/Api/LocalhostSplitFactory.swift b/Split/Api/LocalhostSplitFactory.swift index 1347514fc..356dad373 100644 --- a/Split/Api/LocalhostSplitFactory.swift +++ b/Split/Api/LocalhostSplitFactory.swift @@ -64,8 +64,7 @@ public class LocalhostSplitFactory: NSObject, SplitFactory { splitManager: localhostManager, splitsStorage: splitsStorage, synchronizer: synchronizer, - eventsManagerCoordinator: eventsManager, - factory: self) + eventsManagerCoordinator: eventsManager) self.synchronizer.synchronize() } diff --git a/Split/Api/SplitClientManager.swift b/Split/Api/SplitClientManager.swift index db20eec6c..5a4054b07 100644 --- a/Split/Api/SplitClientManager.swift +++ b/Split/Api/SplitClientManager.swift @@ -13,7 +13,6 @@ protocol SplitClientManager: AnyObject { func get(forKey key: Key) -> SplitClient func flush() func destroy(forKey key: Key) - var splitFactory: SplitFactory? { get } } class DefaultClientManager: SplitClientManager, @unchecked Sendable { @@ -37,8 +36,6 @@ class DefaultClientManager: SplitClientManager, @unchecked Sendable { private let mySegmentsSyncWorkerFactory: MySegmentsSyncWorkerFactory private let propertyValidator: PropertyValidator private let fallbackTreatmentsCalculator: FallbackTreatmentsCalculator - - weak var splitFactory: SplitFactory? init(config: SplitClientConfig, key: Key, @@ -53,8 +50,7 @@ class DefaultClientManager: SplitClientManager, @unchecked Sendable { eventsManagerCoordinator: SplitEventsManagerCoordinator, mySegmentsSyncWorkerFactory: MySegmentsSyncWorkerFactory, telemetryStopwatch: Stopwatch?, - propertyValidator: PropertyValidator, - factory: SplitFactory) { + propertyValidator: PropertyValidator) { self.defaultKey = key self.apiFacade = apiFacade @@ -72,7 +68,6 @@ class DefaultClientManager: SplitClientManager, @unchecked Sendable { self.eventsTracker = eventsTracker self.propertyValidator = propertyValidator - self.splitFactory = factory fallbackTreatmentsCalculator = DefaultFallbackTreatmentsCalculator(fallbacksConfig: config.fallbackTreatments) evaluator = DefaultEvaluator(splitsStorage: storageContainer.splitsStorage, diff --git a/Split/Events/SplitEventActionTask.swift b/Split/Events/SplitEventActionTask.swift index f434246fb..9f1d37c45 100644 --- a/Split/Events/SplitEventActionTask.swift +++ b/Split/Events/SplitEventActionTask.swift @@ -11,25 +11,22 @@ class SplitEventActionTask: SplitEventTask, @unchecked Sendable { private var queue: DispatchQueue? var event: SplitEvent var runInBackground: Bool = false - var factory: SplitFactory - init(action: @escaping SplitActionWithMetadata, event: SplitEvent, runInBackground: Bool = false, factory: SplitFactory, queue: DispatchQueue? = nil) { - + init(action: @escaping SplitActionWithMetadata, event: SplitEvent, runInBackground: Bool = false, queue: DispatchQueue? = nil) { + self.event = event self.runInBackground = runInBackground self.queue = queue - self.factory = factory - + // Preserve the concrete type using type erasure container self.eventHandlerWithMetadata = TypedEventMetadataHandler(action: action) } - - init(action: @escaping SplitAction, event: SplitEvent, runInBackground: Bool = false, factory: SplitFactory, queue: DispatchQueue? = nil) { + + init(action: @escaping SplitAction, event: SplitEvent, runInBackground: Bool = false, queue: DispatchQueue? = nil) { self.eventHandler = action self.event = event self.runInBackground = runInBackground self.queue = queue - self.factory = factory } func takeQueue() -> DispatchQueue? { diff --git a/Split/Localhost/LocalhostClientManager.swift b/Split/Localhost/LocalhostClientManager.swift index f0349067a..88b94a2cc 100644 --- a/Split/Localhost/LocalhostClientManager.swift +++ b/Split/Localhost/LocalhostClientManager.swift @@ -27,15 +27,13 @@ class LocalhostClientManager: SplitClientManager, @unchecked Sendable { private let evaluator: Evaluator private let splitsStorage: SplitsStorage private let splitManager: SplitManager - weak var splitFactory: SplitFactory? init(config: SplitClientConfig, key: Key, splitManager: SplitManager, splitsStorage: SplitsStorage, synchronizer: FeatureFlagsSynchronizer, - eventsManagerCoordinator: SplitEventsManagerCoordinator, - factory: SplitFactory) { + eventsManagerCoordinator: SplitEventsManagerCoordinator) { self.defaultKey = key self.config = config @@ -43,7 +41,6 @@ class LocalhostClientManager: SplitClientManager, @unchecked Sendable { self.synchronizer = synchronizer self.eventsManagerCoordinator = eventsManagerCoordinator self.splitsStorage = splitsStorage - self.splitFactory = factory evaluator = DefaultEvaluator(splitsStorage: splitsStorage, mySegmentsStorage: EmptyMySegmentsStorage(), @@ -84,7 +81,7 @@ class LocalhostClientManager: SplitClientManager, @unchecked Sendable { let newEventsManager = eventsManager ?? DefaultSplitEventsManager(config: config) let newClient = LocalhostSplitClient(key: key, - splitsStorage: splitsStorage, clientManager: self, + splitsStorage: splitsStorage, eventsManager: newEventsManager, evaluator: evaluator) diff --git a/SplitTests/Fake/ClientManagerMock.swift b/SplitTests/Fake/ClientManagerMock.swift index 5285997e7..432c5f8e6 100644 --- a/SplitTests/Fake/ClientManagerMock.swift +++ b/SplitTests/Fake/ClientManagerMock.swift @@ -10,7 +10,6 @@ import Foundation @testable import Split class ClientManagerMock: SplitClientManager, @unchecked Sendable { - var splitFactory: SplitFactory? = SplitFactoryStub(apiKey: "apiKey") var defaultClient: SplitClient? var clients = [Key: SplitClient]() diff --git a/SplitTests/Helpers/TestSplitFactory.swift b/SplitTests/Helpers/TestSplitFactory.swift index d87761e64..0e5bd4268 100644 --- a/SplitTests/Helpers/TestSplitFactory.swift +++ b/SplitTests/Helpers/TestSplitFactory.swift @@ -226,8 +226,7 @@ class TestSplitFactory: SplitFactory { eventsManagerCoordinator: eventsManager, mySegmentsSyncWorkerFactory: mySegmentsSyncWorkerFactory, telemetryStopwatch: nil, - propertyValidator: propertyValidator, - factory: self) + propertyValidator: propertyValidator) } func client(matchingKey: String) -> SplitClient { diff --git a/SplitTests/Localhost/LocalhostSplitClientTests.swift b/SplitTests/Localhost/LocalhostSplitClientTests.swift index e39e3f2e4..cf0410856 100644 --- a/SplitTests/Localhost/LocalhostSplitClientTests.swift +++ b/SplitTests/Localhost/LocalhostSplitClientTests.swift @@ -28,7 +28,6 @@ class LocalhostSplitClientTests: XCTestCase { client = LocalhostSplitClient(key: Key(matchingKey: "thekey"), splitsStorage: splitsStorage, - clientManager: ClientManagerMock(), eventsManager: eventsManager, evaluator: DefaultEvaluator(splitsStorage: splitsStorage, mySegmentsStorage: EmptyMySegmentsStorage(), diff --git a/SplitTests/Localhost/LocalhostTests.swift b/SplitTests/Localhost/LocalhostTests.swift index 0d999f40a..9fda5dd9b 100644 --- a/SplitTests/Localhost/LocalhostTests.swift +++ b/SplitTests/Localhost/LocalhostTests.swift @@ -85,10 +85,11 @@ class LocalhostTests: XCTestCase { if yamlContent != nil { let updExp = XCTestExpectation() - _ = (factory as? SplitLocalhostDataSource)?.updateLocalhost(yaml: onlyFeature()) + client.on(event: .sdkUpdated) { updExp.fulfill() } + _ = (factory as? SplitLocalhostDataSource)?.updateLocalhost(yaml: onlyFeature()) wait(for: [updExp], timeout: 5.0) let splits = manager.splits diff --git a/SplitTests/SplitClientManagerTest.swift b/SplitTests/SplitClientManagerTest.swift index b64eaedfa..f1e7bbee0 100644 --- a/SplitTests/SplitClientManagerTest.swift +++ b/SplitTests/SplitClientManagerTest.swift @@ -118,8 +118,7 @@ class SplitClientManagerTest: XCTestCase { propertyValidator: DefaultPropertyValidator( anyValueValidator: DefaultAnyValueValidator(), validationLogger: DefaultValidationMessageLogger() - ), - factory: SplitFactoryStub(apiKey: IntegrationHelper.dummyApiKey)) + )) } override func tearDown() { diff --git a/SplitTests/SplitEventsManagerTest.swift b/SplitTests/SplitEventsManagerTest.swift index 7ac01b96c..6350f5bd0 100644 --- a/SplitTests/SplitEventsManagerTest.swift +++ b/SplitTests/SplitEventsManagerTest.swift @@ -322,7 +322,6 @@ class SplitEventsManagerTest: XCTestCase, @unchecked Sendable { let task = SplitEventActionTask(action: handler, event: .sdkReady, runInBackground: false, - factory: SplitFactoryStub(apiKey: IntegrationHelper.dummyApiKey), queue: nil) // Run & test @@ -343,7 +342,7 @@ class SplitEventsManagerTest: XCTestCase, @unchecked Sendable { XCTAssertEqual(handlerMetadata.names, names) taskExp.fulfill() } - let task = SplitEventActionTask(action: handler, event: .sdkReady, runInBackground: false, factory: SplitFactoryStub(apiKey: IntegrationHelper.dummyApiKey), queue: nil) + let task = SplitEventActionTask(action: handler, event: .sdkReady, runInBackground: false, queue: nil) // Run & test task.run(metadata) @@ -360,7 +359,7 @@ class SplitEventsManagerTest: XCTestCase, @unchecked Sendable { XCTAssertEqual(handlerMetadata.isInitialCacheLoad, freshInstall) taskExp.fulfill() } - let task = SplitEventActionTask(action: handler, event: .sdkReady, runInBackground: false, factory: SplitFactoryStub(apiKey: IntegrationHelper.dummyApiKey), queue: nil) + let task = SplitEventActionTask(action: handler, event: .sdkReady, runInBackground: false, queue: nil) // Run & test task.run(metadata) @@ -385,7 +384,7 @@ class TestTask: SplitEventActionTask, @unchecked Sendable { init(exp: XCTestExpectation?, label: String = "", action: SplitActionWithMetadata? = nil, metadata: EventMetadata? = nil) { self.exp = exp self.label = label - super.init(action: action ?? { _ in }, event: .sdkReady, factory: SplitFactoryStub(apiKey: IntegrationHelper.dummyApiKey)) + super.init(action: action ?? { _ in }, event: .sdkReady) } override func run(_ metadata: EventMetadata?) {