新增 SplashView、SplashCoordinator 与 Launch Screen 资源,移除冷启动 Lottie;LoginView 加载 App 配置。同时将 token 存储迁移至 UserDefaults,并更新相关测试与文档。 Co-authored-by: Cursor <cursoragent@cursor.com>
46 lines
1.5 KiB
Swift
46 lines
1.5 KiB
Swift
//
|
||
// SplashCoordinator.swift
|
||
// suixinkan
|
||
//
|
||
// Created by Codex on 2026/6/29.
|
||
//
|
||
|
||
import Combine
|
||
import Foundation
|
||
|
||
@MainActor
|
||
/// 启动页时序协调器,保证品牌页最短展示时长与冷启动 bootstrap 并行完成。
|
||
final class SplashCoordinator: ObservableObject {
|
||
@Published private(set) var isFinished = false
|
||
|
||
private let minimumDisplayDuration: TimeInterval
|
||
private let skipsMinimumDuration: Bool
|
||
|
||
/// 创建启动页协调器,并配置最短展示时长与 UI Test 跳过策略。
|
||
init(
|
||
minimumDisplayDuration: TimeInterval = 1.5,
|
||
skipsMinimumDuration: Bool = AppUITestLaunchState.isRunningUITests
|
||
) {
|
||
self.minimumDisplayDuration = minimumDisplayDuration
|
||
self.skipsMinimumDuration = skipsMinimumDuration
|
||
}
|
||
|
||
/// 并行执行 bootstrap 与最短展示时长,两者都完成后结束 Splash。
|
||
func start(bootstrap: @escaping () async -> Void) async {
|
||
guard !isFinished else { return }
|
||
|
||
async let minimumDelay: Void = waitForMinimumDisplayDuration()
|
||
async let bootstrapWork: Void = bootstrap()
|
||
|
||
_ = await (minimumDelay, bootstrapWork)
|
||
isFinished = true
|
||
}
|
||
|
||
/// 等待最短展示时长;UI Test 模式下直接返回。
|
||
private func waitForMinimumDisplayDuration() async {
|
||
guard !skipsMinimumDuration else { return }
|
||
let nanoseconds = UInt64(max(minimumDisplayDuration, 0) * 1_000_000_000)
|
||
try? await Task.sleep(nanoseconds: nanoseconds)
|
||
}
|
||
}
|