I have a problem updating a SwiftData model by adding a property.
Specifically, I have the following model and I am trying to update it by adding an id. The problem is that, if I do this, all records already stored in the app get updated with the same UUID. Obviously I would like to have a different id for every instance. Am I missing something? Should I do something differently?
Word
model
In the previous version the model did not have the id
property, the corresponding coding key and attribute in the initializer.
@Model
class Word: Codable {
enum CodingKeys: CodingKey {
case id, term, learntOn, notes, category, bookmarked
}
var id: UUID = UUID() // marked it as var for testing
let term: String = ""
let learntOn: Date = Date.now
var notes: String = ""
@Relationship(inverse: Category.words) var category: Category?
var bookmarked: Bool = false
init(id: UUID, term: String, learntOn: Date, notes: String = "", category: Category? = nil, bookmarked: Bool = false) {
self.id = id
self.term = term
self.learntOn = learntOn
self.notes = notes
self.category = category
self.bookmarked = bookmarked
}
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.id = try container.decode(UUID.self, forKey: .id)
self.term = try container.decode(String.self, forKey: .term)
let learntOn = try container.decode(String.self, forKey: .learntOn)
self.learntOn = try Date(learntOn, strategy: .iso8601)
self.notes = try container.decode(String.self, forKey: .notes)
self.category = try container.decode(Category?.self, forKey: .category)
self.bookmarked = try container.decode(Bool.self, forKey: .bookmarked)
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(self.id, forKey: .id)
try container.encode(self.term, forKey: .term)
try container.encode(self.learntOn, forKey: .learntOn)
try container.encode(self.notes, forKey: .notes)
try container.encode(self.category, forKey: .category)
try container.encode(self.bookmarked, forKey: .bookmarked)
}
static func decodeWords(from json: String) throws -> [Word] {
let data = json.data(using: .utf8)!
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601
return try decoder.decode([Word].self, from: data)
}
static let example = Word(id: UUID(), term: "Swift", learntOn: .now, notes: "A swift testing word.", bookmarked: true)