Skip to content

Instantly share code, notes, and snippets.

@stleamist
Last active December 12, 2022 19:28
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stleamist/5433fe5ed17271c841b74bb0d4d3b9be to your computer and use it in GitHub Desktop.
Save stleamist/5433fe5ed17271c841b74bb0d4d3b9be to your computer and use it in GitHub Desktop.
import Foundation
import KeychainAccess
@propertyWrapper
struct KeychainStorage<Value: Codable> {
let key: String
let service: String
let initialValue: Value
private let keychain: KeychainAccess.Keychain
private let encoder = JSONEncoder()
private let decoder = JSONDecoder()
init(wrappedValue initialValue: Value, _ key: String, service: String? = nil) {
self.initialValue = initialValue
self.key = key
self.service = service ?? Bundle.main.bundleIdentifier ?? "com.kishikawakatsumi.KeychainAccess"
self.keychain = KeychainAccess.Keychain(service: self.service)
}
var wrappedValue: Value {
get {
guard let data = try? keychain.getData(key),
let value = try? decoder.decode(Value.self, from: data) else {
return initialValue
}
return value
}
set {
guard let newData = try? encoder.encode(newValue) else {
return
}
try? keychain.set(newData, key: key)
}
}
}
@mromanuk
Copy link

mromanuk commented Dec 12, 2022

Adapted to optional data:

@propertyWrapper
struct KeychainStorage<Value: Codable> {
	
	let key: String
	
	private let keychain: Keychain
	private let encoder = JSONEncoder()
	private let decoder = JSONDecoder()
	
	
	init(wrappedValue initialValue: Value? = nil, _ key: String, service: String? = nil) {
		self.key = key
		self.keychain = Keychain(service: service)
	}
	
	var wrappedValue: Value? {
		get {
			do {
				guard let data = try? keychain.getData(key) else {
					return nil
				}

				let value = try decoder.decode(Value.self, from: data)
				
				return value
			} catch {
				print(error)
			}
			
			return nil
		}
		
		set {
			guard let newData = try? encoder.encode(newValue) else {
				return
			}
			do {
				try keychain.set(newData, key: key)
			} catch {
				print(error)
			}
		}
	}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment