Created
September 24, 2020 16:48
-
-
Save ricardopereira/18e81d84ba0924832fb6c54c6bff4dbd to your computer and use it in GitHub Desktop.
This file contains hidden or 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
// | |
// PasscodeKeychain.swift | |
// Example | |
// | |
// Created by Ricardo Pereira on 23/12/2016. | |
// Copyright © 2016 RP. All rights reserved. | |
// | |
import Foundation | |
class PasscodeKeychain { | |
let bundleIdentifier: String | |
let account: String | |
init(_ account: String, bundleIdentifier: String) { | |
self.account = account | |
self.bundleIdentifier = bundleIdentifier | |
} | |
internal func genericPasswordAttributes() -> [String : AnyObject] { | |
var attributes = [String : AnyObject]() | |
attributes[String(kSecClass)] = kSecClassGenericPassword | |
// Item data can only be accessed while the device is unlocked. | |
attributes[String(kSecAttrAccessible)] = String(kSecAttrAccessibleWhenUnlocked) | |
attributes[String(kSecAttrService)] = bundleIdentifier | |
attributes[String(kSecAttrAccount)] = account | |
return attributes | |
} | |
func setValue(value: String) -> Bool { | |
var attributes = genericPasswordAttributes() | |
let archivedData = NSKeyedArchiver.archivedDataWithRootObject(value) | |
attributes[String(kSecValueData)] = archivedData | |
var statusCode = SecItemAdd(attributes, nil) | |
if statusCode == errSecDuplicateItem { | |
SecItemDelete(attributes) | |
statusCode = SecItemAdd(attributes, nil) | |
} | |
if statusCode != errSecSuccess { | |
return false | |
} | |
return true | |
} | |
func removeValue() -> Bool { | |
let attributes = genericPasswordAttributes() | |
let statusCode = SecItemDelete(attributes) | |
if statusCode != errSecSuccess { | |
return false | |
} | |
return true | |
} | |
func getValue() -> String? { | |
var attributes = genericPasswordAttributes() | |
attributes[String(kSecReturnData)] = true | |
attributes[String(kSecReturnAttributes)] = true | |
var match: AnyObject? | |
let statusCode = withUnsafeMutablePointer(&match) { pointer in | |
SecItemCopyMatching(attributes, UnsafeMutablePointer(pointer)) | |
} | |
if statusCode != errSecSuccess { | |
return nil | |
} | |
guard let result = match as? [String : AnyObject] else { | |
return nil | |
} | |
guard let valueData = result[String(kSecValueData)] as? NSData else { | |
return nil | |
} | |
return NSKeyedUnarchiver.unarchiveObjectWithData(valueData) as? String ?? nil | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment