4

Before using the "New Build System", we had a build phase script like this:

infoplist="$BUILT_PRODUCTS_DIR/$INFOPLIST_PATH"
builddate=`date`
/usr/libexec/PlistBuddy -c "Set :BuildDateString $builddate" "${infoplist}"

The point of this way to write to the plist at runtime without dirtying the project and having to stash the changes. This still works well and perfectly when using the "Legacy Build System".

On the "New Build System", this script does not work. The directory variables and writing to the plist will works but the changes are somehow overwritten.

Is there a way to write to a built plist via the build phase script? If not, is there a way to achieve the goal of writing information only when the application runs without dirtying the local repo.

FireDragonMule
  • 1,347
  • 2
  • 16
  • 27
  • Is it possible for you to git ignore the file? – jlew Oct 02 '18 at 17:32
  • We are unable to ignore the info.plist file because it's an essential part of the code. In theory, we can write to a file within the project (that is gitignored) then load that plist into the info.plist at runtime. – FireDragonMule Oct 02 '18 at 17:44
  • Makes sense. Probably silly question, but I assume your Run Script phase that is doing the substitution is at the end of the phase list? – jlew Oct 02 '18 at 17:51
  • Yes. We have 3 phase scripts that happen at the end of the phase list. The first 2 modify the info.plist file but the 3rd script is the Carthage script. I don't know if that makes a difference. There are no silly questions :) – FireDragonMule Oct 02 '18 at 18:08

2 Answers2

1

enter image description here

It looks like that sometimes, under the "New Build System", the Process Info.plist step is after all the Run custom scripts step.

So I use script to generate another custom.plist at the bundle

#!/usr/bin/env ruby
require 'cfpropertylist'
require 'pathname'

build_info = {
    'Time' => Time.now.to_s,
    'CommitHash' => `git log --pretty="%h" | head -n1`.rstrip
}

plist = CFPropertyList::List.new
plist.value = CFPropertyList.guess(build_info)
plist_path = Pathname.new(ENV['BUILT_PRODUCTS_DIR']) /  ENV['CONTENTS_FOLDER_PATH'] / 'build_info.plist'
plist.save(plist_path, CFPropertyList::List::FORMAT_XML)
rpstw
  • 1,582
  • 14
  • 16
1

As @rpstw points out, any custom build steps will run before the New Build System's Process .../Info.plist step.

  • To run a shell script after Xcode finishes building, you can add it to your scheme(s) as a build post-action:

Product > Scheme > Edit Scheme... > Build > Post-actions

enter image description here

  • If you're going to reference any build system environment variables (e.g. BUILT_PRODUCTS_DIR or INFOPLIST_PATH), make sure you change the Provide build settings from selection.

  • Add your shell script, but remember that if you edit any file in the app bundle (i.e. Info.plist), you'll need to re-sign the app. Add this to your post build step:

export CODESIGN_ALLOCATE=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/codesign_allocate
/usr/bin/codesign --force --sign - --entitlements "${TARGET_TEMP_DIR}/${FULL_PRODUCT_NAME}.xcent" --timestamp=none "${CODESIGNING_FOLDER_PATH}"
sam-w
  • 7,478
  • 1
  • 47
  • 77
  • The resign app code doesn't work. I need to somehow get the EXPANDED_CODESIGN_IDENTITY for the `--sign` parameter. – Winston Du Jan 05 '21 at 10:51
  • @WinstonDu I ran into the same limitation -- seems Xcode really goes out of its way to prevent you from accessing that an other codesigning ENV vars. Did you find a way around this? – Alexander Wallace Matchneer Apr 05 '23 at 01:10
  • @WinstonDu i found a way around this! For some reason XCode strips the EXPANDED_CODESIGN_IDENTITY env var (and its sibling vars) from the context when it runs your post-build actions, but these variables ARE available during Build Phase scripts. I was able to get access to EXPANDED_CODESIGN_IDENTITY by writing it to a file in my build directory from a Build Phase script, and then reading that file from within a post-build action. – Alexander Wallace Matchneer Apr 05 '23 at 18:37