EDIT
2 solutions:
To be honest I think the XCConfig
solution is much much more elegant. You just swap things in and out rather than trying to override everything in a very specific order...
Every other answer had a piece of what was necessary. With some important modifications to this post I was able to get things right.
You need to do three things:
- Change bundleId of appex (app extension)
- re-sign appex after its bundle is changed. While the app runs on simulator correctly it won't work on real device without this step.
- set appropriate provisioning profiles. (excluded from this answer as I don't know how to do that yet)
Note: You can't sign the appex until it's embedded. So the 're-sign appex' step needs to happen after the 'embed App extension' step. Similarly the appex can't be embedded if the bundleId isn't prefixed with the parent app's bundleId.
The final order should look like this:
change bundleId of appex
plutil
's sytanx is like this:
-replace keypath -type value
So just do:
plutil -replace \
CFBundleIdentifier -string \
$PRODUCT_BUNDLE_IDENTIFIER.contentExt \
"$BUILT_PRODUCTS_DIR/contentExt.appex/Info.plist"
In case you wanted to learn more about plutil
(see here and here for more). PlistBuddy
is kinda old.
Note: ContentExtension is the target name I have. Make sure you use yours correctly
re-sign appex
/usr/bin/codesign \
--force \
--sign $EXPANDED_CODE_SIGN_IDENTITY \
--entitlements $CONFIGURATION_TEMP_DIR/ContentExtension.build/ContentExtension.appex.xcent \
--timestamp=none \
"$BUILT_PRODUCTS_DIR/$FULL_PRODUCT_NAME/$BUNDLE_PLUGINS_FOLDER_PATH/ContentExtension.appex"
Note: ContentExtension is the target name I have. Make sure you use yours correctly
The end result is like this:
Don't forget to repeat the steps for every target. The best way to make sure that you have it right is to set the appex's bundleId to something totally wrong and then test all your targets on a real device. If you test it on the sim then you won't be able to validate if the code-signing works correctly or not.
FWIW it's usually a good idea to dump all your shells in one directory like and then reference them from there. But for the sake of simplicity of this post I'm not doing that.
Also make sure you see the original gist it's much smarter if you use that to change all your appexes. You just have to pass the name of the appex and then it would figure out the rest...