Skip to content

Instantly share code, notes, and snippets.

@ffried
Forked from s-aska/Keychain.swift
Last active July 1, 2017 09:55
Show Gist options
  • Save ffried/2d6b0b8cefa53a1cdddf to your computer and use it in GitHub Desktop.
Save ffried/2d6b0b8cefa53a1cdddf to your computer and use it in GitHub Desktop.
import UIKit
import Security
class Keychain {
class func save(key: String, data: NSData) -> Bool {
let query: [String: AnyObject] = [
kSecClass : kSecClassGenericPassword,
kSecAttrAccount : key,
kSecValueData : data ]
SecItemDelete(query as CFDictionaryRef)
let status: OSStatus = SecItemAdd(query as CFDictionaryRef, nil)
return status == noErr
}
class func load(key: String) -> NSData? {
let query: [String: AnyObject] = [
kSecClass : kSecClassGenericPassword,
kSecAttrAccount : key,
kSecReturnData : kCFBooleanTrue,
kSecMatchLimit : kSecMatchLimitOne ]
var dataTypeRef :Unmanaged<AnyObject>?
let status: OSStatus = SecItemCopyMatching(query, &dataTypeRef)
if status == noErr {
return (dataTypeRef!.takeRetainedValue() as NSData)
} else {
return nil
}
}
class func delete(key: String) -> Bool {
let query: [String: AnyObject] = [
kSecClass : kSecClassGenericPassword,
kSecAttrAccount : key ]
let status: OSStatus = SecItemDelete(query as CFDictionaryRef)
return status == noErr
}
class func clear() -> Bool {
let query: [String: AnyObject] = [ kSecClass : kSecClassGenericPassword ]
let status: OSStatus = SecItemDelete(query as CFDictionaryRef)
return status == noErr
}
}
import UIKit
import XCTest
class KeychainTests: XCTestCase {
override func setUp() {
super.setUp()
Keychain.clear()
}
override func tearDown() {
Keychain.clear()
super.tearDown()
}
func testSaveLoad() {
let key1 = "testSaveLoadKey1"
let key2 = "testSaveLoadKey2"
let saveData = "data".dataValue
XCTAssertTrue(Keychain.load(key1) == nil)
XCTAssertTrue(Keychain.load(key2) == nil)
XCTAssertTrue(Keychain.save(key1, data: saveData))
XCTAssertTrue(Keychain.load(key1) != nil)
XCTAssertTrue(Keychain.load(key2) == nil)
let loadData = Keychain.load(key1)!
XCTAssertEqual(loadData.stringValue, saveData.stringValue)
}
func testDelete() {
let key1 = "testDeleteKey1"
let key2 = "testDeleteKey2"
let saveData = "testDeleteData".dataValue
XCTAssertTrue(Keychain.save(key1, data: saveData))
XCTAssertTrue(Keychain.save(key2, data: saveData))
XCTAssertTrue(Keychain.load(key1) != nil)
XCTAssertTrue(Keychain.load(key2) != nil)
XCTAssertTrue(Keychain.delete(key1))
XCTAssertTrue(Keychain.load(key1) == nil)
XCTAssertTrue(Keychain.load(key2) != nil)
}
func testClear() {
let key = "testClearKey"
let data = "testClearData".dataValue
Keychain.save(key, data: data)
XCTAssertTrue(Keychain.load(key) != nil)
Keychain.clear()
XCTAssertTrue(Keychain.load(key) == nil)
}
}
extension String {
public var dataValue: NSData {
return dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
}
}
extension NSData {
public var stringValue: String {
return NSString(data: self, encoding: NSUTF8StringEncoding)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment