Skip to content
This repository has been archived by the owner on Sep 23, 2023. It is now read-only.

Experiment with generating listener managers in Swift

License

Notifications You must be signed in to change notification settings

antonselyanin/ListenerManagerGenerator

Repository files navigation

ListenerManagerGenerator

This is an experimental repository for Sourcery stencil template for generating listener managers.

Let's say you have a Service class. This Service issues different events during its lifetime. The list of events can be expressed as a protocol or an enum. In this repo I wanted to explore the protocol option.

The events list protocol: ServiceEventListener

protocol ServiceEventListener: class {
    func connectionStateChanged(_ state: ServiceConnectionState)

    func serviceEvent1(event1: ServiceEvent1)

    func serviceEvent2(event2: ServiceEvent2, additionalContext: ServiceContext)

    func serviceReset()
}

Our Service should support multiple listeners, so we need to keep an array of listeners. When an event occurs, we run through the list of listeners and invoke a corresponding method. If we have lots of events and services - we will have to write a lot boilerplate code.

In Objective-C we could implement it via delegate proxies (refer to this article for more details: Smart Proxy Delegation).

In Swift we can generate all the boilerplate using Sourcery.

This stencil template generates the following code (container is a helper class that manages the list of listeners)

class ServiceEventListenerManager: ServiceEventListener {
    private let container: ListenerContainer<ServiceEventListener> = ListenerContainer()

    func addListener(_ listener: ServiceEventListener) {
        container.addListener(listener)
    }

    func removeListener(_ listener: ServiceEventListener) {
        container.removeListener(listener)
    }
    
    func connectionStateChanged(_ state: ServiceConnectionState) {
        container.forEach { listener in
            listener.connectionStateChanged(state)
        }
    }
    
    func serviceEvent1(event1: ServiceEvent1) {
        container.forEach { listener in
            listener.serviceEvent1(event1: event1)
        }
    }
    
    func serviceEvent2(event2: ServiceEvent2, additionalContext: ServiceContext) {
        container.forEach { listener in
            listener.serviceEvent2(event2: event2, additionalContext: additionalContext)
        }
    }
    
    func serviceReset() {
        container.forEach { listener in
            listener.serviceReset()
        }
    }
    
}

About

Experiment with generating listener managers in Swift

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published