I am new to Swift, coming for a primaryly C++ background (with experience in Python, Java, C#, C, and Haskell), as such I am experimenting with eth Swifty way of doing things, but my approach may be clouded my baked in habits carried over from oter languages.
When working with CoreData
I have ended up with the the following code repeated code, where the only change is the TypeX
parameter passed to ManagedObjectContextChanges<Type2>(notification: $0)
private func observeChangeNotification() {
let cancellables1 = NotificationCenter.default.publisher(
for: .NSManagedObjectContextObjectsDidChange,
object: moc)
.compactMap({
ManagedObjectContextChanges<Type1>(notification: $0)
})
.sink { (changes) in print(changes) }
cancellables.append(cancellables1)
let cancellables2 = NotificationCenter.default.publisher(
for: .NSManagedObjectContextObjectsDidChange,
object: moc)
.compactMap({
ManagedObjectContextChanges<Type2>(notification: $0)
})
.sink { (changes) in print(changes) }
cancellables.append(cancellables2)
let cancellables3 = NotificationCenter.default.publisher(
for: .NSManagedObjectContextObjectsDidChange,
object: moc)
.compactMap({
ManagedObjectContextChanges<Type3>(notification: $0)
})
.sink { (changes) in print(changes) }
cancellables.append(cancellables3)
}
I would like to avoid duplicated code and the obvious choice is to use a Generic function. Unfortunatley Swift only support generic functions that use the Type parameter in the function signature. In this case there is no need to pass ot return any objects of the Type which is changing betwen function calls. My solution is to create a simple class that hosts the generic function, as follows:
private func observeChangeNotification() {
PublisherHelper<Widget>.generate(moc: moc, storage: &cancellables)
PublisherHelper<Event>.generate(moc: moc, storage: &cancellables)
PublisherHelper<EventAttribute>.generate(moc: moc, storage: &cancellables)
PublisherHelper<EventAttributeType>.generate(moc: moc, storage: &cancellables)
}
class PublisherHelper<T: NSManagedObject> {
static func generate(moc: NSManagedObjectContext,
storage: inout [AnyCancellable]) {
let cancellableVals = NotificationCenter.default.publisher(
for: .NSManagedObjectContextObjectsDidChange,
object: moc)
.compactMap({
ManagedObjectContextChanges<T>(notification: $0)
})
.sink { (changes) in print(changes) }
storage.append(cancellableVals)
}
All appears to be working as expected and I believe this is a neat solution, but I would like some feedback as to whether or not there is a better way.