skip to Main Content

I have a project where I’m using CocoaPods. As part of the CocoaPods setup, the Xcode "Build Phase" gets two Cocoapods scripts:

  • [CP] Embed Pods Frameworks
  • [CP] Copy Pods Resources

In the same project I use a script that is required to run after [CP] Embed Pods Frameworks. I can setup it up manually and it works having

  • [CP] Embed Pods Frameworks
  • My Script
  • [CP] Copy Pods Resources

Problem is that after running pod deintegrate to reinstall the pods the order of script is reset to:

  • My Script
  • [CP] Embed Pods Frameworks
  • [CP] Copy Pods Resources

As the team work on this project is big. It can happen that the script order is reset by mistake causing the CI to break.

Is there a way in the Podfile to control the order of the scripts?

2

Answers


  1. Chosen as BEST ANSWER

    I haven't found a way to decide a specific order. But it's possible to use a Cocoapods feature that allows to specify User Scripts in the Podfile.

    So if you use the script_phase in your Podfile like

    target 'App' do
        all_your_pods
    
        script_phase :name => 'My Script', :script => 'echo "script"'
    end
    

    you get the My Script to be inserted after all the other [CP] scripts as:

    • [CP] Embed Pods Frameworks
    • [CP] Copy Pods Resources
    • [CP-User] My Script

    This solves my issue even if doesn't allow you to declare a specific ordering.


  2. There’s a ruby gem used by CocoaPods: https://github.com/CocoaPods/Xcodeproj to work with Xcode project file. So with its help it’s possible to manipulate the order of build phases in your project. I did a quick testing and the following script shold do what you want:

    #fix_build_phases.rb
    require 'xcodeproj'
    
    def main
      begin
        proj = Xcodeproj::Project.open("YourProject.xcodeproj")
        target = proj.native_targets.select { |target| target.name == "YourTarget" }.first
        phase = target.build_phases.select { |phase| phase.display_name == "MyScript" }.first
        
        idx = -1
        target.build_phases.each_with_index do |phase, index| 
            if phase.display_name == "[CP] Embed Pods Frameworks"
                idx = index
            end
        end
        if idx > 0
            target.build_phases.move(phase, idx)
        end
        proj.save
      end
    end
    
    main
    

    If you want to ensure the script is always at the right position after the pods are installed you will need to add it to your podfile:

    post_install do |installer|
        system("(sleep 1 && ruby fix_build_phases.rb)&")
    end
    

    There’s some delay because it didn’t work immediately on post_install, probably due to Cocoapods updating the project by itself at that moment.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search