I’m working on an independent watchOS app and I was looking for the best solution to persist data locally and have an online sync with the iCloud storage.
I’ve found out about the SwiftData which is working very well for my app. Then I wanted to hook up the data to the iCloud containers so I picked up the CloudKit. I’m testing the approach with a TestFlight builds for my watchOS app but I cannot see any records being saved in the iCloud container.
I tried running the same configuration and same type for a clean iOS app just to test the syncing system. It’s working with no problem. I can see the data uploaded (in iCloud container) from an iOS as well as in the iOS app while creating a record from the CloudKit Console. Unfortunately it’s not the case for my watchOS app.
@Model
final class Item {
var timestamp: Date = Date()
init(timestamp: Date) {
self.timestamp = timestamp
}
}
@main
struct TestApp: App {
var sharedModelContainer: ModelContainer = {
let schema = Schema([
Item.self,
])
let modelConfiguration = ModelConfiguration(schema: schema, isStoredInMemoryOnly: false)
do {
return try ModelContainer(for: schema, configurations: [modelConfiguration])
} catch {
fatalError("Could not create ModelContainer: \(error)")
}
}()
var body: some Scene {
WindowGroup {
ContentView()
}
.modelContainer(sharedModelContainer)
}
}
struct ContentView: View {
@Environment(\.modelContext) private var modelContext
@Query private var items: [Item]
var body: some View {
NavigationSplitView {
List {
ForEach(items) { item in
NavigationLink {
Text("Item at \(item.timestamp, format: Date.FormatStyle(date: .numeric, time: .standard))")
} label: {
Text(item.timestamp, format: Date.FormatStyle(date: .numeric, time: .standard))
}
}
.onDelete(perform: deleteItems)
}
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
EditButton()
}
ToolbarItem {
Button(action: addItem) {
Label("Add Item", systemImage: "plus")
}
}
}
} detail: {
Text("Select an item")
}
}
private func addItem() {
withAnimation {
let newItem = Item(timestamp: Date())
modelContext.insert(newItem)
}
}
private func deleteItems(offsets: IndexSet) {
withAnimation {
for index in offsets {
modelContext.delete(items[index])
}
}
}
}
Code above is basically an example provided by the Xcode for an app using CloudKit and it’s working very well for the iOS app.
I have added the capability to:
- Background Modes: Remote notifications
- iCloud: CloudKit + added a container
- Push notifications
Did I miss something while configuring the setup? I figured that if Apple provides SwiftData and CloudKit that it would look the same between the platforms in terms of a logic. I cannot find anything more to setup the SwiftData + CloudKit for an independent watchOS app.