I'm trying to understand and learn SwiftData. I want to keep some data in my application. I wanted to use swiftData to learn SwiftData and created a model like this:
import Foundation
import SwiftData
@Model
final class SwiftDataModel {
var height: Optional<Double>
var heightUnit: Optional<String>
var weight: Optional<Double>
var weightUnit: Optional<String>
var gender: Optional<String>
var waterGoal: Optional<Double>
var volumeUnit: Optional<String>
var activity: Optional<Int>
var age : Optional<Int>
var nutritionLog : Optional<Array<Any>>
init(height: Optional<Double>, heightUnit: Optional<String>, weight: Optional<Double>, weightUnit: Optional<String>, gender: Optional<String>, waterGoal: Optional<Double>, volumeUnit: Optional<String>, activity: Optional<Int>, age: Optional<Int>, nutritionLog: Optional<Array<Any>>) {
self.height = height
self.heightUnit = heightUnit
self.weight = weight
self.weightUnit = weightUnit
self.gender = gender
self.waterGoal = waterGoal
self.volumeUnit = volumeUnit
self.activity = activity
self.age = age
self.nutritionLog = nutritionLog
}
}
Maybe I can also add an array like weightlog. As far as I understand swiftData keeps this data in a list. Therefore, I will always need to update index 0 instead of using context.insert(data). Is this true?
My other case is this: After the user logs in, can I check whether the user's age, weight and height information is kept in SwiftData and determine the page to be opened there?
For example :
@main
struct MyApp: App {
var body: some Scene {
WindowGroup {
if (ViewModel.isLogin() && !ViewModel.userId.isEmpty ) {
// If height, weight, and age information is available in swiftData TabBarView()
// else IntroPageView()
{
} else {
LoginView()
}
}
}
}
Is such a check possible or should I use "User Deafults" or "Core Data" instead of SwiftData in my application?
I'm looking forward to your answers. Thanks in advance
Thank you for all the answers. It did what I wanted and I'm using it efficiently.
First, I updated my model like this:
@Model
final class UserInfoSwiftDataModel {
@Attribute(.unique) var userId : String?
var height: Double?
var heightUnit: String?
var weight: Double?
var weightUnit: String?
var gender: String?
var waterGoal: Double?
var consumedWater = [Water]()
var consumedWaterInt : Double?
var volumeUnit: String?
var activity: Int?
var age : Int?
var nutrition = [Nutrition]()
init(userId: String? = nil, height: Double? = nil, heightUnit: String? = nil, weight: Double? = nil, weightUnit: String? = nil, gender: String? = nil, waterGoal: Double? = nil, consumedWater: [Water] = [Water](), consumedWaterInt: Double? = nil, volumeUnit: String? = nil, activity: Int? = nil, age: Int? = nil, nutrition: [Nutrition] = [Nutrition]()) {
self.userId = userId
self.height = height
self.heightUnit = heightUnit
self.weight = weight
self.weightUnit = weightUnit
self.gender = gender
self.waterGoal = waterGoal
self.consumedWater = consumedWater
self.consumedWaterInt = consumedWaterInt
self.volumeUnit = volumeUnit
self.activity = activity
self.age = age
self.nutrition = nutrition
}
}
@Model
final class Water {
var date: String
var consumed : Double
var User : UserInfoSwiftDataModel?
init(date: String, consumed: Double, User: UserInfoSwiftDataModel? =
nil) {
self.date = date
self.consumed = consumed
self.User = User
}
}
@Model
final class Nutrition{
var name: String
var calories: Double
var serving_size_g: Double
var fat_total_g: Double
var fat_saturated_g: Double
var protein_g: Double
var sodium_mg: Int
var potassium_mg: Int
var cholesterol_mg: Int
var carbohydrates_total_g: Double
var fiber_g: Double
var sugar_g: Double
var User : UserInfoSwiftDataModel?
init(name: String, calories: Double, serving_size_g: Double,
fat_total_g: Double, fat_saturated_g: Double, protein_g: Double,
sodium_mg: Int, potassium_mg: Int, cholesterol_mg: Int,
carbohydrates_total_g: Double, fiber_g: Double, sugar_g: Double, User:
UserInfoSwiftDataModel? = nil) {
self.name = name
self.calories = calories
self.serving_size_g = serving_size_g
self.fat_total_g = fat_total_g
self.fat_saturated_g = fat_saturated_g
self.protein_g = protein_g
self.sodium_mg = sodium_mg
self.potassium_mg = potassium_mg
self.cholesterol_mg = cholesterol_mg
self.carbohydrates_total_g = carbohydrates_total_g
self.fiber_g = fiber_g
self.sugar_g = sugar_g
self.User = User
}
}
To stop using Index, I added an id match condition to get the data of the logged in user. This way, I can access and update information in a healthy way. I used it as follows:
@Environment (\.modelContext) private var context
@Query (sort: \UserInfoSwiftDataModel.height, order: .forward) private
var mySwiftData : [UserInfoSwiftDataModel]
var userId : String // Login/SignUp ekranından geliyor
var profile: UserInfoSwiftDataModel? {
return mySwiftData.first { $0.userId == userId }
}
Text(" \(String(format: "%.1f", profile?.weight ?? 0)) \.
(profile?.weightUnit ?? "kg")")
This way, I can easily get my data not only within the list, but everywhere. Thank you for giving a time.