返回

Xcode编译Flutter报错Cycle inside Runner解决实战

IOS

Xcode 编译 Flutter 项目报 “Cycle inside Runner” 错误解决实战

最近把 Xcode 升级到 15,iOS 版本也更到了 17。 结果,兴冲冲地准备在 iPhone 15 Pro Max 上跑一下 Flutter 项目,直接给我报了个错:Error (Xcode): Cycle inside Runner; building could produce unreliable results. 后面还跟了一堆 Cycle details,看得人头大。

这个错误信息,简单说就是 Xcode 在编译过程中检测到了循环依赖。 循环依赖,就像 A 依赖 B,B 又依赖 A,最后形成一个死循环,这会让构建过程出问题,结果也不可靠。

问题原因分析

出现 "Cycle inside Runner" 这类循环依赖错误,通常是 Xcode 项目配置中的构建阶段(Build Phases)出了岔子。 看看 Xcode 报错给出的 Cycle details,问题可能出在以下几个方面:

  1. [CP] Embed Pods Frameworks : 这个阶段负责嵌入 Pods 管理的 Framework。
  2. Thin Binary : 这个阶段通常用于减小二进制文件大小。
  3. Info.plist 处理 : 处理应用的 Info.plist 文件。
  4. [CP] Copy Pods Resources : 复制 Pods 的资源文件。
  5. OneSignalNotificationServiceExtension.appex : 复制或者处理了 OneSignal 的这个拓展。从这里可以猜测项目中使用了 OneSignal 的推送服务。

错误信息明确指出,构建过程产生了循环。 好吧,看来是构建阶段的顺序或者依赖关系搞错了。

解决方案

遇到循环依赖问题,不要慌。 下面我整理了几种解决思路,大家可以根据实际情况,逐一尝试:

方案一:调整 Build Phases 顺序

Xcode 的 Build Phases 是有执行顺序的。 如果顺序不对,就可能产生循环依赖。

  1. 操作步骤:

    • 打开 Xcode,选中你的项目。

    • 选择 Target -> Runner

    • 点击 Build Phases 选项卡。

    • 仔细检查以下几个阶段的顺序:

      • Target Dependencies
      • Copy Bundle Resources
      • Compile Sources
      • Link Binary With Libraries
      • [CP] Embed Pods Frameworks
      • [CP] Copy Pods Resources
      • 其他自定义的 Script Phase
    • [CP] Embed Pods Frameworks 拖到 Link Binary With Libraries 之后 ,但是要在[CP] Copy Pods Resources 之前

    • 尝试重新构建项目。

  2. 原理: 调整 Build Phases 的顺序,其实就是调整了各个构建任务之间的依赖关系。正确的顺序能保证各个阶段的输入输出正确衔接,避免循环。

方案二:检查脚本阶段 (Script Phases)

有些循环依赖,可能是由于自定义的脚本阶段(Script Phases)引起的。

  1. 操作步骤:

    • Build Phases 中,找到所有自定义的脚本阶段 (Run Script)。
    • 仔细检查每个脚本的 Input FilesOutput Files
    • 确保脚本的输出文件,没有同时作为另一个脚本的输入文件,或者和系统自带的构建阶段冲突。
    • 如果有使用到${TARGET_BUILD_DIR}等变量,查看是否可能造成的冲突。
    • 检查 OneSignalNotificationServiceExtension.appex是否在其他 Run Script 中被错误引用或者处理。
    • 重新构建。
  2. 原理: 自定义的脚本,如果没有正确设置输入输出,可能会干扰 Xcode 原本的构建流程。

方案三:检查 Framework 搜索路径

有时候,Framework 搜索路径设置不当,也可能导致问题。

  1. 操作步骤:

    • Build Settings 中,搜索 Framework Search Paths
    • 检查路径设置是否正确,有没有多余或错误的路径。
    • 删除可能引起冲突的路径。
    • 重新构建。
  2. 原理: Xcode 会根据这个设置来查找项目依赖的 Framework。路径配置混乱,会让 Xcode 找不到文件,或找到错误版本的文件,间接导致构建错误。

方案四:清理并重新安装 Pods

如果上面的方法都不奏效,可能是 Pods 本身的问题。

  1. 操作步骤:

    • 在项目根目录下的 ios 文件夹中,打开终端。
    • 执行 pod deintegrate,移除现有的 Pods 集成。
    • 执行 pod clean,清理 Pods 缓存。
    • 执行 rm -rf Podfile.lock,删除 Podfile.lock 文件.
    • 执行 pod install,重新安装 Pods。
    • 在 Xcode 里, Product -> Clean Build Folder.
    • 重新构建。
  2. 原理: Pods 相关文件出错,会导致各种奇怪的问题。 重新安装 Pods 能确保所有依赖项都是干净的。

方案五: OneSignal 专项检查

鉴于错误信息中提到了 OneSignalNotificationServiceExtension.appex,我们可以重点排查一下。

  1. 操作步骤:

    • 在 Xcode 的Build Phases中,找到Embed App Extensions.
    • 确保OneSignalNotificationServiceExtension只被包含了一次,并且"Copy only when installing" 未被勾选
    • Build Settings中,查找Other Linker Flags
      • 确保没有重复或冲突的链接标志与 OneSignal 相关.
    • Build Phases 找到和 OneSignal 相关的 Run Script
      • 重点关注它的 Input FilesOutput Files是否有问题。
      • 输出部分是否与其他构建过程的输出部分有重合
    • 重新构建。
  2. 原理: 针对性排查,找出问题。

进阶使用技巧:

  1. 使用 Xcode 的依赖分析工具

    Xcode 提供了一个依赖分析工具,能帮我们更直观地查看项目中的依赖关系:

    • 打开项目后,选择Product->Perform Action->Build With Timing Summary.
    • 在构建报告中,寻找耗时长的部分和任何关于循环依赖的警告。
  2. 分析构建日志 (Build Log)
    详细的构建日志,会提供构建过程的完整细节:

    • 展开报错信息, 完整查看详细错误报告。
    • 检查各个阶段的输入输出文件, 寻找异常之处。

安全建议:

检查第三方库: 使用第三方库时,要注意它的版本和兼容性。如果有更新,及时更新到最新版本。

这次遇到的 "Cycle inside Runner" 问题,希望这篇整理能给你一些解决思路。