swiftuiswift-data

How can I retrieve data from SwiftData


I'm having a problem with Swift Data, so as you can see in this pic, I want to print out the user information after the user signs in. I have a sign up view and it stores the data in my data class (using Swift Data) really well, but I don't know how to call them in other views.

I hope I made everything clear...

import SwiftUI
import SwiftData
   

struct ProfileView: View {
    @Environment (\.modelContext) private var Context
    @Environment (\.dismiss) private var dismiss
    @Query(sort: \data.username) var profile: [data]
//    @State var isLoggedIn: Bool
    
    var body: some View {
        VStack{
            VStack{
                ZStack{
                    Color.gg.ignoresSafeArea().frame(width: 400,height: 250)
                    
                    Spacer()
                    
                    Spacer()
                    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)
                    Spacer()
                    
                        // Text(profile.username)
                        .font(.title)
                        .bold()
                    Spacer()
                }
            }
            Spacer()
            List {
               /* Section(header: Text("Account Information")){*/
                    Text("Email:")
                   // Text(profile.email)
                        .font(.body)
                        .padding()
                    Text("Username:")
                 //   Text(profile.username)
                            .font(.body)
                            .padding()
                    Button(action: {
//                        logout()
                    }) {
                        Text("Logout")
                            .foregroundColor(.red)
                            .font(.headline)
                            .padding()
                           // .background)
                            .cornerRadius(10)
                    }
                    .listRowBackground(Color.white)
            }.listStyle(.plain)
            }
            
            Spacer()
        }
    
    
//    func logout() {
//      
//        email = ""
//        isLoggedIn = true
//    }
    
}
#Preview {
    ProfileView()
}
------------------swift data -----------------------------
import Foundation
import SwiftData

@Model
class data: Identifiable {
    var Excname: String = ""
    var workname: String = ""
    var numofsets: Int = 0
    var numofreps: Int = 0
    var day: String = ""
    let username: String = ""
    let userID: Int = 0
    let email: String = ""
    let password: String = ""

//    init(username: String, password: String, userID: Int, email: String) {
//        self.username = username
//        self.password = password
//        self.userID = userID
//        self.email = email
//    
//    }

    init(username: String, email: String, password: String) {
        self.username = username
        self.email = email
        self.password = password
        
    }

    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
    }
}

Solution

  • From your code:

    @Query(sort: \data.username) var profile: [data]
    

    profile is an array of data, so you need to either treat it as an array, e.g.:

    List(profile) { person in
        Text(person.username)
        // etc.
    }
    

    or, if you really want to just work with a single item, do something like:

    @Query(sort: \data.username) var profiles: [data]
    var profile: data? { profiles.first }
    

    and then use profile as the single (optional!) item that it is.