One Number To Rule Them All

Abdo Arwish
3 min readSep 22, 2021

--

Numbers Photo by Mick Haupt on Unsplash

Often when dealing with iOS or android projects we tend to do some redundant work that would just be better to be automated, saving time and effort whenever possible.

One of these tasks is keeping track of the version of the app well controlled from one place, that number might as well be mirrored to the code release tag on your git repository to keep track of changes and fixes happening on each release, It would also help if you can determine whether user needs to update based on the app version, and what is a better way to do things other than some plain old scripts and code without using any 3rd party library.

In our example we are going to use React native which has both iOS and android projects within, but the same logic applies to any iOS/android project based on your setup.

Now lets jump ahead and start setting everything up by Creating a new React native project

npx react-native init sampleApp

All React native projects have a package.json file which contains some info about your app, the one we are interested in is the versionwhich we are going to use to control our app version

open the android/app/build.gradle file and add the following code

import groovy.json.JsonSlurper
...
// set the version number out of the a.b.c-d as a.b.c
def getNodeVersionNumber() {
def packageFile = new File(“$rootDir/../package.json”) def packageJson = new JsonSlurper().parseText(packageFile.text) def versionNum = packageJson[“version”].split(“-”)[1]return versionNum}//get the version code out of the a.b.c-d as d
def getNodeBuildNumber() {
def packageFile = new File(“$rootDir/../package.json”) def packageJson = new JsonSlurper().parseText(packageFile.text) def buildNum = packageJson[“version”].split(“-”)[2]return buildNum}
...

This allows us to get a hold of our package.json file from the react native project, parse its content as JSON then get the version, our version is set as a.b.c-d where the a.b.c is the version of the app and the d is to identify different builds of the same version for our QA testing

now u can add the version name and version code from those functions

defaultConfig {
...
versionName getNodeVersionNumber()
versionCode getNodeBuildNumber()
...
}

Thats it for android now lets hop on to the iOS setup

Open the xcode project go to Build Phases, press the + icon, select New Run Script Phase and add this script.

// set the version number out of the a.b.c-d as a.b.c
VERION_NUM=”$(grep -w ‘version”:’ “${SRCROOT}”/../package.json | cut -d ‘“‘ -f4| cut -f1 -d”-” | head -n 1)”
/usr/libexec/PlistBuddy -c “Set :CFBundleShortVersionString ${VERION_NUM}” “${TARGET_BUILD_DIR}/${INFOPLIST_PATH}”//set the build number out of the a.b.c-d as dBUILD_NUM=”$(grep -w ‘version”:’ “${SRCROOT}”/../package.json | cut -d ‘“‘ -f4| cut -f2 -d”-” | head -n 1)”/usr/libexec/PlistBuddy -c “Set :CFBundleVersion ${BUILD_NUM}” “${TARGET_BUILD_DIR}/${INFOPLIST_PATH}”

This script extracts the package.json version number from our react native project, sets up the version and build numbers on the info.plist file on each new build/archive

All you need to do now is update the version on the package.json file whenever you need to make a new release

Thats it for both setup, no need for any future manual commits to your iOS or android projects to keep your versions in sync and automatically updated

--

--

Abdo Arwish

I am Abdo, I have been working with react native since its early years, I like sharing knowledge and having fun while doing so :)