swift
126 lines · 1 tab
Sofia Martinez
Jan 2026
1 tab
import Foundation
import Security
enum KeychainError: Error {
case duplicateItem
case itemNotFound
case invalidData
case unexpectedStatus(OSStatus)
}
class KeychainManager {
static let shared = KeychainManager()
private init() {}
func save(_ data: Data, service: String, account: String) throws {
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrService as String: service,
kSecAttrAccount as String: account,
kSecValueData as String: data,
kSecAttrAccessible as String: kSecAttrAccessibleWhenUnlockedThisDeviceOnly
]
let status = SecItemAdd(query as CFDictionary, nil)
if status == errSecDuplicateItem {
try update(data, service: service, account: account)
} else if status != errSecSuccess {
throw KeychainError.unexpectedStatus(status)
}
}
func save(_ string: String, service: String, account: String) throws {
guard let data = string.data(using: .utf8) else {
throw KeychainError.invalidData
}
try save(data, service: service, account: account)
}
func retrieve(service: String, account: String) throws -> Data {
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrService as String: service,
kSecAttrAccount as String: account,
kSecReturnData as String: true
]
var result: AnyObject?
let status = SecItemCopyMatching(query as CFDictionary, &result)
guard status == errSecSuccess else {
if status == errSecItemNotFound {
throw KeychainError.itemNotFound
}
throw KeychainError.unexpectedStatus(status)
}
guard let data = result as? Data else {
throw KeychainError.invalidData
}
return data
}
func retrieveString(service: String, account: String) throws -> String {
let data = try retrieve(service: service, account: account)
guard let string = String(data: data, encoding: .utf8) else {
throw KeychainError.invalidData
}
return string
}
func delete(service: String, account: String) throws {
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrService as String: service,
kSecAttrAccount as String: account
]
let status = SecItemDelete(query as CFDictionary)
guard status == errSecSuccess || status == errSecItemNotFound else {
throw KeychainError.unexpectedStatus(status)
}
}
private func update(_ data: Data, service: String, account: String) throws {
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrService as String: service,
kSecAttrAccount as String: account
]
let attributes: [String: Any] = [
kSecValueData as String: data
]
let status = SecItemUpdate(query as CFDictionary, attributes as CFDictionary)
guard status == errSecSuccess else {
throw KeychainError.unexpectedStatus(status)
}
}
}
// Convenience extension for auth tokens
extension KeychainManager {
private enum Keys {
static let authToken = "authToken"
static let refreshToken = "refreshToken"
static let service = "com.myapp.auth"
}
func saveAuthToken(_ token: String) throws {
try save(token, service: Keys.service, account: Keys.authToken)
}
func getAuthToken() -> String? {
try? retrieveString(service: Keys.service, account: Keys.authToken)
}
func deleteAuthToken() {
try? delete(service: Keys.service, account: Keys.authToken)
}
}
1 file · swift
Explain with highlit
The Keychain securely stores sensitive data like passwords and tokens, encrypting them at the OS level. Direct Keychain APIs are verbose, so I create a wrapper class that simplifies common operations. The wrapper uses Security framework's SecItemAdd, SecItemCopyMatching, and SecItemDelete functions. I store strings by encoding to Data and specify kSecClassGenericPassword for credentials. Query dictionaries identify items by service and account names. The Keychain persists across app installs and backs up to iCloud Keychain. For access control, I set kSecAttrAccessible to restrict when data is available. This approach is far more secure than UserDefaults for authentication tokens.
Related snips
ruby
payload = {
sub: user.id,
iss: 'https://auth.example.com',
aud: 'codesnips-api',
exp: 15.minutes.from_now.to_i,
iat: Time.now.to_i,
JWT issuance and verification without common footguns
jwt
authentication
api
by Kai Nakamura
2 tabs
swift
import Combine
import Foundation
class SearchViewModel: ObservableObject {
@Published var searchQuery = ""
@Published var results: [SearchResult] = []
Combine operators for data transformation
swift
combine
reactive
by Sofia Martinez
1 tab
bash
#!/usr/bin/env bash
set -euo pipefail
export VAULT_ADDR="https://vault.internal:8200"
export VAULT_TOKEN="${VAULT_TOKEN:?missing VAULT_TOKEN}"
Secrets management with environment isolation and Vault
secrets-management
vault
environment-variables
by Kai Nakamura
1 tab
typescript
import { randomBytes, createHash } from "crypto";
import jwt from "jsonwebtoken";
import { RefreshTokenStore } from "./store";
const ACCESS_SECRET = process.env.ACCESS_SECRET!;
const ACCESS_TTL = "15m";
JWT access + refresh token rotation (conceptual)
security
node
jwt
by codesnips
3 tabs
swift
import SwiftUI
struct ContentView: View {
@State private var username = ""
@State private var isLoggedIn = false
@StateObject private var viewModel = LoginViewModel()
SwiftUI declarative UI with state management
swift
swiftui
ios
by Sofia Martinez
2 tabs
go
package files
import (
"context"
"time"
Presigned S3 upload URLs (AWS SDK v2)
go
aws
s3
by Leah Thompson
1 tab
Share this code
Here's the card — post it anywhere.