Since working with iOS, I really like the delegate pattern, in which it helps us defer the decision to another party.
The iOS application delegates its event to AppDelegate, which over time will be a big mess. Usually, the AppDelegate is where you put your root view controller setup, crash tracking, push notification, debugging, … and we just somehow violent the Single Responsibility principle. Moreover, it makes us hard to reason about code in AppDelegate
Service
I like to think of each task in AppDelegate as a service. And the AppDelegate distributes the events into each service via ServiceDispatcher. Simple plain old composition and looping
I tend to have RootService as a place to setup root view controllers
services.forEach { service in service.application?(application, didFinishLaunchingWithOptions: launchOptions) }
returntrue }
funcapplicationDidBecomeActive(application: UIApplication) { services.forEach { service in service.applicationDidBecomeActive?(application) } }
funcapplicationWillResignActive(application: UIApplication) { services.forEach { service in service.applicationWillResignActive?(application) } }
funcapplicationWillEnterForeground(application: UIApplication) { services.forEach { service in service.applicationWillEnterForeground?(application) } }
funcapplicationDidEnterBackground(application: UIApplication) { services.forEach { service in service.applicationDidEnterBackground?(application) } } }
I have more services like DebugService, PushNotificationService, CrashTrackingService, …
The downside to this approach is that in real life, there will be dependencies between those services, like that UserService must be called before RootService? In this case, I have to use comment to explain why I have that decision, which is hard for newcomers to understand at first. Take a look at How to Move Bootstrapping Code Out of AppDelegate for how dependencies are managed
JSDecoupledAppDelegate comes with another approach, in which service events are named according to the functions, like appStateDelegate, appDefaultOrientationDelegate, watchInteractionDelegate, …
But for me, Service and ServiceDispatcher suit my need