I have some large resources that I only need for my simulator runs—I'd like to have them automatically excluded from all device builds. Is there any way to do this with Xcode 4 short of custom build scripts that copy the resources?
I went with a Run Script phase with the following:
if [ ${PLATFORM_NAME} != "iphonesimulator" ]; then
echo "device build -- removing resources..."
rm "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/test_a.mp3"
rm "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/test_b.mp3"
# reveal the binary in the Finder
/usr/bin/open --reveal "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
else
echo "simulator build..."
fi
Targets dictate what's included in a product. Duplicate your target and create a scheme for it. Modify that target's membership.
Art's answer works well.
I'm adding this alternative answer because I have certain requirements and I found a solution that addresses those.
In my case, I need some large resources to be only in some test builds, but I don't want them to be included in the project or checked in with project. I also want to avoid Xcode pointlessly copying a large file from one folder to another during the build.
My solution is as follows:
Create a new folder on disk under your Resources/
folder, titled FolderLinkedResources
.
Add a folder reference to this folder in the Xcode project. This is a link to an actual folder on hard disk, rather than a project folder group. You do it via an option in the Add Files dialog:
Then at build time I have a custom build phase script (placed earlier than compilation) that hard-links the required resource file into the referenced folder on disk:
# COPY_SPECIAL_RESOURCES is only defined in schemas where I require the special resource(s).
# SpecialResources folder is a sibling folder alongside my entire Xcode project folder
if [ ${COPY_SPECIAL_RESOURCES} == "1" ]; then
ln ../SpecialResources/mySpecialResourceFile.bin Resources/FolderLinkedResources/
fi
Now the build will include your special resource.
Note that since the resource file is inside a folder reference in the project, the built app will actually contain the resource file in a folder, rather than at the top level. This means that the usual call to retrieve your resource will not work:
NSString *resourcePath = [[NSBundle mainBundle]
pathForResource:@"mySpecialResourceFile"
ofType:@"bin"];
To fix this, you need to also provide the folder name containing the resource:
NSString *resourcePath = [[NSBundle mainBundle]
pathForResource:@"mySpecialResourceFile"
ofType:@"bin"
inDirectory:@"FolderLinkedResources"];
Note: this technique also works well for when you don't actually know what the resources are until build time! As long as your script step hard-links in the files, they will make it into the build.
In the interests of tidyness and sanity, I include a run script build phase that happens after the compilation, which clears out the hard link:
if [ ${COPY_SPECIAL_RESOURCES} == "1" ]; then
rm -rf Resources/FolderLinkedResources/*.*
fi
Finally, in case anyone is interested in my actual use case for this: I have pre-recorded HTTP communications data for certain offline test builds of my app. This data is in no way a part of the core app, so I don't want it checked in with app itself, or part of the project by default.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With