feat(ios): add native app foundation and unsigned ipa build

This commit is contained in:
chick
2026-09-09 00:05:51 +08:00
parent fda3e11f1e
commit 54eb8dcb86
29 changed files with 1680 additions and 0 deletions
@@ -0,0 +1,62 @@
import Foundation
public struct SessionMetadata: Equatable, Sendable {
public let instanceID: UUID
public let authenticated: Bool
public let checkedAt: Date
public init(instanceID: UUID, authenticated: Bool, checkedAt: Date) {
self.instanceID = instanceID
self.authenticated = authenticated
self.checkedAt = checkedAt
}
}
public struct InstanceSessionService: Sendable {
private let store: InstanceSessionStore
private let client: any SimAdminClientProtocol
public init(store: InstanceSessionStore, client: any SimAdminClientProtocol) {
self.store = store
self.client = client
}
public func login(_ instance: Instance, password: String) async throws -> SessionMetadata {
do {
let response = try await client.send(
.authLogin(password: password),
baseURL: instance.origin,
cookie: nil
)
if let cookie = Self.sessionCookie(response.setCookie) {
await store.set(instance.id, origin: instance.origin, cookie: cookie)
return SessionMetadata(instanceID: instance.id, authenticated: true, checkedAt: Date())
}
} catch {
// Rejected credentials fall through to the same explicit unauthenticated state.
}
await store.clear(instance.id)
return SessionMetadata(instanceID: instance.id, authenticated: false, checkedAt: Date())
}
public func logout(_ instance: Instance) async throws -> SessionMetadata {
if let cookie = await store.cookie(for: instance.id, origin: instance.origin) {
_ = try? await client.send(.authLogout, baseURL: instance.origin, cookie: cookie)
}
await store.clear(instance.id)
return SessionMetadata(instanceID: instance.id, authenticated: false, checkedAt: Date())
}
public func cookie(for instance: Instance) async -> String? {
await store.cookie(for: instance.id, origin: instance.origin)
}
static func sessionCookie(_ header: String?) -> String? {
guard let header,
let range = header.range(of: "simadmin_session=([^;\\s,]+)", options: .regularExpression)
else {
return nil
}
return String(header[range])
}
}