Skip to content

Instantly share code, notes, and snippets.

@PGMY
Forked from s-aska/Keychain.swift
Created October 28, 2015 02:11
Show Gist options
  • Save PGMY/0f2203b4b831cdddb8c6 to your computer and use it in GitHub Desktop.
Save PGMY/0f2203b4b831cdddb8c6 to your computer and use it in GitHub Desktop.
Swift Keychain class ( supported Xcode 6.0.1 )
import UIKit
import Security
class Keychain {
class func save(key: String, data: NSData) -> Bool {
let query = [
kSecClass as String : kSecClassGenericPassword as String,
kSecAttrAccount as String : key,
kSecValueData as String : data ]
SecItemDelete(query as CFDictionaryRef)
let status: OSStatus = SecItemAdd(query as CFDictionaryRef, nil)
return status == noErr
}
class func load(key: String) -> NSData? {
let query = [
kSecClass as String : kSecClassGenericPassword,
kSecAttrAccount as String : key,
kSecReturnData as String : kCFBooleanTrue,
kSecMatchLimit as String : 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 = [
kSecClass as String : kSecClassGenericPassword,
kSecAttrAccount as String : key ]
let status: OSStatus = SecItemDelete(query as CFDictionaryRef)
return status == noErr
}
class func clear() -> Bool {
let query = [ kSecClass as String : 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