NEW: Subscribe to Hacking with Swift+ and accelerate your learning! >>

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 Paw

SPONSORED Use Paw to build, test and describe web APIs. Paw has a lightning fast native macOS interface to compose requests, collaborate in real-time on API specs, and generate client code for your applications. You can import and export API definitions.

Discover Paw for Mac

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

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

Not logged in

Log in
 

Link copied to your pasteboard.