Created
April 19, 2016 22:17
-
-
Save joshavant/88c5ba4364d0d7161b63f30e953ec289 to your computer and use it in GitHub Desktop.
Swifty Keychain Abstraction
This file contains hidden or 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
protocol KeychainCoding { | |
init?(keychain: KeychainPersistable, identifier: KeychainPersistableIdentifer) | |
func encodeToKeychain(keychain: KeychainPersistable, identifier: KeychainPersistableIdentifer) throws | |
} | |
extension KeychainCoding where Self: NSCoding, Self: InstanceInitializable { | |
init?(keychain: KeychainPersistable, identifier: KeychainPersistableIdentifer) { | |
do { | |
if let data = try keychain.get(identifier) { | |
let unarchivedInstance = NSKeyedUnarchiver.unarchiveObjectWithData(data) as! Self | |
self.init(instance: unarchivedInstance) | |
} else { | |
return nil | |
} | |
} catch { | |
return nil | |
} | |
} | |
func encodeToKeychain(keychain: KeychainPersistable, identifier: KeychainPersistableIdentifer) throws { | |
let data = NSKeyedArchiver.archivedDataWithRootObject(self) | |
try keychain.set(data, identifier: identifier) | |
} | |
} |
This file contains hidden or 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
import Foundation | |
import KeychainAccess | |
typealias KeychainPersistableIdentifer = String | |
protocol KeychainPersistable { | |
func set(value: NSData, identifier: KeychainPersistableIdentifer) throws | |
func get(identifier: KeychainPersistableIdentifer) throws -> NSData? | |
} | |
struct KeychainService: KeychainPersistable { | |
private let keychain: Keychain | |
init(accessGroupIdentifier identifier: String) { | |
keychain = Keychain(accessGroup: identifier) | |
} | |
// MARK: - KeychainPersistable | |
func set(value: NSData, identifier: KeychainPersistableIdentifer) throws { | |
try keychain.set(value, key: identifier) | |
} | |
func get(identifier: KeychainPersistableIdentifer) throws -> NSData? { | |
return try keychain.getData(identifier) | |
} | |
} |
This file contains hidden or 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
let keychain: KeychainPersistable = KeychainService(accessGroupIdentifier: "main") | |
let UserSessionCredentialsKeychainIdentifier = "CredentialsKeychainIdentifier" | |
// persist | |
let credentials = UserSessionCredentials(token: "123", userId: 123, expires: NSDate.distantFuture()) | |
try! credentials.encodeToKeychain(keychain, identifier: UserSessionCredentialsKeychainIdentifier) | |
// fetch | |
let keychainCredentials: UserSessionCredentials? = UserSessionCredentials(keychain: keychain, identifier: UserSessionCredentialsKeychainIdentifier) |
This file contains hidden or 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
class UserSessionCredentials: NSObject, NSCoding, KeychainCoding, InstanceInitializable { | |
let token: String | |
let userId: Int | |
let expires: NSDate | |
private struct PropertyKey { | |
static let tokenKey = "token" | |
static let userIdKey = "userId" | |
static let expiresKey = "expires" | |
} | |
init(token: String, userId: Int, expires: NSDate) { | |
self.token = token | |
self.userId = userId | |
self.expires = expires | |
} | |
// MARK: - NSCoding | |
func encodeWithCoder(aCoder: NSCoder) { | |
aCoder.encodeObject(self.token, forKey: PropertyKey.tokenKey) | |
aCoder.encodeInteger(self.userId, forKey: PropertyKey.userIdKey) | |
aCoder.encodeObject(self.expires, forKey: PropertyKey.expiresKey) | |
} | |
required convenience init?(coder aDecoder: NSCoder) { | |
let token = aDecoder.decodeObjectForKey(PropertyKey.tokenKey) as! String | |
let userId = aDecoder.decodeIntegerForKey(PropertyKey.userIdKey) | |
let expires = aDecoder.decodeObjectForKey(PropertyKey.expiresKey) as! NSDate | |
self.init(token: token, userId: userId, expires: expires) | |
} | |
// MARK: - InstanceInitializable | |
required convenience init(instance: UserSessionCredentials) { | |
self.init(token: instance.token, | |
userId: instance.userId, | |
expires: instance.expires) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment