Files
Yuvomi-App/ios/Sources/NativeSessionVault.swift
T
Yuvomi Mobile Contributors 97570b7fdf feat(ios): replace embedded website with initial native SwiftUI API client
Introduce real SwiftUI auth/dashboard/task/note/shopping screens, a bounded origin-bound URLSession transport and Keychain-backed native sessions. Archive the rejected WebKit renderer rather than embedding it for unfinished modules. Sixteen portable URL/contract/transport tests and Swift format/parsing pass on Linux; Apple SDK application and UI validation remains mandatory. This is an incomplete native slice, not full PWA parity or a release.
2026-10-21 08:57:31 +02:00

41 lines
1.6 KiB
Swift

import Foundation
import Security
/// Native cookies, separate from WebKit and scoped to one configured origin.
struct NativeSessionVault: Sendable {
let origin: String
private var query: [String: Any] {
[
kSecClass as String: kSecClassGenericPassword,
kSecAttrService as String: "community.yuvomi.mobile.native-session",
kSecAttrAccount as String: origin,
]
}
func load() -> Data? {
var request = query
request[kSecReturnData as String] = true
request[kSecMatchLimit as String] = kSecMatchLimitOne
var result: CFTypeRef?
guard SecItemCopyMatching(request as CFDictionary, &result) == errSecSuccess else { return nil }
return result as? Data
}
func save(_ data: Data) throws {
let attributes: [String: Any] = [
kSecValueData as String: data,
kSecAttrAccessible as String: kSecAttrAccessibleWhenUnlockedThisDeviceOnly,
]
let status = SecItemUpdate(query as CFDictionary, attributes as CFDictionary)
if status == errSecItemNotFound {
var request = query
for (key, value) in attributes { request[key] = value }
guard SecItemAdd(request as CFDictionary, nil) == errSecSuccess else { throw NativeAPIError.unavailable }
} else if status != errSecSuccess {
throw NativeAPIError.unavailable
}
}
func clear() throws {
let status = SecItemDelete(query as CFDictionary)
guard status == errSecSuccess || status == errSecItemNotFound else { throw NativeAPIError.unavailable }
}
}