{"id":15170610,"url":"https://github.com/jackstone92/a11yoop","last_synced_at":"2026-02-07T03:31:28.492Z","repository":{"id":43860654,"uuid":"419423583","full_name":"Jackstone92/A11yoop","owner":"Jackstone92","description":"iOS accessibility tools","archived":false,"fork":false,"pushed_at":"2022-02-15T17:53:04.000Z","size":314,"stargazers_count":3,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"develop","last_synced_at":"2025-07-18T07:47:54.731Z","etag":null,"topics":["accessibility","accessibility-analysis","analytics","analytics-tracking","inclusion","ios","swift","swift-package-manager","swiftui"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Jackstone92.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-10-20T17:17:51.000Z","updated_at":"2022-05-24T15:49:11.000Z","dependencies_parsed_at":"2022-09-06T08:10:26.393Z","dependency_job_id":null,"html_url":"https://github.com/Jackstone92/A11yoop","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/Jackstone92/A11yoop","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Jackstone92%2FA11yoop","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Jackstone92%2FA11yoop/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Jackstone92%2FA11yoop/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Jackstone92%2FA11yoop/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Jackstone92","download_url":"https://codeload.github.com/Jackstone92/A11yoop/tar.gz/refs/heads/develop","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Jackstone92%2FA11yoop/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267277023,"owners_count":24063227,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-26T02:00:08.937Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["accessibility","accessibility-analysis","analytics","analytics-tracking","inclusion","ios","swift","swift-package-manager","swiftui"],"created_at":"2024-09-27T08:04:15.088Z","updated_at":"2026-02-07T03:31:28.454Z","avatar_url":"https://github.com/Jackstone92.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# A11yoop - iOS Accessibility Tools \n\n![Run Tests](https://github.com/Jackstone92/CombineRx/workflows/Run%20Tests/badge.svg)\n[![codecov](https://codecov.io/gh/Jackstone92/A11yoop/branch/develop/graph/badge.svg?token=5CUD7R531H)](https://codecov.io/gh/Jackstone92/A11yoop)\n[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2FJackstone92%2FA11yoop%2Fbadge%3Ftype%3Dswift-versions)](https://swiftpackageindex.com/Jackstone92/A11yoop)\n[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2FJackstone92%2FA11yoop%2Fbadge%3Ftype%3Dplatforms)](https://swiftpackageindex.com/Jackstone92/A11yoop)\n![SPM](https://img.shields.io/badge/SPM-compatible-ff59b4)\n[![License](https://img.shields.io/badge/license-mit-brightgreen.svg)](https://en.wikipedia.org/wiki/MIT_License)\n\n## A11oopMonitor\nHave you ever wondered which accessibility features users of your app actually have enabled? Do you want to easily be able to prioritise accessibility improvements that should be made to your app based on real data from your user base?\n\n`A11yoopMonitor` allows you to track which accessibility features users have enabled on their iOS devices while they use your app. It is simple to integrate into an existing app and provides an easy way of tracking status changes as users enable/disable features on their devices. It is also highly extendable, providing a simple API that allows you to do whatever you want with the data that is received.\n\n#### **A note about privacy...**\nIt is worth mentioning that any data tracked by `A11yoopMonitor` is completely anonymous and there is no way of identifying one user from another. All that is provided is a unified API to determine accessibility feature status changes as they are occur.\n\n### **Specify which accessibility features you want to monitor**\n\nWhen you instantiate `A11yoopMonitor`, you have the option to specify which accessibility features you want to monitor. These can either be chosen by you or can be omitted and all observable accessibility features will be monitored by default.\n```swift\nimport A11yoopMonitor\n\nfinal class MyClass {\n\n    // In order to only monitor specific accessibility features (eg. voice over and larger text):\n    let specificMonitor = A11yoopMonitor(featureTypes: [.voiceOver, .largerText])\n\n    // In order to monitor all observable accessibility features:\n    let defaultMonitor = A11yoopMonitor()\n}\n```\n\n### **Query accessibility feature statuses**\n\nOnce you have instantiated `A11yoopMonitor`, it is possible to query the current status of an observed accessibility feature at any point. This can be done as follows:\n```swift\nlet monitor = A11yoopMonitor(featureTypes: [.voiceOver, ...])\n\n// In order to query current status of voice over accessibility feature\nlet status = monitor.isFeatureEnabled(.voiceOver)\n```\n\nWhen querying the status of an accessibility feature that is not currently being monitored, the resulting status will be `.notMonitored`.\n```swift\nlet monitor = A11yoopMonitor(featureTypes: [.voiceOver]) // Only monitors voice over\n\nlet status = monitor.isFeatureEnabled(.boldText) // Query an accessibility feature that isn't monitored\n/// - .notMonitored\n```\n\nFinally, if an accessibility feature that you are monitoring is not currently supported on a user's device, the status is returned as `.notSupported`.\n\n### **Integrate with Analytics APIs**\n\nIn order to provide easy integration with third-party analytics SDK APIs, `A11yoopMonitor` provides a way to convert all currently monitored accessibility features into a params dictionary (of type `[String: Any]`), which is compatible with most analytics SDK APIs. This dictionary would contain key-value pairs mapping the feature type description to the current feature status description (eg. `[\"Bold Text\": \"Disabled\"`]).\n\nThis conversion is possible by using the `asAnalyticsParams(prefixedBy:)` adapter, which transforms a sequence of `A11yFeature` into a `[String: Any]` representation.\n\nA sample use-case would be including accessibility feature statuses in a tracking event:\n```swift\nfunc sendEvent() {\n\n    let params = self.monitor.allFeatures.asAnalyticsParams()\n    let eventName = \"A11yoop features\"\n\n    // Firebase\n    Analytics.logEvent(eventName, parameters: params)\n}\n```\n\nIn order to prevent conflicts, it is also possible to pass a prefix, which will be applied to all parameter keys (eg. resulting in \"A11yoop Bold Text\" with a prefix applied rather than \"Bold Text\" without).\n\nAlternatively, it you want to represent monitored accessibility features in a completely different way, there are a number of computed properties available that can be used for convenience. These are as follows:\n```swift\n// `.enabledFeatures` provides only the monitored accessibility features that are currently enabled.\nlet formattedEnabledFeatures =  self.monitor.enabledFeatures.map(\\.type.description).joined(separator: \",\")\n\n// `.disabledFeatures` provides only the monitored accessibility features that are currently disabled.\nlet formattedDisabledFeatures = self.monitor.disabledFeatures.map(\\.type.description).joined(separator: \",\")\n\n// `.unsupportedFeatures` provides only the monitored accessibility features that are unsupported.\nlet formattedUnsupportedFeatures = self.monitor.unsupportedFeatures.map(\\.type.description).joined(separator: \",\")\n```\n\nThis allows you to format them in whichever way you want (eg. as a comma-separated String).\n\n### Extend functionality with custom emitters\n\nIt is possible to write custom emitters in order to react to accessibility feature status changes in whatever way you want.\nFor example, if you wanted to send individual analytics events specific to each accessibility feature (rather than using `asAnalyticsParams(prefixedBy:)`), then the best way to achieve this is to write your own custom emitter.\n\nThis can be done by extending `A11yStatusEmitter` and creating your own static configuration that can then be included in your `A11yoopMonitor(featureTypes:emitters:)` initialisation:\n```swift\n\nextension A11yStatusEmitter {\n\n    static var analyticsEventEmitter: Self {\n        Self { feature in\n            // The feature argument is the updated feature. Do with it whatever you want...\n\n            Analytics.logEvent(\n                \"A11yoop Feature Updated\",\n                parameters: [feature.type.description: feature.status.description])\n        }\n    }\n}\n\nfinal class MyClass {\n\n    // Include the custom emitter in your `A11yoopMonitor` initialisation\n    let monitor = A11yoopMonitor(emitters: [.analyticsEventEmitter, .log())\n}\n```\n\n## Installation\nIt is currently possible to install this library using Swift Package Manager. In order to do so, please add the current repository as a package dependency using Xcode or include the following in your `Package.swift` file:\n\n```swift\nimport PackageDescription\n\nlet package = Package(\n    ...\n    dependencies: [\n        .package(url: \"https://github.com/Jackstone92/A11yoop\", .upToNextMajor(from: \"3.1.0\")),\n    ],\n    ...\n    targets: [\n        .target(name: \"MyTarget\", dependencies: [\"A11yoop\"]),\n    ]\n)\n```\n\nFor further information on how `A11yoopMonitor` might be used in your app, please take a look at the [preview app](https://github.com/Jackstone92/A11yoop/tree/main/Preview). This provides a playground environment where you can toggle accessibility features and track the changes in the app. All changes are monitored using `A11yoopMonitor`.\n\n## Additional Resources\n- [Apple Accessibility](https://developer.apple.com/accessibility/)\n- [WWDC Accessibility \u0026 Inclusion Videos](https://developer.apple.com/videos/accessibility-inclusion)\n- [A11y iOS Guidelines](https://a11y-guidelines.orange.com/en/mobile/ios/)\n\n## Contributions\nAny contributions to *A11yoop* are more than welcome, whether they be feature requests, bug reports or any general questions and feedback! Please take a quick look at the contribution guidelines if you want to contribute.\n\n## License\nCopyright 2021 © Jack Stone\n\n*A11yoop* is made available under the [MIT License](https://github.com/Jackstone92/A11yoop/blob/develop/LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjackstone92%2Fa11yoop","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjackstone92%2Fa11yoop","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjackstone92%2Fa11yoop/lists"}