如何将accessibilityIdentifier设置为UIAlertController?

Bar*_*zyk 18 accessibility ios swift

这就是我UIAlertController在屏幕上创建和呈现它的方法:

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)
}
Run Code Online (Sandbox Code Playgroud)

这就是我在UITests下访问它的方式:

emailAlert = app.alerts["First Name"] //for title "First Name"
Run Code Online (Sandbox Code Playgroud)

但我想设置自定义标识符,并通过firstName这样访问:

emailAlert = app.alerts["firstName"]
Run Code Online (Sandbox Code Playgroud)

可能吗?

Jan*_*Jan 8

这是一个旧线程,但是有人可以使用它。

我能够这样设置可访问性标识符:

let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
alert.view.accessibilityIdentifier = "custom_alert"
alert.view.accessibilityValue = "\(title)-\(message)"

alert.addAction(
    UIAlertAction(
        title: "ALERT_BUTTON_OK".localized,
        style: .default,
        handler: handler
    )
)

present(alert, animated: true)
Run Code Online (Sandbox Code Playgroud)

这样,我可以通过可访问性标识符访问警报,并在可访问性值中检查其内容。

当然,它并不是完美的,但它可以工作-至少对于我使用Appium进行的测试而言。

  • 您写道您检查了其内容,但是如何检查按钮的文本呢?它没有辅助功能 ID。 (3认同)

Ant*_*lds 5

我发现做到这一点的唯一方法是使用Apple的私有API。你叫valueForKey的上UIAlertAction的对象与这个超级秘密密钥:"__representer"得到什么叫_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"
    })
Run Code Online (Sandbox Code Playgroud)

这必须在完成处理程序中完成,因为_UIAlertControllerActionView在呈现视图之前,该功能将不存在。在我的项目的一个旁注中,我使用了以下这些扩展来使事情更容易/更具可读性:

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
    }
}
Run Code Online (Sandbox Code Playgroud)

因此,上面的代码将被重写:

    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()
    })
Run Code Online (Sandbox Code Playgroud)

我的第一次尝试是尝试浏览视图层次结构,但是由于UIAlertControllerActionView它不是公共API的一部分,因此变得很困难。无论如何,我可能会尝试ifdef valueForKey("__representer")为应用商店提交的for版本,否则Apple可能会给您一个麻烦。

  • 这奏效了。我刚刚向 Apple 打开了一个错误,希望如果我们中的许多人抱怨,他们会做些什么。 (2认同)