You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 08:40:05