Created
December 18, 2014 20:22
-
-
Save fwhenin/51190216c821e0d40cc2 to your computer and use it in GitHub Desktop.
iOS Keychain Wrapper
This file contains 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
// | |
// 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