mirror of
https://github.com/SideStore/SideStore.git
synced 2026-02-20 12:13:26 +01:00
Updates KeychainAccess pod
This commit is contained in:
2
Podfile
2
Podfile
@@ -28,7 +28,7 @@ target 'AltStoreCore' do
|
|||||||
use_frameworks!
|
use_frameworks!
|
||||||
|
|
||||||
# Pods for AltServer
|
# Pods for AltServer
|
||||||
pod 'KeychainAccess', '~> 3.2.0'
|
pod 'KeychainAccess', '~> 4.2.0'
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -7,14 +7,14 @@ PODS:
|
|||||||
- AppCenter/Core (3.1.0)
|
- AppCenter/Core (3.1.0)
|
||||||
- AppCenter/Crashes (3.1.0):
|
- AppCenter/Crashes (3.1.0):
|
||||||
- AppCenter/Core
|
- AppCenter/Core
|
||||||
- KeychainAccess (3.2.0)
|
- KeychainAccess (4.2.1)
|
||||||
- Nuke (7.6.3)
|
- Nuke (7.6.3)
|
||||||
- Sparkle (1.21.3)
|
- Sparkle (1.21.3)
|
||||||
- STPrivilegedTask (1.0.7)
|
- STPrivilegedTask (1.0.7)
|
||||||
|
|
||||||
DEPENDENCIES:
|
DEPENDENCIES:
|
||||||
- AppCenter (~> 3.1.0)
|
- AppCenter (~> 3.1.0)
|
||||||
- KeychainAccess (~> 3.2.0)
|
- KeychainAccess (~> 4.2.0)
|
||||||
- Nuke (~> 7.0)
|
- Nuke (~> 7.0)
|
||||||
- Sparkle
|
- Sparkle
|
||||||
- STPrivilegedTask (from `https://github.com/rileytestut/STPrivilegedTask.git`)
|
- STPrivilegedTask (from `https://github.com/rileytestut/STPrivilegedTask.git`)
|
||||||
@@ -37,11 +37,11 @@ CHECKOUT OPTIONS:
|
|||||||
|
|
||||||
SPEC CHECKSUMS:
|
SPEC CHECKSUMS:
|
||||||
AppCenter: a1c30c47b7882a04a615ffa5ab26c007326436d8
|
AppCenter: a1c30c47b7882a04a615ffa5ab26c007326436d8
|
||||||
KeychainAccess: 3b1bf8a77eb4c6ea1ce9404c292e48f948954c6b
|
KeychainAccess: 9b07f665298d13c3a85881bd3171f6f49b8151c1
|
||||||
Nuke: 44130e95e09463f8773ae4b96b90de1eba6b3350
|
Nuke: 44130e95e09463f8773ae4b96b90de1eba6b3350
|
||||||
Sparkle: 3f75576db8b0265adef36c43249d747f22d0b708
|
Sparkle: 3f75576db8b0265adef36c43249d747f22d0b708
|
||||||
STPrivilegedTask: 56c3397238a1ec07720fb877a044898373cd2c68
|
STPrivilegedTask: 56c3397238a1ec07720fb877a044898373cd2c68
|
||||||
|
|
||||||
PODFILE CHECKSUM: b687e2aeec1ffc369787e92f2a2fefa460687731
|
PODFILE CHECKSUM: 6e3f9d2fc666262d43ff8079a3f9149b8f3376ee
|
||||||
|
|
||||||
COCOAPODS: 1.8.4
|
COCOAPODS: 1.8.4
|
||||||
|
|||||||
311
Pods/KeychainAccess/Lib/KeychainAccess/Keychain.swift
generated
311
Pods/KeychainAccess/Lib/KeychainAccess/Keychain.swift
generated
@@ -106,6 +106,7 @@ public enum Accessibility {
|
|||||||
for anything except system use. Items with this attribute will migrate
|
for anything except system use. Items with this attribute will migrate
|
||||||
to a new device when using encrypted backups.
|
to a new device when using encrypted backups.
|
||||||
*/
|
*/
|
||||||
|
@available(macCatalyst, unavailable)
|
||||||
case always
|
case always
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -148,79 +149,145 @@ public enum Accessibility {
|
|||||||
attribute will never migrate to a new device, so after a backup is
|
attribute will never migrate to a new device, so after a backup is
|
||||||
restored to a new device, these items will be missing.
|
restored to a new device, these items will be missing.
|
||||||
*/
|
*/
|
||||||
|
@available(macCatalyst, unavailable)
|
||||||
case alwaysThisDeviceOnly
|
case alwaysThisDeviceOnly
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Predefined item attribute constants used to get or set values
|
||||||
|
in a dictionary. The kSecUseAuthenticationUI constant is the key and its
|
||||||
|
value is one of the constants defined here.
|
||||||
|
If the key kSecUseAuthenticationUI not provided then kSecUseAuthenticationUIAllow
|
||||||
|
is used as default.
|
||||||
|
*/
|
||||||
|
public enum AuthenticationUI {
|
||||||
|
/**
|
||||||
|
Specifies that authenticate UI can appear.
|
||||||
|
*/
|
||||||
|
case allow
|
||||||
|
|
||||||
|
/**
|
||||||
|
Specifies that the error
|
||||||
|
errSecInteractionNotAllowed will be returned if an item needs
|
||||||
|
to authenticate with UI
|
||||||
|
*/
|
||||||
|
case fail
|
||||||
|
|
||||||
|
/**
|
||||||
|
Specifies that all items which need
|
||||||
|
to authenticate with UI will be silently skipped. This value can be used
|
||||||
|
only with SecItemCopyMatching.
|
||||||
|
*/
|
||||||
|
case skip
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(iOS 9.0, OSX 10.11, *)
|
||||||
|
extension AuthenticationUI {
|
||||||
|
public var rawValue: String {
|
||||||
|
switch self {
|
||||||
|
case .allow:
|
||||||
|
return UseAuthenticationUIAllow
|
||||||
|
case .fail:
|
||||||
|
return UseAuthenticationUIFail
|
||||||
|
case .skip:
|
||||||
|
return UseAuthenticationUISkip
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public var description: String {
|
||||||
|
switch self {
|
||||||
|
case .allow:
|
||||||
|
return "allow"
|
||||||
|
case .fail:
|
||||||
|
return "fail"
|
||||||
|
case .skip:
|
||||||
|
return "skip"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public struct AuthenticationPolicy: OptionSet {
|
public struct AuthenticationPolicy: OptionSet {
|
||||||
/**
|
/**
|
||||||
User presence policy using Touch ID or Passcode. Touch ID does not
|
User presence policy using Touch ID or Passcode. Touch ID does not
|
||||||
have to be available or enrolled. Item is still accessible by Touch ID
|
have to be available or enrolled. Item is still accessible by Touch ID
|
||||||
even if fingers are added or removed.
|
even if fingers are added or removed.
|
||||||
*/
|
*/
|
||||||
@available(iOS 8.0, OSX 10.10, *)
|
@available(iOS 8.0, OSX 10.10, watchOS 2.0, tvOS 8.0, *)
|
||||||
@available(watchOS, unavailable)
|
|
||||||
public static let userPresence = AuthenticationPolicy(rawValue: 1 << 0)
|
public static let userPresence = AuthenticationPolicy(rawValue: 1 << 0)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Constraint: Touch ID (any finger). Touch ID must be available and
|
Constraint: Touch ID (any finger) or Face ID. Touch ID or Face ID must be available. With Touch ID
|
||||||
at least one finger must be enrolled. Item is still accessible by
|
at least one finger must be enrolled. With Face ID user has to be enrolled. Item is still accessible by Touch ID even
|
||||||
Touch ID even if fingers are added or removed.
|
if fingers are added or removed. Item is still accessible by Face ID if user is re-enrolled.
|
||||||
*/
|
*/
|
||||||
@available(iOS 9.0, *)
|
@available(iOS 11.3, OSX 10.13.4, watchOS 4.3, tvOS 11.3, *)
|
||||||
@available(OSX, unavailable)
|
public static let biometryAny = AuthenticationPolicy(rawValue: 1 << 1)
|
||||||
@available(watchOS, unavailable)
|
|
||||||
|
/**
|
||||||
|
Deprecated, please use biometryAny instead.
|
||||||
|
*/
|
||||||
|
@available(iOS, introduced: 9.0, deprecated: 11.3, renamed: "biometryAny")
|
||||||
|
@available(OSX, introduced: 10.12.1, deprecated: 10.13.4, renamed: "biometryAny")
|
||||||
|
@available(watchOS, introduced: 2.0, deprecated: 4.3, renamed: "biometryAny")
|
||||||
|
@available(tvOS, introduced: 9.0, deprecated: 11.3, renamed: "biometryAny")
|
||||||
public static let touchIDAny = AuthenticationPolicy(rawValue: 1 << 1)
|
public static let touchIDAny = AuthenticationPolicy(rawValue: 1 << 1)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Constraint: Touch ID from the set of currently enrolled fingers.
|
Constraint: Touch ID from the set of currently enrolled fingers. Touch ID must be available and at least one finger must
|
||||||
Touch ID must be available and at least one finger must be enrolled.
|
be enrolled. When fingers are added or removed, the item is invalidated. When Face ID is re-enrolled this item is invalidated.
|
||||||
When fingers are added or removed, the item is invalidated.
|
|
||||||
*/
|
*/
|
||||||
@available(iOS 9.0, *)
|
@available(iOS 11.3, OSX 10.13, watchOS 4.3, tvOS 11.3, *)
|
||||||
@available(OSX, unavailable)
|
public static let biometryCurrentSet = AuthenticationPolicy(rawValue: 1 << 3)
|
||||||
@available(watchOS, unavailable)
|
|
||||||
|
/**
|
||||||
|
Deprecated, please use biometryCurrentSet instead.
|
||||||
|
*/
|
||||||
|
@available(iOS, introduced: 9.0, deprecated: 11.3, renamed: "biometryCurrentSet")
|
||||||
|
@available(OSX, introduced: 10.12.1, deprecated: 10.13.4, renamed: "biometryCurrentSet")
|
||||||
|
@available(watchOS, introduced: 2.0, deprecated: 4.3, renamed: "biometryCurrentSet")
|
||||||
|
@available(tvOS, introduced: 9.0, deprecated: 11.3, renamed: "biometryCurrentSet")
|
||||||
public static let touchIDCurrentSet = AuthenticationPolicy(rawValue: 1 << 3)
|
public static let touchIDCurrentSet = AuthenticationPolicy(rawValue: 1 << 3)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Constraint: Device passcode
|
Constraint: Device passcode
|
||||||
*/
|
*/
|
||||||
@available(iOS 9.0, OSX 10.11, *)
|
@available(iOS 9.0, OSX 10.11, watchOS 2.0, tvOS 9.0, *)
|
||||||
@available(watchOS, unavailable)
|
|
||||||
public static let devicePasscode = AuthenticationPolicy(rawValue: 1 << 4)
|
public static let devicePasscode = AuthenticationPolicy(rawValue: 1 << 4)
|
||||||
|
|
||||||
|
/**
|
||||||
|
Constraint: Watch
|
||||||
|
*/
|
||||||
|
@available(iOS, unavailable)
|
||||||
|
@available(OSX 10.15, *)
|
||||||
|
@available(watchOS, unavailable)
|
||||||
|
@available(tvOS, unavailable)
|
||||||
|
public static let watch = AuthenticationPolicy(rawValue: 1 << 5)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Constraint logic operation: when using more than one constraint,
|
Constraint logic operation: when using more than one constraint,
|
||||||
at least one of them must be satisfied.
|
at least one of them must be satisfied.
|
||||||
*/
|
*/
|
||||||
@available(iOS 9.0, *)
|
@available(iOS 9.0, OSX 10.12.1, watchOS 2.0, tvOS 9.0, *)
|
||||||
@available(OSX, unavailable)
|
|
||||||
@available(watchOS, unavailable)
|
|
||||||
public static let or = AuthenticationPolicy(rawValue: 1 << 14)
|
public static let or = AuthenticationPolicy(rawValue: 1 << 14)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Constraint logic operation: when using more than one constraint,
|
Constraint logic operation: when using more than one constraint,
|
||||||
all must be satisfied.
|
all must be satisfied.
|
||||||
*/
|
*/
|
||||||
@available(iOS 9.0, *)
|
@available(iOS 9.0, OSX 10.12.1, watchOS 2.0, tvOS 9.0, *)
|
||||||
@available(OSX, unavailable)
|
|
||||||
@available(watchOS, unavailable)
|
|
||||||
public static let and = AuthenticationPolicy(rawValue: 1 << 15)
|
public static let and = AuthenticationPolicy(rawValue: 1 << 15)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Create access control for private key operations (i.e. sign operation)
|
Create access control for private key operations (i.e. sign operation)
|
||||||
*/
|
*/
|
||||||
@available(iOS 9.0, *)
|
@available(iOS 9.0, OSX 10.12.1, watchOS 2.0, tvOS 9.0, *)
|
||||||
@available(OSX, unavailable)
|
|
||||||
@available(watchOS, unavailable)
|
|
||||||
public static let privateKeyUsage = AuthenticationPolicy(rawValue: 1 << 30)
|
public static let privateKeyUsage = AuthenticationPolicy(rawValue: 1 << 30)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Security: Application provided password for data encryption key generation.
|
Security: Application provided password for data encryption key generation.
|
||||||
This is not a constraint but additional item encryption mechanism.
|
This is not a constraint but additional item encryption mechanism.
|
||||||
*/
|
*/
|
||||||
@available(iOS 9.0, *)
|
@available(iOS 9.0, OSX 10.12.1, watchOS 2.0, tvOS 9.0, *)
|
||||||
@available(OSX, unavailable)
|
|
||||||
@available(watchOS, unavailable)
|
|
||||||
public static let applicationPassword = AuthenticationPolicy(rawValue: 1 << 31)
|
public static let applicationPassword = AuthenticationPolicy(rawValue: 1 << 31)
|
||||||
|
|
||||||
#if swift(>=2.3)
|
#if swift(>=2.3)
|
||||||
@@ -348,6 +415,8 @@ public final class Keychain {
|
|||||||
return options.service
|
return options.service
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This attribute (kSecAttrAccessGroup) applies to macOS keychain items only if you also set a value of true for the
|
||||||
|
// kSecUseDataProtectionKeychain key, the kSecAttrSynchronizable key, or both.
|
||||||
public var accessGroup: String? {
|
public var accessGroup: String? {
|
||||||
return options.accessGroup
|
return options.accessGroup
|
||||||
}
|
}
|
||||||
@@ -392,6 +461,11 @@ public final class Keychain {
|
|||||||
return options.authenticationPrompt
|
return options.authenticationPrompt
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@available(iOS 9.0, OSX 10.11, *)
|
||||||
|
public var authenticationUI: AuthenticationUI {
|
||||||
|
return options.authenticationUI ?? .allow
|
||||||
|
}
|
||||||
|
|
||||||
#if os(iOS) || os(OSX)
|
#if os(iOS) || os(OSX)
|
||||||
@available(iOS 9.0, OSX 10.11, *)
|
@available(iOS 9.0, OSX 10.11, *)
|
||||||
public var authenticationContext: LAContext? {
|
public var authenticationContext: LAContext? {
|
||||||
@@ -433,15 +507,16 @@ public final class Keychain {
|
|||||||
self.init(options)
|
self.init(options)
|
||||||
}
|
}
|
||||||
|
|
||||||
public convenience init(server: String, protocolType: ProtocolType, authenticationType: AuthenticationType = .default) {
|
public convenience init(server: String, protocolType: ProtocolType, accessGroup: String? = nil, authenticationType: AuthenticationType = .default) {
|
||||||
self.init(server: URL(string: server)!, protocolType: protocolType, authenticationType: authenticationType)
|
self.init(server: URL(string: server)!, protocolType: protocolType, accessGroup: accessGroup, authenticationType: authenticationType)
|
||||||
}
|
}
|
||||||
|
|
||||||
public convenience init(server: URL, protocolType: ProtocolType, authenticationType: AuthenticationType = .default) {
|
public convenience init(server: URL, protocolType: ProtocolType, accessGroup: String? = nil, authenticationType: AuthenticationType = .default) {
|
||||||
var options = Options()
|
var options = Options()
|
||||||
options.itemClass = .internetPassword
|
options.itemClass = .internetPassword
|
||||||
options.server = server
|
options.server = server
|
||||||
options.protocolType = protocolType
|
options.protocolType = protocolType
|
||||||
|
options.accessGroup = accessGroup
|
||||||
options.authenticationType = authenticationType
|
options.authenticationType = authenticationType
|
||||||
self.init(options)
|
self.init(options)
|
||||||
}
|
}
|
||||||
@@ -499,6 +574,13 @@ public final class Keychain {
|
|||||||
return Keychain(options)
|
return Keychain(options)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@available(iOS 9.0, OSX 10.11, *)
|
||||||
|
public func authenticationUI(_ authenticationUI: AuthenticationUI) -> Keychain {
|
||||||
|
var options = self.options
|
||||||
|
options.authenticationUI = authenticationUI
|
||||||
|
return Keychain(options)
|
||||||
|
}
|
||||||
|
|
||||||
#if os(iOS) || os(OSX)
|
#if os(iOS) || os(OSX)
|
||||||
@available(iOS 9.0, OSX 10.11, *)
|
@available(iOS 9.0, OSX 10.11, *)
|
||||||
public func authenticationContext(_ authenticationContext: LAContext) -> Keychain {
|
public func authenticationContext(_ authenticationContext: LAContext) -> Keychain {
|
||||||
@@ -510,12 +592,12 @@ public final class Keychain {
|
|||||||
|
|
||||||
// MARK:
|
// MARK:
|
||||||
|
|
||||||
public func get(_ key: String) throws -> String? {
|
public func get(_ key: String, ignoringAttributeSynchronizable: Bool = true) throws -> String? {
|
||||||
return try getString(key)
|
return try getString(key, ignoringAttributeSynchronizable: ignoringAttributeSynchronizable)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func getString(_ key: String) throws -> String? {
|
public func getString(_ key: String, ignoringAttributeSynchronizable: Bool = true) throws -> String? {
|
||||||
guard let data = try getData(key) else {
|
guard let data = try getData(key, ignoringAttributeSynchronizable: ignoringAttributeSynchronizable) else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
guard let string = String(data: data, encoding: .utf8) else {
|
guard let string = String(data: data, encoding: .utf8) else {
|
||||||
@@ -525,8 +607,8 @@ public final class Keychain {
|
|||||||
return string
|
return string
|
||||||
}
|
}
|
||||||
|
|
||||||
public func getData(_ key: String) throws -> Data? {
|
public func getData(_ key: String, ignoringAttributeSynchronizable: Bool = true) throws -> Data? {
|
||||||
var query = options.query()
|
var query = options.query(ignoringAttributeSynchronizable: ignoringAttributeSynchronizable)
|
||||||
|
|
||||||
query[MatchLimit] = MatchLimitOne
|
query[MatchLimit] = MatchLimitOne
|
||||||
query[ReturnData] = kCFBooleanTrue
|
query[ReturnData] = kCFBooleanTrue
|
||||||
@@ -549,8 +631,8 @@ public final class Keychain {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func get<T>(_ key: String, handler: (Attributes?) -> T) throws -> T {
|
public func get<T>(_ key: String, ignoringAttributeSynchronizable: Bool = true, handler: (Attributes?) -> T) throws -> T {
|
||||||
var query = options.query()
|
var query = options.query(ignoringAttributeSynchronizable: ignoringAttributeSynchronizable)
|
||||||
|
|
||||||
query[MatchLimit] = MatchLimitOne
|
query[MatchLimit] = MatchLimitOne
|
||||||
|
|
||||||
@@ -579,28 +661,40 @@ public final class Keychain {
|
|||||||
|
|
||||||
// MARK:
|
// MARK:
|
||||||
|
|
||||||
public func set(_ value: String, key: String) throws {
|
public func set(_ value: String, key: String, ignoringAttributeSynchronizable: Bool = true) throws {
|
||||||
guard let data = value.data(using: .utf8, allowLossyConversion: false) else {
|
guard let data = value.data(using: .utf8, allowLossyConversion: false) else {
|
||||||
print("failed to convert string to data")
|
print("failed to convert string to data")
|
||||||
throw Status.conversionError
|
throw Status.conversionError
|
||||||
}
|
}
|
||||||
try set(data, key: key)
|
try set(data, key: key, ignoringAttributeSynchronizable: ignoringAttributeSynchronizable)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func set(_ value: Data, key: String) throws {
|
public func set(_ value: Data, key: String, ignoringAttributeSynchronizable: Bool = true) throws {
|
||||||
var query = options.query()
|
var query = options.query(ignoringAttributeSynchronizable: ignoringAttributeSynchronizable)
|
||||||
query[AttributeAccount] = key
|
query[AttributeAccount] = key
|
||||||
#if os(iOS)
|
#if os(iOS)
|
||||||
if #available(iOS 9.0, *) {
|
if #available(iOS 9.0, *) {
|
||||||
|
if let authenticationUI = options.authenticationUI {
|
||||||
|
query[UseAuthenticationUI] = authenticationUI.rawValue
|
||||||
|
} else {
|
||||||
query[UseAuthenticationUI] = UseAuthenticationUIFail
|
query[UseAuthenticationUI] = UseAuthenticationUIFail
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
query[UseNoAuthenticationUI] = kCFBooleanTrue
|
query[UseNoAuthenticationUI] = kCFBooleanTrue
|
||||||
}
|
}
|
||||||
#elseif os(OSX)
|
#elseif os(OSX)
|
||||||
query[ReturnData] = kCFBooleanTrue
|
query[ReturnData] = kCFBooleanTrue
|
||||||
if #available(OSX 10.11, *) {
|
if #available(OSX 10.11, *) {
|
||||||
|
if let authenticationUI = options.authenticationUI {
|
||||||
|
query[UseAuthenticationUI] = authenticationUI.rawValue
|
||||||
|
} else {
|
||||||
query[UseAuthenticationUI] = UseAuthenticationUIFail
|
query[UseAuthenticationUI] = UseAuthenticationUIFail
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if let authenticationUI = options.authenticationUI {
|
||||||
|
query[UseAuthenticationUI] = authenticationUI.rawValue
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
var status = SecItemCopyMatching(query as CFDictionary, nil)
|
var status = SecItemCopyMatching(query as CFDictionary, nil)
|
||||||
@@ -717,8 +811,8 @@ public final class Keychain {
|
|||||||
|
|
||||||
// MARK:
|
// MARK:
|
||||||
|
|
||||||
public func remove(_ key: String) throws {
|
public func remove(_ key: String, ignoringAttributeSynchronizable: Bool = true) throws {
|
||||||
var query = options.query()
|
var query = options.query(ignoringAttributeSynchronizable: ignoringAttributeSynchronizable)
|
||||||
query[AttributeAccount] = key
|
query[AttributeAccount] = key
|
||||||
|
|
||||||
let status = SecItemDelete(query as CFDictionary)
|
let status = SecItemDelete(query as CFDictionary)
|
||||||
@@ -741,14 +835,49 @@ public final class Keychain {
|
|||||||
|
|
||||||
// MARK:
|
// MARK:
|
||||||
|
|
||||||
public func contains(_ key: String) throws -> Bool {
|
public func contains(_ key: String, withoutAuthenticationUI: Bool = false) throws -> Bool {
|
||||||
var query = options.query()
|
var query = options.query()
|
||||||
query[AttributeAccount] = key
|
query[AttributeAccount] = key
|
||||||
|
|
||||||
|
if withoutAuthenticationUI {
|
||||||
|
#if os(iOS) || os(watchOS) || os(tvOS)
|
||||||
|
if #available(iOS 9.0, *) {
|
||||||
|
if let authenticationUI = options.authenticationUI {
|
||||||
|
query[UseAuthenticationUI] = authenticationUI.rawValue
|
||||||
|
} else {
|
||||||
|
query[UseAuthenticationUI] = UseAuthenticationUIFail
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
query[UseNoAuthenticationUI] = kCFBooleanTrue
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if #available(OSX 10.11, *) {
|
||||||
|
if let authenticationUI = options.authenticationUI {
|
||||||
|
query[UseAuthenticationUI] = authenticationUI.rawValue
|
||||||
|
} else {
|
||||||
|
query[UseAuthenticationUI] = UseAuthenticationUIFail
|
||||||
|
}
|
||||||
|
} else if #available(OSX 10.10, *) {
|
||||||
|
query[UseNoAuthenticationUI] = kCFBooleanTrue
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
if #available(iOS 9.0, OSX 10.11, *) {
|
||||||
|
if let authenticationUI = options.authenticationUI {
|
||||||
|
query[UseAuthenticationUI] = authenticationUI.rawValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let status = SecItemCopyMatching(query as CFDictionary, nil)
|
let status = SecItemCopyMatching(query as CFDictionary, nil)
|
||||||
switch status {
|
switch status {
|
||||||
case errSecSuccess:
|
case errSecSuccess:
|
||||||
return true
|
return true
|
||||||
|
case errSecInteractionNotAllowed:
|
||||||
|
if withoutAuthenticationUI {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
case errSecItemNotFound:
|
case errSecItemNotFound:
|
||||||
return false
|
return false
|
||||||
default:
|
default:
|
||||||
@@ -830,7 +959,7 @@ public final class Keychain {
|
|||||||
return type(of: self).prettify(itemClass: itemClass, items: items())
|
return type(of: self).prettify(itemClass: itemClass, items: items())
|
||||||
}
|
}
|
||||||
|
|
||||||
#if os(iOS)
|
#if os(iOS) && !targetEnvironment(macCatalyst)
|
||||||
@available(iOS 8.0, *)
|
@available(iOS 8.0, *)
|
||||||
public func getSharedPassword(_ completion: @escaping (_ account: String?, _ password: String?, _ error: Error?) -> () = { account, password, error -> () in }) {
|
public func getSharedPassword(_ completion: @escaping (_ account: String?, _ password: String?, _ error: Error?) -> () = { account, password, error -> () in }) {
|
||||||
if let domain = server.host {
|
if let domain = server.host {
|
||||||
@@ -850,7 +979,7 @@ public final class Keychain {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if os(iOS)
|
#if os(iOS) && !targetEnvironment(macCatalyst)
|
||||||
@available(iOS 8.0, *)
|
@available(iOS 8.0, *)
|
||||||
public func getSharedPassword(_ account: String, completion: @escaping (_ password: String?, _ error: Error?) -> () = { password, error -> () in }) {
|
public func getSharedPassword(_ account: String, completion: @escaping (_ password: String?, _ error: Error?) -> () = { password, error -> () in }) {
|
||||||
if let domain = server.host {
|
if let domain = server.host {
|
||||||
@@ -872,14 +1001,14 @@ public final class Keychain {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if os(iOS)
|
#if os(iOS) && !targetEnvironment(macCatalyst)
|
||||||
@available(iOS 8.0, *)
|
@available(iOS 8.0, *)
|
||||||
public func setSharedPassword(_ password: String, account: String, completion: @escaping (_ error: Error?) -> () = { e -> () in }) {
|
public func setSharedPassword(_ password: String, account: String, completion: @escaping (_ error: Error?) -> () = { e -> () in }) {
|
||||||
setSharedPassword(password as String?, account: account, completion: completion)
|
setSharedPassword(password as String?, account: account, completion: completion)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if os(iOS)
|
#if os(iOS) && !targetEnvironment(macCatalyst)
|
||||||
@available(iOS 8.0, *)
|
@available(iOS 8.0, *)
|
||||||
fileprivate func setSharedPassword(_ password: String?, account: String, completion: @escaping (_ error: Error?) -> () = { e -> () in }) {
|
fileprivate func setSharedPassword(_ password: String?, account: String, completion: @escaping (_ error: Error?) -> () = { e -> () in }) {
|
||||||
if let domain = server.host {
|
if let domain = server.host {
|
||||||
@@ -897,35 +1026,35 @@ public final class Keychain {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if os(iOS)
|
#if os(iOS) && !targetEnvironment(macCatalyst)
|
||||||
@available(iOS 8.0, *)
|
@available(iOS 8.0, *)
|
||||||
public func removeSharedPassword(_ account: String, completion: @escaping (_ error: Error?) -> () = { e -> () in }) {
|
public func removeSharedPassword(_ account: String, completion: @escaping (_ error: Error?) -> () = { e -> () in }) {
|
||||||
setSharedPassword(nil, account: account, completion: completion)
|
setSharedPassword(nil, account: account, completion: completion)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if os(iOS)
|
#if os(iOS) && !targetEnvironment(macCatalyst)
|
||||||
@available(iOS 8.0, *)
|
@available(iOS 8.0, *)
|
||||||
public class func requestSharedWebCredential(_ completion: @escaping (_ credentials: [[String: String]], _ error: Error?) -> () = { credentials, error -> () in }) {
|
public class func requestSharedWebCredential(_ completion: @escaping (_ credentials: [[String: String]], _ error: Error?) -> () = { credentials, error -> () in }) {
|
||||||
requestSharedWebCredential(domain: nil, account: nil, completion: completion)
|
requestSharedWebCredential(domain: nil, account: nil, completion: completion)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if os(iOS)
|
#if os(iOS) && !targetEnvironment(macCatalyst)
|
||||||
@available(iOS 8.0, *)
|
@available(iOS 8.0, *)
|
||||||
public class func requestSharedWebCredential(domain: String, completion: @escaping (_ credentials: [[String: String]], _ error: Error?) -> () = { credentials, error -> () in }) {
|
public class func requestSharedWebCredential(domain: String, completion: @escaping (_ credentials: [[String: String]], _ error: Error?) -> () = { credentials, error -> () in }) {
|
||||||
requestSharedWebCredential(domain: domain, account: nil, completion: completion)
|
requestSharedWebCredential(domain: domain, account: nil, completion: completion)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if os(iOS)
|
#if os(iOS) && !targetEnvironment(macCatalyst)
|
||||||
@available(iOS 8.0, *)
|
@available(iOS 8.0, *)
|
||||||
public class func requestSharedWebCredential(domain: String, account: String, completion: @escaping (_ credentials: [[String: String]], _ error: Error?) -> () = { credentials, error -> () in }) {
|
public class func requestSharedWebCredential(domain: String, account: String, completion: @escaping (_ credentials: [[String: String]], _ error: Error?) -> () = { credentials, error -> () in }) {
|
||||||
requestSharedWebCredential(domain: Optional(domain), account: Optional(account)!, completion: completion)
|
requestSharedWebCredential(domain: Optional(domain), account: Optional(account)!, completion: completion)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if os(iOS)
|
#if os(iOS) && !targetEnvironment(macCatalyst)
|
||||||
@available(iOS 8.0, *)
|
@available(iOS 8.0, *)
|
||||||
fileprivate class func requestSharedWebCredential(domain: String?, account: String?, completion: @escaping (_ credentials: [[String: String]], _ error: Error?) -> ()) {
|
fileprivate class func requestSharedWebCredential(domain: String?, account: String?, completion: @escaping (_ credentials: [[String: String]], _ error: Error?) -> ()) {
|
||||||
SecRequestSharedWebCredential(domain as CFString?, account as CFString?) { (credentials, error) -> () in
|
SecRequestSharedWebCredential(domain as CFString?, account as CFString?) { (credentials, error) -> () in
|
||||||
@@ -960,7 +1089,7 @@ public final class Keychain {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if os(iOS)
|
#if os(iOS) && !targetEnvironment(macCatalyst)
|
||||||
/**
|
/**
|
||||||
@abstract Returns a randomly generated password.
|
@abstract Returns a randomly generated password.
|
||||||
@return String password in the form xxx-xxx-xxx-xxx where x is taken from the sets "abcdefghkmnopqrstuvwxy", "ABCDEFGHJKLMNPQRSTUVWXYZ", "3456789" with at least one character from each set being present.
|
@return String password in the form xxx-xxx-xxx-xxx where x is taken from the sets "abcdefghkmnopqrstuvwxy", "ABCDEFGHJKLMNPQRSTUVWXYZ", "3456789" with at least one character from each set being present.
|
||||||
@@ -1004,14 +1133,15 @@ public final class Keychain {
|
|||||||
|
|
||||||
item["class"] = itemClass.description
|
item["class"] = itemClass.description
|
||||||
|
|
||||||
|
if let accessGroup = attributes[AttributeAccessGroup] as? String {
|
||||||
|
item["accessGroup"] = accessGroup
|
||||||
|
}
|
||||||
|
|
||||||
switch itemClass {
|
switch itemClass {
|
||||||
case .genericPassword:
|
case .genericPassword:
|
||||||
if let service = attributes[AttributeService] as? String {
|
if let service = attributes[AttributeService] as? String {
|
||||||
item["service"] = service
|
item["service"] = service
|
||||||
}
|
}
|
||||||
if let accessGroup = attributes[AttributeAccessGroup] as? String {
|
|
||||||
item["accessGroup"] = accessGroup
|
|
||||||
}
|
|
||||||
case .internetPassword:
|
case .internetPassword:
|
||||||
if let server = attributes[AttributeServer] as? String {
|
if let server = attributes[AttributeServer] as? String {
|
||||||
item["server"] = server
|
item["server"] = server
|
||||||
@@ -1058,7 +1188,9 @@ public final class Keychain {
|
|||||||
@discardableResult
|
@discardableResult
|
||||||
fileprivate class func securityError(status: OSStatus) -> Error {
|
fileprivate class func securityError(status: OSStatus) -> Error {
|
||||||
let error = Status(status: status)
|
let error = Status(status: status)
|
||||||
|
if error != .userCanceled {
|
||||||
print("OSStatus error:[\(error.errorCode)] \(error.description)")
|
print("OSStatus error:[\(error.errorCode)] \(error.description)")
|
||||||
|
}
|
||||||
|
|
||||||
return error
|
return error
|
||||||
}
|
}
|
||||||
@@ -1088,6 +1220,7 @@ struct Options {
|
|||||||
var comment: String?
|
var comment: String?
|
||||||
|
|
||||||
var authenticationPrompt: String?
|
var authenticationPrompt: String?
|
||||||
|
var authenticationUI: AuthenticationUI?
|
||||||
var authenticationContext: AnyObject?
|
var authenticationContext: AnyObject?
|
||||||
|
|
||||||
var attributes = [String: Any]()
|
var attributes = [String: Any]()
|
||||||
@@ -1142,35 +1275,31 @@ private let ValueRef = String(kSecValueRef)
|
|||||||
private let ValuePersistentRef = String(kSecValuePersistentRef)
|
private let ValuePersistentRef = String(kSecValuePersistentRef)
|
||||||
|
|
||||||
/** Other Constants */
|
/** Other Constants */
|
||||||
@available(iOS 8.0, OSX 10.10, *)
|
@available(iOS 8.0, OSX 10.10, tvOS 8.0, *)
|
||||||
private let UseOperationPrompt = String(kSecUseOperationPrompt)
|
private let UseOperationPrompt = String(kSecUseOperationPrompt)
|
||||||
|
|
||||||
#if os(iOS)
|
|
||||||
@available(iOS, introduced: 8.0, deprecated: 9.0, message: "Use a UseAuthenticationUI instead.")
|
@available(iOS, introduced: 8.0, deprecated: 9.0, message: "Use a UseAuthenticationUI instead.")
|
||||||
|
@available(OSX, introduced: 10.10, deprecated: 10.11, message: "Use UseAuthenticationUI instead.")
|
||||||
|
@available(watchOS, introduced: 2.0, deprecated: 2.0, message: "Use UseAuthenticationUI instead.")
|
||||||
|
@available(tvOS, introduced: 8.0, deprecated: 9.0, message: "Use UseAuthenticationUI instead.")
|
||||||
private let UseNoAuthenticationUI = String(kSecUseNoAuthenticationUI)
|
private let UseNoAuthenticationUI = String(kSecUseNoAuthenticationUI)
|
||||||
#endif
|
|
||||||
|
|
||||||
@available(iOS 9.0, OSX 10.11, *)
|
@available(iOS 9.0, OSX 10.11, watchOS 2.0, tvOS 9.0, *)
|
||||||
@available(watchOS, unavailable)
|
|
||||||
private let UseAuthenticationUI = String(kSecUseAuthenticationUI)
|
private let UseAuthenticationUI = String(kSecUseAuthenticationUI)
|
||||||
|
|
||||||
@available(iOS 9.0, OSX 10.11, *)
|
@available(iOS 9.0, OSX 10.11, watchOS 2.0, tvOS 9.0, *)
|
||||||
@available(watchOS, unavailable)
|
|
||||||
private let UseAuthenticationContext = String(kSecUseAuthenticationContext)
|
private let UseAuthenticationContext = String(kSecUseAuthenticationContext)
|
||||||
|
|
||||||
@available(iOS 9.0, OSX 10.11, *)
|
@available(iOS 9.0, OSX 10.11, watchOS 2.0, tvOS 9.0, *)
|
||||||
@available(watchOS, unavailable)
|
|
||||||
private let UseAuthenticationUIAllow = String(kSecUseAuthenticationUIAllow)
|
private let UseAuthenticationUIAllow = String(kSecUseAuthenticationUIAllow)
|
||||||
|
|
||||||
@available(iOS 9.0, OSX 10.11, *)
|
@available(iOS 9.0, OSX 10.11, watchOS 2.0, tvOS 9.0, *)
|
||||||
@available(watchOS, unavailable)
|
|
||||||
private let UseAuthenticationUIFail = String(kSecUseAuthenticationUIFail)
|
private let UseAuthenticationUIFail = String(kSecUseAuthenticationUIFail)
|
||||||
|
|
||||||
@available(iOS 9.0, OSX 10.11, *)
|
@available(iOS 9.0, OSX 10.11, watchOS 2.0, tvOS 9.0, *)
|
||||||
@available(watchOS, unavailable)
|
|
||||||
private let UseAuthenticationUISkip = String(kSecUseAuthenticationUISkip)
|
private let UseAuthenticationUISkip = String(kSecUseAuthenticationUISkip)
|
||||||
|
|
||||||
#if os(iOS)
|
#if os(iOS) && !targetEnvironment(macCatalyst)
|
||||||
/** Credential Key Constants */
|
/** Credential Key Constants */
|
||||||
private let SharedPassword = String(kSecSharedPassword)
|
private let SharedPassword = String(kSecSharedPassword)
|
||||||
#endif
|
#endif
|
||||||
@@ -1196,22 +1325,22 @@ extension Keychain: CustomStringConvertible, CustomDebugStringConvertible {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extension Options {
|
extension Options {
|
||||||
|
func query(ignoringAttributeSynchronizable: Bool = true) -> [String: Any] {
|
||||||
func query() -> [String: Any] {
|
|
||||||
var query = [String: Any]()
|
var query = [String: Any]()
|
||||||
|
|
||||||
query[Class] = itemClass.rawValue
|
query[Class] = itemClass.rawValue
|
||||||
|
if let accessGroup = self.accessGroup {
|
||||||
|
query[AttributeAccessGroup] = accessGroup
|
||||||
|
}
|
||||||
|
if ignoringAttributeSynchronizable {
|
||||||
query[AttributeSynchronizable] = SynchronizableAny
|
query[AttributeSynchronizable] = SynchronizableAny
|
||||||
|
} else {
|
||||||
|
query[AttributeSynchronizable] = synchronizable ? kCFBooleanTrue : kCFBooleanFalse
|
||||||
|
}
|
||||||
|
|
||||||
switch itemClass {
|
switch itemClass {
|
||||||
case .genericPassword:
|
case .genericPassword:
|
||||||
query[AttributeService] = service
|
query[AttributeService] = service
|
||||||
// Access group is not supported on any simulators.
|
|
||||||
#if (!arch(i386) && !arch(x86_64)) || (!os(iOS) && !os(watchOS) && !os(tvOS))
|
|
||||||
if let accessGroup = self.accessGroup {
|
|
||||||
query[AttributeAccessGroup] = accessGroup
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
case .internetPassword:
|
case .internetPassword:
|
||||||
query[AttributeServer] = server.host
|
query[AttributeServer] = server.host
|
||||||
query[AttributePort] = server.port
|
query[AttributePort] = server.port
|
||||||
@@ -1292,7 +1421,6 @@ extension Attributes: CustomStringConvertible, CustomDebugStringConvertible {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extension ItemClass: RawRepresentable, CustomStringConvertible {
|
extension ItemClass: RawRepresentable, CustomStringConvertible {
|
||||||
|
|
||||||
public init?(rawValue: String) {
|
public init?(rawValue: String) {
|
||||||
switch rawValue {
|
switch rawValue {
|
||||||
case String(kSecClassGenericPassword):
|
case String(kSecClassGenericPassword):
|
||||||
@@ -1324,7 +1452,6 @@ extension ItemClass: RawRepresentable, CustomStringConvertible {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extension ProtocolType: RawRepresentable, CustomStringConvertible {
|
extension ProtocolType: RawRepresentable, CustomStringConvertible {
|
||||||
|
|
||||||
public init?(rawValue: String) {
|
public init?(rawValue: String) {
|
||||||
switch rawValue {
|
switch rawValue {
|
||||||
case String(kSecAttrProtocolFTP):
|
case String(kSecAttrProtocolFTP):
|
||||||
@@ -1530,7 +1657,6 @@ extension ProtocolType: RawRepresentable, CustomStringConvertible {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extension AuthenticationType: RawRepresentable, CustomStringConvertible {
|
extension AuthenticationType: RawRepresentable, CustomStringConvertible {
|
||||||
|
|
||||||
public init?(rawValue: String) {
|
public init?(rawValue: String) {
|
||||||
switch rawValue {
|
switch rawValue {
|
||||||
case String(kSecAttrAuthenticationTypeNTLM):
|
case String(kSecAttrAuthenticationTypeNTLM):
|
||||||
@@ -1598,7 +1724,6 @@ extension AuthenticationType: RawRepresentable, CustomStringConvertible {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extension Accessibility: RawRepresentable, CustomStringConvertible {
|
extension Accessibility: RawRepresentable, CustomStringConvertible {
|
||||||
|
|
||||||
public init?(rawValue: String) {
|
public init?(rawValue: String) {
|
||||||
if #available(OSX 10.10, *) {
|
if #available(OSX 10.10, *) {
|
||||||
switch rawValue {
|
switch rawValue {
|
||||||
@@ -1606,16 +1731,20 @@ extension Accessibility: RawRepresentable, CustomStringConvertible {
|
|||||||
self = .whenUnlocked
|
self = .whenUnlocked
|
||||||
case String(kSecAttrAccessibleAfterFirstUnlock):
|
case String(kSecAttrAccessibleAfterFirstUnlock):
|
||||||
self = .afterFirstUnlock
|
self = .afterFirstUnlock
|
||||||
|
#if !targetEnvironment(macCatalyst)
|
||||||
case String(kSecAttrAccessibleAlways):
|
case String(kSecAttrAccessibleAlways):
|
||||||
self = .always
|
self = .always
|
||||||
|
#endif
|
||||||
case String(kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly):
|
case String(kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly):
|
||||||
self = .whenPasscodeSetThisDeviceOnly
|
self = .whenPasscodeSetThisDeviceOnly
|
||||||
case String(kSecAttrAccessibleWhenUnlockedThisDeviceOnly):
|
case String(kSecAttrAccessibleWhenUnlockedThisDeviceOnly):
|
||||||
self = .whenUnlockedThisDeviceOnly
|
self = .whenUnlockedThisDeviceOnly
|
||||||
case String(kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly):
|
case String(kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly):
|
||||||
self = .afterFirstUnlockThisDeviceOnly
|
self = .afterFirstUnlockThisDeviceOnly
|
||||||
|
#if !targetEnvironment(macCatalyst)
|
||||||
case String(kSecAttrAccessibleAlwaysThisDeviceOnly):
|
case String(kSecAttrAccessibleAlwaysThisDeviceOnly):
|
||||||
self = .alwaysThisDeviceOnly
|
self = .alwaysThisDeviceOnly
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -1625,14 +1754,18 @@ extension Accessibility: RawRepresentable, CustomStringConvertible {
|
|||||||
self = .whenUnlocked
|
self = .whenUnlocked
|
||||||
case String(kSecAttrAccessibleAfterFirstUnlock):
|
case String(kSecAttrAccessibleAfterFirstUnlock):
|
||||||
self = .afterFirstUnlock
|
self = .afterFirstUnlock
|
||||||
|
#if !targetEnvironment(macCatalyst)
|
||||||
case String(kSecAttrAccessibleAlways):
|
case String(kSecAttrAccessibleAlways):
|
||||||
self = .always
|
self = .always
|
||||||
|
#endif
|
||||||
case String(kSecAttrAccessibleWhenUnlockedThisDeviceOnly):
|
case String(kSecAttrAccessibleWhenUnlockedThisDeviceOnly):
|
||||||
self = .whenUnlockedThisDeviceOnly
|
self = .whenUnlockedThisDeviceOnly
|
||||||
case String(kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly):
|
case String(kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly):
|
||||||
self = .afterFirstUnlockThisDeviceOnly
|
self = .afterFirstUnlockThisDeviceOnly
|
||||||
|
#if !targetEnvironment(macCatalyst)
|
||||||
case String(kSecAttrAccessibleAlwaysThisDeviceOnly):
|
case String(kSecAttrAccessibleAlwaysThisDeviceOnly):
|
||||||
self = .alwaysThisDeviceOnly
|
self = .alwaysThisDeviceOnly
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -1645,8 +1778,10 @@ extension Accessibility: RawRepresentable, CustomStringConvertible {
|
|||||||
return String(kSecAttrAccessibleWhenUnlocked)
|
return String(kSecAttrAccessibleWhenUnlocked)
|
||||||
case .afterFirstUnlock:
|
case .afterFirstUnlock:
|
||||||
return String(kSecAttrAccessibleAfterFirstUnlock)
|
return String(kSecAttrAccessibleAfterFirstUnlock)
|
||||||
|
#if !targetEnvironment(macCatalyst)
|
||||||
case .always:
|
case .always:
|
||||||
return String(kSecAttrAccessibleAlways)
|
return String(kSecAttrAccessibleAlways)
|
||||||
|
#endif
|
||||||
case .whenPasscodeSetThisDeviceOnly:
|
case .whenPasscodeSetThisDeviceOnly:
|
||||||
if #available(OSX 10.10, *) {
|
if #available(OSX 10.10, *) {
|
||||||
return String(kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly)
|
return String(kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly)
|
||||||
@@ -1657,8 +1792,10 @@ extension Accessibility: RawRepresentable, CustomStringConvertible {
|
|||||||
return String(kSecAttrAccessibleWhenUnlockedThisDeviceOnly)
|
return String(kSecAttrAccessibleWhenUnlockedThisDeviceOnly)
|
||||||
case .afterFirstUnlockThisDeviceOnly:
|
case .afterFirstUnlockThisDeviceOnly:
|
||||||
return String(kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly)
|
return String(kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly)
|
||||||
|
#if !targetEnvironment(macCatalyst)
|
||||||
case .alwaysThisDeviceOnly:
|
case .alwaysThisDeviceOnly:
|
||||||
return String(kSecAttrAccessibleAlwaysThisDeviceOnly)
|
return String(kSecAttrAccessibleAlwaysThisDeviceOnly)
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1668,16 +1805,20 @@ extension Accessibility: RawRepresentable, CustomStringConvertible {
|
|||||||
return "WhenUnlocked"
|
return "WhenUnlocked"
|
||||||
case .afterFirstUnlock:
|
case .afterFirstUnlock:
|
||||||
return "AfterFirstUnlock"
|
return "AfterFirstUnlock"
|
||||||
|
#if !targetEnvironment(macCatalyst)
|
||||||
case .always:
|
case .always:
|
||||||
return "Always"
|
return "Always"
|
||||||
|
#endif
|
||||||
case .whenPasscodeSetThisDeviceOnly:
|
case .whenPasscodeSetThisDeviceOnly:
|
||||||
return "WhenPasscodeSetThisDeviceOnly"
|
return "WhenPasscodeSetThisDeviceOnly"
|
||||||
case .whenUnlockedThisDeviceOnly:
|
case .whenUnlockedThisDeviceOnly:
|
||||||
return "WhenUnlockedThisDeviceOnly"
|
return "WhenUnlockedThisDeviceOnly"
|
||||||
case .afterFirstUnlockThisDeviceOnly:
|
case .afterFirstUnlockThisDeviceOnly:
|
||||||
return "AfterFirstUnlockThisDeviceOnly"
|
return "AfterFirstUnlockThisDeviceOnly"
|
||||||
|
#if !targetEnvironment(macCatalyst)
|
||||||
case .alwaysThisDeviceOnly:
|
case .alwaysThisDeviceOnly:
|
||||||
return "AlwaysThisDeviceOnly"
|
return "AlwaysThisDeviceOnly"
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
97
Pods/KeychainAccess/README.md
generated
97
Pods/KeychainAccess/README.md
generated
@@ -1,13 +1,9 @@
|
|||||||
# KeychainAccess
|
# KeychainAccess
|
||||||
[](https://travis-ci.org/kishikawakatsumi/KeychainAccess)
|
[](https://travis-ci.org/kishikawakatsumi/KeychainAccess)
|
||||||
[](https://codecov.io/gh/kishikawakatsumi/KeychainAccess)
|
|
||||||
[](https://github.com/Carthage/Carthage)
|
[](https://github.com/Carthage/Carthage)
|
||||||
|
[](https://swift.org/package-manager)
|
||||||
[](http://cocoadocs.org/docsets/KeychainAccess)
|
[](http://cocoadocs.org/docsets/KeychainAccess)
|
||||||
[](http://cocoadocs.org/docsets/KeychainAccess)
|
[](http://cocoadocs.org/docsets/KeychainAccess)
|
||||||
[](https://swift.org/)
|
|
||||||
[](https://swift.org/)
|
|
||||||
[](https://swift.org/)
|
|
||||||
[](https://swift.org/)
|
|
||||||
|
|
||||||
KeychainAccess is a simple Swift wrapper for Keychain that works on iOS and OS X. Makes using Keychain APIs extremely easy and much more palatable to use in Swift.
|
KeychainAccess is a simple Swift wrapper for Keychain that works on iOS and OS X. Makes using Keychain APIs extremely easy and much more palatable to use in Swift.
|
||||||
|
|
||||||
@@ -23,9 +19,10 @@ KeychainAccess is a simple Swift wrapper for Keychain that works on iOS and OS X
|
|||||||
- [Support iCloud sharing](#icloud_sharing)
|
- [Support iCloud sharing](#icloud_sharing)
|
||||||
- **[Support TouchID and Keychain integration (iOS 8+)](#touch_id_integration)**
|
- **[Support TouchID and Keychain integration (iOS 8+)](#touch_id_integration)**
|
||||||
- **[Support Shared Web Credentials (iOS 8+)](#shared_web_credentials)**
|
- **[Support Shared Web Credentials (iOS 8+)](#shared_web_credentials)**
|
||||||
- [Works on both iOS & OS X](#requirements)
|
- [Works on both iOS & macOS](#requirements)
|
||||||
- [watchOS and tvOS are supported](#requirements)
|
- [watchOS and tvOS are supported](#requirements)
|
||||||
- **[Swift 4 & Swift 3 compatible](#requirements)**
|
- **[Mac Catalyst is supported](#requirements)**
|
||||||
|
- **[Swift 3, 4 and 5 compatible](#requirements)**
|
||||||
|
|
||||||
## :book: Usage
|
## :book: Usage
|
||||||
|
|
||||||
@@ -183,7 +180,7 @@ do {
|
|||||||
|
|
||||||
```swift
|
```swift
|
||||||
let keychain = Keychain()
|
let keychain = Keychain()
|
||||||
let persistentRef = keychain[attributes: "kishikawakatsumi"].persistentRef
|
let persistentRef = keychain[attributes: "kishikawakatsumi"]?.persistentRef
|
||||||
...
|
...
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -191,7 +188,7 @@ let persistentRef = keychain[attributes: "kishikawakatsumi"].persistentRef
|
|||||||
|
|
||||||
```swift
|
```swift
|
||||||
let keychain = Keychain()
|
let keychain = Keychain()
|
||||||
let creationDate = keychain[attributes: "kishikawakatsumi"].creationDate
|
let creationDate = keychain[attributes: "kishikawakatsumi"]?.creationDate
|
||||||
...
|
...
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -201,9 +198,9 @@ let creationDate = keychain[attributes: "kishikawakatsumi"].creationDate
|
|||||||
let keychain = Keychain()
|
let keychain = Keychain()
|
||||||
do {
|
do {
|
||||||
let attributes = try keychain.get("kishikawakatsumi") { $0 }
|
let attributes = try keychain.get("kishikawakatsumi") { $0 }
|
||||||
print(attributes.comment)
|
print(attributes?.comment)
|
||||||
print(attributes.label)
|
print(attributes?.label)
|
||||||
print(attributes.creator)
|
print(attributes?.creator)
|
||||||
...
|
...
|
||||||
} catch let error {
|
} catch let error {
|
||||||
print("error: \(error)")
|
print("error: \(error)")
|
||||||
@@ -214,10 +211,11 @@ do {
|
|||||||
|
|
||||||
```swift
|
```swift
|
||||||
let keychain = Keychain()
|
let keychain = Keychain()
|
||||||
let attributes = keychain[attributes: "kishikawakatsumi"]
|
if let attributes = keychain[attributes: "kishikawakatsumi"] {
|
||||||
print(attributes.comment)
|
print(attributes.comment)
|
||||||
print(attributes.label)
|
print(attributes.label)
|
||||||
print(attributes.creator)
|
print(attributes.creator)
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### :key: Configuration (Accessibility, Sharing, iCloud Sync)
|
### :key: Configuration (Accessibility, Sharing, iCloud Sync)
|
||||||
@@ -320,12 +318,15 @@ do {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### <a name="touch_id_integration"> :fu: Touch ID integration
|
### <a name="touch_id_integration"> :cyclone: Touch ID (Face ID) integration
|
||||||
|
|
||||||
**Any Operation that require authentication must be run in the background thread.**
|
**Any Operation that require authentication must be run in the background thread.**
|
||||||
**If you run in the main thread, UI thread will lock for the system to try to display the authentication dialog.**
|
**If you run in the main thread, UI thread will lock for the system to try to display the authentication dialog.**
|
||||||
|
|
||||||
#### :closed_lock_with_key: Adding a Touch ID protected item
|
|
||||||
|
**To use Face ID, add `NSFaceIDUsageDescription` key to your `Info.plist`**
|
||||||
|
|
||||||
|
#### :closed_lock_with_key: Adding a Touch ID (Face ID) protected item
|
||||||
|
|
||||||
If you want to store the Touch ID protected Keychain item, specify `accessibility` and `authenticationPolicy` attributes.
|
If you want to store the Touch ID protected Keychain item, specify `accessibility` and `authenticationPolicy` attributes.
|
||||||
|
|
||||||
@@ -344,7 +345,7 @@ DispatchQueue.global().async {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
#### :closed_lock_with_key: Updating a Touch ID protected item
|
#### :closed_lock_with_key: Updating a Touch ID (Face ID) protected item
|
||||||
|
|
||||||
The same way as when adding.
|
The same way as when adding.
|
||||||
|
|
||||||
@@ -370,7 +371,7 @@ DispatchQueue.global().async {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
#### :closed_lock_with_key: Obtaining a Touch ID protected item
|
#### :closed_lock_with_key: Obtaining a Touch ID (Face ID) protected item
|
||||||
|
|
||||||
The same way as when you get a normal item. It will be displayed automatically Touch ID or passcode authentication If the item you try to get is protected.
|
The same way as when you get a normal item. It will be displayed automatically Touch ID or passcode authentication If the item you try to get is protected.
|
||||||
If you want to show custom authentication prompt message, specify an `authenticationPrompt` attribute.
|
If you want to show custom authentication prompt message, specify an `authenticationPrompt` attribute.
|
||||||
@@ -392,7 +393,7 @@ DispatchQueue.global().async {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
#### :closed_lock_with_key: Removing a Touch ID protected item
|
#### :closed_lock_with_key: Removing a Touch ID (Face ID) protected item
|
||||||
|
|
||||||
The same way as when you remove a normal item.
|
The same way as when you remove a normal item.
|
||||||
There is no way to show Touch ID or passcode authentication when removing Keychain items.
|
There is no way to show Touch ID or passcode authentication when removing Keychain items.
|
||||||
@@ -467,15 +468,15 @@ let password = Keychain.generatePassword() // => Nhu-GKm-s3n-pMx
|
|||||||
#### How to set up Shared Web Credentials
|
#### How to set up Shared Web Credentials
|
||||||
|
|
||||||
> 1. Add a com.apple.developer.associated-domains entitlement to your app. This entitlement must include all the domains with which you want to share credentials.
|
> 1. Add a com.apple.developer.associated-domains entitlement to your app. This entitlement must include all the domains with which you want to share credentials.
|
||||||
|
>
|
||||||
> 2. Add an apple-app-site-association file to your website. This file must include application identifiers for all the apps with which the site wants to share credentials, and it must be properly signed.
|
> 2. Add an apple-app-site-association file to your website. This file must include application identifiers for all the apps with which the site wants to share credentials, and it must be properly signed.
|
||||||
|
>
|
||||||
> 3. When the app is installed, the system downloads and verifies the site association file for each of its associated domains. If the verification is successful, the app is associated with the domain.
|
> 3. When the app is installed, the system downloads and verifies the site association file for each of its associated domains. If the verification is successful, the app is associated with the domain.
|
||||||
|
|
||||||
**More details:**
|
**More details:**
|
||||||
<https://developer.apple.com/library/ios/documentation/Security/Reference/SharedWebCredentialsRef/>
|
<https://developer.apple.com/library/ios/documentation/Security/Reference/SharedWebCredentialsRef/>
|
||||||
|
|
||||||
### :key: Debugging
|
### :mag: Debugging
|
||||||
|
|
||||||
#### Display all stored items if print keychain object
|
#### Display all stored items if print keychain object
|
||||||
|
|
||||||
@@ -529,19 +530,34 @@ item: [authenticationType: Default, key: hirohamada, server: github.com, class:
|
|||||||
item: [authenticationType: Default, key: honeylemon, server: github.com, class: InternetPassword, protocol: https]
|
item: [authenticationType: Default, key: honeylemon, server: github.com, class: InternetPassword, protocol: https]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Keychain sharing capability
|
||||||
|
|
||||||
|
If you encounter the error below, you need to add an `Keychain.entitlements`.
|
||||||
|
|
||||||
|
```
|
||||||
|
OSStatus error:[-34018] Internal error when a required entitlement isn't present, client has neither application-identifier nor keychain-access-groups entitlements.
|
||||||
|
```
|
||||||
|
|
||||||
|
<img alt="Screen Shot 2019-10-27 at 8 08 50" src="https://user-images.githubusercontent.com/40610/67627108-1a7f2f80-f891-11e9-97bc-7f7313cb63d1.png" width="500">
|
||||||
|
|
||||||
|
<img src="https://user-images.githubusercontent.com/40610/67627072-333b1580-f890-11e9-9feb-bf507abc2724.png" width="500" />
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
| | OS | Swift |
|
| | OS | Swift |
|
||||||
|------------|----------------------------------------|---------------|
|
|------------|------------------------------------------------------------|--------------------|
|
||||||
| **v1.1.x** | iOS 7+, OSX 10.9+ | 1.1 |
|
| **v1.1.x** | iOS 7+, macOS 10.9+ | 1.1 |
|
||||||
| **v1.2.x** | iOS 7+, OSX 10.9+ | 1.2 |
|
| **v1.2.x** | iOS 7+, macOS 10.9+ | 1.2 |
|
||||||
| **v2.0.x** | iOS 7+, OSX 10.9+, watchOS 2+ | 2.0 |
|
| **v2.0.x** | iOS 7+, macOS 10.9+, watchOS 2+ | 2.0 |
|
||||||
| **v2.1.x** | iOS 7+, OSX 10.9+, watchOS 2+ | 2.0 |
|
| **v2.1.x** | iOS 7+, macOS 10.9+, watchOS 2+ | 2.0 |
|
||||||
| **v2.2.x** | iOS 8+, OSX 10.9+, watchOS 2+, tvOS 9+ | 2.0, 2.1 |
|
| **v2.2.x** | iOS 8+, macOS 10.9+, watchOS 2+, tvOS 9+ | 2.0, 2.1 |
|
||||||
| **v2.3.x** | iOS 8+, OSX 10.9+, watchOS 2+, tvOS 9+ | 2.0, 2.1, 2.2 |
|
| **v2.3.x** | iOS 8+, macOS 10.9+, watchOS 2+, tvOS 9+ | 2.0, 2.1, 2.2 |
|
||||||
| **v2.4.x** | iOS 8+, OSX 10.9+, watchOS 2+, tvOS 9+ | 2.2, 2.3 |
|
| **v2.4.x** | iOS 8+, macOS 10.9+, watchOS 2+, tvOS 9+ | 2.2, 2.3 |
|
||||||
| **v3.0.x** | iOS 8+, OSX 10.9+, watchOS 2+, tvOS 9+ | 3.x |
|
| **v3.0.x** | iOS 8+, macOS 10.9+, watchOS 2+, tvOS 9+ | 3.x |
|
||||||
| **v3.1.x** | iOS 8+, OSX 10.9+, watchOS 2+, tvOS 9+ | 4.0, 4.1, 4.2 |
|
| **v3.1.x** | iOS 8+, macOS 10.9+, watchOS 2+, tvOS 9+ | 4.0, 4.1, 4.2 |
|
||||||
|
| **v3.2.x** | iOS 8+, macOS 10.9+, watchOS 2+, tvOS 9+ | 4.0, 4.1, 4.2, 5.0 |
|
||||||
|
| **v4.0.x** | iOS 8+, macOS 10.9+, watchOS 2+, tvOS 9+ | 4.0, 4.1, 4.2, 5.1 |
|
||||||
|
| **v4.1.x** | iOS 8+, macOS 10.9+, watchOS 3+, tvOS 9+, Mac Catalyst 13+ | 4.0, 4.1, 4.2, 5.1 |
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
@@ -565,14 +581,31 @@ it, simply add the following line to your Cartfile:
|
|||||||
### Swift Package Manager
|
### Swift Package Manager
|
||||||
|
|
||||||
KeychainAccess is also available through [Swift Package Manager](https://github.com/apple/swift-package-manager/).
|
KeychainAccess is also available through [Swift Package Manager](https://github.com/apple/swift-package-manager/).
|
||||||
|
|
||||||
|
#### Xcode
|
||||||
|
|
||||||
|
Select `File > Swift Packages > Add Package Dependency...`,
|
||||||
|
|
||||||
|
<img src="https://user-images.githubusercontent.com/40610/67627000-2833b580-f88f-11e9-89ef-18819b1a6c67.png" width="800px" />
|
||||||
|
|
||||||
|
#### CLI
|
||||||
|
|
||||||
First, create `Package.swift` that its package declaration includes:
|
First, create `Package.swift` that its package declaration includes:
|
||||||
|
|
||||||
```swift
|
```swift
|
||||||
|
// swift-tools-version:5.0
|
||||||
import PackageDescription
|
import PackageDescription
|
||||||
|
|
||||||
let package = Package(
|
let package = Package(
|
||||||
|
name: "MyLibrary",
|
||||||
|
products: [
|
||||||
|
.library(name: "MyLibrary", targets: ["MyLibrary"]),
|
||||||
|
],
|
||||||
dependencies: [
|
dependencies: [
|
||||||
.Package(url: "https://github.com/kishikawakatsumi/KeychainAccess.git", majorVersion: 2)
|
.package(url: "https://github.com/kishikawakatsumi/KeychainAccess.git", from: "3.0.0"),
|
||||||
|
],
|
||||||
|
targets: [
|
||||||
|
.target(name: "MyLibrary", dependencies: ["KeychainAccess"]),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|||||||
8
Pods/Manifest.lock
generated
8
Pods/Manifest.lock
generated
@@ -7,14 +7,14 @@ PODS:
|
|||||||
- AppCenter/Core (3.1.0)
|
- AppCenter/Core (3.1.0)
|
||||||
- AppCenter/Crashes (3.1.0):
|
- AppCenter/Crashes (3.1.0):
|
||||||
- AppCenter/Core
|
- AppCenter/Core
|
||||||
- KeychainAccess (3.2.0)
|
- KeychainAccess (4.2.1)
|
||||||
- Nuke (7.6.3)
|
- Nuke (7.6.3)
|
||||||
- Sparkle (1.21.3)
|
- Sparkle (1.21.3)
|
||||||
- STPrivilegedTask (1.0.7)
|
- STPrivilegedTask (1.0.7)
|
||||||
|
|
||||||
DEPENDENCIES:
|
DEPENDENCIES:
|
||||||
- AppCenter (~> 3.1.0)
|
- AppCenter (~> 3.1.0)
|
||||||
- KeychainAccess (~> 3.2.0)
|
- KeychainAccess (~> 4.2.0)
|
||||||
- Nuke (~> 7.0)
|
- Nuke (~> 7.0)
|
||||||
- Sparkle
|
- Sparkle
|
||||||
- STPrivilegedTask (from `https://github.com/rileytestut/STPrivilegedTask.git`)
|
- STPrivilegedTask (from `https://github.com/rileytestut/STPrivilegedTask.git`)
|
||||||
@@ -37,11 +37,11 @@ CHECKOUT OPTIONS:
|
|||||||
|
|
||||||
SPEC CHECKSUMS:
|
SPEC CHECKSUMS:
|
||||||
AppCenter: a1c30c47b7882a04a615ffa5ab26c007326436d8
|
AppCenter: a1c30c47b7882a04a615ffa5ab26c007326436d8
|
||||||
KeychainAccess: 3b1bf8a77eb4c6ea1ce9404c292e48f948954c6b
|
KeychainAccess: 9b07f665298d13c3a85881bd3171f6f49b8151c1
|
||||||
Nuke: 44130e95e09463f8773ae4b96b90de1eba6b3350
|
Nuke: 44130e95e09463f8773ae4b96b90de1eba6b3350
|
||||||
Sparkle: 3f75576db8b0265adef36c43249d747f22d0b708
|
Sparkle: 3f75576db8b0265adef36c43249d747f22d0b708
|
||||||
STPrivilegedTask: 56c3397238a1ec07720fb877a044898373cd2c68
|
STPrivilegedTask: 56c3397238a1ec07720fb877a044898373cd2c68
|
||||||
|
|
||||||
PODFILE CHECKSUM: b687e2aeec1ffc369787e92f2a2fefa460687731
|
PODFILE CHECKSUM: 6e3f9d2fc666262d43ff8079a3f9149b8f3376ee
|
||||||
|
|
||||||
COCOAPODS: 1.8.4
|
COCOAPODS: 1.8.4
|
||||||
|
|||||||
82
Pods/Pods.xcodeproj/project.pbxproj
generated
82
Pods/Pods.xcodeproj/project.pbxproj
generated
@@ -986,7 +986,7 @@
|
|||||||
};
|
};
|
||||||
name = Release;
|
name = Release;
|
||||||
};
|
};
|
||||||
4D7B47C1C925E85EF583F90672CFDCED /* Release */ = {
|
45293695F003AF5DCBA69464D33BD875 /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
baseConfigurationReference = 64D9DBBA06AB12F798AE3F1F91A19FAF /* KeychainAccess.xcconfig */;
|
baseConfigurationReference = 64D9DBBA06AB12F798AE3F1F91A19FAF /* KeychainAccess.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
@@ -1014,13 +1014,12 @@
|
|||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
SKIP_INSTALL = YES;
|
SKIP_INSTALL = YES;
|
||||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) ";
|
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) ";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.1;
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
VALIDATE_PRODUCT = YES;
|
|
||||||
VERSIONING_SYSTEM = "apple-generic";
|
VERSIONING_SYSTEM = "apple-generic";
|
||||||
VERSION_INFO_PREFIX = "";
|
VERSION_INFO_PREFIX = "";
|
||||||
};
|
};
|
||||||
name = Release;
|
name = Debug;
|
||||||
};
|
};
|
||||||
4F7F91411B6EC0AEB386B2E5FE5F20E8 /* Release */ = {
|
4F7F91411B6EC0AEB386B2E5FE5F20E8 /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
@@ -1101,41 +1100,6 @@
|
|||||||
};
|
};
|
||||||
name = Debug;
|
name = Debug;
|
||||||
};
|
};
|
||||||
5D237BFE5BE554A49204FA025EAC7A41 /* Debug */ = {
|
|
||||||
isa = XCBuildConfiguration;
|
|
||||||
baseConfigurationReference = 64D9DBBA06AB12F798AE3F1F91A19FAF /* KeychainAccess.xcconfig */;
|
|
||||||
buildSettings = {
|
|
||||||
CODE_SIGN_IDENTITY = "";
|
|
||||||
"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
|
|
||||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
|
|
||||||
"CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
|
|
||||||
CURRENT_PROJECT_VERSION = 1;
|
|
||||||
DEFINES_MODULE = YES;
|
|
||||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
|
||||||
DYLIB_CURRENT_VERSION = 1;
|
|
||||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
|
||||||
GCC_PREFIX_HEADER = "Target Support Files/KeychainAccess/KeychainAccess-prefix.pch";
|
|
||||||
INFOPLIST_FILE = "Target Support Files/KeychainAccess/KeychainAccess-Info.plist";
|
|
||||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 12.2;
|
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
|
||||||
"$(inherited)",
|
|
||||||
"@executable_path/Frameworks",
|
|
||||||
"@loader_path/Frameworks",
|
|
||||||
);
|
|
||||||
MODULEMAP_FILE = "Target Support Files/KeychainAccess/KeychainAccess.modulemap";
|
|
||||||
PRODUCT_MODULE_NAME = KeychainAccess;
|
|
||||||
PRODUCT_NAME = KeychainAccess;
|
|
||||||
SDKROOT = iphoneos;
|
|
||||||
SKIP_INSTALL = YES;
|
|
||||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) ";
|
|
||||||
SWIFT_VERSION = 5.0;
|
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
|
||||||
VERSIONING_SYSTEM = "apple-generic";
|
|
||||||
VERSION_INFO_PREFIX = "";
|
|
||||||
};
|
|
||||||
name = Debug;
|
|
||||||
};
|
|
||||||
5E307238EB942E7EC9F39671288715AE /* Release */ = {
|
5E307238EB942E7EC9F39671288715AE /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
baseConfigurationReference = CAC29D24D26CC8214B6B5A283B48A108 /* Pods-AltStoreCore.release.xcconfig */;
|
baseConfigurationReference = CAC29D24D26CC8214B6B5A283B48A108 /* Pods-AltStoreCore.release.xcconfig */;
|
||||||
@@ -1578,6 +1542,42 @@
|
|||||||
};
|
};
|
||||||
name = Release;
|
name = Release;
|
||||||
};
|
};
|
||||||
|
FF3EC215E8144B4CBE1F2C8440716AA6 /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
baseConfigurationReference = 64D9DBBA06AB12F798AE3F1F91A19FAF /* KeychainAccess.xcconfig */;
|
||||||
|
buildSettings = {
|
||||||
|
CODE_SIGN_IDENTITY = "";
|
||||||
|
"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
|
||||||
|
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
|
||||||
|
"CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
|
||||||
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
|
DEFINES_MODULE = YES;
|
||||||
|
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||||
|
DYLIB_CURRENT_VERSION = 1;
|
||||||
|
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||||
|
GCC_PREFIX_HEADER = "Target Support Files/KeychainAccess/KeychainAccess-prefix.pch";
|
||||||
|
INFOPLIST_FILE = "Target Support Files/KeychainAccess/KeychainAccess-Info.plist";
|
||||||
|
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 12.2;
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"@executable_path/Frameworks",
|
||||||
|
"@loader_path/Frameworks",
|
||||||
|
);
|
||||||
|
MODULEMAP_FILE = "Target Support Files/KeychainAccess/KeychainAccess.modulemap";
|
||||||
|
PRODUCT_MODULE_NAME = KeychainAccess;
|
||||||
|
PRODUCT_NAME = KeychainAccess;
|
||||||
|
SDKROOT = iphoneos;
|
||||||
|
SKIP_INSTALL = YES;
|
||||||
|
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) ";
|
||||||
|
SWIFT_VERSION = 5.1;
|
||||||
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
|
VALIDATE_PRODUCT = YES;
|
||||||
|
VERSIONING_SYSTEM = "apple-generic";
|
||||||
|
VERSION_INFO_PREFIX = "";
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
/* End XCBuildConfiguration section */
|
/* End XCBuildConfiguration section */
|
||||||
|
|
||||||
/* Begin XCConfigurationList section */
|
/* Begin XCConfigurationList section */
|
||||||
@@ -1611,8 +1611,8 @@
|
|||||||
4BEE926243448802ACA6F07A75D9C025 /* Build configuration list for PBXNativeTarget "KeychainAccess" */ = {
|
4BEE926243448802ACA6F07A75D9C025 /* Build configuration list for PBXNativeTarget "KeychainAccess" */ = {
|
||||||
isa = XCConfigurationList;
|
isa = XCConfigurationList;
|
||||||
buildConfigurations = (
|
buildConfigurations = (
|
||||||
5D237BFE5BE554A49204FA025EAC7A41 /* Debug */,
|
45293695F003AF5DCBA69464D33BD875 /* Debug */,
|
||||||
4D7B47C1C925E85EF583F90672CFDCED /* Release */,
|
FF3EC215E8144B4CBE1F2C8440716AA6 /* Release */,
|
||||||
);
|
);
|
||||||
defaultConfigurationIsVisible = 0;
|
defaultConfigurationIsVisible = 0;
|
||||||
defaultConfigurationName = Release;
|
defaultConfigurationName = Release;
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>FMWK</string>
|
<string>FMWK</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>3.2.0</string>
|
<string>4.2.1</string>
|
||||||
<key>CFBundleSignature</key>
|
<key>CFBundleSignature</key>
|
||||||
<string>????</string>
|
<string>????</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
|
|||||||
Reference in New Issue
Block a user