swiftswiftdata

Is there any SwiftData equivalent willSave?


With NSManagedObject there are a few hooks like awakeFromInsert() and willSave() among others. Are there methods to override that can serve the same function? awakeFromInsert can be replaced with the init method, but willSave() I currently use to update modification dates. I'd like an easy way to do those, rather than observing all the properties that would update the modification date.

I've tried looking at expanded macros from the @Model but haven't seen anything that it looks like I can override, or hook into.

A couple ways that I could do this is observe all the properties that would cause the modification date to update, or create custom function for each property that updates the modification date as well.

These both seem inelegant, error prone and hard to maintain. Anyone else have another solution?


Solution

  • ModelContext.willSave and ModelContext.didSave finally works on iOS 18.

    NotificationCenter.default.publisher(for: ModelContext.willSave)
        .receive(on: RunLoop.main)
        .sink { noti in
            guard let modelContext = noti.object as? ModelContext else { return }
        }
        .store(in: &cancellable)
    
    NotificationCenter.default.publisher(for: ModelContext.didSave)
        .receive(on: RunLoop.main)
        .sink { noti in
            guard let modelContext = noti.object as? ModelContext else { return }
            let changedModelsArray = modelContext.changedModelsArray
            let deletedModelsArray = modelContext.deletedModelsArray
            let insertedModelsArray = modelContext.insertedModelsArray
            if let userInfo = noti.userInfo {
                let inserted = (userInfo["inserted"] as? [PersistentIdentifier]) ?? []
                let deleted = (userInfo["deleted"] as? [PersistentIdentifier]) ?? []
                let updated = (userInfo["updated"] as? [PersistentIdentifier]) ?? []
            }
        }
        .store(in: &cancellable)