Skip to content

Commit

Permalink
Updated checks collection APIs used to get built in checks and README…
Browse files Browse the repository at this point in the history
… to reflect those changes and also some additional examples.
  • Loading branch information
j-sid committed May 16, 2018
1 parent 57b4f47 commit 067f831
Show file tree
Hide file tree
Showing 6 changed files with 161 additions and 198 deletions.
75 changes: 34 additions & 41 deletions Classes/GTXChecksCollection.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,77 +18,70 @@

#import "GTXChecking.h"

FOUNDATION_EXTERN NSString *const kGTXCheckNameAccessibilityLabelPresent;
FOUNDATION_EXTERN NSString *const kGTXCheckNameAccessibilityLabelNotPunctuated;
FOUNDATION_EXTERN NSString *const kGTXCheckNameAccessibilityTraitsDontConflict;
FOUNDATION_EXTERN NSString *const kGTXCheckNameMinimumTappableArea;
FOUNDATION_EXTERN NSString *const kGTXCheckNameMinimumContrastRatio;

/**
* An enumeration of various versions of GTXSystems supported by GTX.
*
* Ideally we would like everyone to use one stable version but since several users are using GTX
* and adding new checks can require work on part of those users - new checks for example, may
* expose new accessibility issues in those apps that will need to be fixed to get all tests to
* pass. Versions allow for easy development and deployment of those checks. All the users are on
* "stable" version and all new checks are developed under "latest" version when ready, the
* checks are moved into the "stable" version so that everyone gets it. Users can easily test (and
* debug/fix) their apps with latest checks by switching to the "latest" version.
Enum of all versions supported by GTXiLib.
*/
typedef NS_ENUM(NSUInteger, GTXSystemVersion) {

typedef NS_ENUM(NSUInteger, GTXVersion) {
/**
* The default version of checker uses all the latest *stable* checks.
Placeholder enum for the latest version of GTX.
*/
GTXSystemVersionStable = 0,
GTXVersionLatest,

/**
* The version of the checker that uses *all* the latest checks.
Placeholder enum for the prerelease version of GTX.
*/
GTXSystemVersionLatest,
GTXVersionPreRelease,

/**
* A placeholder for determining maximum count of the versions available.
Enum for Version 0 of GTX.
*/
GTXSystemVersionMax,
GTXVersion_0,
};

/**
* Organizes all GTX checks supported by GTXSystem.
* Organizes all checks provided by GTX, developers can use these as a starting point
* for implementing their own checks. These checks are based on recommendations found in
* "Accessibility Programming Guide for iOS"
@link https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/iPhoneAccessibility/Introduction/Introduction.html
* and on WCAG.
*/
@interface GTXChecksCollection : NSObject

/**
* @return An array of all supported GTXChecks for the given @c version.
*/
+ (NSArray<GTXChecking> *)allChecksForVersion:(GTXVersion)version;

/**
* @return An array of all supported GTXChecks.
*/
+ (NSArray *)allGTXChecks;
+ (NSArray<GTXChecking> *)allGTXChecks;

/**
* @return a check that verifies that accessibility label is present on all accessibility elements.
*/
+ (id<GTXChecking>)checkForAXLabelPresent;

/**
* @return An array of GTXChecks under the given version.
* @return a check that verifies that accessibility labels are not punctuated as recommended by
* "Accessibility Programming Guide for iOS" (see class docs).
*/
+ (NSArray *)checksWithVersion:(GTXSystemVersion)version;
+ (id<GTXChecking>)checkForAXLabelNotPunctuated;

/**
* The GTX check instance that has the specified @c name, or @c nil if no such check exists.
*
* @param name The name of the GTX check.
*
* @return The GTX check instance that has the specified @c name.
* @return a check that verifies that accessibility traits dont conflict with each other as
* recommended by "Accessibility Programming Guide for iOS" (see class docs).
*/
+ (id<GTXChecking>)GTXCheckWithName:(NSString *)name;
+ (id<GTXChecking>)checkForAXTraitDontConflict;

/**
* Registers the provided check and makes it available to all @c GTXSystem objects.
*
* @param check The check to be registered, must conform to @c GTXChecking protocol.
* @return a check that verifies that tappable areas of all buttons are at least 48X48 points.
*/
+ (void)registerCheck:(id<GTXChecking>)check;
+ (id<GTXChecking>)checkForMinimumTappableArea;

/**
* Deregisters a previously registered check.
*
* @param checkName The name of the check to be unregistered.
* @return a check that verifies that contrast of all text based elements is at least 3.0.
*/
+ (void)deRegisterCheck:(NSString *)checkName;
+ (id<GTXChecking>)checkForSufficientContrastRatio;

@end
111 changes: 17 additions & 94 deletions Classes/GTXChecksCollection.m
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,7 @@
#pragma mark - Globals

/**
* The minimum size (width or height) for a given element to be accessible as per iOS Accessibility
* standards. For more info see go/ios-gtx-touch-target-ref.
* The minimum size (width or height) for a given element to be easily accessible.
*/
static const float kMinSizeForAccessibleElements = 48.0;

Expand All @@ -45,104 +44,29 @@
*/
static const float kMinContrastRatioForAccessibleText = 3.0;

/**
* A global array of dictionaries mapping default GTX check names to their instances.
*/
NSArray *gGTXBuiltInChecks;

/**
* A global dictionary mapping custom GTX check names to their instances.
*/
NSMutableDictionary *gGTXCustomChecks;

#pragma mark - Implementations

@implementation GTXChecksCollection

+ (NSArray *)gGTXDefaultChecks {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSMutableArray *mutableBuiltInChecks = [[NSMutableArray alloc] init];
for (NSUInteger i = 0; i < GTXSystemVersionMax; i++) {
[mutableBuiltInChecks addObject:[[NSMutableDictionary alloc] init]];
}
gGTXBuiltInChecks = mutableBuiltInChecks;
});
return gGTXBuiltInChecks;
}

+ (NSMutableDictionary *)gGTXCustomChecks {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
gGTXCustomChecks = [[NSMutableDictionary alloc] init];
});
return gGTXCustomChecks;
}

+ (NSArray *)checksWithVersion:(GTXSystemVersion)version {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
// Register the default checks.
// GTXSystemVersionLatest will have *all* checks.
[self registerDefaultCheck:[self GTXCheckForAXLabelPresent]
forVersion:GTXSystemVersionLatest];
[self registerDefaultCheck:[self GTXCheckForAXLabelNotPunctuated]
forVersion:GTXSystemVersionLatest];
[self registerDefaultCheck:[self GTXCheckForAXTraitDontConflict]
forVersion:GTXSystemVersionLatest];
[self registerDefaultCheck:[self GTXCheckForMinimumTappableArea]
forVersion:GTXSystemVersionLatest];
[self registerDefaultCheck:[self GTXCheckForContrastRatio]
forVersion:GTXSystemVersionLatest];

// GTXSystemVersionStable currently has the following checks.
[self registerDefaultCheck:[self GTXCheckForAXLabelPresent]
forVersion:GTXSystemVersionStable];
[self registerDefaultCheck:[self GTXCheckForAXLabelNotPunctuated]
forVersion:GTXSystemVersionStable];
[self registerDefaultCheck:[self GTXCheckForAXTraitDontConflict]
forVersion:GTXSystemVersionStable];
});
NSArray *defaultChecks = [[self gGTXDefaultChecks][version] allValues];
NSArray *customChecks = [[self gGTXCustomChecks] allValues];
return [defaultChecks arrayByAddingObjectsFromArray:customChecks];
}

+ (NSArray *)allGTXChecks {
return [self checksWithVersion:GTXSystemVersionLatest];
}

+ (id<GTXChecking>)GTXCheckWithName:(NSString *)name {
for (id<GTXChecking> check in [self allGTXChecks]) {
if ([name isEqualToString:[check name]]) {
return check;
}
+ (NSArray<GTXChecking> *)allChecksForVersion:(GTXVersion)version {
switch (version) {
case GTXVersionLatest: return [self allGTXChecks];
case GTXVersionPreRelease: return [self allGTXChecks];
case GTXVersion_0: return [self allGTXChecks];
}
return nil;
}

+ (void)registerDefaultCheck:(id<GTXChecking>)check forVersion:(GTXSystemVersion)version {
NSMutableDictionary *defaultChecks = [self gGTXDefaultChecks][version];
NSAssert(!defaultChecks[[check name]],
@"GtxCheck with name %@ already registered.", [check name]);
defaultChecks[[check name]] = check;
}

+ (void)registerCheck:(id<GTXChecking>)check {
NSAssert(![self gGTXCustomChecks][[check name]],
@"GtxCheck with name %@ already registered.", [check name]);
[self gGTXCustomChecks][[check name]] = check;
}

+ (void)deRegisterCheck:(NSString *)checkName {
NSAssert([self gGTXCustomChecks][checkName],
@"GtxCheck with name %@ was not registered.", checkName);
[[self gGTXCustomChecks] removeObjectForKey:checkName];
+ (NSArray<id<GTXChecking>> *)allGTXChecks {
return @[[self checkForAXLabelPresent],
[self checkForAXLabelNotPunctuated],
[self checkForAXTraitDontConflict],
[self checkForMinimumTappableArea],
[self checkForSufficientContrastRatio]];
}

#pragma mark - GTXChecks

+ (id<GTXChecking>)GTXCheckForAXLabelPresent {
+ (id<GTXChecking>)checkForAXLabelPresent {
id<GTXChecking> check = [GTXCheckBlock GTXCheckWithName:kGTXCheckNameAccessibilityLabelPresent
block:^BOOL(id element, GTXErrorRefType errorOrNil) {
if ([self gtx_isTextDisplayingElement:element]) {
Expand Down Expand Up @@ -174,7 +98,7 @@ + (void)deRegisterCheck:(NSString *)checkName {
return check;
}

+ (id<GTXChecking>)GTXCheckForAXLabelNotPunctuated {
+ (id<GTXChecking>)checkForAXLabelNotPunctuated {
id<GTXChecking> check =
[GTXCheckBlock GTXCheckWithName:kGTXCheckNameAccessibilityLabelNotPunctuated
block:^BOOL(id element, GTXErrorRefType errorOrNil) {
Expand Down Expand Up @@ -217,7 +141,7 @@ + (void)deRegisterCheck:(NSString *)checkName {
return check;
}

+ (id<GTXChecking>)GTXCheckForAXTraitDontConflict {
+ (id<GTXChecking>)checkForAXTraitDontConflict {
id<GTXChecking> check =
[GTXCheckBlock GTXCheckWithName:kGTXCheckNameAccessibilityTraitsDontConflict
block:^BOOL(id element, GTXErrorRefType errorOrNil) {
Expand Down Expand Up @@ -265,7 +189,7 @@ + (void)deRegisterCheck:(NSString *)checkName {
return check;
}

+ (id<GTXChecking>)GTXCheckForMinimumTappableArea {
+ (id<GTXChecking>)checkForMinimumTappableArea {
id<GTXChecking> check =
[GTXCheckBlock GTXCheckWithName:kGTXCheckNameMinimumTappableArea
block:^BOOL(id element, GTXErrorRefType errorOrNil) {
Expand Down Expand Up @@ -311,7 +235,7 @@ + (void)deRegisterCheck:(NSString *)checkName {
return check;
}

+ (id<GTXChecking>)GTXCheckForContrastRatio {
+ (id<GTXChecking>)checkForSufficientContrastRatio {
id<GTXChecking> check =
[GTXCheckBlock GTXCheckWithName:kGTXCheckNameMinimumContrastRatio
block:^BOOL(id element, GTXErrorRefType errorOrNil) {
Expand All @@ -337,7 +261,6 @@ + (void)deRegisterCheck:(NSString *)checkName {
return check;
}


#pragma mark - Private

/**
Expand Down
2 changes: 1 addition & 1 deletion Classes/GTXiLibCore.m
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ + (BOOL)_checkElement:(id)element {
}

/**
Executes the currently installed checks on the all elements of the accessibility tree under the
Executes the currently installed checks on all the elements of the accessibility tree under the
given root elements. In case of failures, the failure handler is invoked.
@param rootElements An array of root elements.
Expand Down
36 changes: 18 additions & 18 deletions FrameworkFiles/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,23 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSPrincipalClass</key>
<string></string>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>
Loading

0 comments on commit 067f831

Please sign in to comment.