At WWDC last month, Apple announced SwiftUI — a new declarative way to write view logic for iOS, MacOS, watchOS, and tvOS apps.
Whether you were writing iPhone apps for a year or 10 years and whether it was in Swift or Objective-C, the patterns with which you described views has stayed relatively consistent. At the fundamental level, you were always using UIKit and thus subclassing UIView and UIViewController.
SwiftUI changes everything.
To understand how it works, I rewrote the main view of Paste, the emoji search app I built at the end of 2015, to use SwiftUI (I call it a rewrite and not an update because from the consumer’s perspective nothing’s changed).
The rewrite was mostly straightforward, with the exception of a few SwiftUI concepts that I found more dense and list here:
The Identifiable protocol enables elements of a type to be iterated through and identified in an array in a List (aka a TableView in UIKit). In my case, Emoji was declared identifiable in an extension at the top of SearchView.swift. In order to make Emoji conform to Identifiable, the property id of type UUID was added to it. Here’s its implementation.
In order to maintain state of the view, I created an EnvironmentObject variable. Whenever an EnvironmentObject variable changes the linked view automatically refreshes. Variables labeled as EnvironmentObject must conform to BindableObject. In Paste, the BindableObject is EmojiStore. In order to have it conform to BindableObject, its implementation includes:
var didChange = PassthroughSubject<EmojiStore, Never>()
EmojiStore has variables results:[Emoji] and searchText:String, both of which are bindable. The results array is in sync with the List of search results and the searchText is in sync with the search text field.
The UIViewControllerRepresentable enables SwiftUI views to call UIViewControllers. In Paste, I kept OptionsViewController as-is in order to understand how SwiftUI and UIKit can co-exist. Instead of making every view controller from UIKit conform to UIViewControllerRepresentable, I borrowed ControllerPage<T: UIViewController>, which conforms to UIViewControllerRepresentable, from Jinxiansen. With ControllerPage, any UIViewController can be called from SwiftUI. OptionsViewController is modally presented from SwiftUI’s SearchView here.
This SwiftUI rewritten version of Paste will be published to the App Store in September when iOS 13 comes out of beta. The only user-facing update would be native iPhone X resolution (ie support for the notch) as this will be the app’s first update since 2016.
Hopefully this little journey and the learnings that came with it were helpful to you. If you have any questions, tweet me @dasmersingh.