|
So, I ran into a problem implementing SwiftData into my project. I've created a simpler one, with the same main idea, with the same problem. I have a model, with an array of another model inside:
The Person model is put into container:
And then for the problem itself:
What I want, is when the function is run, for it to find a person named Thomas, swap his main item to a Backpack, and put 3 items "in". I dont care if he had any items before (inside the array), i want him to have just those 3 new items. When he starts with an empty array, it works just fine, I give him the items, he has them, the UI shows it, I restart the app, he still has them. All good. But then I run the function again - i dont care what items you have before, you now (again) have a Backpack, and [Laptop, Notebook, Pencil]. All good, the UI based on persons array still shows Thomas having 3 items. BUT, when i restart the app, Thomas shows now that he has more than 3 items, ex. [Laptop, Notebook, Notebook, Pencil]. So the model accepted the 3 new items, but didnt dispose all of the previous values. If i run the function multiple times in a row, fast, after each run the UI shows Thomas having 3 items, and after restarting the app somehow he has like 10 or so items. If I change the array inside Person model to be [String] for example, and the function now says:
It works as it suppose to, clearing array of any previous value, I can run the func 100 times, restart the app and Thomas has 3 items i gave him. If the array holds any custom objects, it goes bad mixing old value with the new, resulting in unpredictable array. Am I missing something here? Is this SwiftData bug? |
|
Hi! I have a question to you. If you don't use any relationship between those parts of your data, why do you mark both as If there is no relationship required use struct for that.
Otherwise you creating models many times that just sitting in the db. |
|
I remember adding @Model to the Item struct/class because i got errors while creating Person class without it. I removed @Model, changed it to struct and reinstalled the app and it seems to be the fix to my problem. Thank you @ygeras! |
|
hi, i am speculating: if a model of type A holds on to an array of models of type B, then SwiftData infers that as a relationship and infers that there is an inverse (even though you did not ask for either). i am also speculating: to directly set i don't know ... and i'd agree with Yuri that some of those previous B models are probably now hanging around the database as orphans associated with no A. as for an array of Strings, well those are not hope that helps, DMG |
|
Seems like @delawaremathguy's speculations to be exactly what is going on behind the scenes. I just recreated the similar behavior and watched what is going on in the database. Basically, Paul mentions about implicit relashionships in SwiftData by Example as well as other sources, mention the same, advising explicitly declare them to avoid confusion.
So to my understanding, the behavior in this particular case as follows. You create those implicit relationships and they are in the db. Once you replace again items in backpack.
seems like your view just retrieve that part of data from the db, but basically it still keeps previous as well, and once you reload your app, all relationships are retrieved again that is why you have them all back. in red as can be seen from the pic, we will have primary key for person, meaning the relationships exist. So once the view accesses items property all data is back on the screen. |
SPONSORED Take the pain out of configuring and testing your paywalls. RevenueCat's Paywalls allow you to remotely configure and A/B test your entire paywall UI without any code changes or app updates.
Sponsor Hacking with Swift and reach the world's largest Swift community!
You need to create an account or log in to reply.
All interactions here are governed by our code of conduct.
Link copied to your pasteboard.