diff --git a/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata b/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000..919434a62 --- /dev/null +++ b/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Split.xcodeproj/project.pbxproj b/Split.xcodeproj/project.pbxproj index 3349a1f1e..5bbb570ec 100644 --- a/Split.xcodeproj/project.pbxproj +++ b/Split.xcodeproj/project.pbxproj @@ -5285,8 +5285,9 @@ SUPPORTS_MACCATALYST = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_STRICT_MEMORY_SAFETY = NO; SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = ""; + SWIFT_VERSION = 6.0; TVOS_DEPLOYMENT_TARGET = 15.4; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; @@ -5351,8 +5352,9 @@ SUPPORTS_MACCATALYST = YES; SWIFT_COMPILATION_MODE = wholemodule; SWIFT_OPTIMIZATION_LEVEL = "-O"; + SWIFT_STRICT_MEMORY_SAFETY = NO; SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = ""; + SWIFT_VERSION = 6.0; TVOS_DEPLOYMENT_TARGET = 15.4; VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; @@ -5397,7 +5399,7 @@ SWIFT_OBJC_BRIDGING_HEADER = ""; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 5.0; + SWIFT_VERSION = 6.0; TARGETED_DEVICE_FAMILY = "1,2,3,6"; TVOS_DEPLOYMENT_TARGET = 12.0; USER_HEADER_SEARCH_PATHS = ""; @@ -5440,7 +5442,7 @@ SWIFT_INCLUDE_PATHS = ""; SWIFT_OBJC_BRIDGING_HEADER = ""; SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 5.0; + SWIFT_VERSION = 6.0; TARGETED_DEVICE_FAMILY = "1,2,3,4"; TVOS_DEPLOYMENT_TARGET = 12.0; USER_HEADER_SEARCH_PATHS = ""; @@ -5471,7 +5473,7 @@ SWIFT_OBJC_BRIDGING_HEADER = ""; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 5.0; + SWIFT_VERSION = 6.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; @@ -5498,7 +5500,7 @@ PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = ""; SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 5.0; + SWIFT_VERSION = 6.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Release; diff --git a/Split.xcodeproj/xcshareddata/xcschemes/SplitSwfit6.xcscheme b/Split.xcodeproj/xcshareddata/xcschemes/SplitSwfit6.xcscheme new file mode 100644 index 000000000..40120782b --- /dev/null +++ b/Split.xcodeproj/xcshareddata/xcschemes/SplitSwfit6.xcscheme @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Split/Api/CertificatePinningConfig.swift b/Split/Api/CertificatePinningConfig.swift index db4211880..66b12df74 100644 --- a/Split/Api/CertificatePinningConfig.swift +++ b/Split/Api/CertificatePinningConfig.swift @@ -12,7 +12,7 @@ public typealias CertificatePinningFailureHandler = (String) -> Void /// Custom error type for certificate pinning errors, conforming to LocalizedError. @objc -public class CertificatePinningError: NSObject, LocalizedError { +public class CertificatePinningError: NSObject, LocalizedError, @unchecked Sendable { private let message: String /// Initializes a new instance of CertificatePinningError with a custom message. diff --git a/Split/Api/DefaultSplitClient.swift b/Split/Api/DefaultSplitClient.swift index bbf3aa8a7..3146f2a24 100644 --- a/Split/Api/DefaultSplitClient.swift +++ b/Split/Api/DefaultSplitClient.swift @@ -11,7 +11,7 @@ import Foundation typealias DestroyHandler = () -> Void -public final class DefaultSplitClient: NSObject, SplitClient, TelemetrySplitClient { +public final class DefaultSplitClient: NSObject, SplitClient, TelemetrySplitClient, @unchecked Sendable { private var storageContainer: SplitStorageContainer private var key: Key @@ -309,7 +309,7 @@ extension DefaultSplitClient { destroy(completion: nil) } - public func destroy(completion: (() -> Void)?) { + public func destroy(completion: (@Sendable () -> Void)?) { isClientDestroyed = true treatmentManager.destroy() DispatchQueue.global().async { [weak self] in diff --git a/Split/Api/DefaultSplitFactoryBuilder.swift b/Split/Api/DefaultSplitFactoryBuilder.swift index e2aafa625..583571e43 100644 --- a/Split/Api/DefaultSplitFactoryBuilder.swift +++ b/Split/Api/DefaultSplitFactoryBuilder.swift @@ -33,7 +33,7 @@ import Foundation (Singleton pattern) and reusing it throughout your application. """ - private static let factoryMonitor: FactoryMonitor = { + nonisolated(unsafe) private static let factoryMonitor: FactoryMonitor = { return DefaultFactoryMonitor() }() diff --git a/Split/Api/SplitClient.swift b/Split/Api/SplitClient.swift index ff4df2005..b89d7f966 100644 --- a/Split/Api/SplitClient.swift +++ b/Split/Api/SplitClient.swift @@ -66,7 +66,7 @@ public typealias SplitAction = () -> Void // MARK: Client lifecycle func flush() func destroy() - func destroy(completion: (() -> Void)?) + func destroy(completion: (@Sendable () -> Void)?) @objc(trackWithTrafficType:eventType:properties:) func track(trafficType: String, eventType: String, diff --git a/Split/Api/SplitClientManager.swift b/Split/Api/SplitClientManager.swift index 05d3d26b8..4b05e15c2 100644 --- a/Split/Api/SplitClientManager.swift +++ b/Split/Api/SplitClientManager.swift @@ -16,7 +16,7 @@ protocol SplitClientManager: AnyObject { var splitFactory: SplitFactory? { get } } -class DefaultClientManager: SplitClientManager { +final class DefaultClientManager: SplitClientManager, @unchecked Sendable { private(set) var defaultClient: SplitClient? private var storageContainer: SplitStorageContainer diff --git a/Split/Api/SplitDatabaseHelper.swift b/Split/Api/SplitDatabaseHelper.swift index c30801b19..a7637758d 100644 --- a/Split/Api/SplitDatabaseHelper.swift +++ b/Split/Api/SplitDatabaseHelper.swift @@ -50,7 +50,7 @@ struct SplitDatabaseHelper { GlobalSecureStorage.shared.set(item: keyBytes.base64EncodedString(options: []), for: .dbEncryptionKey(apiKey)) } - static func buildStorageContainer(splitClientConfig: SplitClientConfig, + nonisolated static func buildStorageContainer(splitClientConfig: SplitClientConfig, apiKey: String, userKey: String, databaseName: String, diff --git a/Split/Common/Extensions/Bundle+Finder.swift b/Split/Common/Extensions/Bundle+Finder.swift index 80661c99a..b8d799723 100644 --- a/Split/Common/Extensions/Bundle+Finder.swift +++ b/Split/Common/Extensions/Bundle+Finder.swift @@ -12,7 +12,7 @@ private class BundleFinder {} extension Foundation.Bundle { /// Returns the resource bundle associated with the current Swift module. - static var split: Bundle = { + nonisolated(unsafe) static var split: Bundle = { let bundleName = Bundle.splitBundleName let candidates = [ diff --git a/Split/Common/Extensions/Date+Utils.swift b/Split/Common/Extensions/Date+Utils.swift index 99ee5da11..6b43ad9c9 100644 --- a/Split/Common/Extensions/Date+Utils.swift +++ b/Split/Common/Extensions/Date+Utils.swift @@ -56,7 +56,7 @@ extension Date { return seconds / 86400 } - private static var formatter: DateFormatter = { + nonisolated(unsafe) private static var formatter: DateFormatter = { let formatter = DateFormatter() formatter.dateFormat = "dd-MM-yyyy HH:mm:ss.SSS" return formatter diff --git a/Split/Common/ServiceConstants.swift b/Split/Common/ServiceConstants.swift index b29b0bf1b..f24fbe92c 100644 --- a/Split/Common/ServiceConstants.swift +++ b/Split/Common/ServiceConstants.swift @@ -11,7 +11,7 @@ import Foundation struct ServiceConstants { // Created for testing purposes only - static var values: Values? + nonisolated(unsafe) static var values: Values? static let estimatedImpressionSizeInBytes = 150 // Estimated size of a UniqueKey having a key of 100 chars and diff --git a/Split/Common/Structs/ConcurrentDictionary.swift b/Split/Common/Structs/ConcurrentDictionary.swift index 1827dbd67..a9a60634b 100644 --- a/Split/Common/Structs/ConcurrentDictionary.swift +++ b/Split/Common/Structs/ConcurrentDictionary.swift @@ -8,10 +8,10 @@ import Foundation -class ConcurrentDictionary { +final class ConcurrentDictionary: Sendable { - private var queue: DispatchQueue - private var items: [K: T] + nonisolated(unsafe) private var queue: DispatchQueue + nonisolated(unsafe) private var items: [K: T] var all: [K: T] { var allItems: [K: T]? diff --git a/Split/Common/Structs/ConcurrentDictionaryList.swift b/Split/Common/Structs/ConcurrentDictionaryList.swift index 50e4bda66..69dc2592e 100644 --- a/Split/Common/Structs/ConcurrentDictionaryList.swift +++ b/Split/Common/Structs/ConcurrentDictionaryList.swift @@ -8,7 +8,7 @@ import Foundation -class ConcurrentDictionaryList { +class ConcurrentDictionaryList: @unchecked Sendable { private var queue = DispatchQueue(label: "split-concurrent-dictionary-list", attributes: .concurrent) diff --git a/Split/Common/Structs/LRUCache.swift b/Split/Common/Structs/LRUCache.swift index d4f7a2889..7d4eccfbb 100644 --- a/Split/Common/Structs/LRUCache.swift +++ b/Split/Common/Structs/LRUCache.swift @@ -8,7 +8,7 @@ import Foundation -class LRUCache { +final class LRUCache: @unchecked Sendable { /// Elements queue tracks objects usage /// first element is last used /// last element is least used diff --git a/Split/Common/Utils/Logger.swift b/Split/Common/Utils/Logger.swift index 7ff74628e..319b00272 100644 --- a/Split/Common/Utils/Logger.swift +++ b/Split/Common/Utils/Logger.swift @@ -9,7 +9,7 @@ import Foundation struct TimeChecker { - private static var startTime: Int64 = 0 + nonisolated(unsafe) private static var startTime: Int64 = 0 private static let tag = "[SPTPRF] " private static let showTimestamp = true private static let showSinceMsg = true @@ -71,7 +71,7 @@ class Logger { var level: SplitLogLevel = .none - static let shared: Logger = { + nonisolated(unsafe) static let shared: Logger = { return Logger() }() diff --git a/Split/Common/Utils/NotificationsHelper.swift b/Split/Common/Utils/NotificationsHelper.swift index 31f34532b..88d0e58c2 100644 --- a/Split/Common/Utils/NotificationsHelper.swift +++ b/Split/Common/Utils/NotificationsHelper.swift @@ -71,7 +71,7 @@ class DefaultNotificationHelper: NotificationHelper { #endif - static let instance: DefaultNotificationHelper = { + nonisolated(unsafe) static let instance: DefaultNotificationHelper = { return DefaultNotificationHelper() }() diff --git a/Split/Common/Utils/Spec.swift b/Split/Common/Utils/Spec.swift index 615a52e36..3f985a300 100644 --- a/Split/Common/Utils/Spec.swift +++ b/Split/Common/Utils/Spec.swift @@ -8,6 +8,5 @@ import Foundation class Spec { - static var flagsSpec = "1.3" } diff --git a/Split/Common/Utils/ThreadUtils.swift b/Split/Common/Utils/ThreadUtils.swift index ead56f37c..64fa0a35f 100644 --- a/Split/Common/Utils/ThreadUtils.swift +++ b/Split/Common/Utils/ThreadUtils.swift @@ -50,7 +50,7 @@ class ThreadUtils { } } -protocol CancellableTask { +protocol CancellableTask: Sendable { typealias Work = () -> Void var taskId: Int64 { get } var isCancelled: Bool { get } @@ -59,7 +59,7 @@ protocol CancellableTask { func cancel() } -class DefaultTask: CancellableTask { +final class DefaultTask: CancellableTask, @unchecked Sendable { private(set) var taskId: Int64 private(set) var isCancelled = false @@ -87,11 +87,11 @@ struct TaskExecutor { } extension DispatchQueue { - static var critical: DispatchQueue = { + nonisolated(unsafe) static var critical: DispatchQueue = { return DispatchQueue(label: "split-critical", qos: .userInteractive, attributes: .concurrent) }() - static var general: DispatchQueue = { + nonisolated(unsafe) static var general: DispatchQueue = { return DispatchQueue(label: "split-general", attributes: .concurrent) }() } diff --git a/Split/Common/Validators/ValidationConfig.swift b/Split/Common/Validators/ValidationConfig.swift index f37209e2c..c42ddde93 100644 --- a/Split/Common/Validators/ValidationConfig.swift +++ b/Split/Common/Validators/ValidationConfig.swift @@ -36,7 +36,7 @@ struct ValidationConfig { /// let maxEventPropertiesCount = 300 - static var `default`: ValidationConfig = { + static let `default`: ValidationConfig = { return ValidationConfig() }() } diff --git a/Split/Common/Yaml/YAMLParser.swift b/Split/Common/Yaml/YAMLParser.swift index 1e2f13563..2e6e5cf6e 100755 --- a/Split/Common/Yaml/YAMLParser.swift +++ b/Split/Common/Yaml/YAMLParser.swift @@ -61,7 +61,7 @@ struct Context { private typealias Context = Yaml.Context -private var error = Yaml.Context.error +nonisolated(unsafe) private var error = Yaml.Context.error private typealias ContextValue = (context: Context, value: Yaml) diff --git a/Split/Engine/Splitter.swift b/Split/Engine/Splitter.swift index 86bc61c3f..67030f249 100644 --- a/Split/Engine/Splitter.swift +++ b/Split/Engine/Splitter.swift @@ -14,7 +14,7 @@ protocol SplitterProtocol { class Splitter: SplitterProtocol { - static let shared: Splitter = { + nonisolated(unsafe) static let shared: Splitter = { let instance = Splitter() return instance }() diff --git a/Split/Events/EventsManagerCoordinator.swift b/Split/Events/EventsManagerCoordinator.swift index 3ddf4fe93..ad1db7e73 100644 --- a/Split/Events/EventsManagerCoordinator.swift +++ b/Split/Events/EventsManagerCoordinator.swift @@ -13,7 +13,7 @@ protocol SplitEventsManagerCoordinator: SplitEventsManager { func remove(forKey key: Key) } -class MainSplitEventsManager: SplitEventsManagerCoordinator { +class MainSplitEventsManager: SplitEventsManagerCoordinator, @unchecked Sendable { private var defaultManager: SplitEventsManager? private var managers = [Key: SplitEventsManager]() private var triggered = Set() diff --git a/Split/Events/SplitEvent.swift b/Split/Events/SplitEvent.swift index d2561e2d9..b1fc12144 100644 --- a/Split/Events/SplitEvent.swift +++ b/Split/Events/SplitEvent.swift @@ -7,7 +7,7 @@ import Foundation -@objc public enum SplitEvent: Int { +@objc public enum SplitEvent: Int, Sendable { case sdkReady case sdkReadyTimedOut case sdkReadyFromCache diff --git a/Split/Events/SplitEventActionTask.swift b/Split/Events/SplitEventActionTask.swift index be1368d04..cec32041a 100644 --- a/Split/Events/SplitEventActionTask.swift +++ b/Split/Events/SplitEventActionTask.swift @@ -7,7 +7,7 @@ import Foundation -class SplitEventActionTask: SplitEventTask { +class SplitEventActionTask: SplitEventTask, @unchecked Sendable { private var eventHandler: SplitAction? private var queue: DispatchQueue? diff --git a/Split/Events/SplitEventTask.swift b/Split/Events/SplitEventTask.swift index 1655e2b25..99db343ea 100644 --- a/Split/Events/SplitEventTask.swift +++ b/Split/Events/SplitEventTask.swift @@ -7,7 +7,7 @@ import Foundation -protocol SplitEventTask { +protocol SplitEventTask: Sendable { var event: SplitEvent { get } var runInBackground: Bool { get } func takeQueue() -> DispatchQueue? diff --git a/Split/Events/SplitEventsManager.swift b/Split/Events/SplitEventsManager.swift index 1ad2a1d78..72ba77e29 100644 --- a/Split/Events/SplitEventsManager.swift +++ b/Split/Events/SplitEventsManager.swift @@ -8,7 +8,7 @@ import Foundation -protocol SplitEventsManager: AnyObject { +protocol SplitEventsManager: AnyObject, Sendable { func register(event: SplitEvent, task: SplitEventTask) func notifyInternalEvent(_ event: SplitInternalEvent) func start() @@ -16,14 +16,14 @@ protocol SplitEventsManager: AnyObject { func eventAlreadyTriggered(event: SplitEvent) -> Bool } -class DefaultSplitEventsManager: SplitEventsManager { +final class DefaultSplitEventsManager: SplitEventsManager { private let readingRefreshTime: Int - private var sdkReadyTimeStart: Int64 + nonisolated(unsafe) private var sdkReadyTimeStart: Int64 - private var subscriptions = [SplitEvent: [SplitEventTask]]() - private var executionTimes: [String: Int] - private var triggered: [SplitInternalEvent] + nonisolated(unsafe) private var subscriptions = [SplitEvent: [SplitEventTask]]() + nonisolated(unsafe) private var executionTimes: [String: Int] + nonisolated(unsafe) private var triggered: [SplitInternalEvent] private let processQueue: DispatchQueue private let dataAccessQueue: DispatchQueue private var isStarted: Bool diff --git a/Split/FetcherEngine/Recorder/PeriodicRecorderWorker.swift b/Split/FetcherEngine/Recorder/PeriodicRecorderWorker.swift index 79531746c..df97009af 100644 --- a/Split/FetcherEngine/Recorder/PeriodicRecorderWorker.swift +++ b/Split/FetcherEngine/Recorder/PeriodicRecorderWorker.swift @@ -16,7 +16,7 @@ protocol PeriodicRecorderWorker { func destroy() } // -class DefaultPeriodicRecorderWorker: PeriodicRecorderWorker { +class DefaultPeriodicRecorderWorker: PeriodicRecorderWorker, @unchecked Sendable { private let recorderWorker: RecorderWorker private var fetchTimer: PeriodicTimer diff --git a/Split/FetcherEngine/Refresh/PeriodicSyncWorker.swift b/Split/FetcherEngine/Refresh/PeriodicSyncWorker.swift index c2693d298..49d6f86cd 100644 --- a/Split/FetcherEngine/Refresh/PeriodicSyncWorker.swift +++ b/Split/FetcherEngine/Refresh/PeriodicSyncWorker.swift @@ -70,7 +70,7 @@ protocol PeriodicSyncWorker { func destroy() } -class BasePeriodicSyncWorker: PeriodicSyncWorker { +class BasePeriodicSyncWorker: PeriodicSyncWorker, @unchecked Sendable { private var fetchTimer: PeriodicTimer private let fetchQueue = DispatchQueue.general @@ -137,7 +137,7 @@ class BasePeriodicSyncWorker: PeriodicSyncWorker { } } -class PeriodicSplitsSyncWorker: BasePeriodicSyncWorker { +class PeriodicSplitsSyncWorker: BasePeriodicSyncWorker, @unchecked Sendable { private let splitFetcher: HttpSplitFetcher private let splitsStorage: SplitsStorage @@ -189,7 +189,7 @@ class PeriodicSplitsSyncWorker: BasePeriodicSyncWorker { } } -class PeriodicMySegmentsSyncWorker: BasePeriodicSyncWorker { +class PeriodicMySegmentsSyncWorker: BasePeriodicSyncWorker, @unchecked Sendable { private let mySegmentsStorage: ByKeyMySegmentsStorage private let myLargeSegmentsStorage: ByKeyMySegmentsStorage diff --git a/Split/FetcherEngine/Refresh/RetryableSyncWorker.swift b/Split/FetcherEngine/Refresh/RetryableSyncWorker.swift index 28c0a6f9c..6dcc2ddf2 100644 --- a/Split/FetcherEngine/Refresh/RetryableSyncWorker.swift +++ b/Split/FetcherEngine/Refresh/RetryableSyncWorker.swift @@ -8,7 +8,7 @@ import Foundation -protocol RetryableSyncWorker { +protocol RetryableSyncWorker: Sendable { typealias SyncCompletion = (Bool) -> Void typealias ErrorHandler = (Error) -> Void var completion: SyncCompletion? { get set } @@ -23,7 +23,7 @@ protocol RetryableSyncWorker { /// This class retryies when fetching is not possible do to /// nettwork connection and http server errors /// -class BaseRetryableSyncWorker: RetryableSyncWorker { +class BaseRetryableSyncWorker: RetryableSyncWorker, @unchecked Sendable { var completion: SyncCompletion? var errorHandler: ErrorHandler? @@ -100,7 +100,7 @@ class BaseRetryableSyncWorker: RetryableSyncWorker { } } -class RetryableSplitsSyncWorker: BaseRetryableSyncWorker { +class RetryableSplitsSyncWorker: BaseRetryableSyncWorker, @unchecked Sendable { private let splitFetcher: HttpSplitFetcher private let splitsStorage: SplitsStorage @@ -156,7 +156,7 @@ class RetryableSplitsSyncWorker: BaseRetryableSyncWorker { } } -class RetryableSplitsUpdateWorker: BaseRetryableSyncWorker { +class RetryableSplitsUpdateWorker: BaseRetryableSyncWorker, @unchecked Sendable { private let splitsFetcher: HttpSplitFetcher private let splitsStorage: SplitsStorage diff --git a/Split/FetcherEngine/Refresh/SplitBgSynchronizer.swift b/Split/FetcherEngine/Refresh/SplitBgSynchronizer.swift index 0cd4c02a7..66987cefe 100644 --- a/Split/FetcherEngine/Refresh/SplitBgSynchronizer.swift +++ b/Split/FetcherEngine/Refresh/SplitBgSynchronizer.swift @@ -10,7 +10,7 @@ import Foundation #if os(iOS) || os(tvOS) import BackgroundTasks -@objc public class SplitBgSynchronizer: NSObject { +@objc public class SplitBgSynchronizer: NSObject, @unchecked Sendable { @objc public static let shared = SplitBgSynchronizer() @@ -129,7 +129,7 @@ import BackgroundTasks } } -struct BackgroundSyncExecutor { +struct BackgroundSyncExecutor: @unchecked Sendable { private let splitDatabase: SplitDatabase private let splitsSyncWorker: BackgroundSyncWorker private let eventsRecorderWorker: RecorderWorker diff --git a/Split/Impressions/ImpressionsCounter.swift b/Split/Impressions/ImpressionsCounter.swift index 84d578f75..6e7d5827f 100644 --- a/Split/Impressions/ImpressionsCounter.swift +++ b/Split/Impressions/ImpressionsCounter.swift @@ -8,7 +8,7 @@ import Foundation -class ImpressionsCounter { +final class ImpressionsCounter: @unchecked Sendable { struct Key: Hashable { let featureName: String let timeframe: Int64 diff --git a/Split/Initialization/SplitComponentFactory.swift b/Split/Initialization/SplitComponentFactory.swift index 47330c5d4..aadf6aa94 100644 --- a/Split/Initialization/SplitComponentFactory.swift +++ b/Split/Initialization/SplitComponentFactory.swift @@ -31,7 +31,7 @@ class SplitComponentFactory { self.userKey = userKey } - func buildStorageContainer(databaseName: String, + nonisolated func buildStorageContainer(databaseName: String, telemetryStorage: TelemetryStorage?, testDatabase: SplitDatabase?) throws -> SplitStorageContainer { let component: SplitStorageContainer = diff --git a/Split/Models/Key.swift b/Split/Models/Key.swift index ca00a80c8..c2d65514b 100644 --- a/Split/Models/Key.swift +++ b/Split/Models/Key.swift @@ -8,7 +8,7 @@ import Foundation -public class Key: NSObject { +final public class Key: NSObject, Sendable { public let matchingKey: String public let bucketingKey: String? diff --git a/Split/Models/SplitModel/Split.swift b/Split/Models/SplitModel/Split.swift index 6a487b777..cee2302d0 100644 --- a/Split/Models/SplitModel/Split.swift +++ b/Split/Models/SplitModel/Split.swift @@ -8,7 +8,7 @@ import Foundation typealias Split = SplitDTO -class SplitDTO: NSObject, SplitBase, Codable { +class SplitDTO: NSObject, SplitBase, Codable, @unchecked Sendable { var name: String? var seed: Int? var status: Status? diff --git a/Split/Network/HttpClient/HttpClient.swift b/Split/Network/HttpClient/HttpClient.swift index f605acf83..1a3647ab9 100644 --- a/Split/Network/HttpClient/HttpClient.swift +++ b/Split/Network/HttpClient/HttpClient.swift @@ -74,7 +74,7 @@ typealias HttpHeaders = [String: String] class HttpSessionConfig { static let kDefaultConnectionTimeout: TimeInterval = 30 - static let `default`: HttpSessionConfig = { + nonisolated(unsafe) static let `default`: HttpSessionConfig = { return HttpSessionConfig() }() var connectionTimeOut: TimeInterval = kDefaultConnectionTimeout @@ -101,7 +101,7 @@ extension HttpClient { class DefaultHttpClient { - static let shared: HttpClient = { + nonisolated(unsafe) static let shared: HttpClient = { return DefaultHttpClient() }() diff --git a/Split/Network/HttpClient/HttpRequest.swift b/Split/Network/HttpClient/HttpRequest.swift index 8677d1942..e0c281783 100644 --- a/Split/Network/HttpClient/HttpRequest.swift +++ b/Split/Network/HttpClient/HttpRequest.swift @@ -8,8 +8,8 @@ import Foundation protocol HttpRequest { - typealias RequestCompletionHandler = (HttpResponse) -> Void - typealias RequestErrorHandler = (HttpError) -> Void + typealias RequestCompletionHandler = @Sendable (HttpResponse) -> Void + typealias RequestErrorHandler = @Sendable (HttpError) -> Void var identifier: Int { get } var url: URL { get } diff --git a/Split/Network/HttpClient/HttpRequestList.swift b/Split/Network/HttpClient/HttpRequestList.swift index 2917815dd..daaf7e03d 100644 --- a/Split/Network/HttpClient/HttpRequestList.swift +++ b/Split/Network/HttpClient/HttpRequestList.swift @@ -9,7 +9,7 @@ import Foundation // MARK: Request list -class HttpRequestList { +class HttpRequestList: @unchecked Sendable { private let queueName = "split.http-request-queue" private var queue: DispatchQueue private var requests: [Int: HttpRequest] diff --git a/Split/Network/HttpClient/HttpRequestManager.swift b/Split/Network/HttpClient/HttpRequestManager.swift index c4bddf25d..8821daef0 100644 --- a/Split/Network/HttpClient/HttpRequestManager.swift +++ b/Split/Network/HttpClient/HttpRequestManager.swift @@ -20,13 +20,13 @@ protocol HttpRequestManager { func destroy() } -class DefaultHttpRequestManager: NSObject { - private var requests = HttpRequestList() - private var authenticator: SplitHttpsAuthenticator? +class DefaultHttpRequestManager: NSObject, @unchecked Sendable { + private nonisolated(unsafe) var requests = HttpRequestList() + private nonisolated(unsafe) var authenticator: SplitHttpsAuthenticator? - private let pinChecker: TlsPinChecker? + nonisolated(unsafe) private let pinChecker: TlsPinChecker? - private let notificationHelper: NotificationHelper? + nonisolated(unsafe) private let notificationHelper: NotificationHelper? init(authententicator: SplitHttpsAuthenticator? = nil, pinChecker: TlsPinChecker?, diff --git a/Split/Network/NetworkReachabilityManager.swift b/Split/Network/NetworkReachabilityManager.swift index d05c8692d..f058beeb0 100644 --- a/Split/Network/NetworkReachabilityManager.swift +++ b/Split/Network/NetworkReachabilityManager.swift @@ -33,7 +33,7 @@ import SystemConfiguration /// Reachability can be used to determine background information about why a network operation failed, or to retry /// network requests when a connection is established. It should not be used to prevent a user from initiating a network /// request, as it's possible that an initial request may be required to establish reachability. -class NetworkReachabilityManager { +class NetworkReachabilityManager: @unchecked Sendable { /// Defines the various states of network reachability. /// /// - unknown: It is unknown whether the network is reachable. diff --git a/Split/Network/RestClient/RestClient+Impressions.swift b/Split/Network/RestClient/RestClient+Impressions.swift index aaa38213d..c5450d0cf 100644 --- a/Split/Network/RestClient/RestClient+Impressions.swift +++ b/Split/Network/RestClient/RestClient+Impressions.swift @@ -9,11 +9,11 @@ import Foundation protocol RestClientImpressions: RestClient { - func sendImpressions(impressions: [ImpressionsTest], completion: @escaping (DataResult) -> Void) + func sendImpressions(impressions: [ImpressionsTest], completion: @Sendable @escaping (DataResult) -> Void) } extension DefaultRestClient: RestClientImpressions { - func sendImpressions(impressions: [ImpressionsTest], completion: @escaping (DataResult) -> Void) { + func sendImpressions(impressions: [ImpressionsTest], completion: @Sendable @escaping (DataResult) -> Void) { do { self.execute( endpoint: endpointFactory.impressionsEndpoint, diff --git a/Split/Network/RestClient/RestClient+ImpressionsCount.swift b/Split/Network/RestClient/RestClient+ImpressionsCount.swift index bddd164f8..7f8225443 100644 --- a/Split/Network/RestClient/RestClient+ImpressionsCount.swift +++ b/Split/Network/RestClient/RestClient+ImpressionsCount.swift @@ -9,11 +9,11 @@ import Foundation protocol RestClientImpressionsCount: RestClient { - func send(counts: ImpressionsCount, completion: @escaping (DataResult) -> Void) + func send(counts: ImpressionsCount, completion: @Sendable @escaping (DataResult) -> Void) } extension DefaultRestClient: RestClientImpressionsCount { - func send(counts: ImpressionsCount, completion: @escaping (DataResult) -> Void) { + func send(counts: ImpressionsCount, completion: @Sendable @escaping (DataResult) -> Void) { do { self.execute( endpoint: endpointFactory.impressionsCountEndpoint, diff --git a/Split/Network/RestClient/RestClient+SplitChanges.swift b/Split/Network/RestClient/RestClient+SplitChanges.swift index 98b277bc4..28ae712e7 100644 --- a/Split/Network/RestClient/RestClient+SplitChanges.swift +++ b/Split/Network/RestClient/RestClient+SplitChanges.swift @@ -39,7 +39,7 @@ protocol RestClientSplitChanges: RestClient { till: Int64?, headers: HttpHeaders?, spec: String, - completion: @escaping (DataResult) -> Void) + completion: @Sendable @escaping (DataResult) -> Void) } extension DefaultRestClient: RestClientSplitChanges { @@ -48,7 +48,7 @@ extension DefaultRestClient: RestClientSplitChanges { till: Int64?, headers: HttpHeaders?, spec: String = Spec.flagsSpec, - completion: @escaping (DataResult) -> Void) { + completion: @Sendable @escaping (DataResult) -> Void) { let errorHandler = SplitChangesErrorHandler(serviceEndpoints: endpointFactory.serviceEndpoints) diff --git a/Split/Network/RestClient/RestClient+TelemetryStats.swift b/Split/Network/RestClient/RestClient+TelemetryStats.swift index cff1a8f2d..7daf149a5 100644 --- a/Split/Network/RestClient/RestClient+TelemetryStats.swift +++ b/Split/Network/RestClient/RestClient+TelemetryStats.swift @@ -9,11 +9,11 @@ import Foundation protocol RestClientTelemetryStats: RestClient { - func send(stats: TelemetryStats, completion: @escaping (DataResult) -> Void) + func send(stats: TelemetryStats, completion: @Sendable @escaping (DataResult) -> Void) } extension DefaultRestClient: RestClientTelemetryStats { - func send(stats: TelemetryStats, completion: @escaping (DataResult) -> Void) { + func send(stats: TelemetryStats, completion: @Sendable @escaping (DataResult) -> Void) { do { self.execute( endpoint: endpointFactory.telemetryUsageEndpoint, diff --git a/Split/Network/RestClient/RestClient+UniqueKeys.swift b/Split/Network/RestClient/RestClient+UniqueKeys.swift index 0f2864604..10d4ecaf4 100644 --- a/Split/Network/RestClient/RestClient+UniqueKeys.swift +++ b/Split/Network/RestClient/RestClient+UniqueKeys.swift @@ -9,11 +9,11 @@ import Foundation protocol RestClientUniqueKeys: RestClient { - func send(uniqueKeys: UniqueKeys, completion: @escaping (DataResult) -> Void) + func send(uniqueKeys: UniqueKeys, completion: @Sendable @escaping (DataResult) -> Void) } extension DefaultRestClient: RestClientUniqueKeys { - func send(uniqueKeys: UniqueKeys, completion: @escaping (DataResult) -> Void) { + func send(uniqueKeys: UniqueKeys, completion: @Sendable @escaping (DataResult) -> Void) { do { self.execute( endpoint: endpointFactory.uniqueKeysEndpoint, diff --git a/Split/Network/RestClient/RestClient.swift b/Split/Network/RestClient/RestClient.swift index 80c661c6e..b61c2c589 100644 --- a/Split/Network/RestClient/RestClient.swift +++ b/Split/Network/RestClient/RestClient.swift @@ -56,9 +56,9 @@ class DefaultRestClient: SplitApiRestClient { parameters: HttpParameters? = nil, body: Data? = nil, headers: HttpHeaders? = nil, - customDecoder: ((Data) throws -> T)? = nil, - customFailureHandler: ((Int) throws -> Error?)? = nil, - completion: @escaping (DataResult) -> Void) where T: Decodable { + customDecoder: ( @Sendable (Data) throws -> T)? = nil, + customFailureHandler: ( @Sendable (Int) throws -> Error?)? = nil, + completion: @Sendable @escaping (DataResult) -> Void) where T: Decodable { do { _ = try httpClient.sendRequest( diff --git a/Split/Network/Streaming/BackoffCounterTimer.swift b/Split/Network/Streaming/BackoffCounterTimer.swift index 049e750dc..642a74057 100644 --- a/Split/Network/Streaming/BackoffCounterTimer.swift +++ b/Split/Network/Streaming/BackoffCounterTimer.swift @@ -9,11 +9,11 @@ import Foundation protocol BackoffCounterTimer { - func schedule(handler: @escaping () -> Void) + func schedule(handler: @Sendable @escaping () -> Void) func cancel() } -class DefaultBackoffCounterTimer: BackoffCounterTimer { +class DefaultBackoffCounterTimer: BackoffCounterTimer, @unchecked Sendable { private let reconnectBackoffCounter: ReconnectBackoffCounter private let queue = DispatchQueue(label: "split-backoff-timer") private let timersQueue = DispatchQueue.general @@ -24,7 +24,7 @@ class DefaultBackoffCounterTimer: BackoffCounterTimer { self.reconnectBackoffCounter = reconnectBackoffCounter } - func schedule(handler: @escaping () -> Void) { + func schedule(handler: @Sendable @escaping () -> Void) { queue.async { self.schedule(handler) } diff --git a/Split/Network/Streaming/PushNotificationManager.swift b/Split/Network/Streaming/PushNotificationManager.swift index 38aa4f28f..e47a923ce 100644 --- a/Split/Network/Streaming/PushNotificationManager.swift +++ b/Split/Network/Streaming/PushNotificationManager.swift @@ -19,7 +19,7 @@ protocol PushNotificationManager { func reset() } -class DefaultPushNotificationManager: PushNotificationManager { +class DefaultPushNotificationManager: PushNotificationManager, @unchecked Sendable { private let kSseKeepAliveTimeInSeconds = 70 private let kReconnectTimeBeforeTokenExpInASeconds: Int64 = 600 diff --git a/Split/Network/Streaming/SseClient.swift b/Split/Network/Streaming/SseClient.swift index eebff7cba..878afae9c 100644 --- a/Split/Network/Streaming/SseClient.swift +++ b/Split/Network/Streaming/SseClient.swift @@ -16,13 +16,13 @@ struct SseClientConstants { } protocol SseClient: AnyObject { - typealias CompletionHandler = (Bool) -> Void + typealias CompletionHandler = @Sendable (Bool) -> Void func connect(token: String, channels: [String], completion: @escaping CompletionHandler) func disconnect() var isConnectionOpened: Bool { get } } -class DefaultSseClient: SseClient { +class DefaultSseClient: SseClient, @unchecked Sendable { /// /// NOTE: diff --git a/Split/Network/Streaming/SseConnectionHandler.swift b/Split/Network/Streaming/SseConnectionHandler.swift index 8e4a78d40..0349ae69f 100644 --- a/Split/Network/Streaming/SseConnectionHandler.swift +++ b/Split/Network/Streaming/SseConnectionHandler.swift @@ -8,7 +8,7 @@ import Foundation -class SseConnectionHandler { +class SseConnectionHandler: @unchecked Sendable { private let clientLock = NSLock() private let sseClientFactory: SseClientFactory private var curClientId: String? diff --git a/Split/Network/Streaming/SyncEventBroadcaster.swift b/Split/Network/Streaming/SyncEventBroadcaster.swift index 393563509..51ce0cf1e 100644 --- a/Split/Network/Streaming/SyncEventBroadcaster.swift +++ b/Split/Network/Streaming/SyncEventBroadcaster.swift @@ -22,7 +22,7 @@ enum SyncStatusEvent: Equatable { } protocol SyncEventBroadcaster { - typealias IncomingMessageHandler = (SyncStatusEvent) -> Void + typealias IncomingMessageHandler = @Sendable (SyncStatusEvent) -> Void func push(event: SyncStatusEvent) func register(handler: @escaping IncomingMessageHandler) func destroy() @@ -32,7 +32,7 @@ protocol SyncEventBroadcaster { /// Component to allow push notification manager to comunicate status events /// to other components /// -class DefaultSyncEventBroadcaster: SyncEventBroadcaster { +class DefaultSyncEventBroadcaster: SyncEventBroadcaster, @unchecked Sendable { let messageQueue = DispatchQueue(label: "split-sync-event-broadcaster", attributes: .concurrent) var handlers = [IncomingMessageHandler]() diff --git a/Split/Network/Streaming/SyncSegmentsUpdateWorker.swift b/Split/Network/Streaming/SyncSegmentsUpdateWorker.swift index c8ec78ae4..411ddf1c7 100644 --- a/Split/Network/Streaming/SyncSegmentsUpdateWorker.swift +++ b/Split/Network/Streaming/SyncSegmentsUpdateWorker.swift @@ -8,7 +8,7 @@ import Foundation -class SegmentsUpdateWorker: UpdateWorker { +class SegmentsUpdateWorker: UpdateWorker, @unchecked Sendable { private let synchronizer: SegmentsSynchronizerWrapper private let mySegmentsStorage: MySegmentsStorage diff --git a/Split/Network/Streaming/SyncUpdateWorker.swift b/Split/Network/Streaming/SyncUpdateWorker.swift index e9c90f2c5..1df3034c9 100644 --- a/Split/Network/Streaming/SyncUpdateWorker.swift +++ b/Split/Network/Streaming/SyncUpdateWorker.swift @@ -24,7 +24,7 @@ class UpdateWorker { } } -class SplitsUpdateWorker: UpdateWorker { +class SplitsUpdateWorker: UpdateWorker, @unchecked Sendable { private let synchronizer: Synchronizer private let splitsStorage: SplitsStorage @@ -204,7 +204,7 @@ class SplitsUpdateWorker: UpdateWorker { } } -class SplitKillWorker: UpdateWorker { +class SplitKillWorker: UpdateWorker, @unchecked Sendable { private let synchronizer: Synchronizer private let splitsStorage: SplitsStorage diff --git a/Split/Network/Sync/FeatureFlagsSynchronizer.swift b/Split/Network/Sync/FeatureFlagsSynchronizer.swift index e65e49790..a1c2d5ce5 100644 --- a/Split/Network/Sync/FeatureFlagsSynchronizer.swift +++ b/Split/Network/Sync/FeatureFlagsSynchronizer.swift @@ -21,7 +21,7 @@ protocol FeatureFlagsSynchronizer { func destroy() } -class DefaultFeatureFlagsSynchronizer: FeatureFlagsSynchronizer { +class DefaultFeatureFlagsSynchronizer: FeatureFlagsSynchronizer, @unchecked Sendable { private var storageContainer: SplitStorageContainer private var splitsSyncWorker: RetryableSyncWorker! diff --git a/Split/Network/Sync/MySegmentsSynchronizer.swift b/Split/Network/Sync/MySegmentsSynchronizer.swift index efdc2bcfc..a0131460c 100644 --- a/Split/Network/Sync/MySegmentsSynchronizer.swift +++ b/Split/Network/Sync/MySegmentsSynchronizer.swift @@ -20,7 +20,7 @@ protocol MySegmentsSynchronizer { } // One instance per client -class DefaultMySegmentsSynchronizer: MySegmentsSynchronizer { +class DefaultMySegmentsSynchronizer: MySegmentsSynchronizer, @unchecked Sendable { private let mySegmentsStorage: ByKeyMySegmentsStorage private let myLargeSegmentsStorage: ByKeyMySegmentsStorage diff --git a/Split/Network/Sync/Synchronizer.swift b/Split/Network/Sync/Synchronizer.swift index d3155a193..3927c0df7 100644 --- a/Split/Network/Sync/Synchronizer.swift +++ b/Split/Network/Sync/Synchronizer.swift @@ -44,7 +44,7 @@ protocol Synchronizer: ImpressionLogger { func disableTelemetry() } -class DefaultSynchronizer: Synchronizer { +class DefaultSynchronizer: Synchronizer, @unchecked Sendable { private let splitConfig: SplitClientConfig private let splitStorageContainer: SplitStorageContainer diff --git a/Split/Network/Sync/TelemetrySynchronizer.swift b/Split/Network/Sync/TelemetrySynchronizer.swift index b28c04fda..8cdc5df68 100644 --- a/Split/Network/Sync/TelemetrySynchronizer.swift +++ b/Split/Network/Sync/TelemetrySynchronizer.swift @@ -17,7 +17,7 @@ protocol TelemetrySynchronizer { func destroy() } -class DefaultTelemetrySynchronizer: TelemetrySynchronizer { +class DefaultTelemetrySynchronizer: TelemetrySynchronizer, @unchecked Sendable { private let configRecorderWorker: RecorderWorker private let statsRecorderWorker: RecorderWorker diff --git a/Split/Secure/SecureDataStore.swift b/Split/Secure/SecureDataStore.swift index 84fc44dc6..3a9a83f7b 100644 --- a/Split/Secure/SecureDataStore.swift +++ b/Split/Secure/SecureDataStore.swift @@ -15,7 +15,7 @@ class SecureDataStore { private var token: String? - static let shared: SecureDataStore = { + nonisolated(unsafe) static let shared: SecureDataStore = { let instance = SecureDataStore() return instance diff --git a/Split/Storage/Attributes/OneKeyAttributesStorage.swift b/Split/Storage/Attributes/OneKeyAttributesStorage.swift index a4cf22203..6ab179575 100644 --- a/Split/Storage/Attributes/OneKeyAttributesStorage.swift +++ b/Split/Storage/Attributes/OneKeyAttributesStorage.swift @@ -20,10 +20,15 @@ protocol OneKeyAttributesStorage { func destroy() } +struct AnySendable: Sendable { + let value: Any + init(_ value: Any) { self.value = value } +} + @available(*, deprecated, message: "Gonna be replaced by AttributesStorage and ByKeyAttributesStorage") class OneKeyDefaultAttributesStorage: OneKeyAttributesStorage { - private let inMemoryAttributes: ConcurrentDictionary + private let inMemoryAttributes: ConcurrentDictionary private let persistentStorage: OneKeyPersistentAttributesStorage? init(persistentAttributesStorage: OneKeyPersistentAttributesStorage? = nil) { diff --git a/Split/Storage/CoreDataContextBuilder.swift b/Split/Storage/CoreDataContextBuilder.swift index edcf439e8..12c68f26d 100644 --- a/Split/Storage/CoreDataContextBuilder.swift +++ b/Split/Storage/CoreDataContextBuilder.swift @@ -14,7 +14,7 @@ class CoreDataHelperBuilder { private static let kDataModelName = "split_cache" private static let kDataModelExtentsion = "momd" - static func build(databaseName: String) -> CoreDataHelper? { + nonisolated static func build(databaseName: String) -> CoreDataHelper? { let bundle = Bundle.split guard let modelUrl = bundle.url(forResource: kDataModelName, withExtension: kDataModelExtentsion) else { @@ -32,7 +32,7 @@ class CoreDataHelperBuilder { let managedObjContext = NSManagedObjectContext( concurrencyType: NSManagedObjectContextConcurrencyType.privateQueueConcurrencyType) - managedObjContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy + managedObjContext.mergePolicy = NSMergePolicy.mergeByPropertyObjectTrump managedObjContext.persistentStoreCoordinator = persistenceCoordinator guard let docURL = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).last else { diff --git a/Split/Storage/Global/GlobalSecureStorage.swift b/Split/Storage/Global/GlobalSecureStorage.swift index 2a183fa69..1817ca3d7 100644 --- a/Split/Storage/Global/GlobalSecureStorage.swift +++ b/Split/Storage/Global/GlobalSecureStorage.swift @@ -9,10 +9,10 @@ import Foundation class GlobalSecureStorage: KeyValueStorage { - private static let prodStorage: KeyValueStorage = GlobalSecureStorage() + nonisolated(unsafe) private static let prodStorage: KeyValueStorage = GlobalSecureStorage() // Only for testing - static var testStorage: KeyValueStorage? + nonisolated(unsafe) static var testStorage: KeyValueStorage? static var shared: KeyValueStorage { return testStorage ?? prodStorage diff --git a/Split/Storage/MySegments/PersistentMySegmentsStorage.swift b/Split/Storage/MySegments/PersistentMySegmentsStorage.swift index 025a3460f..9e2240d17 100644 --- a/Split/Storage/MySegments/PersistentMySegmentsStorage.swift +++ b/Split/Storage/MySegments/PersistentMySegmentsStorage.swift @@ -8,13 +8,13 @@ import Foundation -protocol PersistentMySegmentsStorage { +protocol PersistentMySegmentsStorage: Sendable { func set(_ change: SegmentChange, forKey key: String) func getSnapshot(forKey key: String) -> SegmentChange? func deleteAll() } -class PersistentSegmentsStorage: PersistentMySegmentsStorage { +class PersistentSegmentsStorage: PersistentMySegmentsStorage, @unchecked Sendable { private let dao: MySegmentsDao @@ -35,13 +35,13 @@ class PersistentSegmentsStorage: PersistentMySegmentsStorage { } } -class DefaultPersistentMySegmentsStorage: PersistentSegmentsStorage { +class DefaultPersistentMySegmentsStorage: PersistentSegmentsStorage, @unchecked Sendable { init(database: SplitDatabase) { super.init(dao: database.mySegmentsDao) } } -class DefaultPersistentMyLargeSegmentsStorage: PersistentSegmentsStorage { +class DefaultPersistentMyLargeSegmentsStorage: PersistentSegmentsStorage, @unchecked Sendable { init(database: SplitDatabase) { super.init(dao: database.myLargeSegmentsDao) } diff --git a/Split/Storage/RuleBasedSegments/RuleBasedSegment.swift b/Split/Storage/RuleBasedSegments/RuleBasedSegment.swift index 50e01485b..0e56886ad 100644 --- a/Split/Storage/RuleBasedSegments/RuleBasedSegment.swift +++ b/Split/Storage/RuleBasedSegments/RuleBasedSegment.swift @@ -126,7 +126,7 @@ class Excluded: NSObject, Codable { } } -class RuleBasedSegment: NSObject, Codable { +class RuleBasedSegment: NSObject, Codable, @unchecked Sendable { var name: String? var trafficTypeName: String? var changeNumber: Int64 = -1 diff --git a/Split/Storage/Splits/SplitsDecoder.swift b/Split/Storage/Splits/SplitsDecoder.swift index 85e88826d..e55b0aed7 100644 --- a/Split/Storage/Splits/SplitsDecoder.swift +++ b/Split/Storage/Splits/SplitsDecoder.swift @@ -12,7 +12,7 @@ protocol SplitsDecoder { func decode(_ list: [String]) -> [Split] } -struct SplitsParallelDecoder: SplitsDecoder { +struct SplitsParallelDecoder: SplitsDecoder, @unchecked Sendable { private var minTaskPerThread: Int private let serialDecoder: SplitsSerialDecoder init(minTaskPerThread: Int = 10, cipher: Cipher? = nil) { diff --git a/Split/Telemetry/Storage/TelemetryInMemoryStorage.swift b/Split/Telemetry/Storage/TelemetryInMemoryStorage.swift index 038f28151..2e2412354 100644 --- a/Split/Telemetry/Storage/TelemetryInMemoryStorage.swift +++ b/Split/Telemetry/Storage/TelemetryInMemoryStorage.swift @@ -8,7 +8,7 @@ import Foundation -class InMemoryTelemetryStorage: TelemetryStorage { +final class InMemoryTelemetryStorage: TelemetryStorage, @unchecked Sendable { private static let kQueuePrefix = "split-telemetry" private let queue = DispatchQueue(label: "split-telemetry") diff --git a/Split/Telemetry/Storage/TelemetryStorage.swift b/Split/Telemetry/Storage/TelemetryStorage.swift index 01b4e5310..152b24c41 100644 --- a/Split/Telemetry/Storage/TelemetryStorage.swift +++ b/Split/Telemetry/Storage/TelemetryStorage.swift @@ -108,12 +108,12 @@ protocol TelemetryRuntimeConsumer { protocol TelemetryProducer: TelemetryInitProducer, TelemetryEvaluationProducer, - TelemetryRuntimeProducer { + TelemetryRuntimeProducer, Sendable { } protocol TelemetryConsumer: TelemetryInitConsumer, TelemetryEvaluationConsumer, - TelemetryRuntimeConsumer { + TelemetryRuntimeConsumer, Sendable { } protocol TelemetryStorage: TelemetryProducer, TelemetryConsumer { diff --git a/Split/Track/Models/EventDTO.swift b/Split/Track/Models/EventDTO.swift index d95e6d6db..4a9e2facf 100644 --- a/Split/Track/Models/EventDTO.swift +++ b/Split/Track/Models/EventDTO.swift @@ -8,7 +8,7 @@ import Foundation // TODO: Rename to Event -class EventDTO: DynamicCodable { +class EventDTO: DynamicCodable, @unchecked Sendable { var storageId: String? var key: String? var eventTypeId: String diff --git a/SplitTests/Fake/Network/HttpSessionMock.swift b/SplitTests/Fake/Network/HttpSessionMock.swift index 9aad4b603..98fac27b7 100644 --- a/SplitTests/Fake/Network/HttpSessionMock.swift +++ b/SplitTests/Fake/Network/HttpSessionMock.swift @@ -14,7 +14,7 @@ class HttpSessionMock: HttpSession { func finalize() { } - private (set) var dataTaskCallCount: Int = 0 + private(set) var dataTaskCallCount: Int = 0 func startTask(with request: HttpRequest) -> HttpTask? { dataTaskCallCount+=1 return HttpTaskMock(identifier: 100) diff --git a/SplitTests/InitDbCipherTest.swift b/SplitTests/InitDbCipherTest.swift index bbf033234..77e7568ba 100644 --- a/SplitTests/InitDbCipherTest.swift +++ b/SplitTests/InitDbCipherTest.swift @@ -17,13 +17,11 @@ class InitDbCipherTest: XCTestCase { let apiKey1 = IntegrationHelper.dummyApiKey let apiKey2 = "42bc399049fd8653247c5ea42bc3c1ae2c6a" var secureStorage = SecureStorageStub() + override func setUp() { GlobalSecureStorage.testStorage = secureStorage dbHelper = createDbHelper() - db = TestingHelper.createTestDatabase(name: "test", - queue: DispatchQueue.test, - helper: dbHelper) - + db = TestingHelper.createTestDatabase(name: "test", queue: DispatchQueue.test, helper: dbHelper) } func testEncryptDb() throws {