SwiftUI was warmly welcomed by the development community when it was announced at this year’s Apple Worldwide Developers Conference (WWDC). Given the wide variety of platforms and screen sizes, it makes sense for Apple to provide a standard UI abstraction layer which works across all of their devices. Creating, managing, and positioning each UI view, and their countless properties, to form the expected layout is a time consuming and error-prone task. It adds little value, but a lot of development effort, to the resulting apps – even more so if multiple device types are to be supported. SwiftUI addresses these challenges, improving application quality and decreasing development effort.

This article will provide a simple example of using SwiftUI, compare SwiftUI to ReactNative and Flutter, discuss adoption strategies, and consider future directions in which Apple may take the framework.

Hello World: Building a list with SwiftUI

For a UI abstraction layer to be effective, it must result in a user interface which feels like it belongs on the device where it’s presented. As a result the same app running on a point-and-click device should –and will, with SwiftUI– appear completely different from those on a touch screen or a TV. For a simple example, let’s look at some SwiftUI code.

The following code lays out a screen that displays the applications with the most usage on a given mobile phone.

struct AppsView: View {
    let apps: [App]
    
    var body: some View {
        NavigationView {
            Text("").navigationBarTitle(Text("Apps"))
            List(apps) { AppRow(app: $0) }
        }
    }
}

Before SwiftUI we would have to create a UINavigationController, pushing a UIViewController to it that holds a UITableViewController with UITableViewCells in them, and then configure with UIKit by hand. iOS developers know how time consuming and error-prone this is.

But With SwiftUI, we simply declare that we want a List of AppRows within a NavigationView titled “Apps”, and SwiftUI automatically renders the controls properly on all supported platforms. It’s easier, faster, and less error prone than using UIKit.

Let’s now examine the AppRow code. All we have to do is declare we want to render an image with some text. That’s it. SwiftUI does this, of course, using the correct controls for each target platform..

struct AppRow: View {
    let app: App
    
    var body: some View {
        HStack {
            Image(systemName: app.imageName)
            Text(app.name)
        }
    }
}

The result on iOS looks something like the following (left image). While that looks nice, there’s much more that we get for free with SwiftUI.

First, we get a nice animation when we scroll up that shows smaller and centered title (as illustrated in the center image). We also get dark mode support (right image), along with automatic support for dynamic type sizing, localization and accessibility. There was no need to write any code for those things, SwiftUI provided them by default.

Apps

Now, even if you didn’t need to take advantage of these features, just by adopting SwiftUI, you’d be already saving on a ton of code when compared with UIKit.

With SwiftUI you get more with a whole lot less code.

Comparison of SwiftUI with other cross-platform technologies

SwiftUI is a cross-platform technology which targets different types of Apple devices, but does not run on non-Apple devices. This can be confusing because the term “cross-platform” is often meant to indicate that single codebases can run on devices from different vendors (e.g. iPhone vs. Android).

Though SwiftUI is only cross-platform for Apple devices, it’s useful to compare it to the most notable and widely adopted cross-platform development technologies available for mobile today. These are ReactNative (by Facebook) and Flutter (by Google).

ReactNative

ReactNative –a React mobile extension– has been around for awhile and runs on both iOS and Android devices. It’s a relatively open standard, and there’s a vast set of developer tools and a robust developer community. ReactNative bridges Javascript commands into native calls on iOS or Android at compile time, generating multiple native applications from a single JavaScript codebase.

While ReactNative is widely known and adopted, it addresses a fundamentally different problem than SwiftUI. React is cross-platform in the sense that a single codebase creates apps which run on both iOS and Android. SwiftUI is cross-platform in the sense that a single codebase creates apps which run on any modern Apple device, such as iPhone, iPad, Apple Watch, and Apple TV.

ReactNative has nearly no UI abstraction, so you must explicitly state which control you want to use at each position of the screen. This creates apps which will look very similar on iOS and Android - not necessarily a good thing. This may give the app a ‘generic’ feel which may not be desirable. It’s easy to spot in global elements such as navigation and tab bars which lack a platform-specific “look-and-feel”. Because users become accustomed to the standard look-and-feel of their device, this may create a confusing and frustrating user experience.

In addition, because there is no UI abstraction, each platform’s optimized components (such as tables or collections) aren’t used to their full potential. This can result in lower run-time performance as well.

On the plus side, building a simple application in ReactNative is typically faster and cheaper to build than a native application. In addition, novice developers may find them easier to build as well, especially if they are more skilled in JavaScript than the native platform language (Swift for iOS, Java/Kotlin for Android).

Flutter

Flutter is a new cross-platform mobile framework released by Google which is very promising.

Flutter is “cross-platform” in two ways. First, like ReactNative, it allows a single codebase to compile to multiple platforms. Second, like SwitfUI, it has a UI abstraction layer which ensures that applications have the correct native look-and-feel on each platform.

Flutter applications are written in a new programming language called Dart. Dart code is compiled into native binary executables for mobile, desktop, or even web devices. Depending on the configured targets, it will also even build natively for desktops with macOS, Windows or Linux! And even more, the very same single source code can produce HTML to serve to web clients.

While it’s currently a bit immature, Google is pouring a great deal of time and money into it. The key here is that Flutter delivers a one-two punch: it’s a single codebase which will generate different UI elements on each platform, across different vendors. This means the same Flutter code will build to an iOS app, an AppleTV app, and an Android Tablet app - each which has the correct look-and-feel for the platform.

This combined benefit makes Flutter the main SwiftUI competitor at this time.

Now, jumping between platform vendors (e.g. Microsoft, Apple, Android, etc) can be tricky and Google’s habit of launching early could backfire. In addition, Flutter will not be updated to fix “breaking changes” when iOS is pdated. This means that each time iOS is updated, core Flutter libraries may need to be fixed, and those fixes depend on Google’s goodwill, schedule, and feasibility.

Weighing the options

ReactNative’s biggest convenience is in development resources and operations management, providing a nearly unified technology stack. Your team will need some knowledge of iOS and Android when working with ReactNative. But if your team is short on native mobile developers, and already has React or Javascript developers, then ReactNative may be the right approach for you.

When considering ReactNative, keep in mind that the performance and user experience don’t measure up to native apps, so only use ReactNative for “simple” applications which don’t need advanced UI styling.

Another issue to consider when evaluating ReactNative is Facebook’s licensing terms of the React library. At one point, Facebook changed the terms on React so that if you used it, you couldn’t sue Facebook for infringing your patents. We recommend checking with your legal counsel to evaluate ReactNative’s licensing before committing to it.

Flutter is also not mature enough yet for widespread adoption. Google seemes to have nailed the abstraction and targeting part, especially the wide range of targets available across vendors. Given the wide number of vendors and devices, which continues to grow, full maturity may take some time to be achieved.

Developers also have to learn to program in new language Dart as well as the Flutter framework, which constitutes a steep learning curve. This may be worthwhile in scenarios where you must deliver on most of these targets, including multiple desktop clients. If it’s only for mobile platforms, or if you’re developing a complicated application with a customized UI, a native application solution may be the best solution.

Apple’s been clear about SwiftUI being the way to write for all their platforms: iPhone, iPad, Apple Watch, AppleTV and Mac. Their ability or willingness to add more platforms (such as the web) and makers (such as Android or Windows) to it in the future is a complete mystery, as is usually the case with Apple.

It seems safe to assume that future Apple platforms will be supported. Adopting early with Apple has always paid off in the past, so if you are building for Apple platforms, natively adopting SwiftUI is a great decision. If you go with SwiftUI and want to target Android as well, you will need an Android development team to build a separate Android applications.

Overall, if you have trouble finding good native developers or have available web developers and you are concerned about maintaining multiple code bases, ReactNative could serve that purpose well. If you need to deploy to a multitude of platforms and you don’t have a large budget, Flutter may be the way. If you need to build a mobile app that will run on both iOS and Android, and performance and user experience are a priority, and you need to play it safe, native is the way to go.

When to adopt SwiftUI

So, you decided to go with a native approach. Your team is either comprised of iOS and Android developers or you are confident you know where to find them. Your app’s success depends (or will benefit from) great system performance and user experience. Finally, you’ve got the development budget and resources to invest in a native application. Good for you.

But, before you get too excited, you need to know that SwiftUI comes with a major restriction. It’s only deployable for devices with iOS 13 or higher, or macOS Catalina or higher. Yet, those haven’t even been released yet! How can we commit to only supporting something that’s still in beta?

In the past Apple’s been very consistent with release dates and has published historic adoption rates for each version. Using the current trends as a guide, specifically how iOS adoption rates have evolved in the past, we can see that iOS 12 reached 75% adoption by the end of November last year and that it beat iOS 11 to that mark by a few weeks (the previous year.) If that trend continues we could assume that somewhere between the beginning and the middle of November 2019, we’ll see a 75% adoption rate of iOS 13.

That means an app released at that time won’t be usable by 25% of platform users because they won’t have upgraded to iOS 13 yet. While this sounds terrible, it might not be so bad. It’s a common practice when launching and maintaining an iOS app to support the latest major version of the OS and the latest minor version of the previous major version of the OS. That means that typically, we should ready ourselves for maintaining iOS 13 + iOS 12.3.1 somewhere around September 2019. Just as a comparison, not supporting the whole major previous version (iOS 11.x) today means not supporting only 9% of devices.

This is all speculation, of course, but you might be willing to temporarily trade 9% of your users for a faster, cheaper, higher-quality development process which uses SwiftUI. Given all the benefits, I certainly would.

Each app update will inevitably lose some users who haven’t updated to the required iOS version. In this case, there’s only a 10% difference between supporting iOS 13 (25% loss) and iOS 12.3.1 (15% loss). Of course, not being able to use their favorite app is often the nudge users need to update to the latest iOS version. But, for new apps this isn’t an issue, because there aren’t existing users to lose. We suggest focusing more on the longer-term strategy than a temporary 10% loss in potential users.

If after running these numbers, your are still unsure which side to lean towards, you may want to consider that they may also be (heavily) influenced by the target audience of your apps. Say you are building an app for a tech blog or a gizmos reviews website, then your audience will typically be tech-savvy and thus more prone to having their technology –their phones– updated. Maybe you are building an app that tracks the users health or their everyday habits, then your app will likely be running on their primary device and thus be more prone to be updated. Now, what if you are building a luxury catalog or a high-end shopping app? Then your users will more likely to be on a recently acquired phone and thus more prone to be updated.

SwiftUI’s influence on operations and release cycles

What if you don’t need all these cross-platform features, and you’re only targeting one device, like an iPhone? Should you consider adopting SwiftUI?

Yes, you should.

SwiftUI code will be faster to develop and debug than traditional UIKit code, meaning you’ll spend less time pixel-pushing and debugging your beautiful designs.

Does that mean we’ll need less iOS Developers than Android Developers? That’s hard to predict. SwiftUI only serves the interface portion of the app.

Most iOS apps start as iPhone-only apps, because UIKit support for iPad is time consuming. But with SwiftUI’s cross-platform support, creating the iPad version may be as easy as choosing a different build target. This may also become the de facto standard that customers come to expect from all applications, whether they are built with SwiftUI or not.

Since the beginning of modern mobile apps, developers have been expected to keep up with the platform enhancements made by vendors. If most apps support localization, your app is expected to support localization; if most apps support dark mode, your app is expected to support dark mode. SwiftUI makes keeping up much easier and cheaper than before.

Users expect mobile apps to be fast, and provide a visually stunning UI. They expect long battery life, localization, and much more. SwiftUI was created to reduce the cost of developing excellent customer experiences. Expect your competitors to adopt SwiftUI early, so you should consider doing the same.

In addition, productivity may rise with the adoption of SwiftUI.

What to expect in the short and medium term

We anticipate a relatively high adoption of SwiftUI for new projects. The convenience of UI abstraction and preparing for future devices outweighs the risk of adopting a new technology. Being able to start a project purely on SwiftUI also means relieving the burden of interoperation and bridging, and knowing you won’t have to re-work the UIKit code in the near future.

Ongoing projects may take longer to catch up. Similar to Objective-C projects which slowly migrate to Swift, UIKit projects may adopt SwiftUI for new UI elements after iOS 13 is well adopted. They may even have to wait until late 2020, when iOS 14 comes out and iOS 13 becomes the new lowest supported target standard.

Eventually teams which do not adopt SwiftUI may have trouble keeping up with Apple’s AppStore standards and requirements. They may also experience higher developer turn-over and struggle to hire new iOS developers to work on their legacy applications. We are seeing these same effects in companies which have been slow to move from Objective-c to Swift.

Next Up, the Web

Apple’s message by launching SwiftUI is pretty clear, in my mind it sounds a bit like:

iPhone apps are great but we want you to build iPad and watch and AppleTV and Mac apps too! …and we don’t mean those crappy little battery and memory devouring Electron apps.

If that could be applied to the web as well, it’d have a huge impact on the development community. Everyone developing for the iPhone could suddenly add a complimentary web application to their mobile apps. This would allow new kinds of integration, such as sharing a sketch made with an iPhone app instantly with someone on a Windows desktop browser.

For a long time, web developers have been looking for ways to port their work into mobile. So far, the solutions proved to be detrimental to performance and user experience. Now the situation is reversing, and mobile developers may use SwiftUI to write web front-ends. If Apple released a SwiftUI to Web adapter, this portability may be accomplished, while keeping high performance and usability on each deploy target.

Some mobile developers would become “SwiftUI developers”, in the same way as we have “React developers” today. Developers have dreamed of a “write once, run anywhere” platform for decades, providing them with a larger reach and audience. SwiftUI in the web may be the tool for achieving just that, and the fact that SwiftUI follows a very similar pattern to React may be a sign of what’s to come.

Apple has also been collaborating and promoting –in their own style– server side Swift. They even partnered with IBM, who is behind the largest server side Swift framework, Kitura.

So, if neither the servers nor the SwiftUI-Web adaptor are out of reach, what’s Apple waiting for? The hardest part may be the community of developers. They will have to convince web developers to migrate from React to SwiftUI, and convince mobile developers to write web front-ends.

To accomplish that we need tools, training, and time. Apple could support this effort with a UI catalog and examples of template/styline, and allow the Swift community to contribute to it. Apple has already licensed Swift as open-source, which is a necessary condition for community innovations.

Apple’s largest asset and partner is this regard is undoubtedly the army of Swift developers that are aching to adopt SwiftUI and to be able to distribute to more devices, including those not done by Apple.

Wrap up

SwiftUI should be adopted for companies developing native Apple applications on any platform, particularly if they want to be used across multiple Apple platforms. While ReactNative is popular, it cannot build the high-performing, beautiful apps that users have come to expect. Flutter, a Google project with similar goals, may become a serious competitor to SwiftUI, but is currently in its infancy. SwiftUI will allow companies to target more platforms, faster than ever before. Finally, we believe Apple should move toward a “SwiftUI web” paradigm, that should allow the same UI code to run on mobile and web applications, revolutionizing web development.

Adopting SwiftUI for new projects which release Q4/2019 or beyond is highly recommended.