iPhone 13 Pro Max启动时Feed显示随机帖子而非关注用户帖子问题
Feed功能启动异常问题排查与解决
问题描述
开发Feed功能时,在iPhone 13 Pro Max设备上出现以下异常:
- APP关闭重启后首次启动,明明用户有关注用户的帖子,却错误显示随机帖子的引导横幅
- 执行下拉刷新(调用同一
fetchFollowingPosts函数)后,能正常加载并显示关注用户的帖子
相关代码已提供(FeedViewModel、FeedView、FeedService)
问题原因
问题核心出在FeedService的fetchFollowingPosts方法中:
- 遍历关注用户列表时,每获取一个用户的帖子就立即调用
completion回调 - 网络请求是异步执行的,如果第一个完成的请求对应用户没有帖子,此时
posts数组为空,会触发ViewModel切换到.empty状态并加载随机帖子 - 后续其他关注用户的帖子请求完成后,虽然
posts数组会被更新,但ViewModel的状态已经是.empty,不会再自动切换回.loaded - 下拉刷新时,之前的异步请求可能已完成并缓存数据,或者所有请求完成后才触发回调,因此能正常显示内容
解决方案
1. 修复FeedService的异步请求逻辑
使用DispatchGroup等待所有关注用户的帖子请求完成后,再统一调用completion,避免提前触发错误状态:
import SwiftUI import FirebaseAuth import FirebaseFirestore import FirebaseFirestoreSwift struct FeedService { func fetchFollowingPosts(forUid uid: String, completion: @escaping([Post]) -> Void) { var posts = [Post]() let group = DispatchGroup() COLLECTION_FOLLOWING.document(uid).collection("user-following") .getDocuments { snapshot, _ in guard let documents = snapshot?.documents else { completion(posts) return } documents.forEach { doc in group.enter() let userId = doc.documentID COLLECTION_POSTS.whereField("uid", isEqualTo: userId) .getDocuments { snapshot, _ in defer { group.leave() } if let documents = snapshot?.documents { let userPosts = documents.compactMap({ try? $0.data(as: Post.self) }) posts.append(contentsOf: userPosts) } else { print("error fetching posts for user: \(userId)") } } } group.notify(queue: .main) { let sortedPosts = posts.sorted(by: { $0.timestamp.dateValue() > $1.timestamp.dateValue() }) completion(sortedPosts) } } } func fetchAllPosts(completion: @escaping([Post]) -> Void) { COLLECTION_POSTS.getDocuments { snapshot, _ in if let documents = snapshot?.documents { let posts = documents.compactMap({ try? $0.data(as: Post.self) }) completion(posts) } else { print("error fetching all posts") } } } }
2. 优化FeedViewModel的状态重置逻辑
每次调用fetchFollowingPosts时先重置状态为.loading,避免旧状态干扰新请求结果:
func fetchFollowingPosts() { guard let uid = Auth.auth().currentUser?.uid else { return } state = .loading service.fetchFollowingPosts(forUid: uid) { posts in if posts.count > 0 { self.followingPosts = posts self.state = .loaded } else { self.fetchAllPosts() } } }
补充说明
DispatchGroup可以确保所有异步请求完成后再处理结果,彻底避免因部分请求提前完成导致的状态错误- 重置状态为
.loading不仅能让用户看到加载反馈,还能避免旧状态(比如之前的.empty)影响新请求的UI展示
内容的提问来源于stack exchange,提问作者amelia
相关产品推荐
相关产品推荐

