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 {