2 years ago

#77239

test-img

zumzum

Combine two publishers in swift to observe NSManagedObjects?

I have the following publisher:

    func publisher<T: NSManagedObject>(for managedObject: T, in context: NSManagedObjectContext, changeTypes: [ChangeType]) -> AnyPublisher<(object: T, type: ChangeType), Never> {

        let notification = NSManagedObjectContext.didSaveObjectIDsNotification
//        let notification = NSManagedObjectContext.didMergeChangesObjectIDsNotification
        return NotificationCenter.default.publisher(for: notification, object: context)
            .compactMap({ notification in
                for type in changeTypes {
                    if let object = self.managedObject(with: managedObject.objectID, changeType: type, from: notification, in: context) as? T {
                        return (object, type)
                    }
                }
                return nil
            })
            .eraseToAnyPublisher()
    }

This allows me to observe around the app a certain change type affecting a certain NSManagedObject when the object is saved on the given context. So I can either be notified of a save on that context for the object or be notified of the merge into that context. I cannot be notified for both at the same time.

If I want to observe the object when it changes on a different context and it is then merged into the context I pass in then I can do that by using the other notification:

let notification = NSManagedObjectContext.didMergeChangesObjectIDsNotification

I would like to modify this function so that it can be used to be notified on both notifications types, meaning both on NSManagedObjectContext.didSaveObjectIDsNotification and NSManagedObjectContext.didMergeChangesObjectIDsNotification at the same time.

The function used inside the call is this:

private func managedObject(with id: NSManagedObjectID, changeType: ChangeType, from notification: Notification, in context: NSManagedObjectContext) -> NSManagedObject? {
    guard let objects = notification.userInfo?[changeType.userInfoKey] as? Set<NSManagedObjectID>, objects.contains(id) else { return nil }
    return context.object(with: id)
}

and ChangeType:

enum ChangeType {
    
    case inserted, deleted, updated
    
    var userInfoKey: String {
        switch self {
        case .inserted: return NSInsertedObjectIDsKey
        case .deleted: return NSDeletedObjectIDsKey
        case .updated: return NSUpdatedObjectIDsKey
        }
    }
}

I tried to combine the two by creating two publishers in the function, one for each notification and then using merge to combine them, but, I couldn't get it working.

How can I combine the two notifications as publishers to be notified of both NSManagedObjectContext.didSaveObjectIDsNotification and NSManagedObjectContext.didMergeChangesObjectIDsNotification cases?

swift

core-data

combine

0 Answers

Your Answer

Accepted video resources