0

I have an Xcode project that builds into a few different apps (whitelabels) using different configurations. For a new payment method I need each app to have a unique CFBundleURLScheme.

I wrote the following "Run Script" that is before Compile Sources in "Build Phases".

INFO_PLIST="${PROJECT_DIR}/${INFOPLIST_FILE}"
plutil -insert CFBundleURLTypes.0.CFBundleURLSchemes.0 -string "swish${PRODUCT_BUNDLE_IDENTIFIER//.}" $INFO_PLIST

This adds the value swishourbundleidentifier. (So, swish + our.bundle.identifier, but without the dots)

This currently changes the actual Info.plist. What I want is that it changes the Info.plist that's in the folder where the app is built to, so that it is overridden each time (so there are no double values) and that the added value doesn't show up in git.

How would I go about that? I guess it's simply changing "${PROJECT_DIR}/${INFOPLIST_FILE}", but to what?

If any more information is needed, please let me know.

EDIT: Actually, if it is possible, a better solution would be to add something like swish${PRODUCT_BUNDLE_IDENTIFIER//.} in the Info.plist's URL Schemes. So that it's compiled to that on build time, but no double values. I tried this but it doesn't seem to work like that unfortunately.

Jeroen
  • 2,011
  • 2
  • 26
  • 50

3 Answers3

1

You could access to build directory with

$CONFIGURATION_BUILD_DIR/$CONTENTS_FOLDER_PATH

Reference: https://help.apple.com/xcode/mac/10.2/#/itcaec37c2a6

carmine
  • 1,597
  • 2
  • 24
  • 33
  • 1
    Absolutely not. This is the folder that contains (among all other files) your info.plist. You can edit, move, rename, remove them as you like. Of course you must garantee the app works after your changes. – carmine May 15 '19 at 08:06
  • Okay! But this is not the same as the Info.plist in the project files, right? (So this is for example a location with pre-build files?) – Jeroen May 15 '19 at 08:10
  • 1
    This is the folder where the build is generated to. Depends on your Build Phases script order when your script is executed. Try to Run script after the Compile source – carmine May 15 '19 at 08:32
  • 1
    My tip: I have several info.plist files in my project, for example info_dev.plist, info_prod.plist and so on. I have a run script after the Compile source phase that rename the file into info.plist and removes the other. – carmine May 15 '19 at 08:34
  • 1
    Thanks! I didn't implement it yet but this sounds to be the correct solution. Thanks a lot! About the multiple Info.plist files, that _is_ a good solution. At the moment we have one file that is altered during build (or archiving using Fastlane) but I would indeed like to change this in the future as changing one build setting could mess up the project. – Jeroen May 15 '19 at 10:24
  • I have this _after_ `Compile Sources`: `INFO_PLIST="$CONFIGURATION_BUILD_DIR/$CONTENTS_FOLDER_PATH"` I get an error (file doesn't exist/not readble/not regular file), but the problem is that it tries `/Users/.....DerivedData/MyAppName-fjhbdjf/Build/Products/AppName` instead of `/Users/.....DerivedData/MyAppName-fjhbdjf/Build/Products/AppName Test-iphoneos`. So yes, of course the file doesn't exist. Anything I'm doing wrong? – Jeroen May 17 '19 at 06:37
  • The problem seemed to be that there's a space in the `App Name`. fixed this by putting quotes `" "` around the path in `plutil`. – Jeroen May 17 '19 at 06:50
  • It works, kind of. I placed the script _after_ *Compile Sources*. When I'm looking in MyApp.app I see the value being added to `Info.plist`. But a few seconds later it's removed (so somehow it gets overridden). I also tried placing it after *Copy Bundle Resources*, but then nothing happens. There are no other build phases doing anything with the plist. – Jeroen May 17 '19 at 06:57
  • Do you have any clue as to why it gets overridden later, while placing it after Compile Sources? – Jeroen May 17 '19 at 07:37
  • Edit: You must place _after_ **Copy Bundle Resources**, as in your last comment. Anyway I suggest to use multiple info.plist files and rename/remove accordingly. This is what I used to do, and it works. No idea why it is overridden – carmine May 17 '19 at 08:12
1

(Xcode 11.2)

It is possible to do what you're asking:

  • You can get the path of the app bundle's Info.plist at ${TARGET_BUILD_DIR}/${INFOPLIST_PATH}.

  • BUT: In the New Build System, any custom build steps will run before the New Build System's Process .../Info.plist step, so you cannot edit the app bundle's plist via a Run Script step to Build Phases, because your changes will just be overwritten:

I stole this image from https://stackoverflow.com/a/54232034/969305

  • 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

  • If you're going to reference any build system environment variables (e.g. BUILT_PRODUCTS_DIR or INFOPLIST_PATH), make sure you select your app target in Provide build settings from.

  • 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 script:

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
0

App bundle is read-only. Info.plist is in app bundle

arts
  • 118
  • 4
  • Hmm okay. So a way would be to add the key to the `Info.plist` before building, then remove it `after` building. Would that be possible with Run Scripts? So one _before_ `compile sources` and one _after_ `copy bundle resources`? – Jeroen May 15 '19 at 06:50
  • 1
    My answer is suitable for change info.plist file when app running. Use `Run script` for pre-build change value – arts May 15 '19 at 08:30
  • @JeroenJK not doable through a Build Phases step, unfortunately. See my answer. – sam-w Dec 10 '19 at 07:08