SHA256
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.
This commit is contained in:
1 parent
11bf4ca620
commit
97570b7fdf
15 files changed
+1182
-11
No files matched your search
@@ -0,0 +1,40 @@
|
||||
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 }
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user