
- 在MomentListHomePage中实现完整的动态列表显示,支持下拉刷新和上拉加载更多功能。 - 使用LazyVStack优化列表渲染性能,确保流畅的用户体验。 - 增强MomentListHomeViewModel,添加分页相关属性和方法,优化数据加载逻辑。 - 更新API请求逻辑,支持动态加载和状态管理,提升用户交互体验。 - 添加详细的调试信息和测试建议,确保功能完整性和代码质量。
172 lines
6.7 KiB
Swift
172 lines
6.7 KiB
Swift
import SwiftUI
|
||
import Combine
|
||
|
||
// MARK: - MomentListHome ViewModel
|
||
|
||
@MainActor
|
||
class MomentListHomeViewModel: ObservableObject {
|
||
// MARK: - Published Properties
|
||
@Published var isLoading: Bool = false
|
||
@Published var error: String? = nil
|
||
@Published var moments: [MomentsInfo] = []
|
||
@Published var isLoaded: Bool = false
|
||
|
||
// MARK: - 分页相关属性
|
||
@Published var isLoadingMore: Bool = false
|
||
@Published var hasMore: Bool = true
|
||
@Published var nextDynamicId: Int = 0
|
||
|
||
// MARK: - Private Properties
|
||
private var cancellables = Set<AnyCancellable>()
|
||
|
||
// MARK: - Public Methods
|
||
func onAppear() {
|
||
debugInfoSync("📱 MomentListHomeViewModel onAppear")
|
||
guard !isLoaded else {
|
||
debugInfoSync("✅ MomentListHomeViewModel: 数据已加载,跳过重复请求")
|
||
return
|
||
}
|
||
fetchLatestDynamics(isRefresh: true)
|
||
}
|
||
|
||
// MARK: - 刷新数据
|
||
func refreshData() {
|
||
debugInfoSync("🔄 MomentListHomeViewModel: 开始刷新数据")
|
||
fetchLatestDynamics(isRefresh: true)
|
||
}
|
||
|
||
// MARK: - 加载更多数据
|
||
func loadMoreData() {
|
||
guard hasMore && !isLoadingMore && !isLoading else {
|
||
debugInfoSync("⏸️ MomentListHomeViewModel: 跳过加载更多 - hasMore: \(hasMore), isLoadingMore: \(isLoadingMore), isLoading: \(isLoading)")
|
||
return
|
||
}
|
||
debugInfoSync("📥 MomentListHomeViewModel: 开始加载更多数据")
|
||
fetchLatestDynamics(isRefresh: false)
|
||
}
|
||
|
||
// MARK: - Private Methods
|
||
private func fetchLatestDynamics(isRefresh: Bool) {
|
||
if isRefresh {
|
||
isLoading = true
|
||
error = nil
|
||
debugInfoSync("🔄 MomentListHomeViewModel: 开始获取最新动态")
|
||
} else {
|
||
isLoadingMore = true
|
||
debugInfoSync("📥 MomentListHomeViewModel: 开始加载更多动态")
|
||
}
|
||
|
||
Task {
|
||
// 检查认证信息
|
||
let accountModel = await UserInfoManager.getAccountModel()
|
||
if accountModel?.uid != nil {
|
||
debugInfoSync("✅ MomentListHomeViewModel: 认证信息已准备好,开始获取动态")
|
||
await performAPICall(isRefresh: isRefresh)
|
||
} else {
|
||
debugInfoSync("⏳ MomentListHomeViewModel: 认证信息未准备好,等待...")
|
||
// 增加等待时间和重试次数
|
||
for attempt in 1...3 {
|
||
try? await Task.sleep(nanoseconds: 500_000_000) // 0.5秒
|
||
let retryAccountModel = await UserInfoManager.getAccountModel()
|
||
if retryAccountModel?.uid != nil {
|
||
debugInfoSync("✅ MomentListHomeViewModel: 第\(attempt)次重试成功,认证信息已保存,开始获取动态")
|
||
await performAPICall(isRefresh: isRefresh)
|
||
return
|
||
} else {
|
||
debugInfoSync("⏳ MomentListHomeViewModel: 第\(attempt)次重试,认证信息仍未准备好")
|
||
}
|
||
}
|
||
debugInfoSync("❌ MomentListHomeViewModel: 多次重试后认证信息仍未准备好")
|
||
await MainActor.run {
|
||
if isRefresh {
|
||
self.isLoading = false
|
||
} else {
|
||
self.isLoadingMore = false
|
||
}
|
||
self.error = "认证信息未准备好"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
private func performAPICall(isRefresh: Bool) async {
|
||
let apiService = LiveAPIService()
|
||
|
||
do {
|
||
// 如果是刷新,使用空字符串;如果是加载更多,使用nextDynamicId
|
||
let dynamicId = isRefresh ? "" : nextDynamicId.description
|
||
let request = LatestDynamicsRequest(dynamicId: dynamicId, pageSize: 20, types: [.text, .picture])
|
||
debugInfoSync("📡 MomentListHomeViewModel: 发送请求: \(request.endpoint)")
|
||
debugInfoSync(" 参数: dynamicId=\(request.dynamicId), pageSize=\(request.pageSize), isRefresh=\(isRefresh)")
|
||
|
||
let response: MomentsLatestResponse = try await apiService.request(request)
|
||
|
||
await MainActor.run {
|
||
self.handleAPISuccess(response, isRefresh: isRefresh)
|
||
}
|
||
} catch {
|
||
await MainActor.run {
|
||
self.handleAPIError(error, isRefresh: isRefresh)
|
||
}
|
||
}
|
||
}
|
||
|
||
private func handleAPISuccess(_ response: MomentsLatestResponse, isRefresh: Bool) {
|
||
if isRefresh {
|
||
isLoading = false
|
||
isLoaded = true
|
||
} else {
|
||
isLoadingMore = false
|
||
}
|
||
|
||
debugInfoSync("✅ MomentListHomeViewModel: API 请求成功")
|
||
debugInfoSync(" 响应码: \(response.code)")
|
||
debugInfoSync(" 消息: \(response.message)")
|
||
debugInfoSync(" 数据数量: \(response.data?.dynamicList.count ?? 0)")
|
||
|
||
if let list = response.data?.dynamicList {
|
||
if isRefresh {
|
||
// 刷新时替换所有数据
|
||
moments = list
|
||
debugInfoSync("✅ MomentListHomeViewModel: 数据刷新成功")
|
||
debugInfoSync(" 动态数量: \(list.count)")
|
||
} else {
|
||
// 加载更多时追加数据
|
||
moments.append(contentsOf: list)
|
||
debugInfoSync("✅ MomentListHomeViewModel: 数据加载更多成功")
|
||
debugInfoSync(" 新增动态数量: \(list.count)")
|
||
debugInfoSync(" 总动态数量: \(moments.count)")
|
||
}
|
||
|
||
// 更新分页信息
|
||
nextDynamicId = response.data?.nextDynamicId ?? 0
|
||
hasMore = list.count == 20 // 如果返回的数据少于20条,说明没有更多数据了
|
||
|
||
debugInfoSync("📄 MomentListHomeViewModel: 分页信息更新")
|
||
debugInfoSync(" nextDynamicId: \(nextDynamicId)")
|
||
debugInfoSync(" hasMore: \(hasMore)")
|
||
|
||
error = nil
|
||
} else {
|
||
if isRefresh {
|
||
moments = []
|
||
}
|
||
error = response.message
|
||
debugErrorSync("❌ MomentListHomeViewModel: 数据为空")
|
||
debugErrorSync(" 错误消息: \(response.message)")
|
||
}
|
||
}
|
||
|
||
private func handleAPIError(_ error: Error, isRefresh: Bool) {
|
||
if isRefresh {
|
||
isLoading = false
|
||
moments = []
|
||
} else {
|
||
isLoadingMore = false
|
||
}
|
||
self.error = error.localizedDescription
|
||
debugErrorSync("❌ MomentListHomeViewModel: API 请求失败")
|
||
debugErrorSync(" 错误: \(error.localizedDescription)")
|
||
}
|
||
}
|