Do we need an app for that?
The current state of app development is summarized pretty well by Chris Nielsen in his recent post. And really, the difficult choice between developing the same app for iOS, Android and Web has been top of mind to most developers since Apple first released the SDK for the first time for iPhoneOS back in 2008, about 9 months after the iPhone was released. Only a small number of native apps were released initially and Steve Jobs recommended building web apps since Safari was very capable for that purpose, which it was. In the US, every iPhone required a data plan and was only available from AT&T and it operated on the Edge network which pre-dates 3G/4G/5G, just to give you a sense of how painfully slow it was.
Today broadband speeds are pretty common everywhere we go. We now have 5G and web pages could load a lot more resources for JS and CSS and we would probably not notice. Back then it was critical to use tools like Packer or JSMin. In early 2008, John Resig wrote about the trade-offs that were made with these tools. You could reduce the size of JS resources so they would be downloaded in less time but the cost of decompressing still represented another delay before a web app could be usuable. One advantage of a native app is that you can install it while your device is connected to WiFi and when you launch the app it is quick. An app can also access the sandboxed filesystem for Documents and Cache so that data which was previously downloaded is immediately available.
By this point in 2008 what made web apps much more capable was HTML5 which nearly eliminated the need for use of any plugins such as Flash. Many features, which would otherwise require a native app, could work in a web browser thanks to Device APIs, such as Geolocation API. Now there are many more device features available as a part of web standards which modern web browsers support. Yet there are still many features which will not be available from a web browser like Bluetooth, NFC, USB and task scheduling. As long as your app is able to leverage the available features you can create an app which can deliver great UX.
When an app tries to do too much, it will harm the reputation of the app and the company. The most high profile example is when Facebook released (Forbes) their app for the iPhone built entirely with HTML5 in 2011. That Forbes article states, “Facebook is investing heavily in HTML5, a new Web standard, as a way to unify the Facebook experience across all mobile platforms.” And after significant investment in HTML5 and a major push with millions of people using the app, it went sour due to slow launch times and long delays to update screens. In 2012, Facebook admitted the betting on HTML5 was a mistake.
Even then Facebook had enormous resources and could put the most capable developers on this project to optimize every aspect of the app and still could not overcome the inherent shortcomings of the technologies at the time. One aspect of improving UX for an app is simple animations, which was later handled well by Lottie. And perhaps making use of Web Workers could have improved the performance of the Facebook app. Besides GPU support for animations, a big issue for users was how slowly screens would load which was largely due to limited caching features at the time. Each time the app is launched it would have to pull in a lot of data for posts, comments and likes as well as other media like photos which depended on HTTP connections. In 2011 the HTTP spec was still 1.1 and the caching spec did not come out until 2014. Later HTTP 2.0 was implemented with many more improvements such as handling multiple requests on the same connection. All the improvements likely would have helped any HTML5 app. Perhaps if Facebook were to try again, making use of GraphQL and Relay it could reach the “good enough” bar this time which was the hope when Facebook started this effort.
You may be building an app which just cannot be built with what HTML5 offers. You may be working on an music streaming app which processes the audio and it requires low level C code to meet performance requirements. You may need to make use of Bluetooth, NFC or USB connections which are just not supported by web standard features. When a developer is forced into this decision it will come down to building a hybrid app or going fully native.
React Native is meant to be a UI solution which works much like PHP does with code mixed in with the markdown used for the UI. The same code can be rendered on iOS and Android, which was the promised benefit of this solution. Any native features would be accessed through a native module like one which can interact with Bluetooth accessories. These native modules offer an abstraction so that is a common denominator between the supported the platforms which are typically iOS and Android. It is often a compromise and it becomes necessary to build out features with native code and make calls over the bridge, which is now being replaced after years of being the source of performance issues.
For apps which cannot be built with just HTML5 it is often not sufficient to just use React Native without additional native code. So instead of going from 2 code bases for iOS and Android you end up with 3 code bases and have to integrate the native apps with React Native. Unfortunately once your app as been in use a while it will be necessary to update the libraries which make up React Native and this process is notorious for being difficult and risky. It is not like it once was with Java where a new SDK would be released after rigorous compatibility testing and then packaged so that it could be dropped in as a quick replacement to a previous version. While React Native appears to be a great option at first, these upgrade costs should really be factored into what is necessary to support the app.
Committing to Native
Still the greatest barrier to entry is the UI. Most code is quite similar for every programming language while building an iPhone app has meant learning to build apps with Storyboards, autolayout and supporting views with Table and Collection views with a great deal of code. And then all of this code relies on UIKit and is not reusable when building a Mac app. That was not a problem when all that mattered was a great iPhone app, but now it is not enough. There are now 4 major platforms in Apple’s ecosystem and building apps for each of them is just not going to be easy for most companies to justify in the budget. Then in 2019 Apple introduced SwiftUI which supports each of these platforms.
Now, in theory, a lot of the same code which is used to build apps for the iPhone can be reused for macOS, watchOS and tvOS. Most apps are probably don’t need to be released on more platforms than iOS, while a subset would really be great on the Mac. Facebook Messenger, Apple’s Messages, Spotify, Apple Music, Slack and many other apps we use often on the iPhone are even better on a Mac. A full-sized keyboard and a larger screen for these apps is much better than typing on a small, virtual keyboard and being limited to a much smaller screen. And if we are already using a Mac it would be great to just leave the iPhone on the wireless charger and use the app on the Mac which syncs to the same cloud backend. Responding to a message on a Mac is the same as doing it on an iPhone, but much faster.
Apps like Slack are built with Electron, a desktop cousin to React Native on mobile. It has it’s own performance issues which includes chewing up the CPU along with a lot of memory at times, but recreating all of the features supported by Slack on every platform it supports is just not reasonable. Clearly HTML, CSS and JS must be used to support this app, perhaps with a bit of help from the native integrations offered by Electron.
While SwiftUI opens up the option to leverage the same Swift code base across all of Apple’s platforms there are diminishing returns once an app is supported beyond the iPhone. Out of 900 million active iPhone users, there are about 100 million who wear an Apple watch. Apple does not regulary report the total of active Mac users, but during the trial with Epic Games and Apple in 2021 Craig Federighi claimed active Mac users to be around 1/10th of iPhone users. With the Apple Watch and Mac representing a slice of iPhone users, there is not a major incentive to invest in an app with a unique code base for those platforms. Yet, there are benefits to using the same code which was already written for iOS to create an app for macOS. And if an app were to benefit from a larger screen, full-sized keyboard and quick access when the user is already sitting in front of their Mac maybe that will be a welcome addition. Having access to messaging apps on the Mac has made it much easier for me. Consider not having a Slack app available on the desktop and using your mobile device to reply to messages with a virtual keyboard which is true for all of the apps which have only been released to the iPhone.
App development with Swift
Today nearly everything an app developer will need is available from Apple thanks to a rich collection of frameworks such as Foundation, AVFoundation, CoreBluetooth, UserNotifications and Network. Many frameworks will cover a developer’s needs and made accessible with a simple import statement. It is not necessary to manage to large number of dependencies which bring in even more dependencies which is common with JS projects.
When you need to make use of an Open Source package or even one which is not public you can now use the Swift Package Manager. Most packages follow Semantic Versioning so it is possible to keep your dependencies current with minimal effort, which was previously handled with CocoaPods, but without native integration with Apple’s IDE, Xcode. Adding a package to your project is now much easier than it once was just a few years ago.
Having access to many frameworks and packages greatly reduces the level of effort needed to build out an app’s features. Data binding is an essential feature in SwiftUI as it has been in the popular JS frameworks for years. The unique workflow which is possible with Xcode and SwiftUI previews has the potential to speed up feature development and reduce overall cost while also creating apps with much better UX. And the way SwiftUI now opens up Apple’s top 4 platforms makes Swift a very appealing option. It compares very well to JS development due to these advantages.
Beyond Apple platforms
It is possible to build and run Swift on Linux and Windows. Check out the Swift download page for a list. There are some limitations. Not all frameworks available on Apple platforms can be imported on Windows and Linux. There may be an equivalent module which can be used, such as Glibc for Linux or WinSDK for Windows. Swift conditionally uses these modules on these platforms to support Foundation and the Swift Standard Library. Not everything will be available, but for some uses there may be enough.
Major frameworks which are missing are SwiftUI and Combine. There are 1.4 billion active users of Windows 10 or 11. If it was possible to run a SwiftUI app on Windows with little to no changes grow their potential market with many more potential users. For developers who have invested years into Apple’s platforms and Swift language, the ability to ship an app originally built for the iPhone to all of these Mac and Windows users would be very worthwhile.
Android apps can already run on Windows. Many Android users own devices which are not able to run the latest Android version, so there is a considerable amount of fragmentation. For iOS, it is possible to update to the latest version on all iPhones going back to iPhone 6s released in 2015. Since over 70% of iPhone owners are running iOS 15 the benefit of leveraging the latest features and releasing the app to a broader base of potential customers is higher than it is for Android since only newer Android devices can make use of newly released features. Is it likely for Apple to release support for SwiftUI on Windows? Perhaps not, but the way these numbers add up there is a case to make for developers who’d like to get more value out of their code.
On June 6 Apple is starting their WWDC conference and perhaps we will see some features announced which will move Apple just a bit closer to a truly cross platform approach with Swift and SwiftUI. At the very least, we should see improvements which make it much easier to bring iPhone apps to the Mac using SwiftUI.