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

如何从SwiftData中获取数据并在SwiftUI视图中展示用户信息

SwiftData 登录后展示用户信息解决方案

核心问题分析

  • 当前@Query获取的是所有data对象的数组,直接访问profile.username会报错,因为数组没有该属性
  • 未区分当前登录用户,无法精准获取目标用户数据
  • 类名data不符合Swift命名规范(类名需首字母大写)

分步解决方案

1. 保存登录状态

用@AppStorage存储当前登录用户的标识(比如用户名),让所有视图能共享登录状态:

// 在登录/注册成功的视图中添加
@AppStorage("currentUsername") var currentUsername: String?
// 登录成功后赋值
currentUsername = "用户注册的用户名"

2. 重构SwiftData模型类

修正命名并拆分职责(建议把用户信息和运动记录分成独立模型,避免职责混乱):

import Foundation
import SwiftData

// 用户账户模型
@Model
class UserAccount: Identifiable {
    let username: String
    let email: String
    let password: String
    let userID: UUID = UUID()
    
    init(username: String, email: String, password: String) {
        self.username = username
        self.email = email
        self.password = password
    }
}

// 运动记录模型
@Model
class ExerciseRecord: Identifiable {
    var excName: String
    var workName: String
    var numOfSets: Int
    var numOfReps: Int
    var day: String
    // 关联用户
    var user: UserAccount?
    
    init(excName: String, workName: String, numOfSets: Int, numOfReps: Int, day: String) {
        self.excName = excName
        self.workName = workName
        self.numOfSets = numOfSets
        self.numOfReps = numOfReps
        self.day = day
    }
}

3. 修改ProfileView获取当前用户数据

添加过滤条件,精准获取当前登录用户,并处理UI展示:

import SwiftUI
import SwiftData

struct ProfileView: View {
    @Environment(\.modelContext) private var modelContext
    @Environment(\.dismiss) private var dismiss
    @AppStorage("currentUsername") var currentUsername: String?
    
    // 过滤当前登录用户的查询
    @Query(filter: #Predicate<UserAccount> { $0.username == currentUsername }) 
    var currentUser: [UserAccount]

    var body: some View {
        VStack{
            VStack{
                ZStack{
                    Color.gray.ignoresSafeArea().frame(width: 400,height: 250)
                    
                    Image("logo")
                        .resizable()
                        .aspectRatio(contentMode: .fill)
                        .frame(width: 180, height: 100)
                        .padding()
                    
                    Image(systemName: "camera.circle")
                        .font(.system(size: 30))
                        .foregroundColor(.blue)
                        .offset(x:60, y:70)
                    
                    // 安全展示用户名
                    if let user = currentUser.first {
                        Text(user.username)
                            .font(.title)
                            .bold()
                            .offset(y: 120)
                    }
                }
            }
            
            Spacer()
            
            List {
                if let user = currentUser.first {
                    Section(header: Text("账户信息")) {
                        HStack {
                            Text("Email:")
                            Spacer()
                            Text(user.email)
                                .font(.body)
                        }
                        .padding()
                        
                        HStack {
                            Text("Username:")
                            Spacer()
                            Text(user.username)
                                .font(.body)
                        }
                        .padding()
                    }
                }
                
                Button(action: logout) {
                    Text("Logout")
                        .foregroundColor(.red)
                        .font(.headline)
                        .padding()
                        .cornerRadius(10)
                }
                .listRowBackground(Color.white)
            }
            .listStyle(.plain)
            
            Spacer()
        }
    }
    
    func logout() {
        currentUsername = nil // 清除登录状态
        dismiss() // 返回登录页
    }
}

#Preview {
    do {
        let config = ModelConfiguration(isStoredInMemoryOnly: true)
        let container = try ModelContainer(for: UserAccount.self, ExerciseRecord.self, configurations: config)
        // 添加测试用户
        let testUser = UserAccount(username: "testUser", email: "test@example.com", password: "123456")
        container.mainContext.insert(testUser)
        return ProfileView()
            .modelContainer(container)
            .environment(\.appStorage, .init(suiteName: "testSuite"))
    } catch {
        return Text("Failed to create preview: \(error.localizedDescription)")
    }
}

4. 关键说明

  • 用#Predicate过滤@Query,只获取当前登录用户的数据
  • 通过currentUser.first安全获取单个用户对象(确保登录状态下数据库中存在该用户)
  • 登录时设置currentUsername,登出时清空,实现状态同步

内容的提问来源于stack exchange,提问作者Modhi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 00:48:09