Choose a distribution path

Set version and build numbers

Give every release a user-facing version and a monotonically increasing build number that support updates and diagnosis.

12 minute lesson

~~~

Every release you ship needs two numbers, and they answer different questions.

The version (CFBundleShortVersionString) is the public release number users see, like 1.2.0. The build (CFBundleVersion) identifies one exact compiled artifact, like 42. The version answers “what did we ship?”. The build answers “which bytes exactly?”.

Read both from a built app:

plutil -extract CFBundleShortVersionString raw Notes.app/Contents/Info.plist
plutil -extract CFBundleVersion raw Notes.app/Contents/Info.plist

Why two numbers? Because you will build version 1.2.0 more than once. You fix a packaging mistake, rebuild, and now two different artifacts both claim to be 1.2.0. The build number is what tells them apart. Increment it for every artifact you hand to anyone, including testers.

Apple’s tooling can bump the numbers for you. agvtool updates every target in one command:

xcrun agvtool new-marketing-version 1.2.0
xcrun agvtool next-version -all

The first command sets the version. The second increments the build.

Two rules keep you sane later. Never reuse a version-and-build pair for different bytes. And put both numbers in your release records, crash reports, and About window, so any bug report can be traced to one exact artifact.

Here’s the failure mode you’re preventing. A user reports a crash “in the latest version”. You have three builds of 1.2.0 on disk: one before the crash fix, one after, one from a different branch. Without a distinct build number in the report, you can’t tell which one they’re running, and you end up debugging the wrong binary.

Check the numbers in the final exported app, not just in Xcode. Build settings and configurations can override what the project editor shows.

Lesson completed

Take this course offline

Get every free book and course as PDF and EPUB files.

Get the download library →