WWDC 2020 is just over and Apple announced a lot new interesting features. One of these new features is the ability to create apps entirely with SwiftUI. Up until this year's release it was necessary to leverage elements from UIKit
and AppKit
to define the entry points for your apps. With iOS 14 it will be possible to create apps without the need of this workaround.
Imagine we want to build an ice cream ordering app with two tabs, one for ordering and one for the settings. With the @main
annotation and conforming to the new App
protocol we tell iOS to use the following code as the main entry point to our application.
@main
struct IceCreamApp: App {
var body: some Scene {
WindowGroup {
TabView {
OrderView()
SettingsView()
}
}
}
}
Just a few lines were necessary to create a fully functional entry point for our app. No more AppDelegate
, SceneDelegate
or UIHostingViewController
, only plain and concise SwiftUI code.
Scene protocol
In the code above we used the new WindowGroup
type which conforms to the new Scene
protocol. The Scene
protocol is the SwiftUI equivalent to the UIScene
API that was introduced with iOS 13. It is even possible to create custom Scene
conforming types, but if you always want to render the same view hierarchy you can stick to WindowGroup
, which is a great default.
Alongside the new Scene
protocol a new environment variable, called scenePhase
, is introduced. With that, we can observe when and how the phase of a scene is changed. For example when a scene has become active
or inactive
.
@main
struct IceCreamApp: App {
@Environment(\.scenePhase) private var scenePhase
var body: some Scene {
WindowGroup {
...
}.onChange(of: scenePhase) { newPhase in
switch newPhase {
case .active:
print("Scene is in the foreground and is active")
case .inactive:
print("Scene is in the foreground but should pause its work")
case .background:
print("Scene is currently not visible in the UI")
@unknown default:
print("Scene case not handled yet")
}
}
}
}
What's about AppDelegate ?
Now you may ask what do to with code that needs to run on certain AppDelegate
lifecycle methods. No worries - there is still a way to access the lifecycle methods of the AppDelegate
. For that we create a class that conforms to the UIApplicationDelegate
protocol and hook it up the @UIApplicationDelegateAdaptor
property wrapper into our app.
class AppDelegate: NSObject, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
print("didFinishLaunchingWithOptions")
return true
}
}
@main
struct IceCreamApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
...
}
Within the newly created class you can access every lifecycle method that you need and execute the code you want.
Conclusion
With iOS 14 the SwiftUI frameworks gained a lot functionality. It is a huge step forward for the SwiftUI framework and enables developer to write their apps with SwiftUI only. It is clearly visible that Apple is pushing SwiftUI to make it the default way to write apps in the future.
Thanks a lot for reading 👋