accessibility engineering and low end disruption
apple doesn’t succeed at making their platforms accessible because they care more, they don’t succeed because they are somehow better at programming
a capable, thoughtful manager, who is correctly assessing risk vs reward, both qualitatively and quantitatively, who is doing their job well, using all of the experience and skill that brought them to where they are, can, and likely will, decide to ship an app that could be accessible, but is not.
this is not a function of callousness (although they may also be quite callous).
this is not a function of engineering aptitude (plenty of our leading lights have let access fall to the wayside1 by making solid engineering choices that are completely defensible).
the apple accessibility teams are made up of disciplined, brilliant engineers. they all work incredibly hard on a problem with unimaginable scale. but their brilliance and discipline and hard work, while necessary, are not sufficient.
what matters here, what sets apple apart, is that they figured out how to go last and contain the risk enough to avoid a revolt from other teams or executive leadership. it costs them a lot to do so, has significant, measurable downsides, and requires a significant rethink of what it means to build good software.
bundles
some of the code that powers accessibility on apple platforms is just disgusting to look at and to work on.
most of the code that makes apple software accessible lives in what’s called an accessibility bundle. without diving into the minutia of the thing, bundles are a way to load something akin to a plugin into a cocoa app at runtime if an assistive technology is activated. it involves manipulating the app or framework class hierarchy and using objective-c dynamism to read app state and build up a usable accessibility hierarchy. insert a super class here, read an instance variable there, swizzle in a method and store the state for it in associated objects.2
bundles are not a good way to build software by any common measure. they don’t make you efficient, or your code correct. the performance can get bad. they’re hard to maintain and involve constant patching to keep them alive. huge chunks of bundle code are thrown away and rewritten multiple times during every major os release.
i found the initial adjustment to working on this code sometimes viscerally upsetting. “i can’t do that!!”, “clearly i should be protecting against…”, “if i do it that way it’ll break when they…”, etc.
the thing is, critically, if a user never activates an assistive technology like voiceover they wouldn’t know bundles even exist. many of the managers at apple don’t know much or care much about accessibility. some of them are borderline hostile to it. the bundles make it possible for the accessibility team to allocate their own resources and set their own priorities with only very limited coordination and fallout contained to people who would benefit most from the upside. they allow the accessibility team to fix the bugs they find, when they find them, with pretty limited opportunities for a manager who’s next promotion is on the line to get cold feet and pull resources or block fixes.
in the model of low end disruption, we can see bundles as a low end entrant, with a product that seems worse, but that solves an important problem in a way that the mature products, by their nature, can’t realistically address.
if the job to be done is “produce easy to understand, correct, maintainable code that engineers who care about those things will enjoy working on” then bundles aren’t even in the competition.
if the job is “manage your team resources responsibly, keep your bug count low, ship your features on time” then bundles aren’t the tool you reach for. why would you load a squirrelly plugin into your own app on purpose?
the chaotic morass of runtime hacks and macros for everything and nearly exclusive dependence on runtime validation3 make them not just not good, but almost aggressively bad. but if the job they are hired to do is make apps that aren’t accessible, they’re incredible. unparalleled. entirely without peer.
almost all the things a good engineer would do to make bundles less gross would make them worse in unacceptable ways. almost anything a high end product might do to accommodate the kind of autonomy bundles demand would make them unacceptable to their current clients.4
apple has a team whose only job is to make things accessible and they have infrastructure that lets that team mostly avoid people who have a different job saying no to them. put those together and you have the most successful accessibility software team (imho) on planet earth.
the gross stuff isn’t desirable, but is maybe necessary
anyone who is steeped in universal design that has made it this far has maybe broken out in hives? please just stick with me, it’ll all come out in the wash.
- well designed apps that take accessibility into consideration from the beginning are better for everyone.
- accessible ramps for getting into buildings are better than those terrible lifts they bolt into the sides of stairs in public buildings.
- we all benefit from features in society that originate as accessibility affordances, like curb cuts for wheelchairs, that everyone with a stroller can now take for granted.
without question these statements are true.
i don’t worry too much about saying things that might make people think i’m a bad engineer or have bad ideas about building software. i do care a lot about not giving people the idea that we should all knock out our accessibility code real quick and sloppy at the end as an afterthought.
my thesis here is that where the effect of failing is very much acute, most of us do not adjust our approach accordingly. likely because we regard assistive technology users as one of many available audiences we may or may not wish to court.
if we ship an app that’s inaccessible, hey we’ll get around to it, we’ve got a roadmap, hasn’t bubbled up yet, software takes time. there are so many bugs in our support tracker and “doesn’t work for blind people” is just a tiny blip.
of course we should be methodical and plan ahead and build our software in a way that is both accessible and maintainable. we should seek to avoid compromising, but should the need to compromise emerge, the balance should unquestionably be tilted towards gross and unmaintainable code where that is the cost of accessibility. if you could fix that missing label but eww i’d have to wire up a very clumsy chain of delegates or fire a notification that clearly violates layering, without question, you should do it.5
we should be willing to find a blend of cultural and political and technical workarounds in our organizations that acknowledge that code can’t be allowed to go out the door that isn’t accessible and that a lot of our ideas about technical excellence and what a good engineering manager does wildly miscalculate the cost of our decisions to “do it right”.
-
what’s good loren brichter? ↩
-
you can find some of the machinery for bundles on your mac if you want to go spelunking, but it involves liberal usage of macros so you’re only getting a piece of the picture. ↩
-
it’s hard to validate code at compile time that’s compiled at a different time from a separate source repository. ↩
-
it’s hard to overstate how impressive it is that objective-c managed to be a language that could credibly accommodate people who cared about correctness and performance and people who cared about doing wild stuff you probably shouldn’t do. ↩
-
you should also try to contain the wild gross nonsense you do so that the “good” engineers don’t chase you out of the building. the thing where bundles only load when voiceover is on might be their most important feature. ↩