Many of us were excited about all the new frameworks at WWDC: SwiftUI and Combine being the biggest ones. You were probably all ready to start using them in your app, until you opened up the documentation and saw this:
And you felt at least one of these feelings:
😡 😭 🙄
You knew at that point, that even with the usual new iOS version adoption curve, unless you’re looking at sacrificing a significant portion of your user base, you’re looking at adopting all these new features in Spring 2020, at the earliest. If your app needs to support older OS versions for a longer period, it could be even longer.
You can’t fix your users: they upgrade whenever they do (but thank Apple for new emoji ever year). But you also don’t need to sit on the sidelines and wait until those features are widely available to start implementing them. There are some things you can do while you’re waiting for your users to catch up, so that you’ll be ready to deliver apps based on these great new frameworks. You can even do some of this work now, while those betas are less than stable. Here are a few things to think about.
Begin transitioning your code away from MVC architecture
UIKit’s dominant architecture is MVC, so more than likely, unless you explicitly chose a long time ago to break with tradition and investigate other architectures like MVVM, MVP, VIPER, or Clean Swift, your code will likely need refactoring to make it more SwiftUI-friendly.
The architecture that best fits the SwiftUI examples so far is MVVM, because
BindableObject in earlier betas) act as a view model of sorts for your views. The correspondence isn’t perfect, but it is enough to get you started.
However, MVVM may not be the best choice if you are interested in getting a bigger bang out of your rearchitecting, so be sure to check out VIPER and Clean Swift, which further break up the objects backing your views into finer-grained components, improving testability.
Whichever architecture you pick, this refactoring pays off multiple ways: you are not only more ready to port your code to SwiftUI when the time comes, but you have refactored your code into an architecture that is broken down into smaller components, is easier to test, and is more resilient to future major changes.
Start prototyping using SwiftUI and Combine
As part of your rearchitecting efforts above, or if your app is already ported to a non-MVC architecture, you can begin prototyping portions of your app. Individual screens are a good place to start.
You can either create a whole new app project to completely separate your prototype from your existing codebase, or do the prototype in-place. The former creates a clean separation between prototype and production, while the latter makes your prototype easier to share across multiple developers using private branches of your main repo.
Don’t be worried about throwing out these prototypes, because SwiftUI and Combine are still in flux, especially during the beta period. With that in mind, it is easier to start with the simpler screens of your app, so you throw away less if you need to do so.
Check out your user’s iOS versions in App Analytics
Understanding your user base could give you a better idea exactly when you can transition your app to use these new iOS 13-only features, and even if you aren’t using third-party analytics of any sort, you can use Apple’s built-in App Analytics to see your installs and active user sessions for each OS version, as far back in time as you need.
Log into App Store Connect, click App Analytics, click the app you want to analyze, and click Metric in the upper left.
From there, you select Platform Version in the View By dropdown, and select any one of the Usage options at the left, to see it broken down by version of iOS. If you want to extend the time range beyond 30 days, change it in the date range widget in the upper right.
This will enable you to look at the trends of your users regarding iOS upgrades and make an informed decision when you can cut off older iOS versions.
See what additional optional features you can add now using if #available()
While SwiftUI is a much more invasive change to your app, and is not suitable for using
if #available, Combine is well suited for adding this functionality.
I am not suggested you implement a feature twice though! Look for features that are:
- Not critical to the app, meaning if they’re missing, they don’t break the functionality of the app, and
- The feature is much easier to implement using Combine’s FRP style
A feature which fits into these criteria would be the username/password checking functionality introduced in the WWDC session on Combine. This is a feature that is very useful for the user, but if it were missing on older iOS versions, it wouldn’t break the app; you could validate on submission (and you should!). Also, the feature is really easy to implement in Combine; if you were interested in implementing this without Combine, it would be much more difficult and time-consuming to get correct.
There’s no need to twiddle your thumbs waiting for your users to upgrade to start moving towards taking advantage of the latest iOS frameworks. Get a jump start using these techniques, and you won’t be playing catch up when it’s time to make the move.