Daily coverage of Apple’s WWDC 2019 conference, by John Sundell.

A Swift by Sundell spin-off.

Answers to the most common questions about SwiftUI

SwiftUI is a fascinating new, shiny UI framework from Apple — so it comes as no surprise that the Swift developer community is now both bursting with excitement about it, and also trying to figure out what it all means for building apps for Apple’s platforms.

Since SwiftUI is not about giving Apple’s various operating systems a new look-and-feel, but rather a quite substantial shift in programming models — it’s completely natural to feel a bit confused (or shocked, even) when looking at some of the sample code, and when watching the WWDC sessions covering this new framework.

Yesterday I spent a big part of the day looking into SwiftUI, playing around with it, and starting to figure out how it all works. So in this article, I want to try to answer the top five most common questions that I’ve seen people ask me and others on Twitter — hopefully it’ll clear some things up.

SwiftUI only runs on Apple’s latest operating systems

SwiftUI is not compatible with earlier versions of iOS, macOS, or any of Apple’s other operating systems. So, to start adopting it, you either need to decide that it’s acceptable for the app in which you’ll use SwiftUI to only work on the latest operating systems — or you’ll need to ”gate off” the features written in Swift UI from older versions, using Swift’s @available syntax:


@available(iOS 13, macOS 10.15, *)
struct MyView: View {
    var body: some View {
        ...
    }
}
                    

The above shouldn’t really come as a surprise, since that’s exactly way Apple has been rolling out new frameworks and developer tools for years. Still, I understand that it might feel frustrating, since it’ll likely take at least a year or two before most apps will be able to fully adopt SwiftUI and its related new developer tools.

SwiftUI doesn’t use Auto Layout

Auto Layout has been Apple’s preferred way of declaring layouts on all of its platforms (except watchOS) for a few years now, since it encourages developers to make fewer assumptions about the actual dimensions of the containers that their UIs will be presented in — making UIs more flexible by default. However, with SwiftUI and its declarative characteristics, Apple is moving most layout declarations up one level higher — by replacing Auto Layout with layout constructs that are very similar to how watchOS has been handling layout so far.

Like we took a look at in “A first look at SwiftUI: Apple’s declarative new UI framework”, examples of such layout constructs include HStack and VStack, which enables us to define stacks of views that are laid out linearly — either horizontally or vertically. Views can also be grouped using the Group type, and individual views can have constraint-like dimension modifiers applied to them using APIs like these:


Text("I'm occupying 50% of my parent's width, and 75% of its height.")
    .relativeWidth(0.5)
    .relativeHeight(0.75)
                    

A big question that’s been circling around the community during the past few days is whether or not SwiftUIs seemingly more simplistic layout system will work for more “complex UIs”. I’m sure it will, but I’ll be reporting back on exactly how to define UIs that are more complex in terms of layout, as soon as I’ve had a bit more time working with these news APIs.

SwiftUI can be mixed and matched with UIKit

Even apps that choose to adopt SwiftUI from day one will likely have a ton of UI code that’s been written using UIKit, and it’d be a shame to have to throw away all of that working code just to adopt the latest tools. Thankfully, we don’t have to — since SwiftUI can quite easily be mixed and matched with UIKit in both directions — SwiftUI views can be displayed as part of a UIKit-based UI, and UIKit views can be wrapped in order to participate in a SwiftUI view hierarchy.

To display a SwiftUI view tree in a UIKit-based UI, we simply have to wrap our root View in a UIHostingController — which can then either be presented on top of another view controller, or embedded as a child view controller. Creating an instance of UIHostingController is as simple as giving it a View instance to display as its main view:


let vc = UIHostingController(rootView: ContentView())
                    

On the flip side, if we want to embed a UIView in a SwiftUI hierarchy, then all we have to do is to write a thin View wrapper that conforms to the specialized UIViewRepresentable protocol — and provide implementations for creating a new instance of our view, as well as updating it when the presenting context was changed:


class ProfileView: UIView {
    let imageView = UIImageView()
    let nameLabel = UILabel()
    ...
}

struct ProfileSwiftUIView: UIViewRepresentable {
    let user: User

    func makeUIView(context: Context) -> ProfileView {
        return ProfileView()
    }

    func updateUIView(_ view: ProfileView, context: Context) {
        view.nameLabel.text = user.name
        view.imageView.image = user.image
    }
}
                    

The Context parameter passed into each of the above two methods is an instance of UIViewRepresentableContext, and contains instructions like what animations to apply, and information about the environment that the view will be presented in.

SwiftUI doesn’t use storyboards

One of the most long-running debates in the iOS community has so far been whether to build UIs completely in code, or whether to (either partially or completely) use Apple’s visual Interface Builder tool — producing either XIB files, or most recently, storyboards.

SwiftUI pokes a hole in that debate by moving to a world where each developer can freely choose whether they want to work directly in code, or in a more visual manner — all while making the source code the single source of truth. When using the visual tool, each change is directly propagated into the source code, which both makes it easier to get an overview of all parts of a specific UI implementation — and will most likely eliminate a whole class of potential merge conflicts between team members.

The only storyboards feature that it doesn’t seem like SwiftUI is able to provide an answer to yet, is visualizing the flow between the various screens of an app. Perhaps that’s something that’s in store for a future version of Xcode, or perhaps someone in the developer community will step up and build a tool like that?

Xcode live previews require macOS 10.15 Catalina

Speaking of visual view editing, while you can use almost all of the new Xcode 11 features — including all of the new SDKs and frameworks, like SwiftUI — using the new auto-updating live preview feature, that’s been demonstrated several times on stage at WWDC, does require your Mac to be running the beta of macOS 10.15 Catalina.

So while you can write SwiftUI code and start building apps using it even when running Xcode 11 on macOS Mojave, the visual tools are only available when running the latest macOS beta.

Conclusion

While there’s still a ton of information left to be discovered about SwiftUI and how it’ll change the way we write apps for Apple’s platforms, I hope this article has cleared up some of the major question marks. I’ll keep digging, and will report all of my new findings as soon as possible.

In the meantime, feel free to follow me on Twitter @johnsundell, and send me any feedback that you might have on this article or any of my other WWDC coverage.

Thanks for reading! 🚀