Created
May 4, 2020 09:52
-
-
Save cipolleschi/41cea57f4fbd41da9b03f223ff27b795 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
func createQuery(for serivce: String) -> [String: Any] { | |
let query: [String: Any] = [ | |
kSecClass as String: kSecClassGenericPassword, | |
kSecAttrService as String: service, | |
kSecReturnAttributes as String: true, | |
kSecReturnData as String: true, | |
kSecMatchLimit as String: kSecMatchLimitAll | |
] | |
return query | |
} | |
func get(service: String, type: Int) throws -> [(account: String, password: Data)] { | |
// 1. create the query to retrieve the type | |
var query = createQuery(for: serive) | |
query[kSecAttrType as String] = type | |
// 2. retrieve the data | |
var extractedData: AnyObject? | |
let status = SecItemCopyMatching(query as CFDictionary, &extractedData) | |
// 3. handle the result | |
guard status == errSecItemNotFound || status == errSecSuccess else { | |
throw Error.otherError(status) | |
} | |
guard status != errSecItemNotFound else { | |
return [] | |
} | |
let array = extractedData as! CFArray | |
let dictionaries: [[String: Any]] = array.toSwiftArray() | |
let pairs = dictionaries.compactMap { $0.accountPasswordPair } | |
return pairs | |
} | |
func get(service: String, label: String) throws -> [(account: String, password: Data)] { | |
var query = createQuery(for: serive) | |
query[kSecAttrLabel as String] = label | |
var extractedData: AnyObject? | |
let status = SecItemCopyMatching(query as CFDictionary, &extractedData) | |
guard status == errSecItemNotFound || status == errSecSuccess else { | |
throw Error.otherError(status) | |
} | |
guard status != errSecItemNotFound else { | |
return [] | |
} | |
let array = extractedData as! CFArray | |
let dictionaries: [[String: Any]] = array.toSwiftArray() | |
let pairs = dictionaries.compactMap { $0.accountPasswordPair } | |
return pairs | |
} | |
// MARK: - Helper extensions to extract data from CFArray and Dictionaries | |
extension CFArray { | |
func toSwiftArray<T>() -> [T] { | |
let array = Array<AnyObject>(_immutableCocoaArray: self) | |
return array.compactMap { $0 as? T } | |
} | |
} | |
extension Dictionary where Key == String, Value == Any { | |
var accountPasswordPair: (account: String, password: Data)? { | |
guard | |
let account = self[kSecAttrAccount as String] as? String, | |
let password = self[kSecValueData as String] as? Data | |
else { | |
return nil | |
} | |
return (account, password) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment