From df481fa1e8239d93a8cf8f9d04b207278f211b57 Mon Sep 17 00:00:00 2001 From: Gaston Thea Date: Tue, 7 Apr 2026 12:38:14 -0300 Subject: [PATCH 1/4] Set up Concurrency module --- Package.swift | 15 +- Sources/Concurrency/Concurrency.swift | 8 + Sources/Concurrency/README.md | 1 + .../Concurrency/Tests/ConcurrencyTests.swift | 9 + Split.xcodeproj/project.pbxproj | 390 +++++++++++++++++- .../xcschemes/ConcurrencyTestsSwift5.xcscheme | 69 ++++ .../xcschemes/ConcurrencyTestsSwift6.xcscheme | 69 ++++ 7 files changed, 557 insertions(+), 4 deletions(-) create mode 100644 Sources/Concurrency/Concurrency.swift create mode 100644 Sources/Concurrency/README.md create mode 100644 Sources/Concurrency/Tests/ConcurrencyTests.swift create mode 100644 Split.xcodeproj/xcshareddata/xcschemes/ConcurrencyTestsSwift5.xcscheme create mode 100644 Split.xcodeproj/xcshareddata/xcschemes/ConcurrencyTestsSwift6.xcscheme diff --git a/Package.swift b/Package.swift index 2b2ea390..6f2b1ead 100644 --- a/Package.swift +++ b/Package.swift @@ -8,13 +8,13 @@ let package = Package( products: [ .library(name: "Split", targets: ["Split"]), - .library(name: "SplitCommons", targets: ["Logging", "Http", "BackoffCounter", "PeriodicRecorderWorker", "Tracker"]),], + .library(name: "SplitCommons", targets: ["Logging", "Http", "BackoffCounter", "PeriodicRecorderWorker", "Tracker", "Concurrency"]),], targets: [ // MARK: Split .target( name: "Split", - dependencies: ["Http", "BackoffCounter", "Logging", "PeriodicRecorderWorker", "Tracker"], + dependencies: ["BackoffCounter", "Concurrency", "Http", "Logging", "PeriodicRecorderWorker", "Tracker"], path: "Split", exclude: [ "Common/Yaml/LICENSE", @@ -88,6 +88,17 @@ let package = Package( dependencies: ["TrackerTests"], path: "Sources/Tracker/Tests" ), + + .target( + name: "Concurrency", + dependencies: [], + exclude: ["Tests", "README.md"] + ), + .testTarget( + name: "ConcurrencyTests", + dependencies: ["Concurrency"], + path: "Sources/Concurrency/Tests" + ), // #INJECT_TARGET ] ) diff --git a/Sources/Concurrency/Concurrency.swift b/Sources/Concurrency/Concurrency.swift new file mode 100644 index 00000000..9bd95474 --- /dev/null +++ b/Sources/Concurrency/Concurrency.swift @@ -0,0 +1,8 @@ +import Foundation + +public struct ConcurrencyInternal { + public init() {} + public func action() { + print("Concurrency ready.") + } +} \ No newline at end of file diff --git a/Sources/Concurrency/README.md b/Sources/Concurrency/README.md new file mode 100644 index 00000000..5cbbf4f4 --- /dev/null +++ b/Sources/Concurrency/README.md @@ -0,0 +1 @@ +# Concurrency diff --git a/Sources/Concurrency/Tests/ConcurrencyTests.swift b/Sources/Concurrency/Tests/ConcurrencyTests.swift new file mode 100644 index 00000000..cedca499 --- /dev/null +++ b/Sources/Concurrency/Tests/ConcurrencyTests.swift @@ -0,0 +1,9 @@ +import XCTest +@testable import Concurrency + +final class ConcurrencyTests: XCTestCase { + func testExample() { + // Add your tests here + XCTAssertTrue(true) + } +} \ No newline at end of file diff --git a/Split.xcodeproj/project.pbxproj b/Split.xcodeproj/project.pbxproj index 5b35a5a2..79ff1067 100644 --- a/Split.xcodeproj/project.pbxproj +++ b/Split.xcodeproj/project.pbxproj @@ -8,6 +8,7 @@ /* Begin PBXBuildFile section */ 139D737E36D5F2FA1834BB96 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DB05351F643A2046D7E1EC50 /* Foundation.framework */; }; + 1510C1BC357260BA871DBE58 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DB05351F643A2046D7E1EC50 /* Foundation.framework */; }; 2459636933868D053A01BC3E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DB05351F643A2046D7E1EC50 /* Foundation.framework */; }; 2DF7C3837113F36647769631 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DB05351F643A2046D7E1EC50 /* Foundation.framework */; }; 31AA21DE01A000A7C30630F2 /* SseClientTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31AA280A65C72BC92858422C /* SseClientTest.swift */; }; @@ -816,6 +817,7 @@ 6CE8968BD9DB0E977DFB1D97 /* PeriodicRecorderWorkerConnector.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9AF03890DEADBEEF00000002 /* PeriodicRecorderWorkerConnector.swift */; }; 87BE6DB19968FB343A338104 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DB05351F643A2046D7E1EC50 /* Foundation.framework */; }; 88E54A26B0FA48B97D7B6AE3 /* LoggingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 23FD80A6B13740C2114DFA2F /* LoggingTests.swift */; }; + 924F1EE2D1B93C994C7BF67E /* Concurrency.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44B69B4718072C5310252A6A /* Concurrency.swift */; }; 945D15B2B918E1875EF7470E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DB05351F643A2046D7E1EC50 /* Foundation.framework */; }; 9500D9B72C5ADBDF00383593 /* SegmentsChange.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9500D9B62C5ADBDF00383593 /* SegmentsChange.swift */; }; 9500D9B82C5ADBFD00383593 /* SegmentsChange.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9500D9B62C5ADBDF00383593 /* SegmentsChange.swift */; }; @@ -1057,7 +1059,7 @@ 958AD2162CA4590200E3DD43 /* MyLargeSegmentsStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9500D9C62C610D1700383593 /* MyLargeSegmentsStorage.swift */; }; 958F98722B1124EC001F35B3 /* SplitBgSynchronizerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 958F98712B1124EC001F35B3 /* SplitBgSynchronizerTests.swift */; }; 958F98742B1129D7001F35B3 /* KeyValueStorageMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 958F98732B1129D7001F35B3 /* KeyValueStorageMock.swift */; }; - 958FD8A12C51318B00E5609B /* (null) in Sources */ = {isa = PBXBuildFile; }; + 958FD8A12C51318B00E5609B /* BuildFile in Sources */ = {isa = PBXBuildFile; }; 958FD8A22C5131A000E5609B /* CertificatePinningConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95F7BC162C35D9C000C5F2E4 /* CertificatePinningConfig.swift */; }; 958FD8A32C51321A00E5609B /* FileUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95F7BC182C36DE2300C5F2E4 /* FileUtil.swift */; }; 9594A45F2BFB917100D4E50B /* HashedImpressionDao.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9594A45E2BFB917100D4E50B /* HashedImpressionDao.swift */; }; @@ -1623,7 +1625,9 @@ C5E9675F2D3849BE00112DAC /* RolloutDefinitionsCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5E9675E2D3849BE00112DAC /* RolloutDefinitionsCache.swift */; }; C5E967602D3849BE00112DAC /* RolloutDefinitionsCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5E9675E2D3849BE00112DAC /* RolloutDefinitionsCache.swift */; }; C5E967622D395DAA00112DAC /* RolloutCacheManagerTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5E967612D395DAA00112DAC /* RolloutCacheManagerTest.swift */; }; + C60F348461E1AEAFBD8A2B95 /* ConcurrencyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC9B39F58A59192CC0BF2CE7 /* ConcurrencyTests.swift */; }; CD311117BB394A70AD6057CD04272DF2 /* DbEncryptionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A0EA0213A424C098E507B2544F5CD6F /* DbEncryptionManager.swift */; }; + F933EFDE638A45CFCFC6DD78 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DB05351F643A2046D7E1EC50 /* Foundation.framework */; }; HTTP001A28F3E1F2CC4D7F9E /* Endpoint.swift in Sources */ = {isa = PBXBuildFile; fileRef = HTTP001B28F3E1F2CC4D7F9E /* Endpoint.swift */; }; HTTP002A28F3E1F2CC4D7F9E /* HostDomainFilter.swift in Sources */ = {isa = PBXBuildFile; fileRef = HTTP002B28F3E1F2CC4D7F9E /* HostDomainFilter.swift */; }; HTTP003A28F3E1F2CC4D7F9E /* HttpAuthenticator.swift in Sources */ = {isa = PBXBuildFile; fileRef = HTTP003B28F3E1F2CC4D7F9E /* HttpAuthenticator.swift */; }; @@ -1743,6 +1747,13 @@ remoteGlobalIDString = 3B6DEE5920EA6A4E0067435E; remoteInfo = Split; }; + 6B69CED613E4B117F9A0B17F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 3B6DEE5120EA6A4D0067435E /* Project object */; + proxyType = 1; + remoteGlobalIDString = 726AE72F409B176D8B564D75; + remoteInfo = Concurrency; + }; 6E4424077045251A1E0C26AF /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 3B6DEE5120EA6A4D0067435E /* Project object */; @@ -1757,6 +1768,13 @@ remoteGlobalIDString = A9E90B2EA117111D127AA72A; remoteInfo = Http; }; + 8ECD345F685F6A3D27AF0571 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 3B6DEE5120EA6A4D0067435E /* Project object */; + proxyType = 1; + remoteGlobalIDString = 726AE72F409B176D8B564D75; + remoteInfo = Concurrency; + }; 913DF4C0D10717B1823C4982 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 3B6DEE5120EA6A4D0067435E /* Project object */; @@ -1785,6 +1803,13 @@ remoteGlobalIDString = A9E90B2EA117111D127AA72A; remoteInfo = Http; }; + C456A304B5221B2EEB6A7D2C /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 3B6DEE5120EA6A4D0067435E /* Project object */; + proxyType = 1; + remoteGlobalIDString = 726AE72F409B176D8B564D75; + remoteInfo = Concurrency; + }; DCEC8C1052CE73767C2802BF /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 3B6DEE5120EA6A4D0067435E /* Project object */; @@ -1943,6 +1968,7 @@ 3B6DEF0620EA6AE40067435E /* ConcurrentArrayQueue.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConcurrentArrayQueue.swift; sourceTree = ""; }; 3B6DEF0920EA6AE40067435E /* DefaultFileStorage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DefaultFileStorage.swift; sourceTree = ""; }; 3BBFF93220EFA2A0005F8C26 /* SplitEventActionTask.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SplitEventActionTask.swift; sourceTree = ""; }; + 44B69B4718072C5310252A6A /* Concurrency.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = Concurrency.swift; sourceTree = ""; }; 46392DA809BDD5397B4D8E6A /* BackoffCounter.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = BackoffCounter.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 5903C496210A5E0900A754B0 /* SynchronizedList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SynchronizedList.swift; sourceTree = ""; }; 5905D4C02555F99D006DA3B1 /* GeneralInfoEntity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeneralInfoEntity.swift; sourceTree = ""; }; @@ -2289,6 +2315,7 @@ 9530FD7B27F253CA005027AA /* SplitEventsCoordinatorTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SplitEventsCoordinatorTest.swift; sourceTree = ""; }; 95342E982A4C71300045B201 /* FeatureFlagsPayloadDecoderMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeatureFlagsPayloadDecoderMock.swift; sourceTree = ""; }; 95342E9A2A4C97F10045B201 /* DecompressionMocks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DecompressionMocks.swift; sourceTree = ""; }; + 9537E9C4A266547CA714BCF5 /* Concurrency.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Concurrency.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 953911A7267A4F250040433A /* LRUCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LRUCache.swift; sourceTree = ""; }; 953911AC267A64FE0040433A /* ImpresionsObserverTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImpresionsObserverTest.swift; sourceTree = ""; }; 953911B2267A97DF0040433A /* ImpressionHasherTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImpressionHasherTest.swift; sourceTree = ""; }; @@ -2617,6 +2644,7 @@ ACD4E80D7EE27E3F45D54F8A /* PeriodicRecorderWorkerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PeriodicRecorderWorkerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; B0C8EC7FC8354849F1782A28 /* HttpTaskMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HttpTaskMock.swift; sourceTree = ""; }; B53126909B1A56DEF7508435 /* Http.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Http.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + BC9B39F58A59192CC0BF2CE7 /* ConcurrencyTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ConcurrencyTests.swift; sourceTree = ""; }; BDAE97952FA0ADED787D7ACC /* Logging.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = Logging.swift; sourceTree = ""; }; C51B9B9FE5CD83450F74F278 /* HttpRequestManagerMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HttpRequestManagerMock.swift; sourceTree = ""; }; C526DE4B2D9B09EB0051DAB8 /* ImpressionsPropertiesE2ETest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImpressionsPropertiesE2ETest.swift; sourceTree = ""; }; @@ -2711,6 +2739,7 @@ DB05351F643A2046D7E1EC50 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS18.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; DC4B8AC48DBBD214B7F18D99 /* HttpStreamRequestTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HttpStreamRequestTest.swift; sourceTree = ""; }; E791A5E93E7E199973015B62 /* HttpTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = HttpTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + F8018233BFFEFC55935AE08B /* ConcurrencyTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ConcurrencyTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; HTTP001B28F3E1F2CC4D7F9E /* Endpoint.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Endpoint.swift; sourceTree = ""; }; HTTP002B28F3E1F2CC4D7F9E /* HostDomainFilter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HostDomainFilter.swift; sourceTree = ""; }; HTTP003B28F3E1F2CC4D7F9E /* HttpAuthenticator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HttpAuthenticator.swift; sourceTree = ""; }; @@ -2760,6 +2789,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 10BAC1B52A4041612018C284 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1510C1BC357260BA871DBE58 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 23BBD654A69F22BA74A196CF /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -2768,6 +2805,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 332F51C02A8E76BC574AABA2 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + F933EFDE638A45CFCFC6DD78 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 3B6DEE5620EA6A4E0067435E /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -2906,6 +2951,7 @@ 85FD20BA040A7382BFC88878 /* Http */, 4B358A3E30C72B70C3F82467 /* PeriodicRecorderWorker */, TRKGROUP0000001 /* Tracker */, + C09F0E3429A91FCE6447F4F2 /* Concurrency */, ); path = Sources; sourceTree = ""; @@ -3000,6 +3046,8 @@ 322B87F9DFD3F12E8C79F2D8 /* PeriodicRecorderWorker.framework */, ACD4E80D7EE27E3F45D54F8A /* PeriodicRecorderWorkerTests.xctest */, 5B0379732F4CD36F00DBD621 /* TrackerTests.xctest */, + 9537E9C4A266547CA714BCF5 /* Concurrency.framework */, + F8018233BFFEFC55935AE08B /* ConcurrencyTests.xctest */, ); name = Products; sourceTree = ""; @@ -4117,6 +4165,15 @@ path = Http; sourceTree = ""; }; + 8A2F693BCFD1D47D0D55C81E /* Tests */ = { + isa = PBXGroup; + children = ( + BC9B39F58A59192CC0BF2CE7 /* ConcurrencyTests.swift */, + ); + name = Tests; + path = Tests; + sourceTree = ""; + }; 8BE4EC5A3813AA16BC2ECBB6 /* Tests */ = { isa = PBXGroup; children = ( @@ -4614,6 +4671,16 @@ path = CertPinning; sourceTree = ""; }; + C09F0E3429A91FCE6447F4F2 /* Concurrency */ = { + isa = PBXGroup; + children = ( + 8A2F693BCFD1D47D0D55C81E /* Tests */, + 44B69B4718072C5310252A6A /* Concurrency.swift */, + ); + name = Concurrency; + path = Concurrency; + sourceTree = ""; + }; C539CAE42D947D2A0050C732 /* Validators */ = { isa = PBXGroup; children = ( @@ -4798,6 +4865,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + BD5CF1A7A93C5299C8BE19DF /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; C4C0EC6DF334FDFB5E0B2A26 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; @@ -4857,6 +4931,7 @@ 1EE383C26717DE81C42D5244 /* PBXTargetDependency */, E86C21454C5FA11C386AF845 /* PBXTargetDependency */, TRKDEP00000001 /* PBXTargetDependency */, + 859BBF09A7D55192CDF825BA /* PBXTargetDependency */, ); name = Split; productName = Split; @@ -4900,6 +4975,24 @@ productReference = 592C6AA5211B6C99002D120C /* SplitTestsSwift5.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; + 59F545C9C0E9AC66629DF494 /* ConcurrencyTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D3F76D3BF57210B7B773174 /* Build configuration list for PBXNativeTarget "ConcurrencyTests" */; + buildPhases = ( + A1F45C7FE36DD4A1B9383547 /* Sources */, + 332F51C02A8E76BC574AABA2 /* Frameworks */, + 59A6DF7E3E51FE0820876F90 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 55B478DD740507D76A3E4638 /* PBXTargetDependency */, + ); + name = ConcurrencyTests; + productName = ConcurrencyTests; + productReference = F8018233BFFEFC55935AE08B /* ConcurrencyTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; 5B3C16342ED76BAD0068D623 /* SplitTestsSwift6 */ = { isa = PBXNativeTarget; buildConfigurationList = 5B3C18012ED76BAD0068D623 /* Build configuration list for PBXNativeTarget "SplitTestsSwift6" */; @@ -4937,6 +5030,24 @@ productReference = ACD4E80D7EE27E3F45D54F8A /* PeriodicRecorderWorkerTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; + 726AE72F409B176D8B564D75 /* Concurrency */ = { + isa = PBXNativeTarget; + buildConfigurationList = 6973C6DCD51F68E8B9ED2C11 /* Build configuration list for PBXNativeTarget "Concurrency" */; + buildPhases = ( + BD5CF1A7A93C5299C8BE19DF /* Headers */, + 0E28252CD1002AC39C50D612 /* Sources */, + 10BAC1B52A4041612018C284 /* Frameworks */, + 7396C5A833D25257642CE20C /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Concurrency; + productName = Concurrency; + productReference = 9537E9C4A266547CA714BCF5 /* Concurrency.framework */; + productType = "com.apple.product-type.framework"; + }; 8000B2F11F535D99847B28BE /* LoggingTests */ = { isa = PBXNativeTarget; buildConfigurationList = 2CC43A0BA4C3F04300DABA16 /* Build configuration list for PBXNativeTarget "LoggingTests" */; @@ -4989,6 +5100,7 @@ 05EB2C0E7481565D7F5CD86C /* PBXTargetDependency */, 29D4E9A146F0931E6D95B75C /* PBXTargetDependency */, TRKDEP00000002 /* PBXTargetDependency */, + EE0FC2C77B831251090C69A4 /* PBXTargetDependency */, ); name = SplitWatchOS; productName = SplitTvOS; @@ -5161,6 +5273,8 @@ 60EAB5B278980408CA33AD72 /* PeriodicRecorderWorkerTests */, TRKTARGET0000001 /* Tracker */, TRKTARGET0000002 /* TrackerTests */, + 726AE72F409B176D8B564D75 /* Concurrency */, + 59F545C9C0E9AC66629DF494 /* ConcurrencyTests */, ); }; /* End PBXProject section */ @@ -5283,6 +5397,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 59A6DF7E3E51FE0820876F90 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5B3C17AB2ED76BAD0068D623 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -5375,6 +5496,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 7396C5A833D25257642CE20C /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 93BF30FE7E9A4DFB1ADAAF9B /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -5453,6 +5581,14 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ + 0E28252CD1002AC39C50D612 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 924F1EE2D1B93C994C7BF67E /* Concurrency.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 20ADABA1D68F08A3F4C5CF4D /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -6659,7 +6795,7 @@ C337B35BD6A7AF02703D6C2F /* PeriodicRecorderWorkerConnector.swift in Sources */, TRKCONNBUILD00002 /* TrackerConnector.swift in Sources */, TRKADAPTBUILD00002 /* TrackerAdapters.swift in Sources */, - 958FD8A12C51318B00E5609B /* (null) in Sources */, + 958FD8A12C51318B00E5609B /* BuildFile in Sources */, 956A7E17297043130080D53C /* ImpressionsStorage.swift in Sources */, 95B02DCD28D0BDE20030EC8B /* split_cache.xcdatamodeld in Sources */, 5B343EAD2E26E93B006BEBE7 /* StorageHelper.swift in Sources */, @@ -7004,6 +7140,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + A1F45C7FE36DD4A1B9383547 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + C60F348461E1AEAFBD8A2B95 /* ConcurrencyTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; DFF6DE370E1783CE0E1E2496 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -7078,6 +7222,12 @@ target = 557D062442413680641861B3 /* Logging */; targetProxy = 6E4424077045251A1E0C26AF /* PBXContainerItemProxy */; }; + 55B478DD740507D76A3E4638 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Concurrency; + target = 726AE72F409B176D8B564D75 /* Concurrency */; + targetProxy = C456A304B5221B2EEB6A7D2C /* PBXContainerItemProxy */; + }; 592C6AAC211B6C99002D120C /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 3B6DEE5920EA6A4E0067435E /* Split */; @@ -7106,6 +7256,12 @@ target = A9E90B2EA117111D127AA72A /* Http */; targetProxy = 913DF4C0D10717B1823C4982 /* PBXContainerItemProxy */; }; + 859BBF09A7D55192CDF825BA /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Concurrency; + target = 726AE72F409B176D8B564D75 /* Concurrency */; + targetProxy = 8ECD345F685F6A3D27AF0571 /* PBXContainerItemProxy */; + }; 8F0C1F550C971F31EF67A81A /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = PeriodicRecorderWorker; @@ -7136,6 +7292,12 @@ target = 97B2B9E50D4E8C459EDD712B /* PeriodicRecorderWorker */; targetProxy = 0B0464F59CDD8E0FA1830606 /* PBXContainerItemProxy */; }; + EE0FC2C77B831251090C69A4 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Concurrency; + target = 726AE72F409B176D8B564D75 /* Concurrency */; + targetProxy = 6B69CED613E4B117F9A0B17F /* PBXContainerItemProxy */; + }; TRKDEP00000001 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = Tracker; @@ -7292,6 +7454,89 @@ }; name = "Debug-Swift5"; }; + 2BEC5BEDC3C284F71B3C16B7 /* Debug-Swift5 */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALLOW_TARGET_PLATFORM_SPECIALIZATION = YES; + CLANG_ENABLE_OBJC_WEAK = NO; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GENERATE_INFOPLIST_FILE = YES; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACOSX_DEPLOYMENT_TARGET = 10.13; + PRODUCT_BUNDLE_IDENTIFIER = "$(inherited).Concurrency"; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SUPPORTED_PLATFORMS = "macosx iphonesimulator iphoneos driverkit appletvsimulator appletvos"; + TARGETED_DEVICE_FAMILY = "1,2,3,6"; + TVOS_DEPLOYMENT_TARGET = 12.0; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = "Debug-Swift5"; + }; + 2C02BB4EEF6D1D8F736A60DF /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "$(inherited).ConcurrencyTests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TEST_HOST = ""; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 348977C469DB712435D89854 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALLOW_TARGET_PLATFORM_SPECIALIZATION = YES; + CLANG_ENABLE_OBJC_WEAK = NO; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GENERATE_INFOPLIST_FILE = YES; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACOSX_DEPLOYMENT_TARGET = 10.13; + PRODUCT_BUNDLE_IDENTIFIER = "$(inherited).Concurrency"; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SUPPORTED_PLATFORMS = "macosx iphonesimulator iphoneos driverkit appletvsimulator appletvos"; + TARGETED_DEVICE_FAMILY = "1,2,3,4"; + TVOS_DEPLOYMENT_TARGET = 12.0; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; 3809C6CC6901B64FF7C40F6F /* Debug-Swift6 */ = { isa = XCBuildConfiguration; buildSettings = { @@ -7646,6 +7891,37 @@ }; name = Debug; }; + 49CEFAF84E796E2A35F3A7A4 /* Debug-Swift6 */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALLOW_TARGET_PLATFORM_SPECIALIZATION = YES; + CLANG_ENABLE_OBJC_WEAK = NO; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GENERATE_INFOPLIST_FILE = YES; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACOSX_DEPLOYMENT_TARGET = 10.13; + PRODUCT_BUNDLE_IDENTIFIER = "$(inherited).Concurrency"; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SUPPORTED_PLATFORMS = "macosx iphonesimulator iphoneos driverkit appletvsimulator appletvos"; + TARGETED_DEVICE_FAMILY = "1,2,3,6"; + TVOS_DEPLOYMENT_TARGET = 12.0; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = "Debug-Swift6"; + }; 592C6AAD211B6C99002D120C /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -7859,6 +8135,56 @@ }; name = "Debug-Swift5"; }; + 75A596DE8B2236512E0710D3 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALLOW_TARGET_PLATFORM_SPECIALIZATION = YES; + CLANG_ENABLE_OBJC_WEAK = NO; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GENERATE_INFOPLIST_FILE = YES; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACOSX_DEPLOYMENT_TARGET = 10.13; + PRODUCT_BUNDLE_IDENTIFIER = "$(inherited).Concurrency"; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SUPPORTED_PLATFORMS = "macosx iphonesimulator iphoneos driverkit appletvsimulator appletvos"; + TARGETED_DEVICE_FAMILY = "1,2,3,6"; + TVOS_DEPLOYMENT_TARGET = 12.0; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 787D81E6FA6FB80B9C67E45D /* Debug-Swift6 */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "$(inherited).ConcurrencyTests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TEST_HOST = ""; + }; + name = "Debug-Swift6"; + }; 7E1E95ACCB03A65CE983118D /* Debug-Swift6 */ = { isa = XCBuildConfiguration; buildSettings = { @@ -7910,6 +8236,25 @@ }; name = "Debug-Swift5"; }; + 85FCB759D98DED0C83545433 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "$(inherited).ConcurrencyTests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TEST_HOST = ""; + }; + name = Debug; + }; 86A8DF82E1CA919282CBC336 /* Debug-Swift6 */ = { isa = XCBuildConfiguration; buildSettings = { @@ -8791,6 +9136,25 @@ }; name = "Debug-Swift6"; }; + D2218B6E8FF12BC43800D3C6 /* Debug-Swift5 */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "$(inherited).ConcurrencyTests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TEST_HOST = ""; + }; + name = "Debug-Swift5"; + }; D8B1833FCA799A2DF55C85DE /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -9158,6 +9522,17 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 1D3F76D3BF57210B7B773174 /* Build configuration list for PBXNativeTarget "ConcurrencyTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 2C02BB4EEF6D1D8F736A60DF /* Release */, + 85FCB759D98DED0C83545433 /* Debug */, + D2218B6E8FF12BC43800D3C6 /* Debug-Swift5 */, + 787D81E6FA6FB80B9C67E45D /* Debug-Swift6 */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 2CC43A0BA4C3F04300DABA16 /* Build configuration list for PBXNativeTarget "LoggingTests" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -9246,6 +9621,17 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 6973C6DCD51F68E8B9ED2C11 /* Build configuration list for PBXNativeTarget "Concurrency" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 348977C469DB712435D89854 /* Release */, + 75A596DE8B2236512E0710D3 /* Debug */, + 2BEC5BEDC3C284F71B3C16B7 /* Debug-Swift5 */, + 49CEFAF84E796E2A35F3A7A4 /* Debug-Swift6 */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 8FCCCF9D7119C5047836E828 /* Build configuration list for PBXNativeTarget "PeriodicRecorderWorkerTests" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/Split.xcodeproj/xcshareddata/xcschemes/ConcurrencyTestsSwift5.xcscheme b/Split.xcodeproj/xcshareddata/xcschemes/ConcurrencyTestsSwift5.xcscheme new file mode 100644 index 00000000..b57d105e --- /dev/null +++ b/Split.xcodeproj/xcshareddata/xcschemes/ConcurrencyTestsSwift5.xcscheme @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Split.xcodeproj/xcshareddata/xcschemes/ConcurrencyTestsSwift6.xcscheme b/Split.xcodeproj/xcshareddata/xcschemes/ConcurrencyTestsSwift6.xcscheme new file mode 100644 index 00000000..8ba19752 --- /dev/null +++ b/Split.xcodeproj/xcshareddata/xcschemes/ConcurrencyTestsSwift6.xcscheme @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + From 09e62f69cce4352334b093e2313c732424925317 Mon Sep 17 00:00:00 2001 From: Gaston Thea Date: Tue, 7 Apr 2026 15:22:14 -0300 Subject: [PATCH 2/4] Concurrency module members --- .../Concurrency}/Atomic.swift | 30 +++++----- Sources/Concurrency/Concurrency.swift | 9 +-- .../Concurrency}/SynchronizedDictionary.swift | 28 ++++----- .../SynchronizedDictionaryComposed.swift | 24 ++++---- .../SynchronizedDictionarySet.swift | 26 +++++---- Split.xcodeproj/project.pbxproj | 58 ++++++++++--------- .../ConcurrencyConnector.swift | 14 +++++ .../ConcurrencyTestConnector.swift | 15 +++++ 8 files changed, 117 insertions(+), 87 deletions(-) rename {Split/Common/Utils => Sources/Concurrency}/Atomic.swift (70%) rename {Split/Common/Structs => Sources/Concurrency}/SynchronizedDictionary.swift (74%) rename {Split/Common/Structs => Sources/Concurrency}/SynchronizedDictionaryComposed.swift (70%) rename {Split/Common/Structs => Sources/Concurrency}/SynchronizedDictionarySet.swift (75%) create mode 100644 Split/ModuleConnectors/ConcurrencyConnector.swift create mode 100644 SplitTests/ModuleConnectors/ConcurrencyTestConnector.swift diff --git a/Split/Common/Utils/Atomic.swift b/Sources/Concurrency/Atomic.swift similarity index 70% rename from Split/Common/Utils/Atomic.swift rename to Sources/Concurrency/Atomic.swift index 70dfa923..3e33205d 100644 --- a/Split/Common/Utils/Atomic.swift +++ b/Sources/Concurrency/Atomic.swift @@ -8,35 +8,35 @@ import Foundation -final class Atomic: @unchecked Sendable { +public final class Atomic: @unchecked Sendable { // private let queue = DispatchQueue(label: "split-atomic", target: DispatchQueue.general) private var currentValue: T private var lock = NSLock() - init(_ value: T) { + public init(_ value: T) { self.currentValue = value } - var value: T { + public var value: T { lock.lock() defer { lock.unlock() } return self.currentValue } - func mutate(_ transformation: (inout T) -> Void) { + public func mutate(_ transformation: (inout T) -> Void) { lock.lock() transformation(&self.currentValue) lock.unlock() } - func mutate(_ transformation: (T, inout T) -> Void) { + public func mutate(_ transformation: (T, inout T) -> Void) { lock.lock() transformation(currentValue, &self.currentValue) lock.unlock() } - func getAndSet(_ newValue: T) -> T { + public func getAndSet(_ newValue: T) -> T { lock.lock() defer { lock.unlock() } let oldValue = self.currentValue @@ -44,28 +44,28 @@ final class Atomic: @unchecked Sendable { return oldValue } - func set(_ newValue: T) { + public func set(_ newValue: T) { lock.lock() self.currentValue = newValue lock.unlock() } } -final class AtomicInt: @unchecked Sendable { +public final class AtomicInt: @unchecked Sendable { private var curValue: Int private var lock = NSLock() - init(_ value: Int) { + public init(_ value: Int) { self.curValue = value } - var value: Int { + public var value: Int { lock.lock() defer { lock.unlock() } return curValue } - func getAndAdd(_ addValue: Int) -> Int { + public func getAndAdd(_ addValue: Int) -> Int { lock.lock() defer { lock.unlock() } let oldValue = self.curValue @@ -73,7 +73,7 @@ final class AtomicInt: @unchecked Sendable { return oldValue } - func addAndGet(_ addValue: Int) -> Int { + public func addAndGet(_ addValue: Int) -> Int { lock.lock() defer { lock.unlock() } curValue+=addValue @@ -81,13 +81,13 @@ final class AtomicInt: @unchecked Sendable { return newValue } - func set(_ newValue: Int) { + public func set(_ newValue: Int) { lock.lock() defer { lock.unlock() } curValue = newValue } - func getAndSet(_ newValue: Int) -> Int { + public func getAndSet(_ newValue: Int) -> Int { lock.lock() defer { lock.unlock() } let oldValue = curValue @@ -95,7 +95,7 @@ final class AtomicInt: @unchecked Sendable { return oldValue } - func mutate(_ transformation: (inout Int) -> Void) { + public func mutate(_ transformation: (inout Int) -> Void) { lock.lock() transformation(&self.curValue) lock.unlock() diff --git a/Sources/Concurrency/Concurrency.swift b/Sources/Concurrency/Concurrency.swift index 9bd95474..521d0e4d 100644 --- a/Sources/Concurrency/Concurrency.swift +++ b/Sources/Concurrency/Concurrency.swift @@ -1,8 +1 @@ -import Foundation - -public struct ConcurrencyInternal { - public init() {} - public func action() { - print("Concurrency ready.") - } -} \ No newline at end of file +import Foundation \ No newline at end of file diff --git a/Split/Common/Structs/SynchronizedDictionary.swift b/Sources/Concurrency/SynchronizedDictionary.swift similarity index 74% rename from Split/Common/Structs/SynchronizedDictionary.swift rename to Sources/Concurrency/SynchronizedDictionary.swift index edcbaa1b..e6b53b20 100644 --- a/Split/Common/Structs/SynchronizedDictionary.swift +++ b/Sources/Concurrency/SynchronizedDictionary.swift @@ -8,18 +8,20 @@ import Foundation -class SynchronizedDictionary: @unchecked Sendable { +public class SynchronizedDictionary: @unchecked Sendable { private var queue: DispatchQueue = DispatchQueue(label: "split-synchronized-dictionary", target: .global()) private var items = [K: T]() - var keys: Set { + public init() {} + + public var keys: Set { queue.sync { let keys = items.keys return Set(keys.map { $0 as K}) } } - var all: [K: T] { + public var all: [K: T] { var allItems: [K: T]? queue.sync { allItems = items @@ -27,7 +29,7 @@ class SynchronizedDictionary: @unchecked Sendable { return allItems! } - var count: Int { + public var count: Int { var count: Int = 0 queue.sync { count = items.count @@ -35,7 +37,7 @@ class SynchronizedDictionary: @unchecked Sendable { return count } - func value(forKey key: K) -> T? { + public func value(forKey key: K) -> T? { var value: T? queue.sync { value = items[key] @@ -43,13 +45,13 @@ class SynchronizedDictionary: @unchecked Sendable { return value } - func removeValue(forKey key: K) { + public func removeValue(forKey key: K) { queue.sync { _ = items.removeValue(forKey: key) } } - func removeValues(forKeys keys: Dictionary.Keys) { + public func removeValues(forKeys keys: Dictionary.Keys) { queue.sync { for key in keys { items.removeValue(forKey: key) @@ -57,19 +59,19 @@ class SynchronizedDictionary: @unchecked Sendable { } } - func removeAll() { + public func removeAll() { queue.sync { items.removeAll() } } - func setValue(_ value: T, forKey key: K) { + public func setValue(_ value: T, forKey key: K) { queue.sync { items[key] = value } } - func setValues(_ values: [K: T]) { + public func setValues(_ values: [K: T]) { queue.sync { items.removeAll() for (key, value) in values { @@ -78,7 +80,7 @@ class SynchronizedDictionary: @unchecked Sendable { } } - func putValues(_ values: [K: T]) { + public func putValues(_ values: [K: T]) { queue.sync { for (key, value) in values { items[key] = value @@ -86,7 +88,7 @@ class SynchronizedDictionary: @unchecked Sendable { } } - func takeValue(forKey key: K) -> T? { + public func takeValue(forKey key: K) -> T? { var value: T? queue.sync { value = items[key] @@ -97,7 +99,7 @@ class SynchronizedDictionary: @unchecked Sendable { return value } - func takeAll() -> [K: T] { + public func takeAll() -> [K: T] { var allItems: [K: T]! queue.sync { allItems = items diff --git a/Split/Common/Structs/SynchronizedDictionaryComposed.swift b/Sources/Concurrency/SynchronizedDictionaryComposed.swift similarity index 70% rename from Split/Common/Structs/SynchronizedDictionaryComposed.swift rename to Sources/Concurrency/SynchronizedDictionaryComposed.swift index 5e9017bc..9fb9d42e 100644 --- a/Split/Common/Structs/SynchronizedDictionaryComposed.swift +++ b/Sources/Concurrency/SynchronizedDictionaryComposed.swift @@ -8,13 +8,15 @@ import Foundation -class SynchronizedDictionaryComposed: @unchecked Sendable { +public class SynchronizedDictionaryComposed: @unchecked Sendable { private var queue: DispatchQueue = DispatchQueue(label: "split-synchronized-dictionary-composed", target: .global()) private var items = [K: [IK: Any]]() - func count(forKey key: K) -> Int { + public init() {} + + public func count(forKey key: K) -> Int { var count: Int? queue.sync { count = items[key]?.count @@ -22,7 +24,7 @@ class SynchronizedDictionaryComposed: @unchecked Send return count ?? 0 } - func values(forKey key: K) -> [IK: Any]? { + public func values(forKey key: K) -> [IK: Any]? { var value: [IK: Any]? queue.sync { value = items[key] @@ -30,7 +32,7 @@ class SynchronizedDictionaryComposed: @unchecked Send return value } - func value(_ innerKey: IK, forKey key: K) -> Any? { + public func value(_ innerKey: IK, forKey key: K) -> Any? { var value: Any? queue.sync { value = items[key]?[innerKey] @@ -38,7 +40,7 @@ class SynchronizedDictionaryComposed: @unchecked Send return value } - func contains(innerKey: IK, forKey key: K) -> Bool { + public func contains(innerKey: IK, forKey key: K) -> Bool { var hasValue: Bool? queue.sync { hasValue = items[key]?.keys.contains(innerKey) @@ -46,13 +48,13 @@ class SynchronizedDictionaryComposed: @unchecked Send return hasValue ?? false } - func set(_ values: [IK: Any], forKey key: K) { + public func set(_ values: [IK: Any], forKey key: K) { queue.sync { self.items[key] = values } } - func set(_ value: Any, forInnerKey innerKey: IK, forKey key: K) { + public func set(_ value: Any, forInnerKey innerKey: IK, forKey key: K) { queue.sync { var values = self.items[key] ?? [:] values[innerKey] = value @@ -60,7 +62,7 @@ class SynchronizedDictionaryComposed: @unchecked Send } } - func putValues(_ values: [IK: Any], forKey key: K) { + public func putValues(_ values: [IK: Any], forKey key: K) { queue.sync { var newValues = self.items[key] ?? [:] for (innerKey, value) in values { @@ -70,19 +72,19 @@ class SynchronizedDictionaryComposed: @unchecked Send } } - func removeValue(_ innerKey: IK, forKey key: K) { + public func removeValue(_ innerKey: IK, forKey key: K) { queue.sync { _ = self.items[key]?.removeValue(forKey: innerKey) } } - func removeValues(forKey key: K) { + public func removeValues(forKey key: K) { queue.sync { _ = self.items.removeValue(forKey: key) } } - func removeAll() { + public func removeAll() { queue.sync { self.items.removeAll() } diff --git a/Split/Common/Structs/SynchronizedDictionarySet.swift b/Sources/Concurrency/SynchronizedDictionarySet.swift similarity index 75% rename from Split/Common/Structs/SynchronizedDictionarySet.swift rename to Sources/Concurrency/SynchronizedDictionarySet.swift index cc098d00..5fe0fa4d 100644 --- a/Split/Common/Structs/SynchronizedDictionarySet.swift +++ b/Sources/Concurrency/SynchronizedDictionarySet.swift @@ -8,20 +8,22 @@ import Foundation -class SynchronizedDictionarySet: @unchecked Sendable { +public class SynchronizedDictionarySet: @unchecked Sendable { private var queue: DispatchQueue = DispatchQueue(label: "split-synchronized-dictionary-set", target: .global()) private var items = [K: Set]() - var keys: Set { + public init() {} + + public var keys: Set { queue.sync { let keys = items.keys return Set(keys.map { $0 as K}) } } - var all: [K: Set] { + public var all: [K: Set] { var all: [K: Set]? queue.sync { all = items @@ -29,7 +31,7 @@ class SynchronizedDictionarySet: @unchecked Sendable { return all ?? [K: Set]() } - func count(forKey key: K) -> Int { + public func count(forKey key: K) -> Int { var count: Int? queue.sync { count = items[key]?.count @@ -37,7 +39,7 @@ class SynchronizedDictionarySet: @unchecked Sendable { return count ?? 0 } - func values(forKey key: K) -> Set? { + public func values(forKey key: K) -> Set? { var value: Set? queue.sync { value = items[key] @@ -45,7 +47,7 @@ class SynchronizedDictionarySet: @unchecked Sendable { return value } - func takeAll() -> [K: Set] { + public func takeAll() -> [K: Set] { var all: [K: Set]? queue.sync { all = items @@ -54,7 +56,7 @@ class SynchronizedDictionarySet: @unchecked Sendable { return all ?? [K: Set]() } - func contains(value: T, forKey key: K) -> Bool { + public func contains(value: T, forKey key: K) -> Bool { var hasValue: Bool? queue.sync { hasValue = items[key]?.contains(value) @@ -62,13 +64,13 @@ class SynchronizedDictionarySet: @unchecked Sendable { return hasValue ?? false } - func set(_ values: Set, forKey key: K) { + public func set(_ values: Set, forKey key: K) { queue.sync { self.items[key] = values } } - func insert(_ value: T, forKey key: K) { + public func insert(_ value: T, forKey key: K) { queue.sync { if items[key] != nil { items[key]?.insert(value) @@ -78,13 +80,13 @@ class SynchronizedDictionarySet: @unchecked Sendable { } } - func removeValues(forKey key: K) { + public func removeValues(forKey key: K) { queue.sync { _ = items.removeValue(forKey: key) } } - func removeValue(_ value: T, forKey key: K) { + public func removeValue(_ value: T, forKey key: K) { queue.sync { var values = items[key] values?.remove(value) @@ -98,7 +100,7 @@ class SynchronizedDictionarySet: @unchecked Sendable { } } - func removeAll() { + public func removeAll() { queue.sync { items.removeAll() } diff --git a/Split.xcodeproj/project.pbxproj b/Split.xcodeproj/project.pbxproj index 79ff1067..f51e1808 100644 --- a/Split.xcodeproj/project.pbxproj +++ b/Split.xcodeproj/project.pbxproj @@ -203,7 +203,6 @@ 595AD25724E56E6200A7B750 /* EventStreamParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 595AD25624E56E6200A7B750 /* EventStreamParser.swift */; }; 595AD25924E59E6200A7B750 /* EventStreamParserTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 595AD25824E59E6200A7B750 /* EventStreamParserTest.swift */; }; 595AD25B24E5C00100A7B750 /* PushNotificationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 595AD25A24E5C00100A7B750 /* PushNotificationManager.swift */; }; - 595AD25F24E5D16300A7B750 /* Atomic.swift in Sources */ = {isa = PBXBuildFile; fileRef = 595AD25E24E5D16300A7B750 /* Atomic.swift */; }; 595AD26524E6C3D200A7B750 /* Timers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 595AD26424E6C3D200A7B750 /* Timers.swift */; }; 595B66CD231D91100030F330 /* SplitChangesTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 595B66CC231D91100030F330 /* SplitChangesTest.swift */; }; 595B66CF231DB0720030F330 /* splitchanges_int_test.json in Resources */ = {isa = PBXBuildFile; fileRef = 595B66CE231DB0720030F330 /* splitchanges_int_test.json */; }; @@ -862,7 +861,6 @@ 9516D0202A2910C80092A9DC /* SyncGuardian.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9516D01F2A2910C80092A9DC /* SyncGuardian.swift */; }; 9516D0222A291D180092A9DC /* SyncGuardianTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9516D0212A291D180092A9DC /* SyncGuardianTest.swift */; }; 9519A8F827D2AE2400278AEC /* AttributesStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9519A8F727D2AE2400278AEC /* AttributesStorage.swift */; }; - 9519A90F27D686A900278AEC /* SynchronizedDictionaryComposed.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9519A90E27D686A900278AEC /* SynchronizedDictionaryComposed.swift */; }; 9519A91127D6935700278AEC /* ByKeyAttributesStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9519A91027D6935700278AEC /* ByKeyAttributesStorage.swift */; }; 9519A91527D6A10F00278AEC /* ByKeyAttributesStorageTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9519A91427D6A10F00278AEC /* ByKeyAttributesStorageTests.swift */; }; 9519A91727D6B9EE00278AEC /* AttributesStorageStub.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9519A91627D6B9EE00278AEC /* AttributesStorageStub.swift */; }; @@ -949,7 +947,6 @@ 955AAB8F283FF1FE00ADFB07 /* HttpUniqueKeysRecorderStub.swift in Sources */ = {isa = PBXBuildFile; fileRef = 955AAB8E283FF1FE00ADFB07 /* HttpUniqueKeysRecorderStub.swift */; }; 955AAB922840182800ADFB07 /* ImpressionsNoneTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 955AAB912840182800ADFB07 /* ImpressionsNoneTest.swift */; }; 955B59522804B52500D105CD /* ByKeyAttributesStorageStub.swift in Sources */ = {isa = PBXBuildFile; fileRef = 955B59512804B52500D105CD /* ByKeyAttributesStorageStub.swift */; }; - 955B595428060CF100D105CD /* SynchronizedDictionary.swift in Sources */ = {isa = PBXBuildFile; fileRef = 955B595328060CF100D105CD /* SynchronizedDictionary.swift */; }; 955B595628076BB900D105CD /* MySegmentsPayloadDecoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 955B595528076BB900D105CD /* MySegmentsPayloadDecoder.swift */; }; 955B5960280DF75E00D105CD /* MySegmentsPayloadDecoderTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 955B595F280DF75E00D105CD /* MySegmentsPayloadDecoderTest.swift */; }; 955B59632811E8E700D105CD /* SplitClientManagerTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 955B59622811E8E700D105CD /* SplitClientManagerTest.swift */; }; @@ -973,7 +970,6 @@ 955E12452BFE758F00AE6D10 /* HashedImpressionsStorageTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 955E12442BFE758F00AE6D10 /* HashedImpressionsStorageTest.swift */; }; 955E124D2C010B9000AE6D10 /* ImpressionsObserverMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 955E124C2C010B9000AE6D10 /* ImpressionsObserverMock.swift */; }; 9560354327D01E8300E35BC8 /* MySegmentsStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9560354227D01E8300E35BC8 /* MySegmentsStorage.swift */; }; - 9560354527D0F53300E35BC8 /* SynchronizedDictionarySet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9560354427D0F53300E35BC8 /* SynchronizedDictionarySet.swift */; }; 9560354927D100A500E35BC8 /* ByKeyMySegmentsStorageTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9560354827D100A500E35BC8 /* ByKeyMySegmentsStorageTests.swift */; }; 9560354F27D16D5700E35BC8 /* MySegmentsStorageStub.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9560354E27D16D5700E35BC8 /* MySegmentsStorageStub.swift */; }; 95623DA82757FDDE0006A8F1 /* TelemetryProducerStub.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95623DA72757FDDE0006A8F1 /* TelemetryProducerStub.swift */; }; @@ -1059,7 +1055,7 @@ 958AD2162CA4590200E3DD43 /* MyLargeSegmentsStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9500D9C62C610D1700383593 /* MyLargeSegmentsStorage.swift */; }; 958F98722B1124EC001F35B3 /* SplitBgSynchronizerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 958F98712B1124EC001F35B3 /* SplitBgSynchronizerTests.swift */; }; 958F98742B1129D7001F35B3 /* KeyValueStorageMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 958F98732B1129D7001F35B3 /* KeyValueStorageMock.swift */; }; - 958FD8A12C51318B00E5609B /* BuildFile in Sources */ = {isa = PBXBuildFile; }; + 958FD8A12C51318B00E5609B /* (null) in Sources */ = {isa = PBXBuildFile; }; 958FD8A22C5131A000E5609B /* CertificatePinningConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95F7BC162C35D9C000C5F2E4 /* CertificatePinningConfig.swift */; }; 958FD8A32C51321A00E5609B /* FileUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95F7BC182C36DE2300C5F2E4 /* FileUtil.swift */; }; 9594A45F2BFB917100D4E50B /* HashedImpressionDao.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9594A45E2BFB917100D4E50B /* HashedImpressionDao.swift */; }; @@ -1115,17 +1111,13 @@ 95B02CC228D0BDC10030EC8B /* CastUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5982D930219EFEF500230F44 /* CastUtils.swift */; }; 95B02CC328D0BDC10030EC8B /* SplitHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5935FDEB226E26E300A23FA6 /* SplitHelper.swift */; }; 95B02CC428D0BDC10030EC8B /* Base64Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 595AD24A24E30C0C00A7B750 /* Base64Utils.swift */; }; - 95B02CC528D0BDC10030EC8B /* Atomic.swift in Sources */ = {isa = PBXBuildFile; fileRef = 595AD25E24E5D16300A7B750 /* Atomic.swift */; }; 95B02CC628D0BDC10030EC8B /* CompressionUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9595911026DFFF87009E7944 /* CompressionUtil.swift */; }; 95B02CC728D0BDC10030EC8B /* Stopwatch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95125624276B72B60091895B /* Stopwatch.swift */; }; 95B02CC828D0BDC10030EC8B /* ConcurrentArrayQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B6DEF0620EA6AE40067435E /* ConcurrentArrayQueue.swift */; }; 95B02CC928D0BDC10030EC8B /* SynchronizedList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5903C496210A5E0900A754B0 /* SynchronizedList.swift */; }; 95B02CCA28D0BDC10030EC8B /* ConcurrentSet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5905D4DE2559CA95006DA3B1 /* ConcurrentSet.swift */; }; 95B02CCB28D0BDC10030EC8B /* ConcurrentDictionaryList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 590DF9ED215038200082B94F /* ConcurrentDictionaryList.swift */; }; - 95B02CCC28D0BDC10030EC8B /* SynchronizedDictionarySet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9560354427D0F53300E35BC8 /* SynchronizedDictionarySet.swift */; }; - 95B02CCD28D0BDC10030EC8B /* SynchronizedDictionaryComposed.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9519A90E27D686A900278AEC /* SynchronizedDictionaryComposed.swift */; }; 95B02CCE28D0BDC20030EC8B /* ConcurrentDictionary.swift in Sources */ = {isa = PBXBuildFile; fileRef = 592D2CF922088606007458F9 /* ConcurrentDictionary.swift */; }; - 95B02CCF28D0BDC20030EC8B /* SynchronizedDictionary.swift in Sources */ = {isa = PBXBuildFile; fileRef = 955B595328060CF100D105CD /* SynchronizedDictionary.swift */; }; 95B02CD028D0BDC20030EC8B /* KeyStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95118EF2281C551A00782F33 /* KeyStorage.swift */; }; 95B02CD228D0BDC20030EC8B /* LRUCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 953911A7267A4F250040433A /* LRUCache.swift */; }; 95B02CD328D0BDC20030EC8B /* Data+StringRepresentation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B6DEE9E20EA6AE10067435E /* Data+StringRepresentation.swift */; }; @@ -1559,6 +1551,14 @@ C53F3C4F2DCD112400655753 /* RuleBasedSegmentChangeProcessorStub.swift in Sources */ = {isa = PBXBuildFile; fileRef = C53F3C4E2DCD110700655753 /* RuleBasedSegmentChangeProcessorStub.swift */; }; C55E82D92EE8E8A300777A06 /* CertificatePinningIntegrationTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C55E82D72EE8E8A300777A06 /* CertificatePinningIntegrationTest.swift */; }; C58F33732BDAC4AC00D66549 /* split_unsupported_matcher.json in Resources */ = {isa = PBXBuildFile; fileRef = C58F33722BDAC4AC00D66549 /* split_unsupported_matcher.json */; }; + C59110AE2F857E0300229EE9 /* ConcurrencyConnector.swift in Sources */ = {isa = PBXBuildFile; fileRef = C59110AD2F857E0300229EE9 /* ConcurrencyConnector.swift */; }; + C59110AF2F857E0300229EE9 /* ConcurrencyConnector.swift in Sources */ = {isa = PBXBuildFile; fileRef = C59110AD2F857E0300229EE9 /* ConcurrencyConnector.swift */; }; + C59110B12F85817200229EE9 /* ConcurrencyTestConnector.swift in Sources */ = {isa = PBXBuildFile; fileRef = C59110B02F85817200229EE9 /* ConcurrencyTestConnector.swift */; }; + C59110B22F85817200229EE9 /* ConcurrencyTestConnector.swift in Sources */ = {isa = PBXBuildFile; fileRef = C59110B02F85817200229EE9 /* ConcurrencyTestConnector.swift */; }; + C59110B72F8581ED00229EE9 /* SynchronizedDictionary.swift in Sources */ = {isa = PBXBuildFile; fileRef = C59110B42F8581ED00229EE9 /* SynchronizedDictionary.swift */; }; + C59110B82F8581ED00229EE9 /* SynchronizedDictionaryComposed.swift in Sources */ = {isa = PBXBuildFile; fileRef = C59110B52F8581ED00229EE9 /* SynchronizedDictionaryComposed.swift */; }; + C59110B92F8581ED00229EE9 /* SynchronizedDictionarySet.swift in Sources */ = {isa = PBXBuildFile; fileRef = C59110B62F8581ED00229EE9 /* SynchronizedDictionarySet.swift */; }; + C59110BA2F8581ED00229EE9 /* Atomic.swift in Sources */ = {isa = PBXBuildFile; fileRef = C59110B32F8581ED00229EE9 /* Atomic.swift */; }; C5977BFF2BF27375003E293A /* Semver.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5977BFE2BF27375003E293A /* Semver.swift */; }; C5977C012BF27390003E293A /* SemverTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5977C002BF27390003E293A /* SemverTest.swift */; }; C5977C062BF273A3003E293A /* valid_semantic_versions.csv in Resources */ = {isa = PBXBuildFile; fileRef = C5977C022BF273A3003E293A /* valid_semantic_versions.csv */; }; @@ -2076,7 +2076,6 @@ 595AD25824E59E6200A7B750 /* EventStreamParserTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventStreamParserTest.swift; sourceTree = ""; }; 595AD25A24E5C00100A7B750 /* PushNotificationManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PushNotificationManager.swift; sourceTree = ""; }; 595AD25C24E5C61C00A7B750 /* BackoffCounter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackoffCounter.swift; sourceTree = ""; }; - 595AD25E24E5D16300A7B750 /* Atomic.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Atomic.swift; sourceTree = ""; }; 595AD26024E5D48500A7B750 /* BackoffCounterTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackoffCounterTest.swift; sourceTree = ""; }; 595AD26424E6C3D200A7B750 /* Timers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Timers.swift; sourceTree = ""; }; 595B66CC231D91100030F330 /* SplitChangesTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SplitChangesTest.swift; sourceTree = ""; }; @@ -2276,7 +2275,6 @@ 9516D0212A291D180092A9DC /* SyncGuardianTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SyncGuardianTest.swift; sourceTree = ""; }; 95192EA92BEA9806004084EA /* SplitiOSUnit_1.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = SplitiOSUnit_1.xctestplan; sourceTree = ""; }; 9519A8F727D2AE2400278AEC /* AttributesStorage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AttributesStorage.swift; sourceTree = ""; }; - 9519A90E27D686A900278AEC /* SynchronizedDictionaryComposed.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SynchronizedDictionaryComposed.swift; sourceTree = ""; }; 9519A91027D6935700278AEC /* ByKeyAttributesStorage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ByKeyAttributesStorage.swift; sourceTree = ""; }; 9519A91427D6A10F00278AEC /* ByKeyAttributesStorageTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ByKeyAttributesStorageTests.swift; sourceTree = ""; }; 9519A91627D6B9EE00278AEC /* AttributesStorageStub.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttributesStorageStub.swift; sourceTree = ""; }; @@ -2360,7 +2358,6 @@ 955AAB8E283FF1FE00ADFB07 /* HttpUniqueKeysRecorderStub.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HttpUniqueKeysRecorderStub.swift; sourceTree = ""; }; 955AAB912840182800ADFB07 /* ImpressionsNoneTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImpressionsNoneTest.swift; sourceTree = ""; }; 955B59512804B52500D105CD /* ByKeyAttributesStorageStub.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ByKeyAttributesStorageStub.swift; sourceTree = ""; }; - 955B595328060CF100D105CD /* SynchronizedDictionary.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SynchronizedDictionary.swift; sourceTree = ""; }; 955B595528076BB900D105CD /* MySegmentsPayloadDecoder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MySegmentsPayloadDecoder.swift; sourceTree = ""; }; 955B595F280DF75E00D105CD /* MySegmentsPayloadDecoderTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MySegmentsPayloadDecoderTest.swift; sourceTree = ""; }; 955B59622811E8E700D105CD /* SplitClientManagerTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SplitClientManagerTest.swift; sourceTree = ""; }; @@ -2384,7 +2381,6 @@ 955E12442BFE758F00AE6D10 /* HashedImpressionsStorageTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HashedImpressionsStorageTest.swift; sourceTree = ""; }; 955E124C2C010B9000AE6D10 /* ImpressionsObserverMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImpressionsObserverMock.swift; sourceTree = ""; }; 9560354227D01E8300E35BC8 /* MySegmentsStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MySegmentsStorage.swift; sourceTree = ""; }; - 9560354427D0F53300E35BC8 /* SynchronizedDictionarySet.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SynchronizedDictionarySet.swift; sourceTree = ""; }; 9560354827D100A500E35BC8 /* ByKeyMySegmentsStorageTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ByKeyMySegmentsStorageTests.swift; sourceTree = ""; }; 9560354E27D16D5700E35BC8 /* MySegmentsStorageStub.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MySegmentsStorageStub.swift; sourceTree = ""; }; 95623D8E275100770006A8F1 /* split_cache_v3.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = split_cache_v3.xcdatamodel; sourceTree = ""; }; @@ -2686,6 +2682,12 @@ C53F3C4E2DCD110700655753 /* RuleBasedSegmentChangeProcessorStub.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuleBasedSegmentChangeProcessorStub.swift; sourceTree = ""; }; C55E82D72EE8E8A300777A06 /* CertificatePinningIntegrationTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CertificatePinningIntegrationTest.swift; sourceTree = ""; }; C58F33722BDAC4AC00D66549 /* split_unsupported_matcher.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = split_unsupported_matcher.json; sourceTree = ""; }; + C59110AD2F857E0300229EE9 /* ConcurrencyConnector.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConcurrencyConnector.swift; sourceTree = ""; }; + C59110B02F85817200229EE9 /* ConcurrencyTestConnector.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConcurrencyTestConnector.swift; sourceTree = ""; }; + C59110B32F8581ED00229EE9 /* Atomic.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Atomic.swift; sourceTree = ""; }; + C59110B42F8581ED00229EE9 /* SynchronizedDictionary.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SynchronizedDictionary.swift; sourceTree = ""; }; + C59110B52F8581ED00229EE9 /* SynchronizedDictionaryComposed.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SynchronizedDictionaryComposed.swift; sourceTree = ""; }; + C59110B62F8581ED00229EE9 /* SynchronizedDictionarySet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SynchronizedDictionarySet.swift; sourceTree = ""; }; C5977BFE2BF27375003E293A /* Semver.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Semver.swift; sourceTree = ""; }; C5977C002BF27390003E293A /* SemverTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SemverTest.swift; sourceTree = ""; }; C5977C022BF273A3003E293A /* valid_semantic_versions.csv */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = valid_semantic_versions.csv; sourceTree = ""; }; @@ -3458,7 +3460,6 @@ 5982D930219EFEF500230F44 /* CastUtils.swift */, 5935FDEB226E26E300A23FA6 /* SplitHelper.swift */, 595AD24A24E30C0C00A7B750 /* Base64Utils.swift */, - 595AD25E24E5D16300A7B750 /* Atomic.swift */, 9595911026DFFF87009E7944 /* CompressionUtil.swift */, 95125624276B72B60091895B /* Stopwatch.swift */, 95715A8229D23F9600A1B2F9 /* DbCipher.swift */, @@ -3476,10 +3477,7 @@ 5903C496210A5E0900A754B0 /* SynchronizedList.swift */, 5905D4DE2559CA95006DA3B1 /* ConcurrentSet.swift */, 590DF9ED215038200082B94F /* ConcurrentDictionaryList.swift */, - 9560354427D0F53300E35BC8 /* SynchronizedDictionarySet.swift */, - 9519A90E27D686A900278AEC /* SynchronizedDictionaryComposed.swift */, 592D2CF922088606007458F9 /* ConcurrentDictionary.swift */, - 955B595328060CF100D105CD /* SynchronizedDictionary.swift */, 95118EF2281C551A00782F33 /* KeyStorage.swift */, 953911A7267A4F250040433A /* LRUCache.swift */, ); @@ -4099,6 +4097,7 @@ 5B0F30622F3F81AE00D7056F /* ModuleConnectors */ = { isa = PBXGroup; children = ( + C59110AD2F857E0300229EE9 /* ConcurrencyConnector.swift */, 9AF0389ED3DEACFCD8CCEAE2 /* BackoffCounterConnector.swift */, 9AF03890DEADBEEF00000001 /* HttpConnector.swift */, 9AF03890DEADBEEF00000002 /* PeriodicRecorderWorkerConnector.swift */, @@ -4170,7 +4169,6 @@ children = ( BC9B39F58A59192CC0BF2CE7 /* ConcurrencyTests.swift */, ); - name = Tests; path = Tests; sourceTree = ""; }; @@ -4674,10 +4672,13 @@ C09F0E3429A91FCE6447F4F2 /* Concurrency */ = { isa = PBXGroup; children = ( + C59110B32F8581ED00229EE9 /* Atomic.swift */, + C59110B42F8581ED00229EE9 /* SynchronizedDictionary.swift */, + C59110B52F8581ED00229EE9 /* SynchronizedDictionaryComposed.swift */, + C59110B62F8581ED00229EE9 /* SynchronizedDictionarySet.swift */, 8A2F693BCFD1D47D0D55C81E /* Tests */, 44B69B4718072C5310252A6A /* Concurrency.swift */, ); - name = Concurrency; path = Concurrency; sourceTree = ""; }; @@ -4781,6 +4782,7 @@ SPLITTESTCONN1 /* ModuleConnectors */ = { isa = PBXGroup; children = ( + C59110B02F85817200229EE9 /* ConcurrencyTestConnector.swift */, 5B0379752F4CD41800DBD621 /* HttpTestConnector.swift */, ); path = ModuleConnectors; @@ -5585,6 +5587,10 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + C59110B72F8581ED00229EE9 /* SynchronizedDictionary.swift in Sources */, + C59110B82F8581ED00229EE9 /* SynchronizedDictionaryComposed.swift in Sources */, + C59110B92F8581ED00229EE9 /* SynchronizedDictionarySet.swift in Sources */, + C59110BA2F8581ED00229EE9 /* Atomic.swift in Sources */, 924F1EE2D1B93C994C7BF67E /* Concurrency.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -5879,11 +5885,9 @@ 590DF9EE215038200082B94F /* ConcurrentDictionaryList.swift in Sources */, 9595AD7527F4DC3B006E3A54 /* SplitClientManager.swift in Sources */, 956816BE2836C91B00206FC5 /* UniqueKeyTracker.swift in Sources */, - 595AD25F24E5D16300A7B750 /* Atomic.swift in Sources */, 95E8193E28786A1C00D99093 /* SplitLogLevel.swift in Sources */, 95DE8EA027C54858009FAC01 /* SplitDatabaseHelper.swift in Sources */, 95B1801027629B5E002DC9DF /* TelemetryStatsRecorder.swift in Sources */, - 9560354527D0F53300E35BC8 /* SynchronizedDictionarySet.swift in Sources */, 3B6DEF6620EA6AE50067435E /* EndsWithMatcher.swift in Sources */, 3B6DEF4B20EA6AE50067435E /* Split.swift in Sources */, 95ABF4BE2930FCEF006ED016 /* ImpressionsStorage.swift in Sources */, @@ -5907,7 +5911,6 @@ 950B7417268F4716005FD649 /* ImpressionsMode.swift in Sources */, 95DFD14C260A156000776E0A /* ChangesChecker.swift in Sources */, 5905D4DF2559CA95006DA3B1 /* ConcurrentSet.swift in Sources */, - 955B595428060CF100D105CD /* SynchronizedDictionary.swift in Sources */, 3B6DEF6220EA6AE50067435E /* ContainsAnyOfSetMatcher.swift in Sources */, 95DE293727395E7300DB3EAD /* AttributeEntity.swift in Sources */, 595AD20A24DDC77C00A7B750 /* RestClient+SseAuthenticator.swift in Sources */, @@ -5923,13 +5926,13 @@ 599EA57722666B84006CBA89 /* YAMLTokenizer.swift in Sources */, 3B6DEF5F20EA6AE50067435E /* BaseMatcher.swift in Sources */, 5905D4D22555F99D006DA3B1 /* SplitEntity.swift in Sources */, - 9519A90F27D686A900278AEC /* SynchronizedDictionaryComposed.swift in Sources */, 9519A91E27D947C300278AEC /* SyncCommons.swift in Sources */, 59D84BD422158A07003DA248 /* LocalhostSplitClient.swift in Sources */, C5977C0D2BF27786003E293A /* BetweenSemverMatcher.swift in Sources */, 3B6DEF1D20EA6AE50067435E /* PeriodicTaskManager.swift in Sources */, 5903C497210A5E0900A754B0 /* SynchronizedList.swift in Sources */, 3B6DEF2F20EA6AE50067435E /* EvaluatorError.swift in Sources */, + C59110AE2F857E0300229EE9 /* ConcurrencyConnector.swift in Sources */, 95CED0382B45D115005E3C34 /* LocalhostFileDataSource.swift in Sources */, 955892AB25C187EA00F67FBA /* CoreDataContextBuilder.swift in Sources */, C53EDFC82DD3DD3E000DCDBC /* OutdatedSplitProxyHandler.swift in Sources */, @@ -6061,6 +6064,7 @@ 59FB7C1621F79B8200ECC96A /* EventTypeNameHelper.swift in Sources */, 9595910526DFB1AB009E7944 /* DecompressionTest.swift in Sources */, 594F5F55253A1A6500A945B4 /* StreamingSplitKillTest.swift in Sources */, + C59110B12F85817200229EE9 /* ConcurrencyTestConnector.swift in Sources */, 595AD20024DAF61700A7B750 /* FetchSpecificSplitsTest.swift in Sources */, 59F4AAA5250007BD00A1C69A /* SseHandlerStub.swift in Sources */, 59F4AAA82508120500A1C69A /* SyncManagerTest.swift in Sources */, @@ -6556,6 +6560,7 @@ 5B3C16E92ED76BAD0068D623 /* EventsSynchronizerStub.swift in Sources */, 5B3C16EA2ED76BAD0068D623 /* PersistentImpressionsStorageTest.swift in Sources */, 5B3C16EB2ED76BAD0068D623 /* CsvHelper.swift in Sources */, + C59110B22F85817200229EE9 /* ConcurrencyTestConnector.swift in Sources */, 5B3C16EC2ED76BAD0068D623 /* ImpressionsCounterTest.swift in Sources */, 5B3C16ED2ED76BAD0068D623 /* SplitBgSynchronizerTests.swift in Sources */, 5B3C16EE2ED76BAD0068D623 /* PeriodicSplitsSyncWorkerTest.swift in Sources */, @@ -6795,7 +6800,7 @@ C337B35BD6A7AF02703D6C2F /* PeriodicRecorderWorkerConnector.swift in Sources */, TRKCONNBUILD00002 /* TrackerConnector.swift in Sources */, TRKADAPTBUILD00002 /* TrackerAdapters.swift in Sources */, - 958FD8A12C51318B00E5609B /* BuildFile in Sources */, + 958FD8A12C51318B00E5609B /* (null) in Sources */, 956A7E17297043130080D53C /* ImpressionsStorage.swift in Sources */, 95B02DCD28D0BDE20030EC8B /* split_cache.xcdatamodeld in Sources */, 5B343EAD2E26E93B006BEBE7 /* StorageHelper.swift in Sources */, @@ -6829,7 +6834,6 @@ 9500D9C02C5D458F00383593 /* Set+Extension.swift in Sources */, 95B02CC328D0BDC10030EC8B /* SplitHelper.swift in Sources */, 95B02CC428D0BDC10030EC8B /* Base64Utils.swift in Sources */, - 95B02CC528D0BDC10030EC8B /* Atomic.swift in Sources */, 95B02CC628D0BDC10030EC8B /* CompressionUtil.swift in Sources */, 95B02CC728D0BDC10030EC8B /* Stopwatch.swift in Sources */, 95B02CC828D0BDC10030EC8B /* ConcurrentArrayQueue.swift in Sources */, @@ -6838,11 +6842,8 @@ 95B02CCA28D0BDC10030EC8B /* ConcurrentSet.swift in Sources */, C539CADC2D93229D0050C732 /* EvaluationOptions.swift in Sources */, 95B02CCB28D0BDC10030EC8B /* ConcurrentDictionaryList.swift in Sources */, - 95B02CCC28D0BDC10030EC8B /* SynchronizedDictionarySet.swift in Sources */, - 95B02CCD28D0BDC10030EC8B /* SynchronizedDictionaryComposed.swift in Sources */, 95B02CCE28D0BDC20030EC8B /* ConcurrentDictionary.swift in Sources */, 9500D9D12C61814000383593 /* MySegmentEntity.swift in Sources */, - 95B02CCF28D0BDC20030EC8B /* SynchronizedDictionary.swift in Sources */, 95B02CD028D0BDC20030EC8B /* KeyStorage.swift in Sources */, 95B02CD228D0BDC20030EC8B /* LRUCache.swift in Sources */, 95B02CD328D0BDC20030EC8B /* Data+StringRepresentation.swift in Sources */, @@ -7105,6 +7106,7 @@ 95B02DAB28D0BDC30030EC8B /* KeyValueStorage.swift in Sources */, 95B02DAC28D0BDC30030EC8B /* GeneralInfoEntity.swift in Sources */, 95B02DAD28D0BDC30030EC8B /* GeneralInfoDao.swift in Sources */, + C59110AF2F857E0300229EE9 /* ConcurrencyConnector.swift in Sources */, 95B02DAE28D0BDC30030EC8B /* ImpressionEntity.swift in Sources */, 95B02DAF28D0BDC30030EC8B /* ImpressionDao.swift in Sources */, 95CED04F2B4DCDAB005E3C34 /* LocalhostFileDataSource.swift in Sources */, diff --git a/Split/ModuleConnectors/ConcurrencyConnector.swift b/Split/ModuleConnectors/ConcurrencyConnector.swift new file mode 100644 index 00000000..c0e350e3 --- /dev/null +++ b/Split/ModuleConnectors/ConcurrencyConnector.swift @@ -0,0 +1,14 @@ +// Concurrency module imports for the Split module +// Copyright © 2026 Split. All rights reserved. + +#if !COCOAPODS + +import Concurrency + +// MARK: - Internal use +typealias Atomic = Concurrency.Atomic +typealias AtomicInt = Concurrency.AtomicInt +typealias SynchronizedDictionary = Concurrency.SynchronizedDictionary +typealias SynchronizedDictionaryComposed = Concurrency.SynchronizedDictionaryComposed +typealias SynchronizedDictionarySet = Concurrency.SynchronizedDictionarySet +#endif diff --git a/SplitTests/ModuleConnectors/ConcurrencyTestConnector.swift b/SplitTests/ModuleConnectors/ConcurrencyTestConnector.swift new file mode 100644 index 00000000..e0e8a59b --- /dev/null +++ b/SplitTests/ModuleConnectors/ConcurrencyTestConnector.swift @@ -0,0 +1,15 @@ +// ConcurrencyTestConnector.swift +// Created by Split Team. +// Copyright © 2025 Split. All rights reserved. + +#if !COCOAPODS +import Concurrency + +// MARK: - Concurrency types for testing + +typealias Atomic = Concurrency.Atomic +typealias AtomicInt = Concurrency.AtomicInt +typealias SynchronizedDictionary = Concurrency.SynchronizedDictionary +typealias SynchronizedDictionaryComposed = Concurrency.SynchronizedDictionaryComposed +typealias SynchronizedDictionarySet = Concurrency.SynchronizedDictionarySet +#endif From 3a2afe1dee877651bd1c62b657f4d80ce4c36a97 Mon Sep 17 00:00:00 2001 From: Gaston Thea Date: Tue, 7 Apr 2026 15:24:25 -0300 Subject: [PATCH 3/4] Fix doc --- Split/ModuleConnectors/ConcurrencyConnector.swift | 1 - SplitTests/ModuleConnectors/ConcurrencyTestConnector.swift | 2 -- 2 files changed, 3 deletions(-) diff --git a/Split/ModuleConnectors/ConcurrencyConnector.swift b/Split/ModuleConnectors/ConcurrencyConnector.swift index c0e350e3..0e9b3bc6 100644 --- a/Split/ModuleConnectors/ConcurrencyConnector.swift +++ b/Split/ModuleConnectors/ConcurrencyConnector.swift @@ -1,5 +1,4 @@ // Concurrency module imports for the Split module -// Copyright © 2026 Split. All rights reserved. #if !COCOAPODS diff --git a/SplitTests/ModuleConnectors/ConcurrencyTestConnector.swift b/SplitTests/ModuleConnectors/ConcurrencyTestConnector.swift index e0e8a59b..b000f5f3 100644 --- a/SplitTests/ModuleConnectors/ConcurrencyTestConnector.swift +++ b/SplitTests/ModuleConnectors/ConcurrencyTestConnector.swift @@ -1,6 +1,4 @@ // ConcurrencyTestConnector.swift -// Created by Split Team. -// Copyright © 2025 Split. All rights reserved. #if !COCOAPODS import Concurrency From 191b4ec942e09635193bb59e3f22ca4ab7423048 Mon Sep 17 00:00:00 2001 From: Gaston Thea Date: Tue, 7 Apr 2026 15:49:04 -0300 Subject: [PATCH 4/4] Fix WatchOS build --- Split.xcodeproj/project.pbxproj | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Split.xcodeproj/project.pbxproj b/Split.xcodeproj/project.pbxproj index f51e1808..265ca4ea 100644 --- a/Split.xcodeproj/project.pbxproj +++ b/Split.xcodeproj/project.pbxproj @@ -8160,8 +8160,8 @@ PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; SDKROOT = iphoneos; SKIP_INSTALL = YES; - SUPPORTED_PLATFORMS = "macosx iphonesimulator iphoneos driverkit appletvsimulator appletvos"; - TARGETED_DEVICE_FAMILY = "1,2,3,6"; + SUPPORTED_PLATFORMS = "watchsimulator watchos macosx iphonesimulator iphoneos driverkit appletvsimulator appletvos"; + TARGETED_DEVICE_FAMILY = "1,2,3,4,6"; TVOS_DEPLOYMENT_TARGET = 12.0; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; @@ -8300,7 +8300,7 @@ SDKROOT = iphoneos; SKIP_INSTALL = YES; SUPPORTED_PLATFORMS = "macosx iphonesimulator iphoneos driverkit appletvsimulator appletvos watchsimulator watchos"; - TARGETED_DEVICE_FAMILY = "1,2,3,6"; + TARGETED_DEVICE_FAMILY = "1,2,3,4,6"; TVOS_DEPLOYMENT_TARGET = 12.0; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = "";