Automatically add build phases in Cordova based Xcode project

Viewed 2381

I have a Cordova based iOS project in which I need to add a custom script to the build phases. I have one set up and it works fine, however I need to be able to add the build phase automatically somehow, as I need the project to be able to install and build automatically on a CI server, without having to manually add the phase in Xcode.

To clarify, when cordova platform add ios is run the project is created without build phases, I need to add a build phase in programmatically, before (or during) cordova build ios.

I can add custom build settings in the .xcconfig file, is there somewhere I can define build phases? I see that the build phase is present in my .pbxproj file, however this is automatically generated and contains some random IDs so I am not sure its something I can just parse and insert arbitrary stuff into?

2 Answers

Based on an accepted answer i created the code maybe somebody can use it :)

Install xcode npm with:

npm i xcode

Create extend_build_phase.js in root:

var xcode = require('xcode');
var fs = require('fs');
var path = require('path');

const xcodeProjPath = fromDir('platforms/ios', '.xcodeproj', false);
const projectPath = xcodeProjPath + '/project.pbxproj';
const myProj = xcode.project(projectPath);
// Here you can add your own shellScript
var options = { shellPath: '/bin/sh', shellScript: 'echo "hello world!"' };

myProj.parse(function(err) {
  myProj.addBuildPhase([], 'PBXShellScriptBuildPhase', 'Run a script',myProj.getFirstTarget().uuid, options);
  fs.writeFileSync(projectPath, myProj.writeSync());
})

function fromDir(startPath, filter, rec, multiple) {
  if (!fs.existsSync(startPath)) {
    console.log("no dir ", startPath);
    return;
  }
  const files = fs.readdirSync(startPath);
  var resultFiles = [];
  for (var i = 0; i < files.length; i++) {
    var filename = path.join(startPath, files[i]);
    var stat = fs.lstatSync(filename);
    if (stat.isDirectory() && rec) {
      fromDir(filename, filter); //recurse
    }

    if (filename.indexOf(filter) >= 0) {
      if (multiple) {
        resultFiles.push(filename);
      } else {
        return filename;
      }
    }
  }
  if (multiple) {
    return resultFiles;
  }
}

Extend config.xml with the following code:

<platform name="ios">
    ...
    <hook src="extend_build_phase.js" type="after_platform_add" />
    ...
</platform>

I'm created an Ionic project so to make it work I use the following commands:

ionic cordova platform rm ios
ionic cordova platform add ios
ionic cordova build ios
Related