Keep track of accessibility settings, leverage high contrast colors, and use scalable fonts to enable users with disabilities to use your app.

Overview


Awesome Swift Platforms Cocoapods compatible SPM Twitter

Accessibility for iOS, macOS, tvOS, and watchOS

πŸŽ‰ What's new in Capable 2.0 πŸŽ‰

Here are the most important changes:

  • πŸ› New framework architecture and project structure that makes contributing support for upcoming accessibility settings easier.
  • 🎯 Focus on an unified API for Apple accessibility settings: While support for scalable fonts & handicap grouping was dropped entirely, the APIs for calculating high contrast color pairs based on WCAG 2.1 success criteria has moved to it's own repository WCAG-Colors.
  • βœ… Support for new accessibility APIs.

Research & React

Have you ever thought about improving accessibility within your apps to gain your user base instead of spending a lot of time implementing features no-one really ever asked for? Most of us did, however there has never been an easy way to tell if anyone benefits from that. What if there was a simple way to figure out if there's a real need to support accessibility right now. Or even better, which disability exists most across your user base.

While Apple's accessibility API are different across all platforms and might be located in a variety of system frameworks, Capable offers a unified and centralized API to get the current status of accessibility settings. This info can be sent to your analytics backend to learn, if people with specific handicaps are blocked from doing certain actions within your app. Furthermore, this data will help you to prioritize accessibility work.

Once you've figured out that users with specific handicaps get stuck at a certain stage, you can make use of various Capable APIs to enable/disable accessibility support based on the user's accessibility settings.

Documentation

Capable offers a whole lot of features along with a bunch of configurations. To find more about how to use them inside the documentation section.

Installation

There are currently three different ways to integrate Capable into your apps.

CocoaPods

use_frameworks!

target 'MyApp' do
  pod 'Capable'
end

Carthage

github "chrs1885/Capable"

Swift Package Manager

dependencies: [
    .package(url: "https://github.com/chrs1885/Capable.git", from: "2.0.1")
]

Usage

Register for (specific) accessibility settings

Firstly, you need to import the Capable framework in your class by adding the following import statement:

import Capable

There are two different ways to initialize the framework instance. You can either set it up to consider all accessibility features

let capable = Capable()

or by passing in only specific feature names

let capable = Capable(withFeatures: [.largerText, .boldText, .shakeToUndo])

You can find a list of all accessibility features available on each platform in the accessibility feature overview section.

Get accessibility status

If you are interested in a specific accessibility feature, you can retrieve its current status as follows:

let capable = Capable()
let isVoiceOverEnabled: Bool = capable.isFeatureEnable(feature: .voiceOver)

To get a dictionary of all features, that the Capable instance has been initialized with you can use:

let capable = Capable()
let statusMap = capable.statusMap

This will return each feature name (key) along with its current value as described in the accessibility feature overview section.

Send accessibility status

The statusMap object is compatible with most analytic SDK APIs. Here's a quick example of how to send your data along with user properties or custom events.

func sendMetrics() {
    let statusMap = self.capable.statusMap
    let eventName = "Capable features received"
    
    // App Center
    MSAnalytics.trackEvent(eventName, withProperties: statusMap)
    
    // Firebase
    Analytics.logEvent(eventName, parameters: statusMap)
    
    // Fabric
    Answers.logCustomEvent(withName: eventName, customAttributes: statusMap)
}

Listen for settings changes

After initialization, notifications for all features that have been registered can be retrieved. To react to changes, you need to add your class as an observer as follows:

NotificationCenter.default.addObserver(
    self,
    selector: #selector(self.featureStatusChanged),
    name: .CapableFeatureStatusDidChange,
    object: nil)

Inside your featureStatusChanged you can parse the specific feature and value:

@objc private func featureStatusChanged(notification: NSNotification) {
    if let featureStatus = notification.object as? FeatureStatus {
        let feature = featureStatus.feature
        let currentValue = featureStatus.statusString
    }
}

Accessibility feature overview

The following table contains all features that are available:

βœ… API provided by Apple and fully supported by Capable

β˜‘οΈ API provided by Apple (status only, no notification) and fully supported by Capable

❌ API provided by Apple but not supported by Capable due to missing system settings entry.

iOS macOS tvOS watchOS
.assistiveTouch βœ… ❌
.boldText βœ… βœ… β˜‘οΈ
.buttonShapes βœ… (iOS14) ❌
.closedCaptioning βœ… βœ…
.darkerSystemColors βœ… ❌
.differentiateWithoutColor βœ… (iOS13) βœ… ❌
.fullKeyboardAccess β˜‘οΈ
.grayscale βœ… βœ…
.guidedAccess βœ… ❌
.hearingDevice βœ…
.increaseContrast βœ…
.invertColors βœ… βœ… βœ…
.largerText βœ… ❌ β˜‘οΈ
.monoAudio βœ… βœ…
.onOffSwitchLabels βœ… (iOS13) ❌
.prefersCrossFadeTransitions βœ… (iOS14) ❌
.reduceMotion βœ… βœ… βœ… βœ…
.reduceTransparency βœ… βœ… βœ…
.shakeToUndo βœ… ❌
.speakScreen βœ… ❌
.speakSelection βœ… ❌
.switchControl βœ… βœ… βœ…
.videoAutoplay βœ… (iOS13) βœ… (iOS13)
.voiceOver βœ… βœ… βœ… βœ…

While most features can only have a statusMap value set to enabled or disabled, the .largerText and .hearingDevice feature do offer specific values:

LargerText

iOS
  • XS
  • S
  • M (default)
  • L
  • XL
  • XXL
  • XXXL
  • Accessibility M
  • Accessibility L
  • Accessibility XL
  • Accessibility XXL
  • Accessibility XXXL
  • Unknown
watchOS
  • XS
  • S (default watch with 38mm)
  • L (default watch with 42mm)
  • XL
  • XXL
  • XXXL
  • Unknown

HearingDevice

  • both
  • left
  • right
  • disabled

Logging with OSLog

The Capable framework provides a logging mechanism that lets you keep track of what's going on under the hood. You'll get information regarding your current setup, warnings about anything that might cause issues further on, and errors that will lead to misbehavior.

By default, all messages will be logged automatically by using Apple's Unified Logging System. However, it also integrates with your specific logging environment by providing a custom closure that will be called instead. For example, you may want to send all errors coming from the Capable framework to your analytics service:

// Send error messages to your data backend
Capable.onLog = { message, logType in
    if logType == OSLogType.error {
        sendLog("Capable Framework: \(message)")
    }
}

Furthermore, you can specify the minimum log level that should be considered when logging messages:

// Configure logger to only log warnings and errors (.default, .error, and .fault)
Capable.minLogType = OSLogType.default

Here's a list of the supported log types, their order, and what kind of messages they are used for:

OSLogType Usage
.debug Verbose logging *
.info Information regarding the framework setup and status changes
.default Warnings that may lead to unwanted behavior
.error Errors caused by the framework
.fault Errors caused by the framework due to system issues *

* Currently not being used by the framework when logging messages.

Resources

Contributions

We'd love to see you contributing to this project by proposing or adding features, reporting bugs, or spreading the word. Please have a quick look at our contribution guidelines.

License

Capable is available under the MIT license. See the LICENSE file for more info.

Comments
  • Fix converting NSNotification.Name to String error

    Fix converting NSNotification.Name to String error

    This is an attempt to fix the "Cannot convert value of type 'NSNotification.Name' to expected argument type 'String'" issue.

    Although appending '.rawValue' resolves the error, it would probably be more elegant if that line is just: name: UIAccessibility.differentiateWithoutColorDidChangeNotification

    Issue information

    Right now, I'm getting the following issue when I try and build Capable as a SPM dependency: "Cannot convert value of type 'NSNotification.Name' to expected argument type 'String'".

    Goal

    Try and get Capable to compile when used as SPM dependency.

    Implementation

    Added .rawValue so NSNotification.Name is passed the string value.

    Testing

    Code compiles after making the change.

    opened by acosmicflamingo 9
  • Cannot install via Carthage anymore for 1.1.1

    Cannot install via Carthage anymore for 1.1.1

    What did you do?

    I was trying to install Capable 1.1.1 by using Carthage.

    What did you expect to happen?

    Carthage should be able to build Capable as per 1.1.0 and before.

    What happened instead?

    I got this error message:

    Dependency "Capable" has no shared framework schemes for any of the platforms: iOS
    
    If you believe this to be an error, please file an issue with the maintainers at https://github.com/chrs1885/Capable/issues/new
    

    I found that Capable.xcodeproj was removed since 11.1.1 in cd49b00d3b9f0dd968524f25d76c8afd877111a1, I believe this is the cause of the issue.

    Setup

    • Added this in the Cartfile
    github "chrs1885/Capable"
    
    • Run the command
    carthage update --platform iOS
    
    opened by jefflen 5
  • Add Carthage support by sharing Pod schemes

    Add Carthage support by sharing Pod schemes

    Issue information

    Alternative to #48 #47 by sharing schemes of the Pods-project.

    Goal

    Adding Carthage support without explicitly re-adding the Capable project file.

    Implementation

    Sharing the shemes.

    Testing

    opened by chrs1885 4
  • Add back Capable.xcodeproj for Carthage support.

    Add back Capable.xcodeproj for Carthage support.

    Please fill out all lines starting with a πŸ“ when filing a pull request to give us an idea of what you did.

    Issue information

    πŸ“This resolved issue #47 for not having Carthage support in version 1.1.1.

    Goal

    πŸ“Re-supporting Carthage

    Implementation

    πŸ“Re-introducing the Capable.xcodeproj file

    Testing

    πŸ“Tested on Carthage which worked.

    opened by jefflen 4
  • Build error while importing Capable 2.0.0 using SPM

    Build error while importing Capable 2.0.0 using SPM

    Please fill out all lines starting with a πŸ“ when filing a bug to give us an idea of what exactly went wrong.

    What did you do?

    πŸ“ Impoorting Capable using SPM, at version 2.0.0

    What did you expect to happen?

    πŸ“ The project to build successfully πŸ˜…

    What happened instead?

    πŸ“ Error when DifferentiateWithoutColor observation is created, on iOS platforms : Screenshot 2022-02-06 at 18 41 56 The NSNotification.Name(rawValue:) wrapping is too much, just use directly UIAccessibility.differentiateWithoutColorDidChangeNotification for observer.

    Setup

    πŸ“ Just import Capable 2.0.0 using SPM.

    opened by jtouzy 3
  • Feature/lowercase enums

    Feature/lowercase enums

    As of Swift 3 (see Proposal-0006) it is common code style to use lowercase enums. Therefore I refactored the existing enum to begin with a lowercase letter.

    enhancement 
    opened by dehlen 3
  • Capable framework appearing in scheme when it doesn't need to

    Capable framework appearing in scheme when it doesn't need to

    I noticed that the Capable framework appears in the list of schemes when it is added as a SPM dependency when I don't think should be there: image I believe this can be fixed by simply adding .swiftpm to .gitignore (which Point Free had done to address the issue with the Composable Architecture repo: https://github.com/pointfreeco/swift-composable-architecture/discussions/1371 & https://github.com/pointfreeco/swift-composable-architecture/pull/1378). However, I don't know if Capable can take this same approach because the file appears in several places (specifically in BuildTools).

    opened by acosmicflamingo 1
  • Create dedicated lib for color extensions

    Create dedicated lib for color extensions

    Since most old feature have been removed from Capable 2.0, the main purpose of the framework should be focusing on an unified accessibility API. The WCAG color extension should be moved to its own library project.

    in progress 
    opened by chrs1885 1
  • Refactor Capable feature to support plugin based approach

    Refactor Capable feature to support plugin based approach

    Rather than having a single wrapper class for all accessibility settings, rewrite the framework to support a more plugin based approach. This will make it easier (possible) to maintain it. Also, upcoming accessibility settings can easily be provided by new contributors without having them to know anything about the framework's architecture.

    opened by chrs1885 1
  • Fix naming collisions with SwiftUI

    Fix naming collisions with SwiftUI

    Issue information

    Capable is using typealias names (e.g. NSColor, UIColor) inside extensions to avoid code duplication. When using the framework along with SwiftUI, building fails due to naming collisions (SwiftUI Color and typealias Color for NSColor, UIColor).

    Goal

    Avoid naming collisions 😁

    Implementation

    Rename typealias names

    Testing

    Run Unit Tests

    opened by chrs1885 1
  • CocoaPods subspec for UIFontMetrics/UIFont extension

    CocoaPods subspec for UIFontMetrics/UIFont extension

    What kind of feature would you like to see?

    Devs who would like to integrate Capable for autoscaling fonts within their apps might not want to use the whole pod but the extension code instead. CocoaPods supports subspecs to only distribute certain parts of the framework.

    How does it work in detail?

    Add extension subspec to the podspec.

    What does the API look like?

    Any existing projects that do something similiar?

    PromiseKit

    opened by chrs1885 1
  • Article/tutorial on user segregation (Capable & Firebase)

    Article/tutorial on user segregation (Capable & Firebase)

    What kind of feature would you like to see?

    The vision for using this framework is not clear, yet. We could provide an article on how to use Capable together with Firebase Analytics to:

    • Basic usage of the Capable framework
    • User segregation: How many app users do have handicaps
    • Capable status meets custom events: Where in your app flow do people with certain handicaps get stuck
    • DSGVO: Is it allowed to send this kind of data anonymously?

    How does it work in detail?

    Publish the article as part of the repo docs and on Medium.

    What does the API look like?

    Any existing projects that do something similiar?

    help wanted 
    opened by chrs1885 0
Releases(2.0.1)
Owner
Christoph Wendt
πŸ‘¨πŸΌβ€πŸ’»+πŸ‘¨β€πŸ‘¦ from Karlsruhe, Germany.
Christoph Wendt
A keychain wrapper that is so easy to use that your cat could use it.

A keychain wrapper that is so easy to use that your cat could use it.

HyperRedink 71 Oct 15, 2022
A Layer-2 framework built over Keychain API which helps in using Keychain in all your Apple devices with easiness and flexibility.

Keychain Manager Keychain Manager is a Layer-2 framework built over Keychain API which helps in using Keychain in all your Apple devices with easiness

Gokul Nair 14 Jan 1, 2023
A simple wrapper for the iOS Keychain to allow you to use it in a similar fashion to User Defaults. Written in Swift.

SwiftKeychainWrapper A simple wrapper for the iOS / tvOS Keychain to allow you to use it in a similar fashion to User Defaults. Written in Swift. Prov

Jason 1.5k Jan 8, 2023
Simple Swift wrapper for Keychain that works on iOS, watchOS, tvOS and macOS.

KeychainAccess KeychainAccess is a simple Swift wrapper for Keychain that works on iOS and OS X. Makes using Keychain APIs extremely easy and much mor

Kishikawa Katsumi 7.2k Jan 5, 2023
UICKeyChainStore is a simple wrapper for Keychain on iOS, watchOS, tvOS and macOS. Makes using Keychain APIs as easy as NSUserDefaults.

UICKeyChainStore UICKeyChainStore is a simple wrapper for Keychain that works on iOS and OS X. Makes using Keychain APIs as easy as NSUserDefaults. Lo

Kishikawa Katsumi 3.1k Dec 28, 2022
Simple Objective-C wrapper for the keychain that works on Mac and iOS

SAMKeychain SAMKeychain is a simple wrapper for accessing accounts, getting passwords, setting passwords, and deleting passwords using the system Keyc

Sam Soffes 5.4k Jan 8, 2023
iOS Trakt Client - Keep track of your favorite TV shows and movies on your iPhone. (Under development)

CouchTracker Keep track of your favorite movies and tv shows on your iPhone Setup for development You will need Xcode 11.2.1 Swift 5.1.2 Run the follo

Pietro Caselani 42 Apr 19, 2022
Pegase is a beautifully easy tool to keep track of your financial life on all your macOS

Pegase ?? Features ?? Documentation Personal account software Pegase is a beautifully easy tool to keep track of your financial life on all your macOS

null 2 Oct 12, 2021
Swift CLI for strong-typing images, colors, storyboards, fonts and localizations

Shark Shark is a Swift command line tool that generates type safe enums for your images, colors, storyboards, fonts and localizations. Because Shark r

Kaan Dedeoglu 377 Dec 1, 2022
This iOS framework allows settings to be in-app in addition to or instead of being in the Settings app.

InAppSettingsKit InAppSettingsKit (IASK) is an open source framework to easily add in-app settings to your iOS or Catalyst apps. Normally iOS apps use

Ortwin Gentz, FutureTap 3.1k Jan 2, 2023
Stuff application – keep track of your stuff.

stuff-app Stuff application – keep track of your stuff. Platforms App to be released for iOS 15, iPadOS 15 and macOS 12 Monterey. Purpose Project is d

Danis Tazetdinov 1 Dec 15, 2021
Stuff application – keep track of your stuff

stuff-app Stuff application – keep track of your stuff. Platforms App to be released for iOS 15, iPadOS 15 and macOS 12 Monterey. Purpose Project is d

Danis Tazetdinov 1 Dec 15, 2021
BoldContacts mobile app for people with visual/cognitive/motor disabilities

BoldContacts mobile app BoldContactsβ„’ is a mobile app that helps you browse your contacts and connect with them. BoldContacts is intended for people w

SixArm 25 Dec 15, 2022
A fan-made passion project. iOS app designed to keep track of data mined from Animal Crossing: New Horizons

DataCrossing A fan-made passion project. iOS app designed to keep track of data

Natalie 1 Jan 10, 2022
Random-Colors-iOS - Random colors generator app with auto layout

Random Colors Random colors generator app with auto layout Demo demo.mp4 Depende

Adem Γ–zcan 8 Mar 23, 2022
AppVersion - Keep users on the up-to date version of your App.

?? App Version Don't let you users to get stuck on outdated version of your app. Automatic update tracking using Semantic Versioning Buil-in UI alerts

Ameba Labs 31 Sep 30, 2022
Jitsi Meet - Secure, Simple and Scalable Video Conferences that you use as a standalone app or embed in your web application.

Jitsi Meet is a set of Open Source projects which empower users to use and deploy video conferencing platforms with state-of-the-art video quality and features.

Jitsi 19.1k Jan 5, 2023
With EconoApp you can keep track of economic information such as GDP, GDP per capita

EconoApp With EconoApp you can keep track of economic information such as GDP, GDP per capita, inflation and more. As simple as picking the country an

Vinicius Vieira 4 Feb 9, 2022
Color framework for Swift & Objective-C (Gradient colors, hexcode support, colors from images & more).

Swift 3 To use the Swift 3 version, add this to your Podfile (until 2.2 or higher is released): pod 'ChameleonFramework/Swift', :git => 'https://githu

Vicc Alexander 12.5k Dec 27, 2022
Tourist App enable users to search about touristic places in saudi arabia

TouristApp Project Name: Tourist Project Description : Tourist it's App enable users to search about touristic places in saudi arabia . Features List:

tasneemJafsher 0 Jan 6, 2022