In my continued quest to banish as many string literals as I possibly can from my project, I wrote a little tool to generate a header file containing string constants for the names of all the images in my .xcassets
bundle.
This means you get compile-time checking of two things — you misspelling the image name, and images being named incorrectly.
The tool is very simple, and is mostly a duplicate of the generate-string-symbols
tool I wrote a while ago. It runs through your .xcassets
directory and writes the found image names out to a header file. You can see the source over on GitHub.
For consistency’s sake, you can pass -prefix
and -suffix
parameters to the tool, which do what they say on the tin. A prefix of CBL
and a suffix of ImageName
will convert and image named Awesome
into CBLAwesomeImageName
, with a value of @"Awesome"
.
Putting It All Together
To integrate this into your project, there are three steps:
- Generating the header files when your project builds.
- Telling Xcode where to find the generated files at build time.
- Importing the generated header files so you can use them.
First, you want to create a custom build step in Xcode before the Compile Sources build step to generate header files from your image assets. My custom build step looks like this:
"$PROJECT_DIR/Vendor/generate-imageasset-symbols/generate-imageasset-symbols"
-assets "$PROJECT_DIR/Cascable/Images.xcassets"
-out "$BUILT_PRODUCTS_DIR/include/CBLImageNames.h"
-prefix CBL
-suffix ImageName
It uses /bin/sh
as its shell, and I have the generate-imageasset-symbols
binary in the Vendor/generate-imageasset-symbols
directory of my project. It places the generated header file in the include
directory of the build directory.
Next, you need to tell Xcode where to search for your files. Make sure your project’s Header Search Paths setting contains $BUILD_PRODUCTS_DIR/include
.
At this point, you can start using the symbols in your project. However, you’ll need to #import
your generated header files(s) in each file you want to use localised strings in.
To get around this, can #import
them in your project’s prefix header file.
#import <CBLImageNames.h> // Generated from image assets
UIImage *image = [UIImage imageNamed:CBLAwesomeImageName];
…and you’re done! You can find the generate-imageasset-symbols
project over on GitHub under a BSD license. Enjoy!