Motion-Accessibility
I just released my second RubyMotion gem. I call it motion-accessibility. It makes it much easier to make your applications accessible by providing Ruby-like names to Apple’s accessibility APIs. I have some great plans for the future as well. It feels great to contribute to the RubyMotion and iOS community.
It all began at the RubyMotion conference. Colin gave me a little sneak peak at what would become motion-xray. We talked about accessibility, and I had the idea to make some sort of automated accessibility test. This way developers could get an idea of the accessibility of their views, with easily understood error messages telling them exactly what to do. I first thought of it in the context of Colin’s view inspector, but quickly realized the general application. I’d love it if in a spec file someone could just write:
view.should.be.accessible
And at that point I foresaw that I would write this gem, and call it motion-accessibility, and so help elevate the collective spirit of humanity.
I didn’t start work immediately, I needed some time to wind down. Instead I released another gem, golden-sections, but I knew I would have to do this. Then while on my Asbury Park adventure, someone asked if RubyMotion made it any easier to program accessibility. “Well…no…not really…but….” I knew I had to start work.
It took me two weeks to get the first version working. I kept thinking I had finished, but would then find one more thing that needed doing. First I realized that I couldn’t just alias the methods. Apple lets you define attributes in two ways: by using a setter or by overriding a method. Using a setter wouldn’t present a problem:
alias :accessibility_label= :setAccessibilityLabel
But what if someone wanted to override the method? I asked for help, and my friend Thomas from Germany suggested the method_added method. Now I had gotten into the interesting realm of metaprogramming. And it all worked. Now you can do:
def accessibility_label
“Hello”
end
and it will also override the original accessibilityLabel method. It works both ways. Ruby rocks!
I came up with some neat solutions to some things. For example, setting accessibility traits could take a lot of writing. Now instead of
accessibilityTraits=UIAccessibilityTraitImage | UIAccessibilityTraitLink |
you can write
accessibility_traits=[:image, :link]
Notifications also bothered me. Let’s say you have a view controller that at some point makes a change to the screen. You should tell VoiceOver of this by posting a screen changed notification. Before you would have to do
UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification)
Ouch! How about
Accessibility.post_notification(:screen_changed)
Much easier, don’t you think?
Apple has a bunch of protocols. At one point I swore if I read the word UIAccessibility again I would go mad. I kept finding new ones and new methods and figuring out the best ways to add them. I think I got them all.
Then came a real shocker, for me at least. I thought of these attributes and methods as relating to views or accessibility elements. I realized that they actually belong to the root NSObject class. As I explained in another post, in Ruby all objects have a parent. All objects go back to Object, or NSObject in RubyMotion. You can’t get any more “baked in” than that!
Now I can proudly say that yes, RubyMotion does make it easier to program accessibility. Enjoy more Ruby-like names and ways of doing things. I hope this will encourage developers to make their apps more accessible. I know it will help me. And the future looks bright, with thoughts of automated accessibility testing.
By the way I just got accepted to speak at the Nickel City Ruby conference in Buffalo, New York. I will demo this gem there. Just think how much more awesome motion-accessibility will make my speech!