Versions- und Build-Nummer auslesen

Versions- und Build-Nummern spielen bei der App-Entwicklung eine wichtige Rolle. Sie dienen nicht nur dazu, den Endnutzern eine Orientierung bei der Veröffentlichung von Updates zu geben, sondern können auch bei der Umsetzung neuer Funktionen dabei helfen, den Überblick über an beispielsweise Testnutzer verteilte Vorabversionen zu behalten.

Als Apple Developer pflegt man die Informationen zu Versions- und Build-Nummer typischerweise in den zugehörigen Target-Einstellungen. Dort stehen zwei Textfelder namens Version und Build zur Verfügung, in denen die entsprechenden Daten eingetragen werden. Intern wird diese Information in der Info.plist-Datei gespeichert.

Die Informationen zu Versions- und Build-Nummer werden in den jeweiligen Target-Einstellungen gepflegt.
Die Informationen zu Versions- und Build-Nummer werden in den jeweiligen Target-Einstellungen gepflegt.

So weit, so gut. Und so praktisch. Doch in vielen App-Projekten werden Versions- und oftmals auch Build-Nummern zusätzlich innerhalb der App ausgegeben, beispielsweise in den Einstellungen. Das kann nicht nur für interessierte Nutzer eine spannende Information sein, sondern beim Verteilen von Vorabversionen an Testgruppen eine wichtige Rolle spielen. Sollten Fehler auftreten, ist es oft wichtig zu wissen, bei welchem konkreten Build es zu dem Problem kam. Neben Crash Reports können hier auch die eigentlichen Nutzer weiterhelfen, wenn die die Informationen zur Version einfach aus der App auslesen können.

Womöglich denkt man bei einer entsprechenden Umsetzung zunächst daran, Versions- und Build-Nummer fest an der zugehörigen Stelle im Code zu hinterlegen, von wo aus sie später auch abgerufen werden, doch das ist zweifellos recht umständlich und fehleranfällig. Schließlich muss man dann bei jeder Aktualisierung von Versions- und Build-Nummer daran denken, diese Aktualisierung auch an genannter Stelle im Code durchzuführen.

Schöner und praktischer ist es da, wenn die Versions- und Build-Nummer direkt aus den Target-Einstellungen ausgelesen werden; dann erhält man immer das korrekte Ergebnis. Und mithilfe der Klasse Bundle aus dem Foundation-Framework ist ein solches Auslesen erfreulicherweise auch ohne Probleme möglich.

Zugriff auf Info.plist mit Bundle

Die praktische Umsetzung an sich ist recht trivial: Da Versions- und Build-Nummer intern in der Info.plist-Datei gespeichert werden, greifen wir schlicht mithilfe der Bundle-Klasse auf diese Datei zu und lesen die Information mithilfe der passenden Schlüssel aus. Für die Versionsnummer ist das CFBundleShortVersionString, für die Build-Nummer CFBundleVersion. Beide Informationen werden als Strings abgebildet. Um so beispielsweise auf die Versionsnummer zuzugreifen, kann der folgende Befehl genutzt werden:

Bundle.main.infoDictionary!["CFBundleShortVersionString"] as! String

Auf die Bundle-Instanz greift man typischerweise über die main-Property zu. Die Inhalte der Info.plist-Datei können dann über die infoDictionary-Property ausgelesen werden.

Das folgende Listing zeigt ein vollständiges Beispiel einer Structure namens AppInformation, die ich so gerne in so ziemlich jedem meiner Projekte einsetze. Sie verfügt über zwei Type Properties namens versionNumber and buildNumber, die jeweils die Version- und Build-Nummer des zugrundeliegenden Targets auslesen und zurückgeben. Darüber hinaus steht mit der Computed Type Property formattedVersionNumber ein weiterer String zum Abruf zur Verfügung, der die Versions- und Build-Nummer zusammen in formatierter Form zurückliefert. Dieser String ist wie folgt aufgebaut: <Versionsnummer> (<Build-Nummer>).

struct AppInformation {
    
    static let versionNumber: String = {
        if let versionNumber = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String {
            return versionNumber
        }
        return "0.0"
    }()
    
    static let buildNumber: String = {
        if let buildNumber = Bundle.main.infoDictionary?["CFBundleVersion"] as? String {
            return buildNumber
        }
        return ("0")
    }()
    
    static var formattedVersionNumber: String {
        return "\(versionNumber) (\(buildNumber))"
    }
    
}

Die Structure AppInformation trägt hierbei auch dem Umstand Rechnung, dass es sich bei der infoDictionary-Property um ein Optional handelt. Da darüber hinaus die Werte dieses Dictionaries als Elemente vom Typ Any definiert sind, ist ein Type Casting in Richtung String notwendig, das theoretisch aber fehlschlagen kann. Darum werden diese beiden Aspekte mittels einer Abfrage geprüft um sicherzustellen, dass sowohl Versions- als auch Build-Nummer tatsächlich zur Verfügung stehen. Alternativ wird ein von mir definierter Standardwert (0.0 für die Versions- und 0 für die Build-Nummer) zurückgegeben.

Wer mag darf die gezeigte Structure gerne in eigene Projekte einbinden und darüber auf die Informationen zu Versions- und Build-Nummer zugreifen. 🙂 Bei Fragen oder Anmerkungen stehe ich euch gerne über die Kommentarsektion des Artikels zur Verfügung. 🙂

Euer Thomas


Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert