diff --git a/FirebaseCore/Internal/Sources/HeartbeatLogging/HeartbeatController.swift b/FirebaseCore/Internal/Sources/HeartbeatLogging/HeartbeatController.swift index e4a2cc4c335..cc80c3e158b 100644 --- a/FirebaseCore/Internal/Sources/HeartbeatLogging/HeartbeatController.swift +++ b/FirebaseCore/Internal/Sources/HeartbeatLogging/HeartbeatController.swift @@ -15,7 +15,7 @@ import Foundation /// An object that provides API to log and flush heartbeats from a synchronized storage container. -public final class HeartbeatController { +public final class HeartbeatController: Sendable { /// Used for standardizing dates for calendar-day comparison. private enum DateStandardizer { private static let calendar: Calendar = { @@ -31,11 +31,11 @@ public final class HeartbeatController { } /// The thread-safe storage object to log and flush heartbeats from. - private let storage: HeartbeatStorageProtocol + private let storage: any HeartbeatStorageProtocol /// The max capacity of heartbeats to store in storage. - private let heartbeatsStorageCapacity: Int = 30 + private static let heartbeatsStorageCapacity: Int = 30 /// Current date provider. It is used for testability. - private let dateProvider: () -> Date + private let dateProvider: @Sendable () -> Date /// Used for standardizing dates for calendar-day comparison. private static let dateStandardizer = DateStandardizer.self @@ -51,7 +51,7 @@ public final class HeartbeatController { /// - Parameters: /// - id: The id to associate this controller's heartbeat storage with. /// - dateProvider: A date provider. - convenience init(id: String, dateProvider: @escaping () -> Date) { + convenience init(id: String, dateProvider: @escaping @Sendable () -> Date) { let storage = HeartbeatStorage.getInstance(id: id) self.init(storage: storage, dateProvider: dateProvider) } @@ -61,7 +61,7 @@ public final class HeartbeatController { /// - storage: A heartbeat storage container. /// - dateProvider: A date provider. Defaults to providing the current date. init(storage: HeartbeatStorageProtocol, - dateProvider: @escaping () -> Date = Date.init) { + dateProvider: @escaping @Sendable () -> Date = Date.init) { self.storage = storage self.dateProvider = { Self.dateStandardizer.standardize(dateProvider()) } } @@ -76,7 +76,7 @@ public final class HeartbeatController { storage.readAndWriteAsync { heartbeatsBundle in var heartbeatsBundle = heartbeatsBundle ?? - HeartbeatsBundle(capacity: self.heartbeatsStorageCapacity) + HeartbeatsBundle(capacity: Self.heartbeatsStorageCapacity) // Filter for the time periods where the last heartbeat to be logged for // that time period was logged more than one time period (i.e. day) ago. @@ -109,7 +109,7 @@ public final class HeartbeatController { // The new value that's stored will use the old's cache to prevent the // logging of duplicates after flushing. return HeartbeatsBundle( - capacity: self.heartbeatsStorageCapacity, + capacity: Self.heartbeatsStorageCapacity, cache: oldHeartbeatsBundle.lastAddedHeartbeatDates ) } @@ -129,14 +129,14 @@ public final class HeartbeatController { @available(iOS 13.0, macOS 10.15, macCatalyst 13.0, tvOS 13.0, watchOS 6.0, *) public func flushAsync() async -> HeartbeatsPayload { return await withCheckedContinuation { continuation in - let resetTransform = { (heartbeatsBundle: HeartbeatsBundle?) -> HeartbeatsBundle? in + let resetTransform = { @Sendable (heartbeatsBundle: HeartbeatsBundle?) -> HeartbeatsBundle? in guard let oldHeartbeatsBundle = heartbeatsBundle else { return nil // Storage was empty. } // The new value that's stored will use the old's cache to prevent the // logging of duplicates after flushing. return HeartbeatsBundle( - capacity: self.heartbeatsStorageCapacity, + capacity: Self.heartbeatsStorageCapacity, cache: oldHeartbeatsBundle.lastAddedHeartbeatDates ) } diff --git a/FirebaseCore/Internal/Sources/HeartbeatLogging/HeartbeatStorage.swift b/FirebaseCore/Internal/Sources/HeartbeatLogging/HeartbeatStorage.swift index 991e6e15a15..1061d3478ed 100644 --- a/FirebaseCore/Internal/Sources/HeartbeatLogging/HeartbeatStorage.swift +++ b/FirebaseCore/Internal/Sources/HeartbeatLogging/HeartbeatStorage.swift @@ -15,7 +15,7 @@ import Foundation /// A type that can perform atomic operations using block-based transformations. -protocol HeartbeatStorageProtocol { +protocol HeartbeatStorageProtocol: Sendable { func readAndWriteSync(using transform: (HeartbeatsBundle?) -> HeartbeatsBundle?) func readAndWriteAsync(using transform: @escaping @Sendable (HeartbeatsBundle?) -> HeartbeatsBundle?)