Reputation: 3367
I received the following email from Apple when I submit an app update:
We have discovered one or more issues with your recent delivery for "Project". Your delivery was successful, but you may wish to correct the following issues in your next delivery:
CFBundleVersion Mismatch - The CFBundleVersion value '1' of extension 'Project.app/PlugIns/ProjectTodayExtension.appex' does not match the CFBundleVersion value '985' of its containing iOS application 'Project.app'.
CFBundleShortVersionString Mismatch - The CFBundleShortVersionString value '1.0' of extension 'Project.app/PlugIns/ProjectTodayExtension.appex' does not match the CFBundleShortVersionString value '2.1.6' of its containing iOS application 'Project.app'.
After you’ve corrected the issues, you can use Xcode or Application Loader to upload a new binary to iTunes Connect.
Is there any way of use the same CFBundleVersion and CFBundleShortVersionString in all targets to prevent this?
Upvotes: 15
Views: 9589
Reputation: 21
I utilized the excellent answer from stk, but there was a snag that I wanted to mention so others are aware:
Setting the user-defined constants for the primary target (main app executable) resulted in errors when uploading the app to the store. At least in Xcode 13.0, Xcode crashed when it was trying to create a URL parameter to verify the version number with the server. Directly setting the version numbers for the main target fixed the issue. All the other "sub-targets" work fine using the defined constants.
Upvotes: 0
Reputation: 402
I was able to achieve keeping the target extension version and build strings in sync with the main app with the following:
Run Script Phase
above Compile Sources
WIDGET_EXTENSION="${SRCROOT}/MyWidget/Info.plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString ${MARKETING_VERSION}" "$WIDGET_EXTENSION"
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion ${CURRENT_PROJECT_VERSION}" "$WIDGET_EXTENSION"
Upvotes: 5
Reputation: 13726
1) Go to project settings, choose PROJECT (above targets), go to Build Settings
2) Press Add User-Defined Setting
and add APP_BUILD
and APP_VERSION
3) In your targets go to Info
and replace Bundle version
to $(APP_BUILD)
and Bundle version string
to $(APP_VERSION)
in all targets and extensions where you need to sync.
4) Woila! You should change bundle versions only in one place - in Build Settings
of your PROJECT.
Upvotes: 2
Reputation: 295
There is a really sweet version management system that Twitch has shared.
Described in this blog post, it is somewhat similar to stk's accepted answer but cleaner and also supports the following:
Ties the build number directly (and reversibly) to the git commit before the build. Go back easily to the exact version built for use with crash report.
Handles version generation through a target dependency, which is easier to share across multiple targets.
Uses C Preprocessor on Info.plist functionality built into Xcode build settings to allow the version numbers to be substituted on the fly, with no modification of the Info.plist file.
It is a little more complex to implement, but it's the best solution I've found, particularly if you have extensions or other targets whose versions must be kept in sync.
Installation Notes: Note the blog does a great job of describing the four shell files, but doesn't really give installation or customization instructions. Here's what I did:
Create a Versions subdirectory at the top level of your project (where the .xcodeproj lives).
Download the four files indicated from the gist link at bottom left of the code samples. Move the four files into your Versions directory.
Using terminal, cd to your Versions directory, then execute the cmd: chmod +x *
to make the shell files executable
Now follow the directions in the blog from the start to create your dependency target.
You probably should customize the scripts a bit. I altered the naming and refactored to move the 4 tools to a separate tools directory that I share across projects. YMMV.
Upvotes: 2
Reputation: 1
When trying to validate my archive I got an error message CFBundleShortVersionString missing. To fix the problem I went into Info.plist in the xml code and added CFBundleShortVersionString new version number This produced in plist format Bundle versions string, short This solve my problem
Upvotes: -1
Reputation: 5103
The scheme actions aren't in source control so it's better to add a build phase into your app's target. Syncing the versions across all targets can be solved with a simple script that can be modified for every target you want synced:
Rename the script to something like "Sync Versions" and drag it above "Compile Sources" (NOTE: Xcode has a bug that may prevent the drag-drop to work. If so, you'll need to manually edit the .pbxproj file so the build phase goes in the right spot
Paste the following script into the shell:
INFOPLIST_MYAPP="${SRCROOT}/MyApp/MyApp-Info.plist"
myAppVersion=$(/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "$INFOPLIST_MYAPP")
myAppBuild=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "$INFOPLIST_MYAPP")
INFOPLIST_SHAREEXT="${SRCROOT}/ShareExtension/Info.plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString $myAppVersion" "$INFOPLIST_SHAREEXT"
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $myAppBuild" "$INFOPLIST_SHAREEXT"
Upvotes: 16
Reputation: 6461
My solution is:
For CFBundleShortVersionString:
CFBundleVersion: you could do the same for CFBundleVersion, but somehow I wanted this value to be computed from my GIT repo commit count. I´ve done it like this:
\#!/bin/sh INFOPLIST="${SRCROOT}/MyApp/MyApp-Info.plist" INFOPLIST_WKAPP="${SRCROOT}/MyApp-WKApp/Info.plist" INFOPLIST_WKEXT="${SRCROOT}/MyApp-WKExt/Info.plist" PLISTCMD="Set :CFBundleVersion $(git rev-list --all|wc -l)" echo -n "$INFOPLIST" | xargs -0 /usr/libexec/PlistBuddy -c "$PLISTCMD" echo -n "$INFOPLIST_WKAPP" | xargs -0 /usr/libexec/PlistBuddy -c "$PLISTCMD" echo -n "$INFOPLIST_WKEXT" | xargs -0 /usr/libexec/PlistBuddy -c "$PLISTCMD"
\#!/bin/sh INFOPLIST="${SRCROOT}/MyApp/MyApp-Info.plist" INFOPLIST_WKAPP="${SRCROOT}/MyApp-WKApp/Info.plist" INFOPLIST_WKEXT="${SRCROOT}/MyApp-WKExt/Info.plist" PLISTCMD="Set :CFBundleVersion SCRIPTED" echo -n "$INFOPLIST" | xargs -0 /usr/libexec/PlistBuddy -c "$PLISTCMD" echo -n "$INFOPLIST_WKAPP" | xargs -0 /usr/libexec/PlistBuddy -c "$PLISTCMD" echo -n "$INFOPLIST_WKEXT" | xargs -0 /usr/libexec/PlistBuddy -c "$PLISTCMD"
Upvotes: 17
Reputation: 27
The version of your ProjectTodayExtension.appex have to be the same as your app. example:
Target> General:
Version: 1.0 <- change here Biuld: 1.0
If the version of your app to get on itunes connect is 2.3, then you must change the version of your TodayExtension to the same version 2.3.
Upvotes: 1