// // SplashCoordinator.swift // suixinkan // // Created by Codex on 2026/6/29. // import Combine import Foundation @MainActor /// 启动页时序协调器,并行执行冷启动 bootstrap,Splash 结束时机以 bootstrap 完成为准。 final class SplashCoordinator: ObservableObject { @Published private(set) var isFinished = false private let minimumDisplayDuration: TimeInterval private let skipsMinimumDuration: Bool /// 创建启动页协调器;默认无最短展示时长,测试可注入自定义 delay。 init( minimumDisplayDuration: TimeInterval = 0, 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) } }