3 Ways to Observe App’s Lifecycle in SwiftUI
There are things that weren’t that difficult in UIKit but in SwiftUI. Tracking an app’s life cycle is one of those things. We’ve had to write extra codes to track the status such as applicationWillEnterForeground or applicationDidEnterBackground which are provided in AppDelegate
(or SceneDelegate
).
In fact, rather than turning the app back to the past version, there are possible solutions to make things much easier in SwiftUI. I’d like to introduce how I handled this and show you some examples in this post.
Summary
- Bring
AppDelegate
andSceneDelegate
back (iOS 13+) scenePhase
,.onChange
and.onOpenUrl
(iOS 14+)NotificationCenter
(iOS 4+) andCombine
(iOS 13+)
Reference
1. Bring AppDelegate and SceneDelegate back (iOS 13+)
One way of doing this is to bring AppDelegate
and SceneDelegate
back. It would be the most familiar way for those who have been developing iOS apps before SwiftUI was introduced. Here’s an example:
You can also skip SceneDelegate
. Then you go back to even much old-fashioned way of using only AppDelegate
to manage events.
I’m not sure how long these delegates will still be supported, but for now, it doesn’t seem like a big deal.
2. Use scenePhase with .onChange (iOS 14+)
Transition from UIKit to SwiftUI in iOS 13 was a real pain in the ass. Compared to UIKit, a lot of features were not implemented and building view components was really annoying.
Anyway, in iOS 14, Apple came up with several improvements for SwiftUI. scenePhase
and .onChange
are the parts of those things. Let me show you an example.
As you can see, it’s very easy to use. However, there is a critical shortcoming that scenePhase
only offers three status: active
, inactive
, background
.
For those who imagined a perfect replacement of AppDelegate
, it would be a big disappointment. Besides that, the availability(iOS 14 +) is another barrier that makes developers reluctant to use.
+ onOpenURL
(iOS 14+)
Ever since the Universal link was introduced, it has become a common way to open an app. As you may know, SceneDelegate
or AppDelegate
has been dealing with opened by url event. That also means, in SwiftUI, we should find other ways to get this event.
Fortunately, Apple offers the method onOpenURL
from iOS 14 that enables us to get the opened by url event anywhere in a project.
If you are interested, you can take a look at Universal link and custom scheme link.
3. NotificationCenter (iOS 4+)
It is another traditional way to observe life cycle events with Swift. Within the class UIApplication
, several notifications are provided by iOS(UIApplicationDelegate | Apple Developer Documentation).
Especially, in the document, notifications at the category Responding to App Life-Cycle Events are related to the life cycle events. All you have to do is just picking up a proper notification for your purpose.
I’ll show you two examples to get notified the moment the app is entering or did enter each status with those Notification
s.
A. NotificationCenter + addObserver (iOS 4+)
It’s’ pretty simple and straightforward to understand. Choose proper Notification
among the given ones and add it to NotificationCenter
using addObserver
. It works fine as you can see.
B. NotificationCenter + Combine (iOS 13+)
As you can see in here, Apple offers a way to route Notifications
to Combine
subscribers from iOS 13.
It may seem like there is no advantage over using addObserver
, but actually it has really powerful features. With this, you can write a function making a Publisher
like below.
You can make it more useful by categorizing events with enum
and giving it to the function as a parameter.
Also you can utilize it in a variety of ways by wrapping the method.
Now we have a very useful life cycle observer which you can add features to as many as you want.
You can choose one of them according to your needs but I personally prefer the last method using Combine
. Publisher
definitely has advantages over the others because it goes well with SwiftUI and Apple keeps trying to expand support for Combine
.
Thanks for reading it!