【问题标题】:How can I programmatically add a run script build phase to an Xcode project?如何以编程方式将运行脚本构建阶段添加到 Xcode 项目?
【发布时间】:2013-10-18 14:05:33
【问题描述】:

我想知道是否可以从我的 Mac 实用程序应用程序中将运行脚本构建阶段添加到另一个 Xcode 项目。我可以看到添加运行脚本(执行 diff)时 Xcode 项目中发生了什么,但我不知道如何安全地在代码中添加等效项。

我应该手动解析它吗?是否有可用的文档或库?如果我能确保安全正确地执行此操作,这将是一个有用的功能。我不想弄乱人们的 Xcode 项目!

【问题讨论】:

    标签: ios xcode macos build-process run-script


    【解决方案1】:

    对于任何寻找简单方法的人来说,有一个很棒的 python 库可以让你修改 .pbxproj 文件中的所有类型的东西。你可以在这里查看:https://github.com/kronenthaler/mod-pbxproj

    现在要添加运行脚本构建阶段,您可以编写一个简单的 python 脚本,例如:

    from pbxproj import XcodeProject
    import sys
    
    project = XcodeProject.load('path/to/my-project.xcodeproj/project.pbxproj')
    project.add_run_script('bash my_run_script.sh')
    project.save()
    

    现在只需运行 python 脚本就可以了。

    【讨论】:

    • 我运行脚本后完全搞砸了我的项目
    【解决方案2】:

    可能最简单的解决方案是向另一个项目添加一个运行脚本阶段,该阶段定义了一个执行脚本的命令行,该脚本作为特定文件驻留在某个已知位置。

    然后第一个项目可能有一个运行脚本阶段,或者执行一个创建修改这个脚本文件的程序。当另一个项目启动时,它会启动运行脚本阶段并 ​​- 瞧 - 执行已定义的任何内容。

    【讨论】:

    • 感谢您的回答!仍然试图把我的头绕在它周围:)。我的 Mac 应用程序在商店中,我想要做的是在我的应用程序中有一个按钮,它将运行脚本阶段添加到用户在文件系统上指定的任何项目中。它需要在运行时。终端仍然是最佳选择吗?
    • 嗯,这可能会变得复杂(摆弄 Xcode 项目的 XML)。也许,一个初步的解决方案是您的应用程序创建一个脚本文件,并告诉用户如何在运行脚本阶段执行该脚本文件。此运行脚本阶段需要用户在其项目中添加。
    • 很公平。这个问题的目的是看看它是否可能和可行。我不想冒着损坏人们的项目文件的风险,因此寻找解决方法可能会更好。谢谢!
    • 欢迎您,当我知道实用程序应用程序会影响我的 Xcode 项目时,我也会感到不满... ;)
    【解决方案3】:

    我的解决方案需要一点红宝石知识。有一个名为 xcodeproj 的库,它包含在 Cocoapods 中

    sudo gem install cocoapods
    

    或者,

    gem install xcodeproj
    

    仅安装库。

    创建一个 ruby​​ 文件,将运行脚本阶段添加到您的目标中:

    require 'xcodeproj'
    
    project = Xcodeproj::Project.open "./TargetTest.xcodeproj"
    
    for target in project.targets 
        puts "Target -> " + target.name
        phase = target.shell_script_build_phases().find {|item| item.name == "My run phase"}
        if (phase.nil?)
            puts "Creating script 'My run phase'"
            phase = target.new_shell_script_build_phase("My run phase")
            phase.shell_script = "echo Hello script"
        else
            puts "'My run phase' already exist"
            phase.shell_script = "echo modified"
        end
    end
    
    project.save() 
    

    你可以运行它:

    ruby add_run_phase_script.rb
    

    编辑:将find中的“=”替换为“==”,否则第一个脚本会被替换,我们需要一个追加

    【讨论】:

      【解决方案4】:

      我实际上决定添加一个运行脚本。事实证明这很容易。首先,在 Xcode 中,将运行脚本添加到您的项目中,并通过 diff 工具观察更改。 'buildPhases' 数组有一个附加项(在一些任意命名的字典中嵌套得很深),然后添加到 'buildPhases' 数组中的键也被添加到 'objects' 字典中表示实际运行脚本构建阶段格式。

      因此,要以编程方式复制此内容,请将 pbxproj 文件的内容放入 NSDictionary,然后遍历字典以查找 buildPhases 数组。然后,添加您的密钥。最后,将一个对象添加到 'objects' 数组中,其中包含一个键和一个镜像 Xcode 中格式的字典。

      将文件保存回磁盘的相同位置,瞧!您已经以编程方式添加了运行脚本构建阶段。

      【讨论】:

      • 您何时/使用什么运行此代码?它是一个快速脚本吗?你介意在这里分享还是以gist 或其他方式分享?
      猜你喜欢
      • 2013-12-03
      • 2011-10-26
      • 2014-11-01
      • 2010-11-23
      • 1970-01-01
      • 1970-01-01
      • 2021-05-15
      • 2014-01-25
      • 2020-09-04
      相关资源
      最近更新 更多