This commit is contained in:
JinJiangHuang
2026-03-01 20:34:43 +08:00
parent 3f302f83b3
commit 54de47deb1
10 changed files with 487 additions and 211 deletions
+90 -54
View File
@@ -13,6 +13,7 @@ class ApiConfig: ObservableObject {
@Published var dohList: [(name: String, url: String)] = []
@Published var isLoaded: Bool = false
@Published var configUrl: String = ""
@Published var liveConfigUrl: String = ""
@Published var wallpaper: String = ""
private let network = NetworkManager.shared
@@ -21,8 +22,36 @@ class ApiConfig: ObservableObject {
///
func loadConfig(from apiUrl: String) async throws {
self.configUrl = apiUrl
try await loadConfigs(vodApiUrl: apiUrl, liveApiUrl: apiUrl)
}
///
func loadConfigs(vodApiUrl: String, liveApiUrl: String) async throws {
let trimmedVod = vodApiUrl.trimmingCharacters(in: .whitespacesAndNewlines)
let trimmedLive = liveApiUrl.trimmingCharacters(in: .whitespacesAndNewlines)
guard !trimmedVod.isEmpty else {
throw ConfigError.parseError("点播接口地址不能为空")
}
let resolvedLive = trimmedLive.isEmpty ? trimmedVod : trimmedLive
self.configUrl = trimmedVod
self.liveConfigUrl = resolvedLive
if trimmedVod == resolvedLive {
let config = try await fetchConfig(from: trimmedVod)
parseConfig(config, apiUrl: trimmedVod, includeSources: true, includeLive: true)
} else {
let vodConfig = try await fetchConfig(from: trimmedVod)
parseConfig(vodConfig, apiUrl: trimmedVod, includeSources: true, includeLive: false)
let liveConfig = try await fetchConfig(from: resolvedLive)
parseConfig(liveConfig, apiUrl: resolvedLive, includeSources: false, includeLive: true)
}
self.isLoaded = true
}
private func fetchConfig(from apiUrl: String) async throws -> AppConfigData {
let jsonStr = try await network.getString(from: apiUrl)
// JSONAndroid Gson Swift
@@ -32,8 +61,7 @@ class ApiConfig: ObservableObject {
throw ConfigError.parseError("无法解析配置数据")
}
let config = try JSONDecoder().decode(AppConfigData.self, from: data)
parseConfig(config, apiUrl: apiUrl)
return try JSONDecoder().decode(AppConfigData.self, from: data)
}
/// JSON // TVBox
@@ -97,59 +125,67 @@ class ApiConfig: ObservableObject {
}
///
private func parseConfig(_ config: AppConfigData, apiUrl: String) {
//
var sources: [SourceBean] = []
if let sites = config.sites {
for site in sites {
let bean = SourceBean(
key: site.key ?? UUID().uuidString,
name: site.name ?? "未命名",
api: site.api ?? "",
searchable: site.searchable?.value ?? 1,
filterable: site.filterable?.value ?? 1,
playerType: site.playerType?.value ?? 0,
type: site.type?.value ?? 1,
ext: site.ext?.stringValue
)
sources.append(bean)
private func parseConfig(
_ config: AppConfigData,
apiUrl: String,
includeSources: Bool,
includeLive: Bool
) {
if includeSources {
//
var sources: [SourceBean] = []
if let sites = config.sites {
for site in sites {
let bean = SourceBean(
key: site.key ?? UUID().uuidString,
name: site.name ?? "未命名",
api: site.api ?? "",
searchable: site.searchable?.value ?? 1,
filterable: site.filterable?.value ?? 1,
playerType: site.playerType?.value ?? 0,
type: site.type?.value ?? 1,
ext: site.ext?.stringValue
)
sources.append(bean)
}
}
self.sourceBeanList = sources
// Swift
if let saved = UserDefaults.standard.string(forKey: HawkConfig.HOME_API),
let found = sources.first(where: { $0.key == saved }) {
self.homeSourceBean = found
} else {
// type 0/1/4 type=3 (JAR)
self.homeSourceBean = sources.first(where: { $0.isSupportedInSwift }) ?? sources.first
}
//
if let parses = config.parses {
self.parseBeanList = parses.map { p in
ParseBean(name: p.name ?? "", url: p.url ?? "", type: p.type?.value ?? 0)
}
}
// DoH
if let dohs = config.doh {
self.dohList = dohs.compactMap { d in
guard let name = d.name, let url = d.url else { return nil }
return (name: name, url: url)
}
}
//
self.wallpaper = config.wallpaper ?? ""
}
if includeLive {
if let lives = config.lives {
parseLives(lives, apiUrl: apiUrl)
} else {
liveChannelGroupList = []
}
}
self.sourceBeanList = sources
// Swift
if let saved = UserDefaults.standard.string(forKey: HawkConfig.HOME_API),
let found = sources.first(where: { $0.key == saved }) {
self.homeSourceBean = found
} else {
// type 0/1/4 type=3 (JAR)
self.homeSourceBean = sources.first(where: { $0.isSupportedInSwift }) ?? sources.first
}
//
if let parses = config.parses {
self.parseBeanList = parses.map { p in
ParseBean(name: p.name ?? "", url: p.url ?? "", type: p.type?.value ?? 0)
}
}
// DoH
if let dohs = config.doh {
self.dohList = dohs.compactMap { d in
guard let name = d.name, let url = d.url else { return nil }
return (name: name, url: url)
}
}
//
self.wallpaper = config.wallpaper ?? ""
//
if let lives = config.lives {
parseLives(lives, apiUrl: apiUrl)
}
self.isLoaded = true
}
///