Files
openclaw/apps/ios/Sources/Gateway/KeychainStore.swift
Peter Steinberger 62bd760c0e chore(swift): enforce current formatting and lint rules (#103313)
* style: apply SwiftFormat 0.62.1 rules

Refs #103202

* ci: enforce deterministic Swift lint

Refs #103202

* refactor: keep gateway connect lint-clean

Refs #103202

* style: keep iOS typography checks warning-free

* ci: route MLX Swift changes through pre-push

* fix: preserve native i18n extraction after Swift cleanup

* refactor: keep rebased Swift surfaces lint-clean

* style: format latest Swift additions

* chore: refresh native i18n inventory

* style: keep generated Swift formatter-clean

* fix: preserve node route invalidation callbacks

* fix: keep native translation IDs stable

* fix: retain native translation identifiers

* fix: preserve translations across Swift source moves
2026-07-10 11:54:08 +01:00

46 lines
1.6 KiB
Swift

import Foundation
import OpenClawKit
import Security
enum KeychainStore {
static func loadString(service: String, account: String) -> String? {
GenericPasswordKeychainStore.loadString(service: service, account: account)
}
static func saveString(_ value: String, service: String, account: String) -> Bool {
GenericPasswordKeychainStore.saveString(value, service: service, account: account)
}
static func delete(service: String, account: String) -> Bool {
GenericPasswordKeychainStore.delete(service: service, account: account)
}
static func deleteAll(service: String) -> Bool {
GenericPasswordKeychainStore.deleteAll(service: service)
}
static func deleteAccounts(service: String, accountPrefix: String) -> Bool {
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrService as String: service,
kSecReturnAttributes as String: true,
kSecMatchLimit as String: kSecMatchLimitAll,
]
var item: CFTypeRef?
let status = SecItemCopyMatching(query as CFDictionary, &item)
if status == errSecItemNotFound {
return true
}
guard status == errSecSuccess else { return false }
let matches = item as? [[String: Any]] ?? []
let accounts = matches
.compactMap { $0[kSecAttrAccount as String] as? String }
.filter { $0.hasPrefix(accountPrefix) }
var deletedAll = true
for account in accounts where !self.delete(service: service, account: account) {
deletedAll = false
}
return deletedAll
}
}