How to read current app version in Xcode 11 with script
Asked Answered
R

12

54

Until Xcode 11, I used a script that reads the current app version (for the AppStore) and help me change the LaunchScreen since we can't use swift for that.

sourceFilePath="$PROJECT_DIR/$PROJECT_NAME/App/Base.lproj/LaunchScreen.storyboard"
versionNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "$INFOPLIST_FILE")
buildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "$INFOPLIST_FILE")

sed -i .bak -e "/userLabel=\"APP_VERSION_LABEL\"/s/text=\"[^\"]*\"/text=\"v$versionNumber\"/" "$PROJECT_DIR/$PROJECT_NAME/App/Base.lproj/LaunchScreen.storyboard"

But in Xcode 11 there is a new section inside the project's build settings called Versioning

enter image description here

And CFBundleShortVersionString automatically changed to $(MARKETING_VERSION). Xcode automatically handles that and I don't want to change it manually to an static number and let Xcode do it's work.

11

So the question is how can I access this new MARKETING_VERSION and set it to my launchScreen label using run script?

Redaredact answered 23/6, 2019 at 9:41 Comment(0)
I
19

You can use it like any other project variable:

sourceFilePath="$PROJECT_DIR/$PROJECT_NAME/App/Base.lproj/LaunchScreen.storyboard"
versionNumber="$MARKETING_VERSION"
buildNumber="$CURRENT_PROJECT_VERSION"

sed -i .bak -e "/userLabel=\"APP_VERSION_LABEL\"/s/text=\"[^\"]*\"/text=\"v$versionNumber\"/" "$PROJECT_DIR/$PROJECT_NAME/App/Base.lproj/LaunchScreen.storyboard"
Interviewer answered 8/7, 2019 at 17:53 Comment(3)
This is not working for me or I'm missing something.Germin
Is there a way to print the current value of $MARKETING_VERSION also in the terminal?Golter
@HansBondoka echo "The marketing version is: $MARKETING_VERSION"Varien
F
50

Xcode 11-15

In terminal or bash script in your project you can use:

App version

xcodebuild -showBuildSettings | grep MARKETING_VERSION | tr -d 'MARKETING_VERSION =' // will be displayed 1.1.6

Build version

xcodebuild -showBuildSettings | grep CURRENT_PROJECT_VERSION | tr -d 'CURRENT_PROJECT_VERSION =' // will be displayed 7

Or (don't forget to change YouProjectName to your project name):

App version

cat YouProjectName.xcodeproj/project.pbxproj | grep -m1 'MARKETING_VERSION' | cut -d'=' -f2 | tr -d ';' | tr -d ' '

Build version

cat YouProjectName.xcodeproj/project.pbxproj | grep -m1 'CURRENT_PROJECT_VERSION' | cut -d'=' -f2 | tr -d ';' | tr -d ' '

Or slower method (Thx Joshua Kaden):

App version

xcodebuild -project YouProjectName.xcodeproj -showBuildSettings | grep "MARKETING_VERSION" | sed 's/[ ]*MARKETING_VERSION = //'

Build version

xcodebuild -project YouProjectName.xcodeproj -showBuildSettings | grep "CURRENT_PROJECT_VERSION" | sed 's/[ ]*CURRENT_PROJECT_VERSION = //'

Fealty answered 9/1, 2020 at 20:4 Comment(3)
This works great if you have multiple build schemes that you need to get their version numbers. Just pass --scheme {SCHEME} to in the xcodebuild command.Underdog
@Underdog should be -scheme {SCHEME}, working along with -workspace {name}.xcodeworkspaceYep
cat worked like charm! Good one!Ottoman
M
20

Couldn't find right answer on the internet, so I started digging.

Version and build numbers are displayed in ./PROJECTNAME.xcodeproj/project.pbxproj as MARKETING VERSION (MV) and CURRENT PROJECT VERSION (CPV).

version number

build number

I used sed to get the numbers. It finds first occurrence of MV or CPV, removes everything except the number, and returns result. In order for this to work, you need to do 2 things:

  • navigate to projects root folder
  • change PROJECTNAME to your project's name

Commands:

version_number=`sed -n '/MARKETING_VERSION/{s/MARKETING_VERSION = //;s/;//;s/^[[:space:]]*//;p;q;}' ./PROJECTNAME.xcodeproj/project.pbxproj`
build_number=`sed -n '/CURRENT_PROJECT_VERSION/{s/CURRENT_PROJECT_VERSION = //;s/;//;s/^[[:space:]]*//;p;q;}' ./PROJECTNAME.xcodeproj/project.pbxproj`

Result:

version and build numbers

Note: If you have more targets in your workspace with different version and build numbers, this might or might not work for you, because it stops on first occurrence. In that case, good luck :)

Mar answered 8/11, 2019 at 15:56 Comment(6)
Nice. Works for me.Denver
You should use xcodebuild -showBuildSettings instead on direct reading project fileEmbolism
xcodebuild -project ThreeOneOne.xcodeproj -showBuildSettings | grep "MARKETING_VERSION" | sed 's/[ ]*MARKETING_VERSION = //'Hyoscyamine
Tried with -showBuildSettings on three projects and not getting the MARKETING_VERSION, nor CURRENT_PROJECT_VERSION. If you are getting it, thumbs up, go with it :)Mar
@Mar hope you're already solved the problem. The reason you cannot obtain the MARKETING_VERSION is that you are working in a workspace instead of a project (hinted by you have three projects in hand). To get the version, you can issue this command: xcodebuild -workspace YourName.xcodeworkspace -scheme YourSchemeName -showBuildSettings | grep "MARKETING_VERSION"Yep
Any ideas on how to get the first occurrence where its a number and not "$(inherited)"Milling
I
19

You can use it like any other project variable:

sourceFilePath="$PROJECT_DIR/$PROJECT_NAME/App/Base.lproj/LaunchScreen.storyboard"
versionNumber="$MARKETING_VERSION"
buildNumber="$CURRENT_PROJECT_VERSION"

sed -i .bak -e "/userLabel=\"APP_VERSION_LABEL\"/s/text=\"[^\"]*\"/text=\"v$versionNumber\"/" "$PROJECT_DIR/$PROJECT_NAME/App/Base.lproj/LaunchScreen.storyboard"
Interviewer answered 8/7, 2019 at 17:53 Comment(3)
This is not working for me or I'm missing something.Germin
Is there a way to print the current value of $MARKETING_VERSION also in the terminal?Golter
@HansBondoka echo "The marketing version is: $MARKETING_VERSION"Varien
H
6

I miss here a solution for multiple targets and configurations:

xcodebuild -target <target> -configuration <configuaration> -showBuildSettings  | grep -i 'MARKETING_VERSION' | sed 's/[ ]*MARKETING_VERSION = //'
  • target: the name of the target
  • configuration: Release, Debug
Hadfield answered 24/7, 2020 at 8:19 Comment(1)
Thank you! That's exactly what I neededSpud
M
3

If you use Bitrise then the following script will save you:

Extracting App Marketing Version

envman add --key=APP_VERSION_NO --value=`sed -n '/MARKETING_VERSION/{s/MARKETING_VERSION = //;s/;//;s/^[[:space:]]*//;p;q;}' ./${PATH_TO_YOUR_PROJECT_XCODEPROJ_FILE}/project.pbxproj`

Extracting App Build Number

Extract the Build Number from xcodeproj file only if you use Apple Generic versioning system otherwise extract the Build Number from the XCode project info.plist file.

Note: The following script extracts the Build Number from the xcodeproj file.

envman add --key=APP_BUILD_NO --value=`sed -n '/CURRENT_PROJECT_VERSION/{s/CURRENT_PROJECT_VERSION = //;s/;//;s/^[[:space:]]*//;p;q;}' ./${PATH_TO_YOUR_PROJECT_XCODEPROJ_FILE}/project.pbxproj`

Printing to console:

envman run bash -c 'echo "App Version: $APP_VERSION_NO"'

envman run bash -c 'echo "App Build No: $APP_BUILD_NO"'

Thanks to the answer by @babac

Metonymy answered 24/11, 2019 at 21:12 Comment(0)
P
3

Most voted answers by now show how to extract the value through sed and further tools in the chain. Thought to provide a (simpler?) solution just through awk.

Just to give a little bit of context, following one-liner shows the culprit row:

xcodebuild -project MyProj/MyProj.xcodeproj -showBuildSettings | awk '/MARKETING_VERSION/ { print }'

# output
    MARKETING_VERSION = 0.0.1

Default awk field separator should be the space, and so it's just a matter of extracting the third field (MARKETING_VERSION is first, the equal sign is second):

xcodebuild -project MyProj/MyProj.xcodeproj -showBuildSettings | awk '/MARKETING_VERSION/ { print $3 }'

# output
0.0.1

HTH

Porshaport answered 1/6, 2021 at 15:13 Comment(2)
why I get an error said DVTAssertions: Warning in /Library/Caches/com.apple.xbs/Sources/DVTiOSFrameworks/DVTiOSFrameworks-19450/DTDeviceKitBase/DTDKRemoteDeviceData.m:373Stedt
Hi @user2027712. With info provided, I have no idea. I suggest you open a dedicated question for that, providing all needed context, more information, etc. Better yet, if you haven't done already, try searching for that error message on the web. It does not look like an error coming from command line, which is the main topic of this answer. There must be something else wrong in your Xcode build I guess.Porshaport
G
1

How about saving a value to CURRENT_PROJECT_VERSION ? did anyone managed to do this?

I can get the value like

buildNumber=$CURRENT_PROJECT_VERSION

but this doesn't work:

CURRENT_PROJECT_VERSION=""    or   $CURRENT_PROJECT_VERSION=""

In my case I'm trying to set it to ""

This line doesn't set the CURRENT_PROJECT_VERSION field too

/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "$appInfoPlist"
Gallion answered 2/4, 2020 at 23:31 Comment(0)
G
1

If your project is set up to use Apple Generic Versioning then you may use this command:

agvtool what-marketing-version -terse1

More info on how to set up AGV can be found here.

Gauvin answered 26/1, 2021 at 10:18 Comment(1)
This is actually a cleaner way if the version is set in the Info.plist file rather than in build settings. Thank you!Fortier
C
0

For Node.js: there is xcode package. Example of usage:

const xcode = require('xcode');

const project = xcode.project('ios/PROJECT_NAME.xcodeproj/project.pbxproj').parse(() => {
  const config = project.pbxXCBuildConfigurationSection();
  const releaseScheme = Object.keys(config).find(key => config[key].name === 'Release');

  const version = config[releaseScheme].buildSettings.MARKETING_VERSION;
});

Previously I used the plist package, but with latest xCode changes it became outdated, since I'm not able to extract a version from Info.plist for React Native projects.

Cavity answered 10/10, 2019 at 16:27 Comment(0)
F
0

I had similar issue and made it work by displaying MARKETING_VERSION itself:

version="$MARKETING_VERSION"
version+=" ("
version+=`/usr/libexec/PlistBuddy -c "Print CFBundleVersion" $SRCROOT/MyApp/Info.plist`
version+=")"

/usr/libexec/PlistBuddy "$SRCROOT/MyApp/Settings.bundle/Root.plist" -c "set PreferenceSpecifiers:1:DefaultValue $version"
Floorman answered 26/10, 2019 at 7:0 Comment(0)
U
0

I'm developing a framework with this scenario:

  • A workspace
  • A framework target
  • An aggregate target with 2 external scripts:
    • one for build a fat framework
    • other for prepare the release framework

The key is that in XCode 11 the aggregate framework script doesn't get run environment variables for other workspace targets so it's impossible to read the $MARKETING_VERSION from my framework target.

So the solution that works for me has been use PlistBuddy specifying the Info.plist result of the framework target build in this way:

FAT_FRAMEWORK="${SRCROOT}/build/${FRAMEWORK_NAME}.framework"
BUILD_NUMBER=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "${FAT_FRAMEWORK}/Info.plist")
VERSION_NUMBER=$(/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${FAT_FRAMEWORK}/Info.plist")
Underclothing answered 15/11, 2019 at 14:53 Comment(0)
M
0

You can use jq because xcodebuild has -json option.

❯ xcodebuild -showBuildSettings -json 2>/dev/null | jq '.[0].buildSettings.MARKETING_VERSION'
"0.1.0"
❯ xcodebuild -showBuildSettings -json 2>/dev/null | jq '.[0].buildSettings.CURRENT_PROJECT_VERSION'
"1"

jq -r prints raw value:

❯ xcodebuild -showBuildSettings -json 2>/dev/null | jq -r '.[0].buildSettings.MARKETING_VERSION'
0.1.0
❯ xcodebuild -showBuildSettings -json 2>/dev/null | jq -r '.[0].buildSettings.CURRENT_PROJECT_VERSION'
1
Modlin answered 9/8, 2023 at 6:56 Comment(3)
What is jq? There's nothing on my Mac named jq.Spanjian
It is a well-known JSON processing OSS software. jq is not installed by default. github.com/jqlang/jq / You may use any scripting language that can process JSON, or you may install jq with Homebrew.Modlin
It would be helpful to put that info in your answer.Spanjian

© 2022 - 2024 — McMap. All rights reserved.