Apple Worldwide Developers Conference (WWDC) 2019 brought in a number of high-profile announcements, new technologies that aroused deep interest of Apple developers. The idea of this article to highlight one of them — the new declarative UI framework for Swift named “SwiftUI”.
This article was written by Nail Shakirov, the Director of Engineering at Akvelon’s Kazan office, and was originally published in Medium.
To provide a detailed tutorial for Apple developers community how to boost development using SwiftUI implementing an example of Weather application with the support of newly introduced Dark Mode, Accessibility, and Dynamic Font Types.
In the past 5 years, Swift proved itself to be the best and most loved programming language to develop Apps for Apple platforms. After WWDC 2019, developers have reasons to be even more excited as Apple introduced SwiftUI — innovative, exceptionally simple way to build user interfaces across all Apple platforms with the power of declarative Swift syntax. So what does it mean for iOS developers?
- Declarative Syntax. The Code is simpler and easier to read, understand and maintain.
- Design Tools. Xcode 11 brings new design tools that make building interfaces even easier than before. Canvas provides a real-time visual presentation of your code, so you don’t need to re-run the project every time you change something.
- Drag and drop. Drag and drop in canvas allows arranging views simply by moving the mouse cursor.
- Previews. With previews and groups you there’s no need to run your app on a variety of screens as Xcode 11 allows to see UI components in any possible size you like in real-time.
- Native on all Apple platforms. SwiftUI supports all Apple’s platforms from watchOS up to tvOS.
A good way to showcase those new technologies and share our experience of using them is going through building a simple application, compatible with iOS, iPadOS, and macOS.
Creating a new project
Let’s jump in by creating a new project in Xcode 11. Based on the latest update on this Xcode version, we have a new option to Use SwiftUI. This checkmark is creating a bridge between UIKit and SwiftUI using UIHostingController (or NSHostingController for Mac Apps) which are ViewControllers but are capable of holding the new SwiftUI Views.
So we’ve created our default project, and the first thing we see is the “Hello world” scene where we can start coding:
At the left side, we have an editor while on the right there is a new window called “Canvas” which allows us to see our UI changes in real-time.
Note that alongside with View struct, now we also have code for preview which runs on DEBUG scheme only. That code preview is connected directly with the “Canvas” in order to draw our UI in Canvas in real-time.
Building List (as a replacement for UITableView)
The first screen of our App should contain a list of cities with their current weather conditions.
So to start up things, let’s create a prototype cell for displaying a single city with accessibility (Voice Over) compliance in mind:
We can use Groups in preview in order to see UI’s look and feel in different configurations and sizes in real-time.
Go back to the first scene and create a List with cells that we just implemented.
Previews in Canvas
Previews in Canvas can be easily configured using the same declarative semantics as used by SwiftUI (see the comments in the code below):
That allows us to see real-time previews of our view both in light and dark appearances.
Speaking of light and dark appearances, SwiftUI is doing a really good job of tracking changes between dark and light appearances which user can pick in System Setting menu.
First of all, let’s focus on dynamic colors. In order to take advantage of dynamic appearances, colors now should have initializer with a closure that contains current traits. Traits present all user UI preferences including preferred font size, color schemes, etc. The only thing that would be relevant in this case is userInterface enum with two cases: .light and .dark.
It’s even easier if you are using Assets for storing your colors, as Apple added a drop-down menu that allows us to specify different appearances of current color in regards to color scheme.
Any appearance would be used on devices which don’t have Dark Mode (iOS version less than 13).
Light appearance is optional and can be skipped. If not specified, the system will pick Any Appearance option for Light interface of iOS.
Dark appearance specifies display color with Dark Appearance enabled on iOS device.
Remember, user needs to switch device between Light and Dark Appearance settings to see app UI reflecting proper appearance.
Images and SF Symbols
For the second screen, we want to show the weather of the selected city in details. These are expected to be shown on the device properly in both light and dark modes, as well as city images.
Implementation of given screens is rather interesting as now we have to explicitly return View component which is GeometryReader that allows reading current screen size.
There are two components embedded in code above (ConditionColumn and ConditionRow), both configured with Condition object but with slightly different layouts. Let’s take a look at one of them:
GeometryReader component allows getting the actual component size that we can use to adjust image height based on view width.
Image. Image component can be initialized with image name directly (like Image(“Moscow”)) with fully automatic support for Light and Dark Appearances.
Dynamic Images are pretty straightforward to implement as it behaves the same as Colors with three available options for Appearance: Any, Light and Dark. (see picture below).
SF Symbols. Here we have Image component that uses systemImageinitializer in order to grab the image by name from SF Symbols catalog. You can find all supported images directly in SF Symbols App available on the apple.developer.com
Now that we have CityList and CityDetail screens ready, it’s time to connect them. We can do this by implementing push transition with NavigationLinkcomponent. This component will handle user taps on view inside and navigate to destination screen. In our case, tappable view would be CityRow view and destination is CityDetails:
That gives us the ability to push CityDetails in navigationController stack.
Running App on macOS
This code execution will give us the following result:
Apple delivered a new way of building UI with declarative semantics which makes Apps development faster and more efficient across all Apple platforms with the power of Swift.
Utilizing this new approach, we have implemented an iOS App using only SwiftUI capabilities. Yet the resulting app can run on any Apple platform starting from watchOS up to tvOS.
Sources of this application are available on GitHub.
SwiftUI compatible with following Operating Systems: iOS 13, iPadOS 13, watchOS 6, macOS 10.15 and tvOS 13.
We at Akvelon Inc love cutting edge technologies in mobile development, blockchain, big data, machine learning, artificial intelligence, computer vision, and many others. This article is the result of one of many projects developed in our Office Strategy Labs where we’re testing new technologies, approaches before delivering them to our clients.
Akvelon company official logo
If you would like to work with our strong Akvelon team — please see our open positions.
Written in collaboration with Artur Mikhaylov
Nail Shakirov is the Director of Engineering at Akvelon’s Kazan office. He has a solid software development background and experience in all software development stages: technical design, implementation, testing, and operation.