My XCode project is setup in a way that has multiple configurations, allowing me to use the same code base for different variations of my app, but have unique elements in each such as app name, version, bundle identifier, icon, launch screen, etc. I've followed this website in order to do most of the setup:
http://appfoundry.be/blog/2014/07/04/Xcode-Env-Configuration/
I also have a config.plist containing various unique settings associated with each XCode configuration that successfully only gets copied upon being built. Here's a snippet of the Run Script build phase in order to do that:
RESOURCE_PATH=${SRCROOT}/${PRODUCT_NAME}/config/${CONFIGURATION}
BUILD_APP_DIR=${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app
echo "Copying all files under ${RESOURCE_PATH} to ${BUILD_APP_DIR}"
cp -v "${RESOURCE_PATH}/"* "${BUILD_APP_DIR}/"
My next goal is to be able to copy a particular configuration's asset catalog when being built, so as to avoid bundling all of the different configuration's images into the build, causing it to become bloated. I've tried the same solution as above with the Run Script, changing the copy line to include the recursive option (since asset catalog is essentially a directory):
cp -rv "${RESOURCE_PATH}/"* "${BUILD_APP_DIR}/"
However, when I do this, my app fails to build and says it's unable to find the app icon and launch image. Any ideas?
This is what you can do to make this work:
- Add a separate asset catalog per configuration, just as you would normally add an asset catalog to your project. Let's assume for this example we call these catalogs MediaForDebug.xcassets, MediaForAdHoc.xcassets and MediaForRelease.xcassets
- Make sure the newly created asset catalogs are all member of your target (so DO NOT exclude them here, we'll do that later on)
- Now, if not already added to your build settings, add a custom
EXCLUDED_SOURCE_FILE_NAMES
User-Defined setting.
- See the screenshot below for the values to be set for this User-Defined setting.
By doing this, Xcode will only compile the appropriate asset catalogs, and ignore the others. I've tested this on one of our projects, and it works as intended.
Good luck!
REMARK: If you are using CocoaPods, you might run into troubles because CocoaPods adds a build step of its own to compile your assets, and those of your dependencies into on .car file. See https://github.com/CocoaPods/CocoaPods/issues/1546 for the discussion on this issue. TL;DR: make sure this step doesn't execute in your build phase, or edit the CocoaPods script they execute to not do the asset building.
UPDATE 1/19/2019: With the latest stable Xcode (10.1) and Cocoapods (v1.5.3) they work out of the box with the solution above. No need to alter the Cocoapods scripts or build steps, just set EXCLUDED_SOURCE_FILE_NAMES
as described.