Advance UIKit rewrite with AMap integration and core UI modules.

Integrate高德 SDK with simulator-safe build flags, add map views for operating area and punch points, refactor main tabs and key feature screens to UIKit with Diffable lists, and document Swift concurrency defaults in AGENTS.md.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-26 15:16:12 +08:00
parent 9edf993432
commit d99a5b1bf8
124 changed files with 5195 additions and 1536 deletions

View File

@ -14,6 +14,7 @@ struct LiveListResponse: Decodable {
let page: Int
let pageSize: Int
///
enum CodingKeys: String, CodingKey {
case items
case total
@ -21,6 +22,7 @@ struct LiveListResponse: Decodable {
case pageSize = "page_size"
}
///
init(items: [LiveEntity] = [], total: Int = 0, page: Int = 1, pageSize: Int = 10) {
self.items = items
self.total = total
@ -28,6 +30,7 @@ struct LiveListResponse: Decodable {
self.pageSize = pageSize
}
///
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
items = (try? container.decode([LiveEntity].self, forKey: .items)) ?? []
@ -57,6 +60,7 @@ struct LiveEntity: Decodable, Identifiable, Equatable {
let manualPushState: Int
let viewsCount: Int
///
enum CodingKeys: String, CodingKey {
case id
case title
@ -77,6 +81,7 @@ struct LiveEntity: Decodable, Identifiable, Equatable {
case viewsCount = "views_count"
}
///
init(
id: Int = 0,
title: String = "",
@ -115,6 +120,7 @@ struct LiveEntity: Decodable, Identifiable, Equatable {
self.viewsCount = viewsCount
}
///
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
id = try container.liveDecodeLossyInt(forKey: .id) ?? 0
@ -151,6 +157,7 @@ struct LiveCreateRequest: Encodable, Equatable {
let title: String
let coverImg: String
///
enum CodingKeys: String, CodingKey {
case scenicId = "scenic_id"
case title
@ -162,6 +169,7 @@ struct LiveCreateRequest: Encodable, Equatable {
struct LiveControlRequest: Encodable, Equatable {
let liveId: Int
///
enum CodingKeys: String, CodingKey {
case liveId = "live_id"
}
@ -172,6 +180,7 @@ struct LivePushModeRequest: Encodable, Equatable {
let liveId: Int
let manualPushMode: Int
///
enum CodingKeys: String, CodingKey {
case liveId = "live_id"
case manualPushMode = "manual_push_mode"
@ -186,6 +195,7 @@ struct LiveAlbumFolderListResponse: Decodable {
let total: Int
let totalPages: Int
///
enum CodingKeys: String, CodingKey {
case items
case page
@ -194,6 +204,7 @@ struct LiveAlbumFolderListResponse: Decodable {
case totalPages = "total_pages"
}
///
init(items: [LiveAlbumFolderItem] = [], page: Int = 1, pageSize: Int = 10, total: Int = 0, totalPages: Int = 0) {
self.items = items
self.page = page
@ -202,6 +213,7 @@ struct LiveAlbumFolderListResponse: Decodable {
self.totalPages = totalPages
}
///
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
items = (try? container.decode([LiveAlbumFolderItem].self, forKey: .items)) ?? []
@ -220,6 +232,7 @@ struct LiveAlbumFolderItem: Decodable, Identifiable, Equatable {
let creator: String
let items: [LiveAlbumFileItem]
///
enum CodingKeys: String, CodingKey {
case id
case albumId = "album_id"
@ -228,6 +241,7 @@ struct LiveAlbumFolderItem: Decodable, Identifiable, Equatable {
case items
}
///
init(id: Int = 0, albumId: Int = 0, name: String = "", creator: String = "", items: [LiveAlbumFileItem] = []) {
self.id = id
self.albumId = albumId
@ -236,6 +250,7 @@ struct LiveAlbumFolderItem: Decodable, Identifiable, Equatable {
self.items = items
}
///
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
id = try container.liveDecodeLossyInt(forKey: .id) ?? 0
@ -254,6 +269,7 @@ struct LiveAlbumFileItem: Decodable, Identifiable, Hashable {
let size: Int64
let coverImg: String?
///
enum CodingKeys: String, CodingKey {
case id
case url
@ -262,6 +278,7 @@ struct LiveAlbumFileItem: Decodable, Identifiable, Hashable {
case coverImg = "cover_img"
}
///
init(id: Int = 0, url: String = "", type: Int = 1, size: Int64 = 0, coverImg: String? = nil) {
self.id = id
self.url = url
@ -270,6 +287,7 @@ struct LiveAlbumFileItem: Decodable, Identifiable, Hashable {
self.coverImg = coverImg
}
///
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
id = try container.liveDecodeLossyInt(forKey: .id) ?? 0
@ -295,6 +313,7 @@ struct LiveAlbumCreateFolderRequest: Encodable, Equatable {
let name: String
let items: [LiveAlbumCreateFileItem]
///
enum CodingKeys: String, CodingKey {
case scenicId = "scenic_id"
case name
@ -309,6 +328,7 @@ struct LiveAlbumCreateFileItem: Encodable, Equatable {
let size: Int64
let coverImg: String?
///
enum CodingKeys: String, CodingKey {
case url
case type
@ -321,6 +341,7 @@ struct LiveAlbumCreateFileItem: Encodable, Equatable {
struct LiveAlbumDeleteFolderRequest: Encodable, Equatable {
let folderId: Int
///
enum CodingKeys: String, CodingKey {
case folderId = "folder_id"
}
@ -331,6 +352,7 @@ struct LiveAlbumDeleteFilesRequest: Encodable, Equatable {
let folderId: Int
let fileIds: [Int]
///
enum CodingKeys: String, CodingKey {
case folderId = "folder_id"
case fileIds = "file_ids"
@ -346,6 +368,7 @@ struct LiveAlbumLocalUploadFile: Identifiable, Equatable {
let size: Int64
var uploadedURL: String?
///
init(id: UUID = UUID(), data: Data, fileName: String, fileType: Int, size: Int64? = nil, uploadedURL: String? = nil) {
self.id = id
self.data = data
@ -359,6 +382,7 @@ struct LiveAlbumLocalUploadFile: Identifiable, Equatable {
}
private extension KeyedDecodingContainer {
///
func liveDecodeLossyString(forKey key: Key) throws -> String {
if let value = try? decodeIfPresent(String.self, forKey: key) {
return value
@ -378,6 +402,7 @@ private extension KeyedDecodingContainer {
return ""
}
///
func liveDecodeLossyInt(forKey key: Key) throws -> Int? {
if let value = try? decodeIfPresent(Int.self, forKey: key) {
return value