NEW: Start my new Ultimate Portfolio App course with a free Hacking with Swift+ trial! >>

Generic functions without parameters?

Forums > Swift

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.

1      

Creating an extension to NSManagedObject doesn't work?

   

Hacking with Swift is sponsored by Fernando Olivares

SPONSORED Would you describe yourself as knowledgeable, but struggling when you have to come up with your own code? Fernando Olivares has a new book containing iOS rules you can immediately apply to your coding habits to see dramatic improvements, while also teaching applied programming fundamentals seen in refactored code from published apps.

Try the book!

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.