Hey Ziqiao,
I added further information to this case - it looks like a major bug in CloudKit. I hope it will be fixed soon - currently I could not find any workaround.
FB: FB15271917
Thanks a lot,
Dudi
Post
Replies
Boosts
Views
Activity
Hey everyone,
I found a temp solution -
I added markAsDeleted: Bool to my model
Before deleting the object, I mark it as deleted
And then delete it
session.markAsDeleted = true
modelContext.delete(session)
session.save(modelContext: modelContext)
And in order to handle the crash and the reference issue -
In the relevant SwiftUI View I added -
if !session.markAsDeleted {
//View that uses the session object
} else {
EmptyView()
}
Thank you so much, Ziqiao.
The sync is defined on my main app entitlement. I also tried to define it on the extensions - same results.
I'll fill a new feedback and hopefully wait for a fix in the upcoming versions.
FB: FB15271917
Thanks again!
Dudi
Hey Ziqiao,
More details -
I have a SwiftData Model that can be modified from the app and from a Home Screen widget.
On widget -
I make 3 changes in a raw to the session. 3 tokens are created (e.g. 180, 181, 182)
However, I see that only the latest one is synced to the CloudKit (182).
I open the app. Few seconds later I receive two new tokens (183 and 184) which are the mirroring of 180 & 181.
They override 182. New state = 181 instead of 182. This is the bug.
Any idea how to workaround it?
I just saw this thread -
https://developer.apple.com/forums/thread/759364
I hope this issue will be fixed. As for now, it looks like my app fail into this regression, unfortunately.
Thanks a lot for your help, Ziqiao.
So if I started with an opened session and counter 5.
widget: increase to 8 and end session.
Enter foreground: App UI is synced.
Later: App UI - counter 5. Session is opened. Then counter is 8. Session remains open.
Unlike CoreData - I couldn’t figure out how I can control the incoming actions from cloudkit through swiftdata if I want to ignore exist changes.
Thanks again!
Thanks a lot.
So it looks like the problem is related to the sync with CloudKit.
Any update that happens on the widget extension, is updating the app properly when I enter the foreground and both are synced. Then, few seconds later, the swiftdata receives the updates from the cloud and apparently the history token has not being updated, so it reverts the changes and then sync them again, while not fully synced - there are some changes that not synced somehow.
=>
Hey Reed,
Thank you for your reply!
I'm working with SwiftData. The entity is a model and the counter is one of its properties.
Increase the value -> save modelContext -> reloadAllTimelines/reloadAllControls
It looks like it's related to the cascade rule. Once I remove the item and create a new one with sequential id, in some point it tries to access the old item PersistentIdentifier.ID, which is not available anymore.
Eventually, I decided to work around with adding a markAsDeleted property to the item I want to delete instead of deleting it, and filter it accordingly. In case it's a bug - I'll wait for a hot fix. If it's not - I'll be happy to figure out how to resolve it.
Thanks a lot!
Dudi
Hey,
Exact issue here.
Deleted the item using a modelContext through SwiftUI but it still "keeps a reference" to the view that should have been removed - it doesn't appear on the screen btw.
I tried to check the item.isDeleted property and I found that sometimes the value is false, but once the value is true - I get the crash. Again, it happens when the refresh UI is triggered for this zombie view. It's triggered by detecting changes on environmentObject and binding properties.
Best,
Dudi
I thought I found the problem on my side -
I called the modelContext.insert(session) too early, before I added it to the room and the UI observer tried to create the view that relies on this item before it was ready and available.
It seems that iOS 18 is more robust than iOS 17.
However, I'm still facing a weird issue where my list is empty and before the session is actually created, it fails on the Cell view, that basically, shouldn't be exist. How it is still keeps a reference to this view?