How to Design for Accessibility with Your iOS App
As a software engineer at Intuit working on the Mint iOS app, my goal is to create experiences that empower our customers to find the right financial products and put more money in their pockets. One of our core operating values at Intuit is “customer obsession,” which means we fall in love with our customers’ problems, not the solutions, and we sweat every detail of the experience to deliver excellence.
Customer obsession is embedded in the Design for Delight process we follow to develop deep customer empathy through what we call “Follow Me Homes,” where we observe customers using our products in real-life settings to thoroughly understand the problems they face.
It was at one of these Follow Me Homes with a Mint user who is blind when I first realized we weren’t doing enough to deliver a delightful experience for our customers with disabilities. Visually impaired customers had difficulty with aspects of navigating through the app and using more advanced features. So we embarked on a journey to change that and deliver an exceptional experience to our customers who use assistive technologies.
What is accessibility and why does it matter?
According to data from the CDC, approximately 61 million adults in the U.S. live with a disability. That’s roughly one in four adults. Whether their vision, hearing, mobility, or cognitive function is affected, people with disabilities often interact with technology differently than people without disabilities.
Instead of directly touching their phone’s screen, iPhone users with motor disabilities may use features like Voice Control or Switch Control. People with visual disabilities may use larger text or increased contrast between the background and foreground, or they may have the content on the screen read aloud with VoiceOver or communicated tactilely through a Braille keyboard.
We often use things like color and font size to indicate linked text or section headers. We design beautiful graphs and data visualizations to deliver trends and insights at a glance. But we also need to convey the same information to people who use a screen reader. Luckily, Apple provides a rich set of accessibility APIs for both SwiftUI and UIKit that iOS developers can use to build apps that are fully accessible to everyone.
How we made Mint iOS more accessible
Once I realized we weren’t doing enough to deliver an awesome experience for our Mint iOS customers with disabilities, I turned to Intuit’s Accessibility Champion program to learn more about accessibility. I learned how to use VoiceOver on my own iPhone through online tutorials like this video from Apple, and experimented with several different apps with VoiceOver to get a sense of which handled things well and which didn’t.
I was fascinated by talks at Apple’s Worldwide Developer Conference (WWDC) introducing new accessibility features like audio graphs, which provide a way for VoiceOver users to hear a sonified representation of the data in graphs on the screen. I read through tutorials and blog posts from other iOS developers like Ray Wenderlich and Rob Whitaker. I monitored feedback that customers left in the Mint app for terms related to accessibility to find what worked well and what didn’t for our customers. Then I got to work fixing things.
Diving into the code
Luckily, I had time to do this without disrupting my scheduled work. Twice a year, Intuit holds Global Engineering Days (GED), a full week when engineers can work on projects they’re passionate about. For me, that meant a week in November 2021 to dive headfirst into our Mint iOS code and make as many improvements as possible to our app’s accessibility.
I started by doing a full audit of the app with VoiceOver, which revealed more than 200 changes we could make to improve the app’s accessibility. During GED, I led a team of three other Mint iOS developers to fix as many items on the list as possible.
Most of the fixes we made during GED fell into one of these common and easily fixed mistakes:
- Buttons with an icon and no text. These buttons use the name of the image file as the accessibility label if no label is provided. So for an “x” icon, VoiceOver might read something like “white cross icon” or something even less clear, depending on the name of the image file. To fix this, add an accessibility label with .accessibilityLabel(Text(“Close”)) in SwiftUI or button.accessibilityLabel = “Close” in UIKit.
- Unmarked section headings. In the Mint iOS app, there are screens with several sections for different features, like viewing transactions, tracking spending, and checking budgets. Each section starts with a bold heading but not all of them were properly marked as such, which lets VoiceOver users easily jump between headings to find the content they’re looking for. To fix this, add .accessibilityAddTraits(.isHeader) in SwiftUI or headerLabel.accessibilityTraits.insert(.header) in UIKit.
- Ungrouped screen elements. We can improve ease of navigation by grouping elements or pieces of text that logically go together so VoiceOver reads it as one piece. VoiceOver users primarily navigate an app by swiping left and right to go to the next or previous element on the screen. We made sure to follow this best practice in lists we have in Mint, such as the list of transactions. If each transaction in Mint iOS is a single group with name, date, amount, and category, we can reduce the total number of swipes by a factor of 4. In SwiftUI, add the .accessibilityElement(children: .combine) modifier to a container and it will automatically group its children and combine their accessibility labels. In UIKit, you must first set the container to be an accessibility element (containerView.isAccessibilityElement = true) and then set the accessibility label to be a combination of the title and subtitle (containerView.accessibilityLabel = “\(title), \(subtitle)”).
- Nonstandard clickable elements. Buttons and other clickable elements are the main way to navigate between screens in an app. When you use SwiftUI’s Button or UIKit’s UIButton, VoiceOver automatically announces the element as a button, so the user knows they can click on it to take some action. But if it’s a card, label, or something else serving as a button because we added an onTapGesture (SwiftUI) or UITapGestureRecognizer (UIKit) modifier, it might not be clear to a VoiceOver user that it’s clickable. To let VoiceOver know to announce the element as a button, add .accessibilityAddTraits(.isButton) in SwiftUI or headerLabel.accessibilityTraits.insert(.button) in UIKit.
- Accessibility hints. If it still isn’t obvious what this element does, you can also add an accessibility hint to provide further clarification. For example, when a Mint iOS user is viewing their net worth graph, they can tap on their net worth to view a list of recent transactions. To make this more clear to VoiceOver users, we added .accessibilityHint(Text(“View transactions”)) in SwiftUI or label.accessibilityHint = “View transactions” in UIKit.
We also dove into some exciting new accessibility APIs to provide an exceptional experience for VoiceOver users. In iOS 15, Apple introduced audio graphs. While sighted users can see trends at a glance by looking at graphs, VoiceOver users had to swipe through and hear information about individual data points. With audio graphs, the iPhone can play a sonified version of the data, with the pitch of the sounds representing the position on the y axisMost Mint iOS users open the app to a screen with a line chart of their net worth or spending over time. Thanks to our work during GED, these charts now support audio graphs! To add audio graphs to your app, make sure your graph conforms to the AXChartDescriptorRepresentable protocol in SwiftUI or the AXChart protocol in UIKit, and provide simple descriptions of the axes and data shown in your graph. The system will handle the rest.
Our journey to make the Mint iOS app more accessible coincided with our team starting to adopt SwiftUI. Adding accessibility properties in UIKit is pretty straightforward, but I quickly realized that SwiftUI streamlines accessibility even more. Just like how there are SwiftUI modifiers to set the font or color in a single line, there are also modifiers to easily add an accessibility label to an image, or group labels that logically belong together into a single accessibility element that automatically combines the text from both of them.
I put together a workshop of what I’d learned about accessibility with SwiftUI. The project I used for the workshop, along with examples of components with poor accessibility and how to improve them, is available on GitHub.
I was also intrigued by the possibility of catching accessibility violations at compile time with an open source tool like SwiftLint. Linters for mobile code can be a bit limited in how they apply to accessibility because they analyze code, rather than the UI created by the code. I contributed the first accessibility rule for SwiftLint, which checks for SwiftUI Images that are created without a label and aren’t hidden from assistive technologies like VoiceOver. If you use SwiftLint, make sure you turn on the accessibility_label_for_image rule in your project!
Keeping the feedback loop open!
A key part of being customer obsessed is making sure you’re delivering an exceptional experience to all customers regardless of their abilities. Once you take the time to understand common problems that make apps less accessible, it’s often a simple matter of adding a couple of lines here and there to your code to make sure everything works as expected for people navigating your app with assistive technology. The customer benefit will far exceed the developer effort.
We’re incredibly proud of the progress we’ve made to date, and grateful for the insights and feedback provided by our customers and accessibility community peers that are making it possible.
Special thanks to Brandon Biggs for sparking my interest (and raising my awareness!) in accessibility during that initial Follow Me Home. To Ethan Holliger for providing ongoing user feedback that has led to meaningful improvements for Mint customers. To Lucy Greco, a web accessibility evangelist at UC Berkeley, who generously shared her knowledge at an Accessibility Champion Lunch and Learn, and walked through the Mint iOS app to provide feedback. And, to Ted Drake, Global Accessibility Leader for Intuit’s Accessibility Champion program, for all of his support and guidance.
Want to come help us build accessible mobile apps at Intuit? Check out open positions at https://www.intuit.com/careers.