
主要变更: 1. 移除不必要的模块导入,简化 AppDelegate 中的代码结构。 2. 引入新的 EPConfigManager 和 EPNIMManager,统一配置管理和 NIMSDK 初始化逻辑。 3. 更新相关方法以使用 block 回调,提升代码的可读性和维护性。 4. 新增 EPClientAPIBridge 和相关配置文件,增强项目的模块化。 此更新旨在提升代码的可维护性,减少冗余实现,确保配置管理的一致性。
134 lines
4.2 KiB
Swift
134 lines
4.2 KiB
Swift
//
|
||
// EPConfigManager.swift
|
||
// YuMi
|
||
//
|
||
// Cold boot configuration manager for client/init and client/config flows
|
||
//
|
||
|
||
import Foundation
|
||
|
||
@objc final class EPConfigManager: NSObject {
|
||
@objc static let shared = EPConfigManager()
|
||
|
||
// MARK: - State
|
||
@objc private(set) var isInitReady: Bool = false
|
||
@objc private(set) var isConfigReady: Bool = false
|
||
@objc private(set) var isUsingPersistedInit: Bool = false
|
||
|
||
// 原始数据(向后兼容)
|
||
@objc private(set) var initModelRaw: [String: Any]? = nil
|
||
@objc private(set) var configModelRaw: [String: Any]? = nil
|
||
|
||
// 强类型模型
|
||
@objc private(set) var clientDataModel: ClientDataModel? = nil
|
||
|
||
private var hasStarted = false
|
||
|
||
// 回调闭包
|
||
private var successCallback: (() -> Void)?
|
||
private var failureCallback: ((String) -> Void)?
|
||
|
||
// MARK: - Public API
|
||
@objc(startColdBootWithOnSuccess:onFailure:)
|
||
func startColdBoot(
|
||
onSuccess: @escaping () -> Void,
|
||
onFailure: @escaping (String) -> Void
|
||
) {
|
||
guard !hasStarted else {
|
||
// 如果已经启动过,根据当前状态直接回调
|
||
if isInitReady && isConfigReady {
|
||
onSuccess()
|
||
} else if !isInitReady {
|
||
onFailure("配置初始化失败")
|
||
}
|
||
return
|
||
}
|
||
hasStarted = true
|
||
|
||
// 保存回调
|
||
self.successCallback = onSuccess
|
||
self.failureCallback = onFailure
|
||
|
||
runClientInitWithRetry(maxRetry: 5, interval: 1.0)
|
||
}
|
||
|
||
// MARK: - Flow
|
||
private func runClientInitWithRetry(maxRetry: Int, interval: TimeInterval) {
|
||
attemptClientInit(remaining: maxRetry, interval: interval)
|
||
}
|
||
|
||
private func attemptClientInit(remaining: Int, interval: TimeInterval) {
|
||
EPConfigAPI.clientInit { [weak self] data, code, msg in
|
||
guard let self = self else { return }
|
||
if code == 200, let dict = data {
|
||
self.onInitSuccess(dict)
|
||
self.runClientConfig()
|
||
} else if remaining > 0 {
|
||
DispatchQueue.main.asyncAfter(deadline: .now() + interval) {
|
||
self.attemptClientInit(remaining: remaining - 1, interval: interval)
|
||
}
|
||
} else {
|
||
self.onInitExhausted()
|
||
}
|
||
}
|
||
}
|
||
|
||
private func onInitSuccess(_ dict: [String: Any]) {
|
||
// 1. 转换为强类型模型
|
||
let model = ClientDataModel.model(withJSON: dict)
|
||
self.clientDataModel = model
|
||
|
||
// 2. 更新 ClientConfig(保持现有代码兼容)
|
||
ClientConfig.share().configInfo = model
|
||
|
||
// 3. 持久化原始字典(避免模型变更时数据失效)
|
||
_ = EPConfigStorage.saveInit(dict)
|
||
|
||
// 4. 更新状态
|
||
isUsingPersistedInit = false
|
||
initModelRaw = dict
|
||
isInitReady = true
|
||
|
||
// 5. 继续执行 client/config
|
||
runClientConfig()
|
||
}
|
||
|
||
private func onInitExhausted() {
|
||
if let persistedDict = EPConfigStorage.loadInit() as? [String: Any] {
|
||
// 使用持久化数据
|
||
let model = ClientDataModel.model(withJSON: persistedDict)
|
||
self.clientDataModel = model
|
||
ClientConfig.share().configInfo = model
|
||
|
||
isUsingPersistedInit = true
|
||
initModelRaw = persistedDict
|
||
isInitReady = true
|
||
|
||
// 尝试获取最新配置
|
||
runClientConfig()
|
||
} else {
|
||
// 无持久化数据,调用失败回调
|
||
failureCallback?("网络异常,请稍后重新启动应用")
|
||
}
|
||
}
|
||
|
||
private func runClientConfig() {
|
||
EPConfigAPI.clientConfig { [weak self] data, code, msg in
|
||
guard let self = self else { return }
|
||
if code == 200 {
|
||
// client/config 成功,标记完成并调用成功回调
|
||
self.isConfigReady = true
|
||
self.successCallback?()
|
||
} else {
|
||
// client/config 失败,但 init 已成功,仍可继续
|
||
self.isConfigReady = true
|
||
self.successCallback?()
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 移除 Notification 扩展,不再需要
|
||
|
||
|