如何在ProfileViewController中显示User对象用户名并解决相关错误
问题解决:ProfileView无法显示用户名及fetchUser方法错误
问题概述
- AuthViewModel的
fetchUser方法调用service.fetchUser时提示Extra trailing closure passed in call错误 - ProfileViewController中
currentUser?.username始终为nil,无法正常显示用户名
相关代码
AuthViewModel.swift
import Foundation import FirebaseAuth import Firebase class AuthViewModel: ObservableObject { @Published var userSession: FirebaseAuth.User? @Published var currentUser: User? private var tempUserSession: FirebaseAuth.User? private let service = UserService() init() { self.userSession = Auth.auth().currentUser } func login(withEmail email: String, password: String) { Auth.auth().signIn(withEmail: email, password: password) { authResult, error in if let e = error { print(e.localizedDescription) } else { guard let user = authResult?.user else {return} self.userSession = user guard let uid = self.userSession?.uid else { return } self.service.fetchUser(withUid: uid) print("Did User log IN") } } } func fetchUser() { guard let uid = self.userSession?.uid else { return } service.fetchUser(withUid: uid) { user in <----- 错误位置:Extra trailing closure passed in call self.currentUser = user } } }
ProfileViewController.swift
import Foundation import UIKit import FirebaseAuth import SwiftUI class ProfileViewController: UIViewController { var authViewModel = AuthViewModel() @IBOutlet weak var userNameLabel: UILabel! override func viewDidLoad() { navigationItem.hidesBackButton = true userNameLabel.text = authViewModel.currentUser?.username // 此处无法获取到用户名,值为nil print(userNameLabel.text) } }
解决方案
1. 修复Extra trailing closure passed in call错误
该错误说明UserService的fetchUser(withUid:)方法定义不支持尾随闭包,需根据方法实际实现调整:
- 如果
UserService.fetchUser是同步返回用户数据(无闭包参数),直接移除多余闭包,同步赋值:func fetchUser() { guard let uid = self.userSession?.uid else { return } self.currentUser = service.fetchUser(withUid: uid) } - 如果
UserService.fetchUser是异步方法(带完成闭包),检查方法定义,确保闭包参数传递正确,可显式指定参数名:func fetchUser() { guard let uid = self.userSession?.uid else { return } service.fetchUser(withUid: uid, completion: { user in self.currentUser = user }) }
2. 修复currentUser?.username为nil的问题
问题根源:
AuthViewModel初始化时未调用fetchUser(),启动阶段未加载用户数据login方法中调用service.fetchUser时未处理返回结果,未给currentUser赋值viewDidLoad中直接读取currentUser,但用户数据加载是异步操作,此时数据尚未返回
修复步骤:
- 在
AuthViewModel初始化方法中调用fetchUser(),确保启动时加载用户信息:init() { self.userSession = Auth.auth().currentUser fetchUser() // 添加此行,初始化时获取用户数据 } - 修复
login方法,处理service.fetchUser的异步回调,赋值currentUser:func login(withEmail email: String, password: String) { Auth.auth().signIn(withEmail: email, password: password) { authResult, error in if let e = error { print(e.localizedDescription) } else { guard let user = authResult?.user else {return} self.userSession = user guard let uid = self.userSession?.uid else { return } // 根据UserService方法实现,添加闭包处理用户数据 self.service.fetchUser(withUid: uid) { user in self.currentUser = user } print("Did User log IN") } } } - 在ProfileViewController中监听
currentUser的变化(利用@Published的Combine特性),确保数据更新时同步更新UI:import Combine // 导入Combine框架 class ProfileViewController: UIViewController { var authViewModel = AuthViewModel() @IBOutlet weak var userNameLabel: UILabel! private var cancellables = Set<AnyCancellable>() // 存储订阅对象,防止被释放 override func viewDidLoad() { super.viewDidLoad() navigationItem.hidesBackButton = true // 订阅currentUser的变化,更新UI authViewModel.$currentUser .receive(on: DispatchQueue.main) // 确保在主线程更新UI .sink { [weak self] user in self?.userNameLabel.text = user?.username print(self?.userNameLabel.text ?? "nil") } .store(in: &cancellables) } }
内容的提问来源于stack exchange,提问作者Branislav Fekeč
相关产品推荐
相关产品推荐

