Skip to content

Instantly share code, notes, and snippets.

@fwhenin
Created December 18, 2014 20:22
Show Gist options
  • Save fwhenin/51190216c821e0d40cc2 to your computer and use it in GitHub Desktop.
Save fwhenin/51190216c821e0d40cc2 to your computer and use it in GitHub Desktop.
iOS Keychain Wrapper
//
// KeychainService.swift
// DMS
//
// Created by Freddy on 10/30/14.
// Copyright (c) 2014 DMSCompany. All rights reserved.
//
import UIKit
import Security
let userAccount = "authenticatedUser"
//-------------------------------------------------------------------------------------------
// MARK: - Arguments for the keychain queries
//-------------------------------------------------------------------------------------------
let kSecClassValue = kSecClass as NSString
let kSecAttrAccountValue = kSecAttrAccount as NSString
let kSecValueDataValue = kSecValueData as NSString
let kSecClassGenericPasswordValue = kSecClassGenericPassword as NSString
let kSecAttrServiceValue = kSecAttrService as NSString
let kSecMatchLimitValue = kSecMatchLimit as NSString
let kSecReturnDataValue = kSecReturnData as NSString
let kSecMatchLimitOneValue = kSecMatchLimitOne as NSString
class KeychainService {
/**
* Exposed methods to perform queries.
* Note: feel free to play around with the arguments
* for these if you want to be able to customise the
* service identifier, user accounts, access groups, etc.
*/
internal class func saveValueForIdentifier(key: KeychainIdentifier, value: NSString) {
self.save(key.rawValue, data: value)
if (value == "" && key == .Token){
saveValueForIdentifier(.Expiration, value: "");
}
}
internal class func loadValue(key: KeychainIdentifier) -> NSString? {
var token = self.load(key.rawValue)
return token
}
internal class func clearKeychain(){
}
/**
* Internal methods for querying the keychain.
*/
private class func save(service: String, data: String) {
var dataFromString: NSData = data.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
// Instantiate a new default keychain query
var keychainQuery: NSMutableDictionary = NSMutableDictionary(objects: [kSecClassGenericPasswordValue, service, userAccount, dataFromString], forKeys: [kSecClassValue, kSecAttrServiceValue, kSecAttrAccountValue, kSecValueDataValue])
// Delete any existing items
SecItemDelete(keychainQuery as CFDictionaryRef)
// Add the new keychain item
var status: OSStatus = SecItemAdd(keychainQuery as CFDictionaryRef, nil)
}
private class func load(service: String) -> String? {
// Instantiate a new default keychain query
// Tell the query to return a result
// Limit our results to one item
var keychainQuery: NSMutableDictionary = NSMutableDictionary(objects: [kSecClassGenericPasswordValue, service, userAccount, kCFBooleanTrue, kSecMatchLimitOneValue], forKeys: [kSecClassValue, kSecAttrServiceValue, kSecAttrAccountValue, kSecReturnDataValue, kSecMatchLimitValue])
var dataTypeRef :Unmanaged<AnyObject>?
// Search for the keychain items
let status: OSStatus = SecItemCopyMatching(keychainQuery, &dataTypeRef)
let opaque = dataTypeRef?.toOpaque()
var contentsOfKeychain: String?
if let op = opaque? {
let retrievedData = Unmanaged<NSData>.fromOpaque(op).takeUnretainedValue()
// Convert the data retrieved from the keychain into a string
contentsOfKeychain = NSString(data: retrievedData, encoding: NSUTF8StringEncoding)
} else {
DDLogWrapper.logError("Nothing was retrieved from the keychain. Status code \(status)")
return "";
}
return contentsOfKeychain
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment