Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Starting A11Y in iOS

439ebe4787a98881df8a59d41baf4a43?s=47 Ryo Aoyama
November 28, 2019

Starting A11Y in iOS

CA11Y #2
Twitter hashtag: #ca11y


Ryo Aoyama

November 28, 2019

More Decks by Ryo Aoyama

Other Decks in Programming


  1. Starting A11Y in iOS Nov 2019 CA11Y #2

  2. Ryo Aoyama CyberAgent, Inc. CATS productivity team Twitter: @ra1028fe5 GitHub:

    @ra1028 OSS: DifferenceKit, Carbon, etc…
  3. A11Y A C C E S S I B I

    L I T Y 11
  4. Voice Over Voice Control Siri Shortcut Zoom Magnifier Larger Text

    Color Contrast etc…
  5. Voice Over

  6. Voice Over VoiceOver is a gesture-based screen reader that lets

    you enjoy using iPhone even if you don’t see the screen. “September event two thousand nineteen, Apple…”
  7. The first step to get interested in Voice Over.

  8. Enabling Voice Over in

  9. https://support.apple.com/en-am/guide/iphone/iph3e2e2281/ios Learn VoiceOver gestures: Let's make sure that whether your

    app available for gestures and screen readers.
  10. Enabling Voice Over with shortcut in

  11. Youtube Airbnb Uber Eats Try to use the app with

    Voice Over habitually.
  12. Voice Over in UIKit

  13. The official programming guide says, “Standard UIKit controls and views

    are automatically accessible. When you use standard controls and views, much of the work of making your app accessible is done for you.”
  14. Accessibility Attributes • Label • Traits • Hint • Frame

    • Value
  15. Spoken by VoiceOver in order; “Value, Label, Traits, Hint” Traits

    are sometimes read before Label.
  16. “બ୒தͷɺຊ೔։࠵ɺϘλϯ” “։࠵தͷϨʔε” When using standard UI such as UILabel or

    UIButton is read correctly by default. Label Label Trait Trait
  17. A short word or phrase that succinctly describes the element,

    but doesn't identify the its type. Examples are "Add", not "Add button”. Some of elements such as UILabel or UIButton are having default label. Label var accessibilityLabel: String?
  18. Label This isn't obvious the behavior of element and also

    disadvantageous for localization, so its better to set an accessibilityLabel. By default, if the button is set an icon only like below, the VoiceOver read an asset name.
  19. Traits A combination of trait that single aspect of an

    element’s state, behavior, or usage. Static Text Image Button Link etc… Selected var accessibilityTraits: UIAccessibilityTraits
  20. Hint A brief phrase that describes the results of an

    action. Examples are “Adds a title” or “Opens the shopping list.” Some controls have default value such as UIDatePicker. var accessibilityHint: String?
  21. Hint The hint describes the element action itself or the

    results of performing it. If the role of the element is clarified by Label and Traits, there is no need to set Hint.
  22. Hint This is not spoken by Voice Over if you

    set the switch off ’Speak Hints’ in setting app: Accessibility > VoiceOver > Verbosity
  23. Frame The frame of the element in screen coordinates that

    specifies an element’s location and size. The UIView subclass defaults to the value same as `frame` property, otherwise zero. var accessibilityFrame: CGRect
  24. Value The current value of an element. It's set by

    default such as UISlider or UITextField. var accessibilityValue: String?
  25. Value print(slider.value) // 0.5 The `value` of UISlider is Float

    value, thus the result of following code is like `0.5`. But, the default accessibilityValue is the text `50%`. Like so, the accessibilityValue should be text that is more user-friendly.
  26. There are many other APIs are provided, but as mentioned

    at the beginning, UIKit is accessible by default. Creating an app using standard UIKit elements whenever possible will help keep the app accessible.
  27. A11Y Scanning Tools

  28. Xcode Accessibility Inspector

  29. Open inspector from the menu Xcode > Open Developer Tool

    > Accessibility Inspector
  30. Automatically runs the VoiceOver in order of elements and revealing

    a11y setting of elements.
  31. Expose the issues by audit and get a fix suggestion.

    Too many issues are lurk in our app
  32. Overwrite the common a11y options to test.

  33. Accessibility Inspector is just for Xcode GUI. Can’t used from

    Swift code or command line…
  34. google/GSCXScanner iOS Accessibility scanner framework to catch a11y issues during

    development. Depending on google/GTXiLib.
  35. target ‘App' do use_frameworks! pod 'GSCXScanner' end What to do

    to get started is only add following to Podfile:
  36. We can always check the a11y on the app runtime

    from the ‘Perform Scan’ button.
  37. Visualize the elements that has issues on the displaying screen.

  38. And you can see issue details on the app.

  39. In-app scanner allows members other than engineers to check a11y.

    It’s not available to be used for unit testing.
  40. google/GTXiLib iOS Accessibility testing library that works with XCTest based

  41. Automatically runs all registered checks for a11y before tear-down on

    each tests. GTXiLib has XCTest integration and can be used with any XCTest-based frameworks such as google/EarlGrey. Can be introduced an arbitrary a11y checks.
  42. final class MyTests: XCTestCase { override class func setUp() {

    super.setUp() GTXiLib.install( on: GTXTestSuite(allTestsIn: self), checks: GTXChecksCollection.allGTXChecks(), elementBlacklists: [] ) } func testXXX() { // Do any unit tests. } }
  43. One or more elements FAILED the accessibility checks: <UIButton: 0x7ff43d82a440;

    frame = (135 418; 105 30); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x60000223bde0>> + Check "Element has Minimum Tappable Area" failed, Suggest increasing element's frame height to at least 44 for a suggested tappable area of at least 44X44
  44. GTXiLib is extracts accessibility elements from the UI displayed on

    the screen on test environment. Can we control the app screen using XCUITest?
  45. XCUITest is a black-box testing Control Installed ❌ Can’t access

    to process
  46. GTXiLib is depends on UIApplication.shared, so it’s not allowed to

    runs on XCUITest-based testing process.
  47. We can use google/EarlGrey v1 for UI automation in XCTest-based

    testing. final class MyTests: XCTestCase { override class func setUp() { super.setUp() GTXiLib.install( on: GTXTestSuite(allTestsIn: self), checks: GTXChecksCollection.allGTXChecks(), elementBlacklists: [] ) } func testXXX() { EarlGrey .selectElement(with: grey_text("Button")) .perform(grey_tap()) } }
  48. Makes some pains, but “barely” possible to check a11y conformance

    with continuous integration.
  49. Conclusion

  50. Appropriate use of UIKit can adapt your app for minimal

    accessibility. Continuous testing for a11y having some pains likewise E2E testing, but it's possible. It’s important to include concerns about a11y in the UI/UX design and debugging process.
  51. Thanks Twitter: @ra1028fe5 GitHub: @ra1028 Ryo Aoyama