Skip to content

Commit

Permalink
Make core types Sendable and @unchecked Sendable (#308)
Browse files Browse the repository at this point in the history
* Make core types Sendable and @unchecked Sendable

* Update Swift version and minimum Xcode version
  • Loading branch information
dfed authored Apr 23, 2024
1 parent c095ce0 commit 3df8eaa
Show file tree
Hide file tree
Showing 18 changed files with 27 additions and 37 deletions.
6 changes: 1 addition & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ jobs:
- name: Select Xcode Version
run: sudo xcode-select --switch /Applications/Xcode_14.3.app/Contents/Developer
- name: Lint Podspec
run: bundle exec pod lib lint --verbose --fail-fast --swift-version=5.0
run: bundle exec pod lib lint --verbose --fail-fast --swift-version=5.4
carthage:
name: Carthage
runs-on: macOS-13
Expand All @@ -118,7 +118,6 @@ jobs:
'iOS_14,tvOS_14,watchOS_7',
'iOS_13,tvOS_13,watchOS_6',
'macOS_11',
'macOS_10_15',
]
fail-fast: false
steps:
Expand All @@ -135,9 +134,6 @@ jobs:
- name: Select Xcode Version
run: sudo xcode-select --switch /Applications/Xcode_12.5.1.app/Contents/Developer
if: ${{ matrix.platforms == 'macOS_11' }}
- name: Select Xcode Version
run: sudo xcode-select --switch /Applications/Xcode_11.7.app/Contents/Developer
if: ${{ matrix.platforms == 'macOS_10_15' }}
- name: Prepare Simulator Runtimes
run: Scripts/github/prepare-simulators.sh ${{ matrix.platforms }}
- name: Build Framework
Expand Down
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// swift-tools-version:5.0
// swift-tools-version:5.4
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ Valet guarantees that reading and writing operations will succeed as long as wri
## Requirements
* Xcode 11.0 or later. Xcode 10 and Xcode 9 require [Valet version 3.2.8](https://github.com/square/Valet/releases/tag/3.2.8). Earlier versions of Xcode require [Valet version 2.4.2](https://github.com/square/Valet/releases/tag/2.4.2).
* Xcode 12.5 or later.
* iOS 9 or later.
* tvOS 9 or later.
* watchOS 2 or later.
Expand Down
10 changes: 2 additions & 8 deletions Scripts/build.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ enum Platform: String, CustomStringConvertible {
case tvOS_15
case tvOS_16
case tvOS_17
case macOS_10_15
case macOS_11
case macOS_12
case macOS_13
Expand Down Expand Up @@ -66,8 +65,7 @@ enum Platform: String, CustomStringConvertible {
case .tvOS_17:
return "platform=tvOS Simulator,OS=17.0,name=Apple TV"

case .macOS_10_15,
.macOS_11,
case .macOS_11,
.macOS_12,
.macOS_13,
.macOS_14:
Expand Down Expand Up @@ -102,8 +100,6 @@ enum Platform: String, CustomStringConvertible {
.tvOS_17:
return "appletvsimulator"

case .macOS_10_15:
return "macosx10.15"
case .macOS_11:
return "macosx11.1"
case .macOS_12:
Expand Down Expand Up @@ -134,7 +130,6 @@ enum Platform: String, CustomStringConvertible {
.tvOS_15,
.tvOS_16,
.tvOS_17,
.macOS_10_15,
.macOS_11,
.macOS_12,
.macOS_13,
Expand Down Expand Up @@ -182,8 +177,7 @@ enum Platform: String, CustomStringConvertible {
.tvOS_17:
return "Valet tvOS"

case .macOS_10_15,
.macOS_11,
case .macOS_11,
.macOS_12,
.macOS_13,
.macOS_14:
Expand Down
2 changes: 1 addition & 1 deletion Sources/Valet/Accessibility.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import Foundation


@objc(VALAccessibility)
public enum Accessibility: Int, CaseIterable, CustomStringConvertible, Equatable {
public enum Accessibility: Int, CaseIterable, CustomStringConvertible, Equatable, Sendable {
/// Valet data can only be accessed while the device is unlocked. This attribute is recommended for data that only needs to be accessible while the application is in the foreground. Valet data with this attribute will migrate to a new device when using encrypted backups.
case whenUnlocked = 1
/// Valet data cannot be accessed after a restart until the device has been unlocked once; data is accessible until the device is next rebooted. This attribute is recommended for data that needs to be accessible by background applications. Valet data with this attribute will migrate to a new device when using encrypted backups.
Expand Down
2 changes: 1 addition & 1 deletion Sources/Valet/CloudAccessibility.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import Foundation


@objc(VALCloudAccessibility)
public enum CloudAccessibility: Int, CaseIterable, CustomStringConvertible, Equatable {
public enum CloudAccessibility: Int, CaseIterable, CustomStringConvertible, Equatable, Sendable {
/// Valet data can only be accessed while the device is unlocked. This attribute is recommended for data that only needs to be accessible while the application is in the foreground. Valet data with this attribute will migrate to a new device when using encrypted backups.
case whenUnlocked = 1
/// Valet data cannot be accessed after a restart until the device has been unlocked once; data is accessible until the device is next rebooted. This attribute is recommended for data that needs to be accessible by background applications. Valet data with this attribute will migrate to a new device when using encrypted backups.
Expand Down
2 changes: 1 addition & 1 deletion Sources/Valet/Identifier.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import Foundation


public struct Identifier: CustomStringConvertible {
public struct Identifier: CustomStringConvertible, Sendable {

// MARK: Initialization

Expand Down
2 changes: 1 addition & 1 deletion Sources/Valet/Internal/Configuration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import Foundation


internal enum Configuration: CustomStringConvertible {
internal enum Configuration: CustomStringConvertible, Sendable {
case valet(Accessibility)
case iCloud(CloudAccessibility)
case secureEnclave(SecureEnclaveAccessControl)
Expand Down
2 changes: 1 addition & 1 deletion Sources/Valet/Internal/Service.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import Foundation


internal enum Service: CustomStringConvertible, Equatable {
internal enum Service: CustomStringConvertible, Equatable, Sendable {
case standard(Identifier, Configuration)
case sharedGroup(SharedGroupIdentifier, Identifier?, Configuration)

Expand Down
2 changes: 1 addition & 1 deletion Sources/Valet/KeychainError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import Foundation


@objc(VALKeychainError)
public enum KeychainError: Int, CaseIterable, CustomStringConvertible, Error, Equatable {
public enum KeychainError: Int, CaseIterable, CustomStringConvertible, Error, Equatable, Sendable {
/// The keychain could not be accessed.
case couldNotAccessKeychain
/// User dismissed the user-presence prompt.
Expand Down
2 changes: 1 addition & 1 deletion Sources/Valet/MigrationError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import Foundation


@objc(VALMigrationResult)
public enum MigrationError: Int, CaseIterable, CustomStringConvertible, Error, Equatable {
public enum MigrationError: Int, CaseIterable, CustomStringConvertible, Error, Equatable, Sendable {
/// Migration failed because the keychain query was not valid.
case invalidQuery
/// Migration failed because a key staged for migration was invalid.
Expand Down
2 changes: 1 addition & 1 deletion Sources/Valet/SecureEnclave.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import Foundation


public final class SecureEnclave {
public final class SecureEnclave: Sendable {

// MARK: Internal Methods

Expand Down
2 changes: 1 addition & 1 deletion Sources/Valet/SecureEnclaveAccessControl.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import Foundation


@objc(VALSecureEnclaveAccessControl)
public enum SecureEnclaveAccessControl: Int, CustomStringConvertible, Equatable {
public enum SecureEnclaveAccessControl: Int, CustomStringConvertible, Equatable, Sendable {
/// Access to keychain elements requires user presence verification via Touch ID, Face ID, or device Passcode. On macOS 10.15 and later, this element may also be accessed via a prompt on a paired watch. Keychain elements are still accessible by Touch ID even if fingers are added or removed. Touch ID does not have to be available or enrolled.
case userPresence = 1

Expand Down
7 changes: 4 additions & 3 deletions Sources/Valet/SecureEnclaveValet.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import Foundation

/// Reads and writes keychain elements that are stored on the Secure Enclave using Accessibility attribute `.whenPasscodeSetThisDeviceOnly`. Accessing these keychain elements will require the user to confirm their presence via Touch ID, Face ID, or passcode entry. If no passcode is set on the device, accessing the keychain via a `SecureEnclaveValet` will fail. Data is removed from the Secure Enclave when the user removes a passcode from the device.
@objc(VALSecureEnclaveValet)
public final class SecureEnclaveValet: NSObject {
public final class SecureEnclaveValet: NSObject, Sendable {

// MARK: Public Class Methods

Expand Down Expand Up @@ -92,7 +92,6 @@ public final class SecureEnclaveValet: NSObject {
self.identifier = identifier
self.service = service
self.accessControl = accessControl
baseKeychainQuery = service.generateBaseQuery()
}

// MARK: Hashable
Expand Down Expand Up @@ -232,7 +231,9 @@ public final class SecureEnclaveValet: NSObject {
// MARK: Private Properties

private let lock = NSLock()
private let baseKeychainQuery: [String : AnyHashable]
private var baseKeychainQuery: [String : AnyHashable] {
return service.generateBaseQuery()
}

}

Expand Down
2 changes: 1 addition & 1 deletion Sources/Valet/SharedGroupIdentifier.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import Foundation


public struct SharedGroupIdentifier: CustomStringConvertible {
public struct SharedGroupIdentifier: CustomStringConvertible, Sendable {

// MARK: Initialization

Expand Down
4 changes: 2 additions & 2 deletions Sources/Valet/SinglePromptSecureEnclaveValet.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ import Foundation
/// Reads and writes keychain elements that are stored on the Secure Enclave using Accessibility attribute `.whenPasscodeSetThisDeviceOnly`. The first access of these keychain elements will require the user to confirm their presence via Touch ID, Face ID, or passcode entry. If no passcode is set on the device, accessing the keychain via a `SinglePromptSecureEnclaveValet` will fail. Data is removed from the Secure Enclave when the user removes a passcode from the device.
@objc(VALSinglePromptSecureEnclaveValet)
@available(watchOS 3, *)
public final class SinglePromptSecureEnclaveValet: NSObject {
public final class SinglePromptSecureEnclaveValet: NSObject, @unchecked Sendable {

// MARK: Public Class Methods

/// - Parameters:
Expand Down
9 changes: 4 additions & 5 deletions Sources/Valet/Valet.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import Foundation

/// Reads and writes keychain elements.
@objc(VALValet)
public final class Valet: NSObject {
public final class Valet: NSObject, Sendable {

// MARK: Public Class Methods

Expand Down Expand Up @@ -198,7 +198,6 @@ public final class Valet: NSObject {
self.configuration = configuration
self.service = service
accessibility = configuration.accessibility
baseKeychainQuery = service.generateBaseQuery()
}

#if os(macOS)
Expand All @@ -207,15 +206,13 @@ public final class Valet: NSObject {
self.configuration = configuration
service = .standardOverride(service: identifier, configuration)
accessibility = configuration.accessibility
baseKeychainQuery = service.generateBaseQuery()
}

private init(overrideSharedAccess identifier: SharedGroupIdentifier, configuration: Configuration) {
self.identifier = identifier.asIdentifier
self.configuration = configuration
service = .sharedGroupOverride(service: identifier, configuration)
accessibility = configuration.accessibility
baseKeychainQuery = service.generateBaseQuery()
}
#endif

Expand Down Expand Up @@ -483,7 +480,9 @@ public final class Valet: NSObject {

internal let configuration: Configuration
internal let service: Service
internal let baseKeychainQuery: [String : AnyHashable]
internal var baseKeychainQuery: [String : AnyHashable] {
return service.generateBaseQuery()
}

// MARK: Private Properties

Expand Down
4 changes: 2 additions & 2 deletions Valet.podspec
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
Pod::Spec.new do |s|
s.name = 'Valet'
s.version = '4.2.0'
s.version = '4.3.0'
s.license = 'Apache License, Version 2.0'
s.summary = 'Securely store data on iOS, tvOS, watchOS, or macOS without knowing a thing about how the Keychain works. It\'s easy. We promise.'
s.homepage = 'https://github.com/square/Valet'
s.authors = 'Square'
s.source = { :git => 'https://github.com/square/Valet.git', :tag => s.version }
s.swift_version = '5.0'
s.swift_version = '5.4'
s.source_files = 'Sources/Valet/**/*.{swift,h}'
s.public_header_files = 'Sources/Valet/*.h'
s.frameworks = 'Security'
Expand Down

0 comments on commit 3df8eaa

Please sign in to comment.