When a new SwiftUI project is created in Xcode using the Single View App template, Xcode generates several files and folders which form the basis of the project, and on which the finished app will eventually be built.
Although it is not necessary to know in detail about the purpose of each of these files when beginning with SwiftUI development, each of them will become useful as you progress to developing more complex applications.
The goal of this chapter, therefore, is to provide a brief overview of each element of a basic project structure.
1.1 Creating an Example Project
It may be useful to create a sample project to review while working through this chapter. To do so, launch Xcode and, on the welcome screen, select the option to create a new project. On the resulting template selection panel, choose the Single View App option before proceeding to the next screen. On the project options screen, name the project ProjectDemo and change the User Interface menu to SwiftUI. Click Next to proceed to the final screen, choose a suitable filesystem location for the project and click on the Create button.
1.2 UIKit and SwiftUI
As discussed previously, before the introduction of SwiftUI, iOS apps were developed using UIKit. In recognition of this reality, Apple has provided a number of ways in which SwiftUI and UIKit code can be integrated within the same project.
It may not be obvious initially, but when creating a new SwiftUI based project, Xcode actually creates a UIKit-based app which uses these integration techniques to host the SwiftUI views that ultimately make up the app. Some of the files described in this chapter are, therefore, UIKit-based and all class names prefixed with “UI“ are UIKit classes.
1.3 The AppDelegate.swift File
Every iOS app has one instance of the UIApplication class which is responsible for handling events and managing the different UIWindow objects that will be used by the app to display user interfaces to the user. UIWindow instances are not visible to the user but instead provide containers to hold the visible objects that make up the user interface.
The UIApplication instance has associated with it a delegate which it notifies via method calls of significant events relating to the lifecycle of the app such as the app launching, incoming notifications, low device memory, the pending termination of the app and the creation of new scenes within the app.
By default, the AppDelegate.swift file generated by Xcode contains only the methods that are mandatory to comply with the AppDelegate protocol but others can be added for the app to receive notification of other app lifecycle events. These methods can be useful for implementing early app specific initialization tasks such as establishing a network connection or setting up database access. The didFinishLaunchingWithOptions method is particularly useful for adding initialization code since it is the first method to be called after the app has finished launching.
1.4 The SceneDelegate.swift File
The entire user interface of an app is represented as a scene in the form of a UIWindowScene object with a UIWindow child. It is important not to confuse this with a UIKit Storyboard scene which represents only a single screen within an app user interface. By default, an app will have only one scene, but with the introduction of multi-window support with iOS 13 it is also possible to configure an app to allow the creation of multiple instances of its user interface. On iPhone devices, the user switches between user interface copies using the app switcher while on the iPad, copies of the user interface can also appear side by side.
While multiple scenes all share the same UIApplication object, each of the UIWindowScene instances in a multi-window configuration has its own scene delegate instance.
The SceneDelegate class file implements the UIWindowSceneDelegate protocol and contains methods to handle events such as a new scene object connecting to the current session, the scene transitioning between background and foreground or a scene disconnecting from the app.
All of the SceneDelegate methods are useful for performing initialization and deinitialization tasks during the lifecycle of the app. The most important delegate method in this file, however, is the willConnectTo method which is called each time a new scene object is added to the app.
By default, the willConnectTo delegate method will have been implemented by Xcode to create an instance of the SwiftUI ContentView view declared in the ContentView.swift file and make it visible to the user. It is within this method that the gap between the UIKit architecture and SwiftUI is bridged.
In order to embed a SwiftUI view into a UIKit project, the SwiftUI view is embedded into a UIHostingController instance (a topic covered in detail starting with the chapter entitled Integrating UIViews with SwiftUI). To achieve this, the willConnectTo delegate method performs the following tasks:
- Creates an instance of ContentView.
- Creates a new UIWindow instance.
- Embeds the ContentView instance into a UIHostingController instance.
- Assigns the UIHostingController as the root view controller for the newly created UIWindow instance.
- Replaces the scene’s current UIWindow instance with the new one.
- Makes the window visible to the user.
Figure 18‑1 illustrates the hierarchy of a single window app:
A multi-window app hierarchy, on the other hand, can be represented as shown in Figure 18‑2 below. Note that while there is only one AppDelegate, each scene has its own SceneDelegate instance:
1.5 ContentView.swift File
This is a SwiftUI View file that contains the content of the first screen to appear when the app starts. This file and others like it are where most of the work is performed when developing apps in SwiftUI. By default, it contains a single Text view displaying the words “Hello World”.
The Assets.xcassets folder contains the asset catalog that is used to store resources used by the app such as images, icons and colors.
The information property list file is an XML file containing key-value pairs used to configure the app. The setting to enable multi-window support, for example, is contained within this file.
Contains the storyboard file containing the user interface layout for the screen displayed to the user while the app is launching. Since this is a UIKit Storyboard scene, it is designed using the Interface Builder tool rather than SwiftUI.
When a new SwiftUI project is created in Xcode using the
Single View App template, Xcode automatically generates a number of files
required for the app to function. All of these files and folders can be
modified to add functionality to the app, both in terms of adding resource
assets, performing initialization and deinitialization tasks and building the
user interface and logic of the app. This chapter has provided a high-level
overview of each of these files together with an outline of the internal
architecture of a SwiftUI-based iOS app.