Skip to content

Instantly share code, notes, and snippets.

@ricardopereira
Created September 24, 2020 16:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ricardopereira/18e81d84ba0924832fb6c54c6bff4dbd to your computer and use it in GitHub Desktop.
Save ricardopereira/18e81d84ba0924832fb6c54c6bff4dbd to your computer and use it in GitHub Desktop.
//
// 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