diff --git a/CHANGELOG.md b/CHANGELOG.md index 57b8247..6e8cf84 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased -## [1.4.0] - 2026-03-18 +## [1.2.1] - 2026-06-17 +### Added +- Added retroactive conformance to `@unchecked Sendable` for `SecCertificate`, `SecIdentity`, `SecKey`, and `SecKeychainItem`. This is safe because Apple eventually adds this same conformance beginning in Xcode 26. + +## [1.2.0] - 2026-03-18 ### Added - Added convenience methods for accessing mock data values on the `HaversackEphemeralStrategy` - Added `Sendable` conformance to all public types, protocols, and enums. @@ -21,7 +25,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Internal `CFString` dictionary keys migrated to `String` for `Sendable` compatibility. - Completion handlers and closure properties marked `@Sendable`. -## [1.3.0] - 2024-02-11 +## [1.2.0-prerelease] - 2024-02-11 ### Added - Added support for visionOS. diff --git a/Sources/Haversack/Entities/PasswordBaseEntity.swift b/Sources/Haversack/Entities/PasswordBaseEntity.swift index 64464f0..577af56 100644 --- a/Sources/Haversack/Entities/PasswordBaseEntity.swift +++ b/Sources/Haversack/Entities/PasswordBaseEntity.swift @@ -65,8 +65,6 @@ public protocol PasswordBaseEntity: KeychainStorable { /// - Note: Uses `kSecValueData`. var passwordData: Data? { get set } - // NOTE: This function has a cyclomatic complexity of 11 instead of the allowed 10. - // swiftlint:disable:next cyclomatic_complexity func entityQuery(includeSecureData: Bool) -> SecurityFrameworkQuery } @@ -76,7 +74,8 @@ extension PasswordBaseEntity { return passwordData == nil } - // swiftlint:disable:next identifier_name + // NOTE: This function has a cyclomatic complexity of 11 instead of the allowed 10. + // swiftlint:disable:next identifier_name cyclomatic_complexity func _entityQuery(includeSecureData: Bool) -> SecurityFrameworkQuery { var newQuery = SecurityFrameworkQuery() diff --git a/Sources/Haversack/NSLocked.swift b/Sources/Haversack/NSLocked.swift index 235dbb6..f23acb2 100644 --- a/Sources/Haversack/NSLocked.swift +++ b/Sources/Haversack/NSLocked.swift @@ -7,11 +7,11 @@ import Foundation public struct NSLocked: @unchecked Sendable { private let lock = NSLock() private var value: T - + public init(wrappedValue: T) { value = wrappedValue } - + public var wrappedValue: T { get { lock.withLock { diff --git a/Sources/Haversack/SecuritySendable.swift b/Sources/Haversack/SecuritySendable.swift new file mode 100644 index 0000000..05a47cb --- /dev/null +++ b/Sources/Haversack/SecuritySendable.swift @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: MIT +// Copyright 2026, Jamf + +import Security + +#if compiler(<6) // conformance for Xcode less than 16.0, @retroactive unavailable until Swift 6 +extension SecCertificate: @unchecked Sendable {} +extension SecIdentity: @unchecked Sendable {} +extension SecKey: @unchecked Sendable {} +#if os(macOS) +extension SecKeychainItem: @unchecked Sendable {} +#endif +#elseif compiler(<6.2) // retroactive conformance for Xcode 16.0 +extension SecCertificate: @retroactive @unchecked Sendable {} +extension SecIdentity: @retroactive @unchecked Sendable {} +extension SecKey: @retroactive @unchecked Sendable {} +#if os(macOS) +extension SecKeychainItem: @retroactive @unchecked Sendable {} +#endif +#endif