I'm using SwiftData to persist my items in storage. I used .modelContext to pass in my shared context, and on iOS 18 (both on a physical device and a simulator), I discovered a bug where SwiftData doesn't automatically save my data. For example, I could add a new item, go to the next screen, change something that reloads a previous screen, and SwiftData just forgets the item that I added. Please find the fully working code attached.
While writing this post, I realized that if I use .modelContainer instead of .modelContext, the issue is solved. So I have two questions:
It seems like .modelContainer is the go-to option when working with SwiftData, but why did an issue occur when I used .modelContext and passed in a shared container? When should we use .modelContext over .modelContainer?
What was the bug? It's working fine in iOS 17, but not in iOS 18. Or is this expected?
Here's the fully working code so you can copy and paste:
import SwiftUI
import SwiftData
typealias NamedColor = (color: Color, name: String)
extension Color {
    
    init(r: Double, g: Double, b: Double) {
        self.init(red: r/255, green: g/255, blue: b/255)
    }
    static let namedColors: [NamedColor] = [
        (.blue, "Blue"),
        (.red, "Red"),
        (.green, "Green"),
        (.orange, "Orange"),
        (.yellow, "Yellow"),
        (.pink, "Pink"),
        (.purple, "Purple"),
        (.teal, "Teal"),
        (.indigo, "Indigo"),
        (.brown, "Brown"),
        (.cyan, "Cyan"),
        (.gray, "Gray")
    ]
    
    static func name(for color: Color) -> String {
        return namedColors.first(where: { $0.color == color })?.name ?? "Blue"
    }
    
    static func color(for name: String) -> Color {
        return namedColors.first(where: { $0.name == name })?.color ?? .blue
    }
}
@main
struct SwiftDataTestApp: 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)")
        }
    }()
    
    @AppStorage("accentColor") private var accentColorName: String = "Blue"
    var body: some Scene {
        WindowGroup {
            NavigationStack {
                HomeView()
            }
                .tint(Color.color(for: accentColorName))
        }
        .modelContainer(sharedModelContainer) // This works
//        .modelContext(ModelContext(sharedModelContainer)) // This doesn't work
    }
}
@Model
final class Item {
    var timestamp: Date
    
    init(timestamp: Date) {
        self.timestamp = timestamp
    }
}
struct HomeView: View {
    
    @State private var showSettings = false
    
    @Environment(\.modelContext) var modelContext
    @AppStorage("accentColor") private var accentColorName: String = "Blue"
    
    @Query private var items: [Item]
    
    var body: some View {
        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))
                }
            }
            
            Button {
                withAnimation {
                    let newItem = Item(timestamp: Date())
                    modelContext.insert(newItem)
                }
            } label: {
                Image(systemName: "plus")
                    .frame(maxWidth: .infinity)
                    .frame(maxHeight: .infinity)
            }
        }
        .navigationTitle("Habits")
        .toolbar {
            ToolbarItem(placement: .navigationBarTrailing) {
                Button(action: { showSettings = true }) {
                    Label("", systemImage: "gearshape.fill")
                }
            }
        }
        .navigationDestination(isPresented: $showSettings) {
            colorPickerView
        }
    }
    
    private var colorPickerView: some View {
        Form {
            Section(header: Text("Accent Color")) {
                Picker("Accent Color", selection: $accentColorName) {
                    ForEach(Color.namedColors, id: \.name) { namedColor in
                        Text(namedColor.name)
                            .tag(namedColor.name)
                            .foregroundColor(namedColor.color)
                    }
                }
                .pickerStyle(.wheel)
            }
        }
        .navigationTitle("Settings")
    }
}
                    
                  
                iCloud & Data
RSS for tagLearn how to integrate your app with iCloud and data frameworks for effective data storage
  
    
    Selecting any option will automatically load the page
  
  
  
  
    
  
  
            Post
Replies
Boosts
Views
Created
                    
                      I have been using the basic NSPersistentContainer with 100k+ records for a while now with no issues.  The database size can fluctuate a bit but on average it takes up about 22mb on device.
When I switch the container to NSPersistentCloudKitContainer, I see a massive increase in size to ~150mb initially.  As the sync engine uploads records to iCloud it has ballooned to over 600mb on device.  On top of that, the user's iCloud usage in settings reports that it takes up 1.7gb in the cloud.
I understand new tables are added and history tracking is enabled but the size increase seems a bit drastic. I'm not sure how we got from 22mb to 1.7gb with the exact same data.
A few other things that are important to note:
I import all the 100k+ records at once when testing the different  containers.  At the time of the initial import there is only 1 relation (an import group record) that all the records are attached to.
I save the background context only once after all the records and the import group have been made and added to the context.
After the initial import, some of these records may have a few new relations added to them over time. I suppose this could be causing some of the size increase, but its only about 20,000 records that are updated.
None of the records include files/ large binary data.
Most of the attributes are encrypted.
I'm syncing to the dev iCloud environment.
When I do make a change to a single attribute in a record, CloudKit reports that every attribute has been modified (not sure if this is normal or not )
Also, When syncing to a new device, the sync can take hours - days. I'm guessing it's having to sync both the new records and the changes, but it exponentially gets slower as more records are downloaded. The console will show syncing activity, but new records are being added at a slower rate as more records are added.  After about 50k records, it grinds to a halt and while the console still shows sync activity, only about 100 records are added every hour.
All this to say i'm very confused where these issues are coming from.  I'm sure its a combination of how i've setup my code and the vast record count, record history, etc.
If anyone has any ideas it would be much appreciated.
                    
                  
                
                    
                      Is it ok to have latency about 4 sec? The amount of downloaded data is less than 1 MB. Maybe I need to setup an index for every field requested?
                    
                  
                
                    
                      I'm still getting this error (SwiftData/ModelContext.swift:3253: Fatal error: Failed to identify a store that can hold instances of SwiftData._KKMDBackingData<Presents_2024.Item> from [:]) in Xcode 16.1 Beta (16B5001e).
The app works for a limited amount of time and then crashes with this error. It looks like the SwiftData model isn't being created properly and when a context is saved it crashes.
Can you tell me if this error will be fixed in the next beta?
                    
                  
                
              
                
              
              
                
                Topic:
                  
	
		App & System Services
  	
                
                
                SubTopic:
                  
                    
	
		iCloud & Data
		
  	
                  
                
              
              
                Tags:
              
              
  
  
    
      
      
      
        
          
            Xcode
          
        
        
      
      
    
      
      
      
        
          
            Xcode Sanitizers and Runtime Issues
          
        
        
      
      
    
      
      
      
        
          
            Core Data
          
        
        
      
      
    
      
      
      
        
          
            SwiftData
          
        
        
      
      
    
  
  
              
                
                
              
            
          
                    
                      Hi guys. Can someone please confirm this bug so I report it? The issue is that SwiftData relationships don't update the views in some specific situations on devices running iOS 18 Beta. One clear example is with CloudKit. I created a small example for testing. The following code creates two @models, one to store bands and another to store their records. The following code works with no issues. (You need to connect to a CloudKit container and test it on two devices)
import SwiftUI
import SwiftData
struct ContentView: View {
    @Environment(\.modelContext) private var modelContext
    @Query private var records: [Record]
    var body: some View {
       NavigationStack {
          List(records) { record in
             VStack(alignment: .leading) {
                Text(record.title)
                Text(record.band?.name ?? "Undefined")
             }
          }
          .toolbar {
              ToolbarItem {
                 Button("Add Record") {
                    let randomNumber = Int.random(in: 1...100)
                    
                    let newBand = Band(name: "New Band \(randomNumber)", records: nil)
                    modelContext.insert(newBand)
                    
                    let newRecord = Record(title: "New Record \(randomNumber)", band: newBand)
                    modelContext.insert(newRecord)
                 }
              }
          }
       }
    }
}
@Model
final class Record {
   var title: String = ""
   var band: Band?
   init(title: String, band: Band?) {
      self.title = title
      self.band = band
   }
}
@Model
final class Band {
   var name: String = ""
   var records: [Record]?
   init(name: String, records: [Record]?) {
      self.name = name
      self.records = records
   }
}
This view includes a button at the top to add a new record associated with a new band. The data appears on both devices, but if you include more views inside the List, the views on the second device are not updated to show the values of the relationships. For example, if you extract the row to a separate view, the second device shows the relationships as "Undefined". You can try the following code.
struct ContentView: View {
    @Environment(\.modelContext) private var modelContext
    @Query private var records: [Record]
    var body: some View {
       NavigationStack {
          List {
             ForEach(records) { record in
                RecordRow(record: record)
             }
          }
          .toolbar {
              ToolbarItem {
                 Button("Add Record") {
                    let randomNumber = Int.random(in: 1...100)
                    
                    let newBand = Band(name: "New Band \(randomNumber)", records: nil)
                    modelContext.insert(newBand)
                    
                    let newRecord = Record(title: "New Record \(randomNumber)", band: newBand)
                    modelContext.insert(newRecord)
                 }
              }
          }
       }
    }
}
struct RecordRow: View {
   let record: Record
   var body: some View {
      VStack(alignment: .leading) {
         Text(record.title)
         Text(record.band?.name ?? "Undefined")
      }
   }
}
Here I use a ForEach loop and move the row to a separate view. Now on the second device the relationships are nil, so the row shows the text "Undefined" instead of the name of the band.
I attached an image from my iPad. I inserted all the information on my iPhone. The first three rows were inserted with the first view. But the last two rows were inserted after I extracted the rows to a separate view. Here you can see that the relationships are nil and therefore shown as "Undefined". The views are not updated to show the real value of the relationship.
This example shows the issue with CloudKit, but this also happens locally in some situations. The system doesn't detect updates in relationships and therefore doesn't refresh the views.
Please, let me know if you can reproduce the issue. I'm using Mac Sequoia 15.1, and two devices with iOS 18.0.
                    
                  
                
                    
                      Some users of my app are reporting total loss of data while using the app.
This is happening specifically when they enable iCloud sync.
I am doing following
private func setupContainer(enableICloud: Bool) {
    container = NSPersistentCloudKitContainer(name: "")
    container.viewContext.automaticallyMergesChangesFromParent = true
    container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
    guard let description: NSPersistentStoreDescription = container.persistentStoreDescriptions.first else {
        fatalError()
    }
    description.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey)
    description.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey)
    if enableICloud == false {
        description.cloudKitContainerOptions = nil
    }
    container.loadPersistentStores { description, error in
        if let error {
            // Handle error
        }
    }
}
When user clicks on Toggle to enable/disable iCloud sync I just set the description.cloudKitContainerOptions to nil and then user is asked to restart the app.
Apart from that I periodically run the clear history
func deleteTransactionHistory() {
    let sevenDaysAgo = Calendar.current.date(byAdding: .day, value: -7, to: Date())!
    let purgeHistoryRequest = NSPersistentHistoryChangeRequest.deleteHistory(before: sevenDaysAgo)
    let backgroundContext = container.newBackgroundContext()
    backgroundContext.performAndWait {
        try! backgroundContext.execute(purgeHistoryRequest)
    }
}
                    
                  
                
                    
                      Hi Folks,
starting with iOS18 and using Xcode16, accessing fetchedProperties results in an error. I identified the issue to occur as soon as the initialization of a fetched property with external binary data storage starts.
Console output during debugging:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'This expression has evaluation disabled'
*** First throw call stack:
[...]
libc++abi: terminating due to uncaught exception of type NSException
Console output when trying to "print" the item via the contact menu of the debugger:
Printing description of variable:
error: error: Execution was interrupted, reason: internal ObjC exception breakpoint(-6)..
The process has been returned to the state before expression evaluation.
Message from debugger: killed
The identical code works with iOS before iOS 18 (same for iPadOS 18).
Does anyone observed a similar issue and figured out a solution already?
Cheers,
folox
                    
                  
                
                    
                      I'm seeing a lot of these in my logs:
PersistentIdentifier PersistentIdentifier(id: SwiftData.PersistentIdentifier.ID(url: x-swiftdata://Course/BC9CF99A-DE6A-46F1-A18D-8034255A56D8), implementation: SwiftData.PersistentIdentifierImplementation) was remapped to a temporary identifier during save: PersistentIdentifier(id: SwiftData.PersistentIdentifier.ID(url: x-coredata:///Course/t58C849CD-D895-4773-BF53-3F63CF48935B210), implementation: SwiftData.PersistentIdentifierImplementation). This is a fatal logic error in DefaultStore
... though everything seems to work.
Does anyone know what this means in this context? Anything I can do to not have this appear?
                    
                  
                
                    
                      Is it possible to track history using the new HistoryDescriptor feature in SwiftData? Or can I only get the current most recent data? Or is it possible to output the changed data itself, along with timestamps?
I am hoping that it is possible to track by a standard feature like NSPersistentHistoryTransaction in CoreData.
Do we still have to use a method in SwiftData that creates more tracking data itself?
                    
                  
                
                    
                      I'm using NSPersistentCloudKitContainer and in the CloudKit dashboards I have added indexes for all my records modifiedTimestamp queryable, modifiedTimestamp sortable and recordName queryable.
But I'm still getting this warning message in the console.
<CKError 0x302acf0c0: "Invalid Arguments" (12/2015); server message = "Field 'recordName' is not marked queryable"; op = FF68EFF8D501AED8; uuid = 12C5C84B-EA9B-41A6-AD85-34023827E6FA; container ID = "z.y.x">
error: CoreData+CloudKit: -[NSCloudKitMirroringDelegate _importFinishedWithResult:importer:](1400): <PFCloudKitImporter: 0x30316c1c0>: Import failed with error:
<CKError 0x302acf0c0: "Invalid Arguments" (12/2015); server message = "Field 'recordName' is not marked queryable"; op = FF68EFF8D501AED8; uuid = 12C5C84B-EA9B-41A6-AD85-34023827E6FA; container ID = "z.y.x">
error: CoreData+CloudKit: -[NSCloudKitMirroringDelegate recoverFromError:](2312): <NSCloudKitMirroringDelegate: 0x301b1cd20> - Attempting recovery from error: <CKError 0x302acf0c0: "Invalid Arguments" (12/2015); server message = "Field 'recordName' is not marked queryable"; op = FF68EFF8D501AED8; uuid = 12C5C84B-EA9B-41A6-AD85-34023827E6FA; container ID = "z.y.x">
error: CoreData+CloudKit: -[NSCloudKitMirroringDelegate _recoverFromError:withZoneIDs:forStore:inMonitor:](2622): <NSCloudKitMirroringDelegate: 0x301b1cd20> - Failed to recover from error: CKErrorDomain:12
Recovery encountered the following error: (null):0
error: CoreData+CloudKit: -[NSCloudKitMirroringDelegate resetAfterError:andKeepContainer:](612): <NSCloudKitMirroringDelegate: 0x301b1cd20> - resetting internal state after error: <CKError 0x302acf0c0: "Invalid Arguments" (12/2015); server message = "Field 'recordName' is not marked queryable"; op = FF68EFF8D501AED8; uuid = 12C5C84B-EA9B-41A6-AD85-34023827E6FA; container ID = "z.y.x">
error: CoreData+CloudKit: -[NSCloudKitMirroringDelegate _requestAbortedNotInitialized:](2200): <NSCloudKitMirroringDelegate: 0x301b1cd20> - Never successfully initialized and cannot execute request '<NSCloudKitMirroringImportRequest: 0x300738eb0> A3F23AAC-F820-4044-B4B9-28DFAC4DE8D7' due to error: <CKError 0x302acf0c0: "Invalid Arguments" (12/2015); server message = "Field 'recordName' is not marked queryable"; op = FF68EFF8D501AED8; uuid = 12C5C84B-EA9B-41A6-AD85-34023827E6FA; container ID = "z.y.x">
                    
                  
                
                    
                      I am encountering an issue with the UndoManager functionality in a SwiftUI application that integrates SwiftData for persistence. This issue occurs specifically in macOS 14 (Sonoma) but works as expected on macOS 15 (Sequoia).
The focused test app I have prepared for demonstration allows users to create ParentItem objects, and for each ParentItem, users can add multiple ChildItem objects. The undo functionality (via Cmd+Z) is not working as expected in Sonoma. When I try to undo a ChildItem addition, the UndoManager does not revert just the last ChildItem added, but instead removes all ChildItems that were added in that session.
Expected Behavior
On macOS 14 (Sonoma), I expect the UndoManager to undo only the most recent transaction (in this case, a single ChildItem insert), similar to how it functions on macOS 15 (Sequoia). Each ChildItem insertion should be treated as a separate undoable action.
Current Behavior
In macOS Sonoma, pressing Cmd+Z undoes the entire list of ChildItems added to a ParentItem in the current session, rather than just the most recent ChildItem. This appears to be an issue with undo grouping, but I’ve confirmed that no explicit grouping is being used.
Question
Is this an issue with UndoManager in macOS Sonoma, particularly in how it interacts with SwiftData persistence? What changes should I make to ensure that each ChildItem insert is treated as an individual undo action in macOS Sonoma, just as it works in Sequoia?
Any guidance on isolating the issue or recommended workarounds would be appreciated. I would expect that undo actions for each child addition would be treated as separate transactions, not grouped.
Steps Taken to Solve the Problem
I attempted to manually save the model context (modelContext.save()) after each ChildItem insert to ensure proper persistence.
I also verified that UndoManager was not grouping operations explicitly by calling beginUndoGrouping() or endUndoGrouping() myself.
This issue seems to be tied specifically to macOS Sonoma, as it does not occur on macOS Sequoia, where undoing behaves as expected.
Conditions
macOS 14 Sonoma: The issue occurs consistently.
macOS 15 Sequoia: The issue does not occur.
This issue appears to be independent of hardware, as I’ve tested it on multiple machines.
APIs/Features Potentially Involved
UndoManager in a SwiftUI application
SwiftData for persistence (using modelContext.save())
macOS version-specific behavior
Steps to reproduce
Clone test project (https://github.com/Maschina/SwiftDataUndoManagerExample), compile and run
Create a new ParentItem in the app (via plus toolbar button in the sidebar).
Add multiple ChildItems to the ParentItem (via plus toolbar button in the content / middle column of the navigation split view).
Press Cmd+Z to undo the last addition.
                    
                  
                
                    
                      I have a strange crash which I have problems understanding. It only happens on a few devices, after a ModelContainer migration, and it doesn't seem to crash on the migration itself.
The fetch is done in onAppear, and shouldn't necessarily result in a crash, as it is an optional try:
let request = FetchDescriptor<Rifle>()
let data = try? modelContext.fetch(request)
if let data, !data.isEmpty {
    rifle = data.first(where: { $0.uuid.uuidString == settings.selectedRifleId }) ?? data.first!
}
When I get logs from users, there seems to be an error in encoding?
Exception Type:  EXC_BREAKPOINT (SIGTRAP)
Exception Codes: 0x0000000000000001, 0x000000018e8bfd78
Termination Reason: SIGNAL 5 Trace/BPT trap: 5
Terminating Process: exc handler [71687]
Triggered by Thread:  0
Thread 0 name:   Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0   libswiftCore.dylib            	       0x18e8bfd78 _assertionFailure(_:_:file:line:flags:) + 264
1   SwiftData                     	       0x24e18b480 0x24e14c000 + 259200
2   SwiftData                     	       0x24e193968 0x24e14c000 + 293224
3   SwiftData                     	       0x24e195a78 0x24e14c000 + 301688
4   libswiftCore.dylib            	       0x18e8e4084 _KeyedEncodingContainerBox.encodeNil<A>(forKey:) + 352
5   libswiftCore.dylib            	       0x18e8d79f0 KeyedEncodingContainer.encodeNil(forKey:) + 64
6   SwiftData                     	       0x24e19f09c 0x24e14c000 + 340124
7   SwiftData                     	       0x24e1a3dec 0x24e14c000 + 359916
8   libswiftCore.dylib            	       0x18ec10be8 dispatch thunk of Encodable.encode(to:) + 32
9   SwiftData                     	       0x24e1cd500 0x24e14c000 + 529664
10  SwiftData                     	       0x24e1cd0c8 0x24e14c000 + 528584
11  SwiftData                     	       0x24e1da960 0x24e14c000 + 584032
12  SwiftData                     	       0x24e1ee2ec 0x24e14c000 + 664300
13  SwiftData                     	       0x24e1d97d8 0x24e14c000 + 579544
14  SwiftData                     	       0x24e1eada0 0x24e14c000 + 650656
15  SwiftData                     	       0x24e1d989c 0x24e14c000 + 579740
16  SwiftData                     	       0x24e1eee78 0x24e14c000 + 667256
17  Impact                        	       0x1027403bc 0x10268c000 + 738236
                    
                  
                
                    
                      I'm using Swift Data for an app that requires iOS 18.
All of my models conform to a protocol that guarantees they have a 'serverID' String variable.
I wrote a function that would allow me to pass in a serverID String and have it fetch the model object that matched. Because I am lazy and don't like writing the same functions over and over, I used a Self reference so that all of my conforming models get this static function.
Imagine my model is called "WhatsNew". Here's some code defining the protocol and the fetching function.
protocol RemotelyFetchable: PersistentModel {
    var serverID: String { get }
}
extension WhatsNew: RemotelyFetchable {}
extension RemotelyFetchable {
    static func fetchOne(withServerID identifier: String, inContext modelContext: ModelContext) -> Self? {
        var fetchDescriptor = FetchDescriptor<Self>()
        fetchDescriptor.predicate = #Predicate<Self> { $0.serverID == identifier }
        do {
            let allModels = try modelContext.fetch(fetchDescriptor)
            
            return allModels.first
        } catch {
            return nil
        }
    }
}
Worked great! Or so I thought...
I built this and happily ran a debug build in the Simulator and on devices for months while developing the initial version but when I went to go do a release build for TestFlight, that build reliably crashed on every device with a message like this:
SwiftData/DataUtilities.swift:65: Fatal error: Couldn't find \WhatsNew. on WhatsNew with fields [SwiftData.Schema.PropertyMetadata(name: "serverID", keypath: \WhatsNew., defaultValue: nil, metadata: Optional(Attribute - name: , options: [unique], valueType: Any, defaultValue: nil, hashModifier: nil)), SwiftData.Schema.PropertyMetadata(name: "title", keypath: \WhatsNew., defaultValue: nil, metadata: nil), SwiftData.Schema.PropertyMetadata(name: "bulletPoints", keypath: \WhatsNew.)>, defaultValue: nil, metadata: nil), SwiftData.Schema.PropertyMetadata(name: "dateDescription", keypath: \WhatsNew., defaultValue: nil, metadata: nil), SwiftData.Schema.PropertyMetadata(name: "readAt", keypath: \WhatsNew.)>, defaultValue: nil, metadata: nil)]
It seems (cannot confirm) that something in the release build optimization process is stripping out some metadata / something about these models that makes this predicate crash.
Tested on iOS 18.0 and 18.1 beta.
How can I resolve this? I have two dozen types that conform to this protocol. I could manually specialize this function for every type myself but... ugh.
                    
                  
                
                    
                      Hi,
I have a mac os app that I am developing. It is backed by a SwiftData database. I'm trying to set up cloudkit so that the app's data can be shared across the user's devices. However, I'm finding that every tutorial i find online makes it sound super easy, but only discusses it from the perspective of ios.
The instructions typically say:
Add the iCloud capability.
Select CloudKit from its options.
Press + to add a new CloudKit container, or select one of your existing ones.
Add the Background Modes capability.
Check the box "Remote Notifications" checkbox from its options.
I'm having issue with the following:
I don't see background modes showing up or remote notifications checkbox since i'm making a mac os app.
If i do the first 3 steps only, when i launch my app i get an app crash while trying to load the persistent store. Here is the exact error message:
Add the iCloud capability.
Select CloudKit from its options.
Press + to add a new CloudKit container, or select one of your existing ones.
Add the Background Modes capability.
Check the box "Remote Notifications" checkbox from its options.
Any help would be greatly appreciated.
 var sharedModelContainer: ModelContainer = {
        let schema = Schema([One.self, Two.self])
        let modelConfiguration = ModelConfiguration(schema: schema, isStoredInMemoryOnly: false)
        do {
            return try ModelContainer(for: schema, configurations: [modelConfiguration])
        } catch {
            fatalError("Could not create ModelContainer: \(error)")
        }
    }()
The fatal error in the catch block happens when i run the app.
                    
                  
                
                    
                      I have a project that currently has data saved locally and I'm trying to get it to sync over multiple devices.
Currently basic data is syncing perfectly fine, but I'm having issues getting the images to convert to data. From what I've researched it because I'm using a UIImage to convert and this caches the image
It works fine when there's only a few images, but if there's several its a pain
The associated code
    func updateLocalImages() {
        autoreleasepool {
            let fetchRequest: NSFetchRequest<Project> = Project.fetchRequest()
            fetchRequest.predicate = NSPredicate(format: "converted = %d", false)
            fetchRequest.sortDescriptors = [NSSortDescriptor(keyPath: \Project.statusOrder?.sortOrder, ascending: true), NSSortDescriptor(keyPath: \Project.name, ascending: true)]
            
            do {
                let projects = try viewContext.fetch(fetchRequest)
                for project in projects {
                    currentPicNumber = 0
                    currentProjectName = project.name ?? "Error loading project"
                    if let pictures = project.pictures {
                        projectPicNumber = pictures.count
                        for pic in pictures {
                            currentPicNumber = currentPicNumber + 1
                            let picture : Picture = pic as! Picture
                            if let imgData = convertImage(picture: picture) {
                                picture.pictureData = imgData
                            }
                        }
                        project.converted = true
                        saveContext()
                    }
                }
            } catch {
                print("Fetch Failed")
            }
        }
    }
    
    func convertImage(picture : Picture)-> Data? {
        let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
        let path = paths[0]
        if let picName = picture.pictureName {
            let imagePath = path.appendingPathComponent(picName)
            if let uiImage = UIImage(contentsOfFile: imagePath.path) {
                if let imageData = uiImage.jpegData(compressionQuality: 0.5) {
                    return imageData
                }
            }
        }
        return nil
    }```
                    
                  
                
                    
                      I created a new index on two record types on Oct 12th. I still cannot query the records using the new queryable index on records that were created before that date. There is no indication in the schema history that the reindexing has started, completed, failed, or still in progress.
What is the expectation for new indices being applied to existing records? Well over a week seems unacceptable for a database that has maybe 5000 records across a few record types.
When I query my data using an old index and an old record field, I get hundreds of matching results so I know the data is there.
FB15554144 - CloudKit / CloudKit Console: PRODUCTION ISSUE - Query against index created two weeks ago not returning all data as expected
                    
                  
                
              
                
              
              
                
                Topic:
                  
	
		App & System Services
  	
                
                
                SubTopic:
                  
                    
	
		iCloud & Data
		
  	
                  
                
              
              
                Tags:
              
              
  
  
    
      
      
      
        
          
            App Store
          
        
        
      
      
    
      
      
      
        
          
            CloudKit
          
        
        
      
      
    
      
      
      
        
          
            CloudKit Console
          
        
        
      
      
    
      
      
      
        
          
            CloudKit Dashboard
          
        
        
      
      
    
  
  
              
                
                
              
            
          
                    
                      Hi,
I did cloudkit synchronization using swiftdata.
However, synchronization does not occur automatically, and synchronization occurs intermittently only when the device is closed and opened.
For confirmation, after changing the data in Device 1 (saving), when the data is fetched from Device 2, there is no change.
I've heard that there's still an issue with swiftdata sync and Apple is currently troubleshooting it, is the phenomenon I'm experiencing in the current version normal?
                    
                  
                
                    
                      Hello,
SwiftData is not working correctly with Swift Concurrency. And it’s sad after all this time.
I personally found a regression. The attached code works perfectly fine on iOS 17.5 but doesn’t work correctly on iOS 18 or iOS 18.1.
A model can be updated from the background (Task, Task.detached or ModelActor) and refreshes the UI, but as soon as the same item is updated from the View (fetched via a Query), the next background updates are not reflected anymore in the UI, the UI is not refreshed, the updates are not merged into the main.
How to reproduce:
Launch the app
Tap the plus button in the navigation bar to create a new item
Tap on the “Update from Task”, “Update from Detached Task”, “Update from ModelActor” many times
Notice the time is updated
Tap on the “Update from View” (once or many times)
Notice the time is updated
Tap again on “Update from Task”, “Update from Detached Task”, “Update from ModelActor” many times
Notice that the time is not update anymore
Am I doing something wrong? Or is this a bug in iOS 18/18.1?
Many other posts talk about issues where updates from background thread are not merged into the main thread. I don’t know if they all are related but it would be nice to have
1/ bug fixed, meaning that if I update an item from a background, it’s reflected in the UI, and
2/ proper documentation on how to use SwiftData with Swift Concurrency (ModelActor). I don’t know if what I’m doing in my buttons is correct or not.
Thanks,
Axel
import SwiftData
import SwiftUI
@main
struct FB_SwiftData_BackgroundApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
                .modelContainer(for: Item.self)
        }
    }
}
struct ContentView: View {
    @Environment(\.modelContext) private var modelContext
    
    @State private var simpleModelActor: SimpleModelActor!
    @Query private var items: [Item]
    
    var body: some View {
        NavigationView {
            VStack {
                if let firstItem: Item = items.first {
                    Text(firstItem.timestamp, format: Date.FormatStyle(date: .omitted, time: .standard))
                        .font(.largeTitle)
                        .fontWeight(.heavy)
                    
                    Button("Update from Task") {
                        let modelContainer: ModelContainer = modelContext.container
                        let itemID: Item.ID = firstItem.persistentModelID
                        
                        Task {
                            let context: ModelContext = ModelContext(modelContainer)
                            
                            guard let itemInContext: Item = context.model(for: itemID) as? Item else { return }
                            
                            itemInContext.timestamp = Date.now.addingTimeInterval(.random(in: 0...2000))
                            try context.save()
                        }
                    }
                    .buttonStyle(.bordered)
                    
                    Button("Update from Detached Task") {
                        let container: ModelContainer = modelContext.container
                        let itemID: Item.ID = firstItem.persistentModelID
                        
                        Task.detached {
                            let context: ModelContext = ModelContext(container)
                            
                            guard let itemInContext: Item = context.model(for: itemID) as? Item else { return }
                            
                            itemInContext.timestamp = Date.now.addingTimeInterval(.random(in: 0...2000))
                            
                            try context.save()
                        }
                    }
                    .buttonStyle(.bordered)
                    
                    Button("Update from ModelActor") {
                        let container: ModelContainer = modelContext.container
                        let persistentModelID: Item.ID = firstItem.persistentModelID
                        
                        Task.detached {
                            let actor: SimpleModelActor = SimpleModelActor(modelContainer: container)
                            await actor.updateItem(identifier: persistentModelID)
                        }
                    }
                    .buttonStyle(.bordered)
                    
                    Button("Update from ModelActor in State") {
                        let container: ModelContainer = modelContext.container
                        let persistentModelID: Item.ID = firstItem.persistentModelID
                        
                        Task.detached {
                            let actor: SimpleModelActor = SimpleModelActor(modelContainer: container)
                            
                            await MainActor.run {
                                simpleModelActor = actor
                            }
                            
                            await actor.updateItem(identifier: persistentModelID)
                        }
                    }
                    .buttonStyle(.bordered)
                    
                    Divider()
                        .padding(.vertical)
                
                    Button("Update from View") {
                        firstItem.timestamp = Date.now.addingTimeInterval(.random(in: 0...2000))
                    }
                    .buttonStyle(.bordered)
                } else {
                    ContentUnavailableView(
                        "No Data",
                        systemImage: "slash.circle", // 
                        description: Text("Tap the plus button in the toolbar")
                    )
                }
            }
            .toolbar {
                ToolbarItem(placement: .primaryAction) {
                    Button(action: addItem) {
                        Label("Add Item", systemImage: "plus")
                    }
                }
            }
        }
    }
    
    private func addItem() {
        modelContext.insert(Item(timestamp: Date.now))
        try? modelContext.save()
    }
}
@ModelActor
final actor SimpleModelActor {
    var context: String = ""
    func updateItem(identifier: Item.ID) {
        guard let item = self[identifier, as: Item.self] else {
            return
        }
        item.timestamp = Date.now.addingTimeInterval(.random(in: 0...2000))
        
        try! modelContext.save()
    }
}
@Model
final class Item: Identifiable {
    var timestamp: Date
    
    init(timestamp: Date) {
        self.timestamp = timestamp
    }
}
                    
                  
                
                    
                      I'm continually getting an error with a new CloudKit container when I try to save data.
error: Couldn't get container configuration from the server for container "iCloud.com.***.***"
here's the class:
private var db = CKContainer(identifier: "iCloud.com.***.***").privateCloudDatabase
func addTask(taskItem: TaskItem) async throws {
    checkStatus()
    do {
        try await db.save(taskItem.record)
    } catch {
        print("error: \(error.localizedDescription)")
    }
}
func checkStatus()  {
    let id = CKContainer(identifier: "iCloud.com.***.***").containerIdentifier
    print(id ?? "unknown")
    Task {
        let status = try await CKContainer(identifier: "iCloud.com.***.***").accountStatus()
        switch status {
            case .available:
            print("available")
        case .noAccount:
            print("no account")
        case .restricted:
            print("restricted")
        case .couldNotDetermine:
            print("could not determine")
        case .temporarilyUnavailable:
            print("temporarily unavailable")
        @unknown default: break
        }
    }
}
The account status reports as available but gives the error on an attempt to save.. I'm trying to work out what I might be doing wrong..
                    
                  
                
                    
                      Is it possible to use CloudKit and add integrations, Google Drive for example. If possible, how?