Skip to content

Instantly share code, notes, and snippets.

@acrookston
Last active March 20, 2016 18:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save acrookston/21d9b0bb4ab5ef0e10f8 to your computer and use it in GitHub Desktop.
Save acrookston/21d9b0bb4ab5ef0e10f8 to your computer and use it in GitHub Desktop.
Keychain struct for Locksmith using accessible option.
SecureKeyValue.loadDataForKey("key", inAccessGroup: nil)
do {
try SecureKeyValue.updateData(object, forKey: "key")
} catch {
print("ERROR: Keychain error: \(error)")
}
do {
try SecureKeyValue.deleteDataForKey("key")
} catch {
print("ERROR: Keychain delete \("key") failed, value might not exist.")
}
//
// SecureKeyValue.swift
//
// Created by Andrew Crookston <andrew@caoos.com> on 1/5/16.
// Copyright © 2016. License: MIT.
//
import Foundation
import Locksmith
// This is a modified version of the Locksmith struct.
struct SecureKeyValue {
private static let KeychainObjectKey = "object"
static func loadDataForKey(key: String) -> AnyObject? {
return loadDataForKey(key, inAccessGroup: nil)
}
static func saveData(data: AnyObject, forKey key: String) throws {
return try saveData(data, forKey: key, inAccessGroup: nil)
}
static func deleteDataForKey(key: String) throws {
try deleteDataForKey(key, inAppGroup: nil)
}
static func loadDataForKey(key: String, inAccessGroup group: String? = nil) -> AnyObject? {
struct ReadRequest: SecureStorable, GenericPasswordSecureStorable, ReadableSecureStorable {
let service = LocksmithDefaultService
let accessible = LocksmithAccessibleOption.AfterFirstUnlock
let account: String
let accessGroup : String?
}
let request = ReadRequest(account: key, accessGroup: group)
if let data = request.readFromSecureStore()?.data {
return data[KeychainObjectKey]
} else {
print("Key \(key) not found")
}
return nil
}
static func saveData(data: AnyObject, forKey key: String, inAccessGroup group: String?) throws {
struct CreateRequest: SecureStorable, GenericPasswordSecureStorable, CreateableSecureStorable {
let service = LocksmithDefaultService
let accessible = LocksmithAccessibleOption.AfterFirstUnlock
let account: String
let data: Hash
let accessGroup : String?
}
let request = CreateRequest(account: key, data: [KeychainObjectKey: data], accessGroup: group)
return try request.createInSecureStore()
}
static func deleteDataForKey(key: String, inAppGroup group: String?) throws {
struct DeleteRequest: SecureStorable, GenericPasswordSecureStorable, DeleteableSecureStorable {
let service = LocksmithDefaultService
let accessible = LocksmithAccessibleOption.AfterFirstUnlock
let account: String
let accessGroup : String?
}
let request = DeleteRequest(account: key, accessGroup: group)
return try request.deleteFromSecureStore()
}
static func updateData(data: AnyObject, forKey key: String) throws {
// Delete and then re-save
do {
try SecureKeyValue.deleteDataForKey(key)
} catch {
// Deletion is likely to fail if the piece of data doesn't exist yet.
// This doesn't matter--we only tell the user about errors on the save request.
}
return try SecureKeyValue.saveData(data, forKey: key)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment