Alerts in SwiftUI

How to present Alerts in SwiftUI efficiently

Archie Edwards
Better Programming

--

Photo by Luís Perdigão on Unsplash

I recently published my first app on the app store written in SwiftUI. During development, finding out how to create a single alert was very easy, with lots of resources online. However, once my application scaled up, I found that the common approach was unreliable when the cases of showing an alert grew.

This led me to write this article to go through the different approaches I have used, starting from a very simple alert to a more efficient approach that handles the different alert types, consecutive alerts, and child views presenting an alert.

Creating a Simple Alert

Creating an alert in SwiftUI can be done with a single @State variable of type Boolean and the .alert(isPresented) modifier. Whenever this variable gets set to true, the view will be reloaded and the alert will be presented. Once the alert is dismissed, Swift will handle setting the variable back to false.

Customising the alert

The content closure of the alert has to be of type alert. These can vary in complexity. Alerts, by default, have a title and a dismiss button, but they can be customised to have a message and up to two buttons which can be tied to any functionality.

Some examples below:

Alert with a custom message and dismiss button.
Alert with a custom message and a primary and secondary button.

Why this approach is not scalable

The above approach works well, but in practice, a view may need to show different alerts depending on the user's actions. In SwiftUI, a view can only have a single .alert modifier attached to it.

A possible solution is to apply an alert modifier to each individual view element, but that brings inefficiency with duplicate code and multiple @State variables, which become challenging to keep track of — especially if child views exist which also present alerts.

Introducing AlertItem

A better solution is to make use of the .alert(item) modifier, which binds to an identifiable object and is presented whenever the identifiable item is not nil or is updated.

I like to use a custom struct which is similar to the SwiftUI alert struct and conforms to the Identifiable protocol.

This allows an alert of varying complexity to be created on the fly when needed and doesn’t require multiple .alert modifiers or @State variables.

Then if you have child views that also present alerts, you can pass the AlertItem as binding and be confident that the behavior should be no different.

Presenting an Alert Within an Alert

If you want to change the value of an AlertItem within the action of another AlertItem in the hope that it will dismiss the first alert and show the second one… it won’t.

This seems like a niche problem to meet; however, in an application, there may be an alert of the form:

Are you sure you want to <some action>?

If the user then confirms but the action fails, i.e loss of network connection, then it will be helpful to show another alert to say an error has occurred.

The solution is to update the value of the AlertItem asynchronously. Once the action of the first alert has finished, the UI will be updated.

If you have any questions, post a comment below and if you would like to be notified when I next write an article join my newsletter below! 👇

--

--

Archie Edwards
Better Programming

Hi I’m Archie 🙂 I’m studying comp sci @unibirmingham . Connect with me on Twitter!