Skip to content

Apps Dissected Posts

Keep control of your modal presentation in iOS 13

You hear about the large features in new major version iOS updates, but it’s often the small changes that cause you headaches: the places where Apple has deprecated functionality or changed defaults that you’ve been relying on for years.

iOS 13 has one of those major changes with respect to how modal ViewControllers are displayed. They are now displayed in a card format by default. That itself is not overly problematic, but as part of that change, it also enables the user to dismiss a modal by swiping down from the top of the screen.

If your app expects that it will have full control over being dismissed, this could be a major problem. Suddenly, your login form that you are displaying with a modal can just be swiped away, leading to unexpected behavior: crashes, unpopulated screens, access to things a user shouldn’t have access to.

Building with the old iOS 12 SDK is an option — for a while. How do you restore that classic functionality, making your modals fullscreen by default, with full control over how they are dismissed? Thankfully, it is not a hard fix, but the fix depends on how you are presenting your ViewController. Let’s cover all of the different fixes now.

4 things you can do *right now* to be ready for SwiftUI and Combine

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.

Catch SwiftUI model updates from bad threads before they crash your app

It hasn’t yet been reflected in the official SwiftUI documentation (yay, betas), but the WWDC presentations and further guidance from Apple engineers have made it very clear about one point of SwiftUI: as with UIKit, you must send SwiftUI updates only from the main thread. The more things change…

The bad thing about this is that if you don’t make your updates on the main thread, you get away with it.

Most of the time.

The reality: updating the UI outside the main thread — in UIKit and in the newer SwiftUI — is going to be a source of hard to debug bugs, possible race conditions when updates are made to the UI, and at worst, app crashes.

Your BindableObjects may have many attributes, all that require you to do a willChange.send(). With so many places where your asynchronous code may need to trigger an update to your Views, what can you do to catch those missed main thread migrations before they become headaches? Xcode can save your sanity with its built-in Main Thread Checker debug functionality. Let’s walk through a basic example.

Order your Core Data entities the right way for maximum speed

One of the earliest things you learn about Core Data is that it doesn’t support ordered entities out of the box. Sometimes you can have an ordered relationship, but the minute you try and move that database to iCloud, you find that ordered relationships aren’t supported. Long story short: if you want to order your entities, then you need to create an index attribute that allows you to sort your entities yourself.

So you do the natural thing: create your index attribute as an Int, and then assign each in order: 1, 2, 3…

This is fine if the data doesn’t change, but if this is data the user can add to and reorder, what if they want to move element 3 between 1 and 2? It means you need to change 2 entities in addition to adding the new one. What if there are 500 entities, and the user wants to insert a new first element. 500 entities to change because the user moved a single entity?!

There must be a way to insert and reorder IDs that avoids all of this rewriting, right?

Thankfully there are a couple of techniques you can use that will almost completely eliminate the need to rewrite a huge number of entities every time you need to insert or rearrange entities. Let’s talk about them now.

Frustrated by missing features in SwiftUI? Using UIViewRepresentable to wrap UIKit controls

When the SwiftUI announcement came out at WWDC 2019, you were buzzing about the new framework. Finally, a new way to build our interfaces. Out with ViewControllers, out with storyboards, in with declarative, programmatic UIs!

Now that we’ve all had some time to play with the framework, we’ve found out what we’re really trading away when we use SwiftUI, at least for now. One of the major things? The vast array of components and configurability available through UIKit.

You’ve probably found through experimenting with the new framework that there are things missing. Entire UIKit components are missing, and things like the broad number of properties you could set on TextFields, and the common pull-to-refresh control are missing.

You really don’t want to continue down the UIKit road. You want to go all in on SwiftUI now; it’s the future of development for all Apple platforms. “But how am I going to get back these features?”

This is where UIViewRepresentable comes in. Apple knew that SwiftUI was not going to be a complete port of UIKit for its first version, and so they provided this protocol which you can implement on a View struct to wrap a UIKit control, making it usable in SwiftUI. Let’s see an example how to use this: getting the pull-to-refresh functionality on a scroll view.