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

如何在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的问题

问题根源:

  1. AuthViewModel初始化时未调用fetchUser(),启动阶段未加载用户数据
  2. login方法中调用service.fetchUser时未处理返回结果,未给currentUser赋值
  3. viewDidLoad中直接读取currentUser,但用户数据加载是异步操作,此时数据尚未返回

修复步骤:

  1. 在AuthViewModel初始化方法中调用fetchUser(),确保启动时加载用户信息:
    init()
    {
        self.userSession = Auth.auth().currentUser
        fetchUser() // 添加此行,初始化时获取用户数据
    }
    
  2. 修复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")
            }
        }
    }
    
  3. 在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č

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 17:46:02