MacPaw Tech Blog — Hackathon Edition

Versioning for iOS & macOS

Announcement by: Yaroslav Valentyi

I was always tangled by

Bundle versions string, short
&
Bundle version
keys in my Info.plist files. But today, I'm not. And I want to share my story along with some links & quotes.

As we all know, those keys are just pretty presented

CFBundleShortVersionString
and
CFBundleVersion
keys (and for Apple only knows reason there is only one constant and it's
kCFBundleVersionKey
and we can only dream about another one).

Let's start with documentation of the CFBudnleShortVersion. It's really close to the Semantic versioning 2.0.0. For the only exception - it doesn't support any pre-release & build metadata (like

-alpha.8
,
-rc.1
or even
-rc.2-build.32.45.6
). It's crucial that
This key is used throughout the system to **identify the version of the bundle**
.

Let's continue with CFBundleVersion. And we have another almost semantic version. But we have a difference:

This key is required by the App Store and is used throughout the system to **identify the version of the build**.
.

And there is a wonderful Technical Note 2420. That explains how those two keys & numbers work together and even more. tl;dr; is that CFBudnleShortVersion is your app version as we understand it, and CFBundleVersion is a build number for the system to differentiate builds of the same version. But there is one serious gem in this note:

So what we have here is just two triples of integers, and if some of you want to make a pile of metadata (long time intervals, commit hashes) in the

CFBundleVersion
(build numbers) with integers, I need to warn you: you have a limit of 18 characters there.

Also, we have

agvtool
that can manage updates of both version & build number. And not to make things easy there we have not only new terms but even places where we can store this information:

  • Marketing version
    for
    CFBundleShortVersionString
    , aka
    Bundle versions string, short
    with corresponding key
    MARKETING_VERSION
    in the project build setting.
  • Current Project Version
    for
    CFBundleVersion
    , aka
    Bundle version
    with corresponding key
    CURRENT_PROJECT_VERSION
    in the project build settings.
  • There is another article by Apple Technical Q&A QA1827: Automating Version and Build Numbers Using agvtool. Which kind of limits our choice of the value in the

    Current Project Version
    :

    And even if you decide to use a floating point number, there is another bummer with automatic increments:

    After reading all this, I've concluded using an integer number for

    CFBundleVersion
    and don't store build metadata in this key (for release builds).

    tl;dr; Roundup:

  • It's easy to remember that in
    *string**, short
    is for the
    Marketing version
    .
  • We have only eighteen symbols in the
    CFBundleVersion
    (like in I'm Eighteen by Alice Cooper).
  • If
    agvtool
    is used,
    CFBundleVersion
    should be an integer number (or a floating point number).
  • For macOS apps, both build number & marketing version should be increased before release.
  • PS. If you are interested what I've come up with for debug builds — stay tuned for the next episode of the Engineering Roundup digest 😉.