The version and build number (or version and short version) of a Watchkit app and extension have to be set to the same value as the containing app.
I use environment variables to set the apps version in the Info.plist
dynamically at build time. That also works fine for the Watchkit extension, but not for the Watchkit app.
The environment variables I use have to be provided in the plist for the main app and extension without ${}
(for variable ${VERSION}
I set VERSION
).
if I do the same for the Watchkit app, it is taking the string itself, not the value. If I provide it with dollar & brackets there is no data in the variable.
Any idea how to set the variables for the Watchkit app?
stk's answer is right, but I wanted to add my findings as well.
One way to solve the problem is by using
agvtools
:Create a new target in OSX > Other > External Build Sytem Add a run script similar to this one:
I have a
version.txt
file with only my version number in it (marketing version or short bundle version) that can be easily adjusted by any CI system and use the number of my git SHAs as build number (bundle version) Adjust the sources forVERSION
andBUILD
to fit your requirementsRun the scheme that has been created for the new target before your build/archiving.
In case you need to have this as a dependency for your main target - this will fail, as it will stop the execution of the following targets (if somebody knows how to prevent that, I would be thankful for a hint)
But you can still achieve that with a script like the following executed for each of your plists (similar to what stk provided):
Save this script as a file, make it executable (
chmod +x SCRIPTNAME
) Then execute it with the mentioned parameter for all your plistsThis solution is not so convenient as the
agvtools
solution, but it should not stop your build when used in a dependency ...I use this to update all the targets:
If it would be useful to supplement other answers with my own personal experience. These centred around build failure caused by
ValidateEmbeddedBinary
.ValidateEmbeddedBinary
will fail if theCFBundleVersion
is not the same in the embedded WatchKit app and the parent app.The error looks something like:
Working in XCode 7.3, the following will first update the parent app's plist. Then it updates the Debug or Release WatchKit app before
PBXCp
executes to copy it to the parent app directory:The above uses git's commit count as
CFBundleVersion
.I have a Run Script that I attach to my main app target. It will propagate the WatchKit Extension and the WatchKit app upon building the app.
It is completely reusable. Enjoy!
My
CFBundleVersion
is the number of commits on mymaster
branch on the git repo.On my main app target, in
Build Phases
>+ New Run Script Phase
I've added this script:From
app WatchKit App
theapp
should be the name of your app, but check the exact path.To extend this thread, if someone encounters similar problem as me, hopefully script below will help.
For instance, I have watch target, watch extension, app share extension in my project.
I used run phase to update project's plist as suggested, and it works if I build the project, the .plist files are all updated as expected.
However the problem is when you archiving app(let's say all targets have different build number), the info plist in the archived projects was not updated. After a few times of try out, I found extension's plist files were copied before this run phase, and then the run phase script(updating project's plist) won't help with the archived plist. So I eventually changed the script to update compiled target's plist, and it works as I expected, I have same build number for all the targets in the application. Here is how I did it: add this script to each target's build phase:
For different target, this
EXECUTABLE_FOLDER_PATH
was different, and it will update the compiled target's info plist, instead of the project's info plist. Just a note I checked "Run script only when installing" as well since I only need this to be run for archiving