Hi everyone,
I've recently implemented CKSyncEngine in my app, and I have two questions regarding its behavior:
Duplicate FetchedRecordZoneChanges After Sending Changes:
I’ve noticed that the engine sometimes receives a FetchedRecordZoneChanges event containing modifications and deletions that were just sent by the same device a few moments earlier. This event arrives after the SentRecordZoneChanges event, and both events share the same recordChangeTag, which results in double-handling the record.
Is this expected behavior? I’d like to confirm if this is how CKSyncEngine works or if I might be overlooking something.
Handling Initial Sync with a "Sync Screen":
When a user opens the app for the first time and already has data stored in iCloud, I need to display a "Sync Screen" temporarily to prevent showing partial data or triggering abrupt, rapid UI changes.
I’ve found that canceling current operations, then awaiting sendChanges() and fetchChanges() works well to ensure data is fully synced before dismissing the sync screen:
displaySyncScreen = true
await syncEngine.cancelOperations()
try await syncEngine.sendChanges()
try await syncEngine.fetchChanges()
displaySyncScreen = false
However, I’m unsure if canceling operations like this could lead to data loss or other issues. Is this a safe approach, or would you recommend a better strategy for handling this initial sync state?
Post
Replies
Boosts
Views
Activity
When working with SwiftUI TabView and ScrollView at root level with scrollPosition(id:anchor:), after tapping on Tab item the ScrollView scrolls to the top, but the scroll position ID does not get updated.
struct ContentView: View {
@State var positionID: Int?
var body: some View {
TabView {
Tab("Test", systemImage: "house") {
ScrollView(.vertical) {
LazyVStack(pinnedViews: [.sectionHeaders]) {
ForEach(0 ... 100, id: \.self) { index in
Text("\(index)")
}
}
.scrollTargetLayout()
}
.scrollPosition(id: $positionID, anchor: .top)
.onChange(of: positionID) { _, newValue in
print(newValue)
}
}
}
}
}
FB15964820
I've encountered what appears to be a bug with widget background image tinting in SwiftUI. When using an image in containerBackground(for: .widget) to fill the entire widget, adding the .containerBackgroundRemovable(false) modifier breaks the widget's tinting behavior:
The background image becomes permanently tinted, ignoring any widgetAccentedRenderingMode(_ renderingMode: WidgetAccentedRenderingMode?) settings
Text elements become tinted even with .widgetAccentable(false) applied
Sample code:
struct MyWidget: Widget {
var body: some WidgetConfiguration {
AppIntentConfiguration(kind: "MyWidget", intent: MyWidgetIntent.self, provider: Provider()) { entry in
MyWidgetView(entry: entry)
.containerBackground(for: .widget) {
Image("background")
.resizable()
.widgetAccentedRenderingMode(.fullColor)
.scaledToFill()
}
}
.containerBackgroundRemovable(false) // This causes the issue
}
}
Workaround: I've managed to resolve this by using a ZStack with disabled content margins and passing the widget size through the entry. However, this seems like unintended behavior with the .containerBackgroundRemovable(false) modifier.
Has anyone else encountered this issue or found a better solution?
Device: iPhone 15 Pro
iOS Version: 18.1
Xcode Version: 16.1