How Time-Consuming Is It to Build an Accessible Mobile App?


The most common misconceptions about accessibility are that it is time-consuming or can be easily left as the last thing to be added. But, of course, this is not the case. We’ll look at how easy and quick adopting accessibility as a First-Class Citizen and, on the contrary, how difficult and time-consuming it is to add accessibility to an existing project.



Hi, is it really true that building an accessible app is time consuming and expensive? In order to answer that question, we're going to divide the agenda into two parts. The first part, we take an existing app and we try to make it accessible. The second part, we start an accessible app from scratch. Now, before starting, my name is Alessandro Senese and I'm a software engineer in Formidable. I started to work with accessibility about four years ago, where my first work with Realm Internet TV involved creating an accessible app for a bank. And so I started learning more and more about accessibility and I never stopped since then. So before we carry on, let's remind us what are we trying to do. Accessibility is the practice of making your mobile app usable by as many people as possible. So that's our target, we want to make sure that as many people as possible can use our app. So let's start. Now this accessibility issue to fix is actually a report we got from an Excel company, where they highlighted a serious and critical issue that we had to fix in our app. In my case, I did use React Native AMA to help me with these fixes. And the library is a React Native library I built after I joined Formidable. It does contain a set of components, hooks, they are designed to enforce minimum accessibility requirements. So first thing I did, I did install the library with Yard. I did import the provider provided by the library and wrapped around my application. So to fix roles, labels, states and hints, I did replace all the imports of the pressable from React Native to React Native AMA. And once I learned that I got around 200 TypeScript errors or missing roles and labels. And in the discussion, you can see how AMA works. Basically, AMA does some runtime check. But apart from the TypeScript typing, does a runtime check of some of the common accessibility issues and if it fails, it does highlight the component inside the UI and shows a banner. And also prints in the console which of the accessibility tests has failed. Now in my case, I had about 200 errors and the big problem I had, I could not assume that everything was a button. And inferred from the code, which a role to use was not always straightforward. So the only option I had was to actually navigate through on the screen to fix the problem. The same was with accessibility label. I had to make sure that the accessibility label was clear for the screen reader user. And also I had to check if it was enough because we had some cases like the one in the screenshot where the button did contain X information, in this case, five message, unread message. So I had to communicate this information to the screen reader user using accessible hint. Also because I haven't worked on all the parts of the app, I wasn't sure how many screens we actually had. So the only option I had was actually go through the entire app by myself and figure it out, all the information that was missing. For headers, it was easier. We just make sure that each screen had the header and everything that looked like a header was actually read, marked as a header for the screen reader. The forms, there was another problem we had. The bigger problem was the user was able to focus the form label and the form input as two different fields. The required option was not read and the message was not read as part of the field. Another problem was that by default React Native does show a keyboard with a return key, but that return key doesn't do anything. The right behavior was to allow the user to navigate through the fields using the next button if needed and allow to submit the form with return one. The last problem was if the form gets submitted and there is any error, the first field that does contain an error should gain the focus. This was not happening for us. So to fix this, I did use React Native Amma, especially the form field is a wrapper that handled the form submit. So if in this case handle submit fails, the form that contains a reference to all the inner field will try to focus the first field that we marked as that contains an error. And also, yeah, the form itself, it's used internally, but the text field and the use text field hook to figure out which keyboard button to show. For the text field, we had to share the components. So what I had to do was wrap, was to use the text input, use text input hook where the ref is used to allow focusing the field internally. See if the field had no validation, if had no errors, all the various attributes and pass that properties back to the text input. And also we have a form field like checkbox or combo. In this case, I had to wrap in the generic form dot field provided by Amma. And this field is able to actually get, receive a screen focus from the screen reader. For the bottom sheet, this show we had the one we were using did not did not get any focus. The user was still able to select anything underneath the overlay, the bottom sheet itself. So we had to replace that. In this case, I used one built in Amma that did address the accessibility issue. Also, this one has the benefit of disabling the animation, the sliding in and slide out animation if the user set the disable animation in the device. The time of the action, we had basically, if you in this case, if you add any time to the card, we show a message for a few seconds. And the report we had that they were supposed to behave more or less like a bottom sheet. It was supposed to gain the focus, allow the user enough time to actually interact with it. And the user was not supposed to select anything, be able to focus anything underneath. In this case, we did use the bottom sheet provided by React Native Amma. So we had all the focus feature and the focus feature. And we used in conjunction with the use them out action. This basically allows trigger the function we give according to the status of the screen reader and the device. For example, in iOS, if the screen reader is on, the timeout is never triggered. While on Android, we use the time to take action settings from the device. So that was the critical and the serious issue we fixed. So how long did it take? From the reset, it also had bug fixes because during the process, we had to replace some library with others that were accessible. So we introduced some bugs. Some of them we were not aware because, for example, the bottom sheet does use model, but React Native does not support opening multiple models unless they are nested. So we had to change a bit of logic around that to make it work in the app. And the whole process took more than five weeks to fix. So let's build an accessible app as first class citizen. How do we do that? How can we make sure that our app is accessible by day zero? The solution is easy. We can build shared components that are accessible by default. So whatever you have buttons with different states, with different hint, we just create a one or multiple shared components that handle all the required properties we need. The same we can do for a header. The same we can do for forms. We just make sure the fields are accessible already. Bottom sheet, overlay if needed, and carousel. In our case, we also had a carousel we had to make accessible. So whatever component we actually need in our app, we can create once and make it accessible. So what we're going to use is already accessible by default. We need a bit, just a bit extra time to make sure that everything works. Because yeah, accessible out of the box doesn't mean that your app is going to be full accessible. There are some checks that are needed to be done manually that we cannot automate. For example, we still need to make sure that whatever feature we build can be done with the screen reader. A screen reader user is able to do that feature. Also the focus is very important. We need to make sure that the elements get focused in the correct order. If a specific order is needed for any reason, we need to make sure that also screen reader user are able to do that order. UI changes are announced. UI change, if as consequence of some user action, we do update the UI or we show some toast elements, we need to make sure that those information is actually provided to the screen reader user. We can make it announced using one of the accessibility API provided by React Native. Or for example, if some elements appear, for example, some error, some validation, some error after an API fails, we make sure that this element gains the focus and so gets announced by the screen reader user. One thing very, very important is that we need to make sure that the appearance and the behavior and the appearance is consistent across the entire app. The app needs to be predictable. And if we have a Bluetooth buttons to the same thing, they need to look like the same. Another element is an important thing to keep in mind is group content if needed. Sometimes this can be part of the shared component we created, but we need to double check every time and make sure that's OK. In our case, we have a context here where we have a title, a header and the copy and the author and a button. The quote of the day, that's a header, can be focused separately. That's fine. But the content of the quote in our case is a quote from Walt Disney. The copy and the author should be focused as one thing. And to do that, usually you can just wrap the multiple text in an accessible view. This will force the screen reader to actually read the text as one. That's another example from our app where we have a subtotal and $20. We want to make sure that the user select the row subtotal $20 and read as one. We don't want the user to select subtotal first and $20 after. So whenever you have a release information that needs to be read together, just make sure that's the case. So here is a small table of quick cons of the link accessibility or build an accessible app from scratch. If you delete the accessibility, you don't get any benefit. Configure after the effort I had to put in, a config of a single benefit that gives you the link accessibility. It's actually very expensive. It requires a big effort. The time needed to address accessibility issue depends by the size of your app. So the bigger the worse. Most of the time and to find the problem and fix them, you need to navigate through the entire app. You can't just look at the code and guess how it's going to work. Also don't forget all the check needs to be done on both platform iOS and Android. So this means double work. You have a risk of introducing new bugs. Can happen if you need to replace some library with another or some of you need to modify the logic to make it work, to make it accessible. Well, if you start with accessible, it does require some effort to make a component accessible. But the thing is you do once. You only make accessible when you create it. Yeah, share the component will already handle most of the accessibility needs. Eventually you just need to put together. Before you do a test, we're going to use the need to test you only test what you actually building. You don't need to test the entire app. All the time from scratch, you just test what you build. So accessibility is expensive and time consuming only if you delete. That's the reality. If we can ignore it, if we know that our app needs to be accessible and we ignore it, we just going to hurt ourselves probably badly. At the end. Here I left some reference if you want to hear information about the React Native AMA and various guidelines you can refer to to know how to build an accessible mobile app. And that's all from me. Thank you very much.
21 min
24 Oct, 2022

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

Workshops on related topic