Skip to content
This repository has been archived by the owner on Jan 10, 2023. It is now read-only.

Swift 5.1 #143

Open
wants to merge 2 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 4 additions & 12 deletions SwiftKeychainWrapper/KeychainItemAccessibility.swift
Original file line number Diff line number Diff line change
Expand Up @@ -92,18 +92,12 @@ public enum KeychainItemAccessibility {
case whenUnlockedThisDeviceOnly

static func accessibilityForAttributeValue(_ keychainAttrValue: CFString) -> KeychainItemAccessibility? {
for (key, value) in keychainItemAccessibilityLookup {
if value == keychainAttrValue {
return key
}
}

return nil
keychainItemAccessibilityLookup.first { $0.value == keychainAttrValue }?.key
}
}

private let keychainItemAccessibilityLookup: [KeychainItemAccessibility:CFString] = {
var lookup: [KeychainItemAccessibility:CFString] = [
[
.afterFirstUnlock: kSecAttrAccessibleAfterFirstUnlock,
.afterFirstUnlockThisDeviceOnly: kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly,
.always: kSecAttrAccessibleAlways,
Expand All @@ -112,12 +106,10 @@ private let keychainItemAccessibilityLookup: [KeychainItemAccessibility:CFString
.whenUnlocked: kSecAttrAccessibleWhenUnlocked,
.whenUnlockedThisDeviceOnly: kSecAttrAccessibleWhenUnlockedThisDeviceOnly
]

return lookup
}()

extension KeychainItemAccessibility : KeychainAttrRepresentable {
internal var keychainAttrValue: CFString {
return keychainItemAccessibilityLookup[self]!
var keychainAttrValue: CFString {
keychainItemAccessibilityLookup[self]!
}
}
91 changes: 23 additions & 68 deletions SwiftKeychainWrapper/KeychainWrapper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,7 @@ open class KeychainWrapper {
/// AccessGroup is used for the kSecAttrAccessGroup property to identify which Keychain Access Group this entry belongs to. This allows you to use the KeychainWrapper with shared keychain access between different applications.
private (set) public var accessGroup: String?

private static let defaultServiceName: String = {
return Bundle.main.bundleIdentifier ?? "SwiftKeychainWrapper"
}()
private static let defaultServiceName = Bundle.main.bundleIdentifier ?? "SwiftKeychainWrapper"

private convenience init() {
self.init(serviceName: KeychainWrapper.defaultServiceName)
Expand All @@ -80,11 +78,7 @@ open class KeychainWrapper {
/// - parameter withAccessibility: Optional accessibility to use when retrieving the keychain item.
/// - returns: True if a value exists for the key. False otherwise.
open func hasValue(forKey key: String, withAccessibility accessibility: KeychainItemAccessibility? = nil) -> Bool {
if let _ = data(forKey: key, withAccessibility: accessibility) {
return true
} else {
return false
}
data(forKey: key, withAccessibility: accessibility) != nil
}

open func accessibilityOfKey(_ key: String) -> KeychainItemAccessibility? {
Expand Down Expand Up @@ -146,35 +140,19 @@ open class KeychainWrapper {
// MARK: Public Getters

open func integer(forKey key: String, withAccessibility accessibility: KeychainItemAccessibility? = nil) -> Int? {
guard let numberValue = object(forKey: key, withAccessibility: accessibility) as? NSNumber else {
return nil
}

return numberValue.intValue
(object(forKey: key, withAccessibility: accessibility) as? NSNumber)?.intValue
}

open func float(forKey key: String, withAccessibility accessibility: KeychainItemAccessibility? = nil) -> Float? {
guard let numberValue = object(forKey: key, withAccessibility: accessibility) as? NSNumber else {
return nil
}

return numberValue.floatValue
(object(forKey: key, withAccessibility: accessibility) as? NSNumber)?.floatValue
}

open func double(forKey key: String, withAccessibility accessibility: KeychainItemAccessibility? = nil) -> Double? {
guard let numberValue = object(forKey: key, withAccessibility: accessibility) as? NSNumber else {
return nil
}

return numberValue.doubleValue
(object(forKey: key, withAccessibility: accessibility) as? NSNumber)?.doubleValue
}

open func bool(forKey key: String, withAccessibility accessibility: KeychainItemAccessibility? = nil) -> Bool? {
guard let numberValue = object(forKey: key, withAccessibility: accessibility) as? NSNumber else {
return nil
}

return numberValue.boolValue
(object(forKey: key, withAccessibility: accessibility) as? NSNumber)?.boolValue
}

/// Returns a string value for a specified key.
Expand All @@ -187,7 +165,7 @@ open class KeychainWrapper {
return nil
}

return String(data: keychainData, encoding: String.Encoding.utf8) as String?
return String(data: keychainData, encoding: .utf8)
}

/// Returns an object that conforms to NSCoding for a specified key.
Expand Down Expand Up @@ -250,19 +228,19 @@ open class KeychainWrapper {
// MARK: Public Setters

@discardableResult open func set(_ value: Int, forKey key: String, withAccessibility accessibility: KeychainItemAccessibility? = nil) -> Bool {
return set(NSNumber(value: value), forKey: key, withAccessibility: accessibility)
set(NSNumber(value: value), forKey: key, withAccessibility: accessibility)
}

@discardableResult open func set(_ value: Float, forKey key: String, withAccessibility accessibility: KeychainItemAccessibility? = nil) -> Bool {
return set(NSNumber(value: value), forKey: key, withAccessibility: accessibility)
set(NSNumber(value: value), forKey: key, withAccessibility: accessibility)
}

@discardableResult open func set(_ value: Double, forKey key: String, withAccessibility accessibility: KeychainItemAccessibility? = nil) -> Bool {
return set(NSNumber(value: value), forKey: key, withAccessibility: accessibility)
set(NSNumber(value: value), forKey: key, withAccessibility: accessibility)
}

@discardableResult open func set(_ value: Bool, forKey key: String, withAccessibility accessibility: KeychainItemAccessibility? = nil) -> Bool {
return set(NSNumber(value: value), forKey: key, withAccessibility: accessibility)
set(NSNumber(value: value), forKey: key, withAccessibility: accessibility)
}

/// Save a String value to the keychain associated with a specified key. If a String value already exists for the given key, the string will be overwritten with the new value.
Expand All @@ -272,11 +250,8 @@ open class KeychainWrapper {
/// - parameter withAccessibility: Optional accessibility to use when setting the keychain item.
/// - returns: True if the save was successful, false otherwise.
@discardableResult open func set(_ value: String, forKey key: String, withAccessibility accessibility: KeychainItemAccessibility? = nil) -> Bool {
if let data = value.data(using: .utf8) {
return set(data, forKey: key, withAccessibility: accessibility)
} else {
return false
}
guard let data = value.data(using: .utf8) else { return false }
return set(data, forKey: key, withAccessibility: accessibility)
}

/// Save an NSCoding compliant object to the keychain associated with a specified key. If an object already exists for the given key, the object will be overwritten with the new value.
Expand Down Expand Up @@ -309,7 +284,7 @@ open class KeychainWrapper {
keychainQueryDictionary[SecAttrAccessible] = KeychainItemAccessibility.whenUnlocked.keychainAttrValue
}

let status: OSStatus = SecItemAdd(keychainQueryDictionary as CFDictionary, nil)
let status = SecItemAdd(keychainQueryDictionary as CFDictionary, nil)

if status == errSecSuccess {
return true
Expand All @@ -322,7 +297,7 @@ open class KeychainWrapper {

@available(*, deprecated, message: "remove is deprecated since version 2.2.1, use removeObject instead")
@discardableResult open func remove(key: String, withAccessibility accessibility: KeychainItemAccessibility? = nil) -> Bool {
return removeObject(forKey: key, withAccessibility: accessibility)
removeObject(forKey: key, withAccessibility: accessibility)
}

/// Remove an object associated with a specified key. If re-using a key but with a different accessibility, first remove the previous key value using removeObjectForKey(:withAccessibility) using the same accessibilty it was saved with.
Expand All @@ -334,13 +309,8 @@ open class KeychainWrapper {
let keychainQueryDictionary: [String:Any] = setupKeychainQueryDictionary(forKey: key, withAccessibility: accessibility)

// Delete
let status: OSStatus = SecItemDelete(keychainQueryDictionary as CFDictionary)

if status == errSecSuccess {
return true
} else {
return false
}
let status = SecItemDelete(keychainQueryDictionary as CFDictionary)
return status == errSecSuccess
}

/// Remove all keychain data added through KeychainWrapper. This will only delete items matching the currnt ServiceName and AccessGroup if one is set.
Expand All @@ -356,13 +326,8 @@ open class KeychainWrapper {
keychainQueryDictionary[SecAttrAccessGroup] = accessGroup
}

let status: OSStatus = SecItemDelete(keychainQueryDictionary as CFDictionary)

if status == errSecSuccess {
return true
} else {
return false
}
let status = SecItemDelete(keychainQueryDictionary as CFDictionary)
return status == errSecSuccess
}

/// Remove all keychain data, including data not added through keychain wrapper.
Expand All @@ -384,13 +349,8 @@ open class KeychainWrapper {
///
@discardableResult private class func deleteKeychainSecClass(_ secClass: AnyObject) -> Bool {
let query = [SecClass: secClass]
let status: OSStatus = SecItemDelete(query as CFDictionary)

if status == errSecSuccess {
return true
} else {
return false
}
let status = SecItemDelete(query as CFDictionary)
return status == errSecSuccess
}

/// Update existing data associated with a specified key name. The existing data will be overwritten by the new data.
Expand All @@ -404,13 +364,8 @@ open class KeychainWrapper {
}

// Update
let status: OSStatus = SecItemUpdate(keychainQueryDictionary as CFDictionary, updateDictionary as CFDictionary)

if status == errSecSuccess {
return true
} else {
return false
}
let status = SecItemUpdate(keychainQueryDictionary as CFDictionary, updateDictionary as CFDictionary)
return status == errSecSuccess
}

/// Setup the keychain query dictionary used to access the keychain on iOS for a specified key name. Takes into account the Service Name and Access Group if one is set.
Expand Down