How to set availability identifier in UIAlertController?

This is how I simply create a UIAlertController and present it on the screen:

 private class func showAlertWithTitle(title: String, message: String) { let alert = UIAlertController(title: title, message: message, preferredStyle: .Alert) //alert.accessibilityLabel = "my string here" //doesnt work let action = UIAlertAction(title: "OK", style: .Default) { action in alert.dismissViewControllerAnimated(true, completion: nil) } alert.addAction(action) UIStoryboard.topViewController()?.presentViewController(alert, animated: true, completion: nil) } 

and this is how I access it under UITests :

 emailAlert = app.alerts["First Name"] //for title "First Name" 

but I would like to set my own identifier there and access this firstName as follows:

 emailAlert = app.alerts["firstName"] 

Is it possible?

+6
source share
2 answers

The only way I decided to do this is to use Apple's private APIs. You call the valueForKey object with this super secret key: "__representer" to get what is called _UIAlertControllerActionView .

  let alertView = UIAlertController(title: "This is Alert!", message: "This is a message!", preferredStyle: .Alert) let okAction = UIAlertAction(title: "OK", style: .Default, handler: nil) alertView.addAction(okAction) self.presentViewController(alertView, animated: true, completion: { let alertButton = action.valueForKey("__representer") let view = alertButton as? UIView view?.accessibilityIdentifier = "okAction_AID" }) 

This must be done in the completion handler because _UIAlertControllerActionView will not exist until the view submission. On the side of the note in my project, I used these following extensions to make things easier / easier to read:

 extension UIAlertController { func applyAccessibilityIdentifiers() { for action in actions { let label = action.valueForKey("__representer") let view = label as? UIView view?.accessibilityIdentifier = action.getAcAccessibilityIdentifier() } } } extension UIAlertAction { private struct AssociatedKeys { static var AccessabilityIdentifier = "nsh_AccesabilityIdentifier" } func setAccessibilityIdentifier(accessabilityIdentifier: String) { objc_setAssociatedObject(self, &AssociatedKeys.AccessabilityIdentifier, accessabilityIdentifier, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN) } func getAcAccessibilityIdentifier() -> String? { return objc_getAssociatedObject(self, &AssociatedKeys.AccessabilityIdentifier) as? String } } 

Thus, the above code will be rewritten:

  let alertView = UIAlertController(title: NSLocalizedString("NMN_LOGINPAGECONTROLLER_ERROR_TITLE", comment: ""), message: message as String, preferredStyle:.Alert) let okAction = UIAlertAction(title: NSLocalizedString("NMN_OK", comment: ""), style: .Default, handler: nil) okAction.setAccessibilityIdentifier(InvalidLoginAlertView_AID) alertView.addAction(okAction) self.presentViewController(alertView, animated: true, completion: { alertView.applyAccessibilityIdentifiers() }) 

My first attempt was to attempt to navigate the view hierarchy, but this became difficult because the UIAlertControllerActionView not part of the public API. Anyway, I would probably try an ifdef from valueForKey("__representer") for the collectors presented for the app store, or Apple could give you a flogging.

+3
source

From Apple docs ...

https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/UIKitUICatalog/UIAlertView.html

Making Alerts Accessible

Alert views are available by default. Alert availability refers to the alert title, warning message, and button names. If VoiceOver is activated, it says the word “warning” when a warning is displayed, and then speaks its heading, followed by its message, if one is set. When the user clicks a button, VoiceOver says its name and the word "button." When a user deletes a text box, VoiceOver says its meaning and “text box” or “protected text box”.

-one
source

All Articles