Interface Builder & Storyboard:将自动布局错误视为构建错误

Interface Builder & Storyboard: treat Autolayout errors as build errors

有没有办法将 Interface Builder 冲突约束 错误传播到构建过程的其余部分并将它们视为构建错误?

当然,LLVM 设置 Treat Warnings as Errors 对 Storyboard 错误没有影响。

我的观点显然不能满足所有限制条件:


在界面生成器中:
这些错误如下所示:

Conflicting Constraints
Can't satisfy all constraints.


在 Xcode 项目中:
错误被降级为警告,以便应用程序编译、构建、link 和 运行.

如果我在 Interface Builder 的 Storyboard 中出现 AutoLayout 错误,如何阻止应用程序构建?

如果不是完整的解决方案,这里有一些调查途径。

首先,请注意自动布局有两个主要来源 errors/warnings — unsatisfiable constraints and ambiguous constraints — 它们以不同的方式处理。

另请注意,Auto Layout 的全部功能只能在 运行 时使用 — Xcode 的工具提供了一些关于情节提要中的约束情况的洞察力,但那是与在应用程序的 "real" view/window 运行 中评估这些约束时发生的情况有点不同。 ("Real" 在引号中,因为 iOS 模拟器非常适合布局调试......它不必是 真实的 设备。)

使用 ibtool

终止构建

当 Xcode "compiles" 故事板作为构建项目的一部分时,它会将此功能委托给命令行程序 ibtool。虽然似乎没有办法改变 Xcode 解释 ibtool 输出的方式(即,将 ibtool 输出的错误视为停止构建的原因),但您可以自己调用 ibtool 额外时间。

  1. 添加自定义构建阶段或构建规则
  2. 在 phase/rule 的 shell 脚本中,调用 ibtool 来处理您的故事板。传递 --warning--error 以获得警告或错误输出。 (查看正常构建的构建日志,and/or man ibtool 以查看您可能需要的其他标志。)
  3. 如果您检测到指示问题的输出(即非空输出,如果您将自己设置为仅接收错误),exit 您的 shell 脚本具有非零状态代码, Xcode 将停止构建。

自动化约束调试Post-构建

如前所述,真正的约束测试是在真实的布局情况下,当您的应用 运行s.因此,捕获约束问题的更好时机可能不是作为 build 自动化的一部分,而是在 testing 自动化中。

  • 对于不明确的布局,您可以在 运行 时使用 UIView 上的 hasAmbiguousLayout 属性 轻松检测到事物。如果你有一个布尔值 属性 你可以在 运行 时间查询,你就有了一些东西的种子可以放入自动化测试中。只需编写一些 运行 通过应用程序 UI 的单元测试,测试 hasAmbiguousLayout 以获得重要的视图,并在 属性 为真时失败。然后你的持续集成系统可以告诉你每当有人提交仍然构建,但打破了 post-commit 单元测试。

  • 对于无法满足的布局,可能会有点棘手。 Auto Layout 系统在检测到此类问题时会自动登录到控制台,因此您可以为 CI 系统编写脚本,在 运行 日志中查找 "Unable to simultaneously satisfy constraints"单元测试。或者...我不确定在通过 CI 执行测试时是否可以 运行 激活特定的 Xcode 调试器断点,但如果可以,您可以在上设置一个符号断点UIViewAlertForUnsatisfiableConstraints.

⚠️ 免责声明: 下面的解决方案不再适用于 Xcode 9.2.


正在使用 ibtool

终止构建

按照 :

的建议提出 运行 脚本阶段
for FILE in `find ${SRCROOT} -name *.storyboard`
do
    IBERROR="`ibtool --errors --warnings --notices --output-format human-readable-text --enable-auto-layout --update-frames $FILE`"
    if [ -n "$IBERROR" ]; then
        echo "${IBERROR}"
        exit 1
    fi
done
exit 0

将上述脚本添加到 Build Phases 部分。