Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add full data-race safety and enable strict concurrency checking for Swift 6 compatibility #174

Merged
merged 11 commits into from
Aug 12, 2024
Prev Previous commit
Next Next commit
Fix leftover issues when calling into UI values for parameters
Jeehut committed Aug 1, 2024
commit 66fe52eac02fed305d1a32ab76690b26d7d8fe63
4 changes: 4 additions & 0 deletions Sources/TelemetryClient/Signal.swift
Original file line number Diff line number Diff line change
@@ -41,6 +41,7 @@ internal struct SignalPostBody: Codable, Equatable {

/// The default payload that is included in payloads processed by TelemetryDeck.
public struct DefaultSignalPayload: Encodable {
@MainActor
public static var parameters: [String: String] {
var parameters: [String: String] = [
// deprecated names
@@ -338,6 +339,7 @@ extension DefaultSignalPayload {
}

/// The current devices screen resolution width in points.
@MainActor
static var screenResolutionWidth: String {
#if os(iOS) || os(tvOS)
return "\(UIScreen.main.bounds.width)"
@@ -354,6 +356,7 @@ extension DefaultSignalPayload {
}

/// The current devices screen resolution height in points.
@MainActor
static var screenResolutionHeight: String {
#if os(iOS) || os(tvOS)
return "\(UIScreen.main.bounds.height)"
@@ -370,6 +373,7 @@ extension DefaultSignalPayload {
}

/// The current devices screen orientation. Returns `Fixed` for devices that don't support an orientation change.
@MainActor
static var orientation: String {
#if os(iOS)
switch UIDevice.current.orientation {
52 changes: 29 additions & 23 deletions Sources/TelemetryClient/SignalManager.swift
Original file line number Diff line number Diff line change
@@ -75,29 +75,34 @@ internal final class SignalManager: SignalManageable, @unchecked Sendable {
customUserID: String?,
configuration: TelemetryManagerConfiguration
) {
DispatchQueue.global(qos: .utility).async {
let enrichedMetadata: [String: String] = configuration.metadataEnrichers
.map { $0.enrich(signalType: signalName, for: customUserID, floatValue: floatValue) }
.reduce([String: String](), { $0.applying($1) })

let payload = DefaultSignalPayload.parameters
.applying(enrichedMetadata)
.applying(parameters)

let signalPostBody = SignalPostBody(
receivedAt: Date(),
appID: UUID(uuidString: configuration.telemetryAppID)!,
clientUser: CryptoHashing.sha256(string: customUserID ?? self.defaultUserIdentifier, salt: configuration.salt),
sessionID: configuration.sessionID.uuidString,
type: "\(signalName)",
floatValue: floatValue,
payload: payload.toMultiValueDimension(),
isTestMode: configuration.testMode ? "true" : "false"
)

configuration.logHandler?.log(.debug, message: "Process signal: \(signalPostBody)")

self.signalCache.push(signalPostBody)
DispatchQueue.main.async {
let defaultUserIdentifier = self.defaultUserIdentifier
let defaultParameters = DefaultSignalPayload.parameters

DispatchQueue.global(qos: .utility).async {
let enrichedMetadata: [String: String] = configuration.metadataEnrichers
.map { $0.enrich(signalType: signalName, for: customUserID, floatValue: floatValue) }
.reduce([String: String](), { $0.applying($1) })

let payload = defaultParameters
.applying(enrichedMetadata)
.applying(parameters)

let signalPostBody = SignalPostBody(
receivedAt: Date(),
appID: UUID(uuidString: configuration.telemetryAppID)!,
clientUser: CryptoHashing.sha256(string: customUserID ?? defaultUserIdentifier, salt: configuration.salt),
sessionID: configuration.sessionID.uuidString,
type: "\(signalName)",
floatValue: floatValue,
payload: payload.toMultiValueDimension(),
isTestMode: configuration.testMode ? "true" : "false"
)

configuration.logHandler?.log(.debug, message: "Process signal: \(signalPostBody)")

self.signalCache.push(signalPostBody)
}
}
}

@@ -211,6 +216,7 @@ private extension SignalManager {
#endif

/// The default user identifier. If the platform supports it, the ``identifierForVendor``. Otherwise, a self-generated `UUID` which is persisted in custom `UserDefaults` if available.
@MainActor
var defaultUserIdentifier: String {
guard configuration.defaultUser == nil else { return configuration.defaultUser! }