Wie kann ich die Version der Anwendungsversion im Einstellungspaket meiner Anwendung anzeigen?


88

Ich möchte die Anwendungsversion und die interne Revision, etwa 1.0.1 (r1243), in das Einstellungspaket meiner Anwendung aufnehmen.

Die Root.plist-Datei enthält ein Fragment wie dieses ...

     <dict>
        <key>Type</key>
        <string>PSTitleValueSpecifier</string>
        <key>Title</key>
        <string>Version</string>
        <key>Key</key>
        <string>version_preference</string>
        <key>DefaultValue</key>
        <string>VersionValue</string>
        <key>Values</key>
        <array>
            <string>VersionValue</string>
        </array>
        <key>Titles</key>
        <array>
            <string>VersionValue</string>
        </array>
    </dict>

und ich möchte die Zeichenfolge "VersionValue" beim Erstellen ersetzen.

Ich habe ein Skript, das die Versionsnummer aus meinem Repository extrahieren kann. Ich benötige eine Möglichkeit, die Root.plist-Datei zum Zeitpunkt der Erstellung zu verarbeiten (vorzuverarbeiten) und die Versionsnummer zu ersetzen, ohne die Quelldatei zu beeinflussen.

Antworten:


68

Es gibt eine andere Lösung, die viel einfacher sein kann als jede der vorherigen Antworten. Apple bündelt ein Befehlszeilentool namens PlistBuddy in den meisten Installationsprogrammen und hat es in Leopard at aufgenommen /usr/libexec/PlistBuddy.

Da Sie ersetzen möchten , können Sie diesen Befehl verwenden VersionValue, vorausgesetzt, Sie haben den Versionswert extrahiert $newVersion:

/usr/libexec/PlistBuddy -c "Set :VersionValue $newVersion" /path/to/Root.plist

Dieser Ansatz ist recht einfach, da Sie nicht mit sed oder regulären Ausdrücken herumspielen müssen. Detaillierte Anweisungen finden Sie auf der Manpage . Mit PlistBuddy können Sie jeden Eintrag in einer Eigenschaftsliste hinzufügen, entfernen oder ändern. Zum Beispiel hat ein Freund von mir über das Inkrementieren von Build-Nummern in Xcode mit PlistBuddy gebloggt.

Hinweis: Wenn Sie nur den Pfad zur Liste angeben, wechselt PlistBuddy in den interaktiven Modus, sodass Sie mehrere Befehle ausgeben können, bevor Sie Änderungen speichern. Ich empfehle dies auf jeden Fall, bevor Sie es in Ihr Build-Skript einfügen.


20
Es dauert eine Weile, bis ich herausgefunden habe, wie ich mich auf die Versionsnummer in meiner Liste beziehen kann. In meinem Fall stellte sich heraus, dass es / usr / libexec / PlistBuddy Settings.bundle / Root.plist -c "set PreferenceSpecifiers: 0: DefaultValue $ newversion" war - hoffentlich ist das für andere Leute nützlich.
JosephH

Quinn Taylor, JosephH, dank Ihrer Antworten konnte ich die Versionsnummer meiner Apps automatisch im Settings.bundle implementieren. +1 für euch beide ;-)
Niko

7
In einer benutzerdefinierten Erstellungsphase "Skript ausführen" musste mehr Pfad zu Root.plist eingefügt werden: / usr / libexec / PlistBuddy $ {TARGET_BUILD_DIR} / $ {FULL_PRODUCT_NAME} /Settings.bundle/Root.plist -c " PreferenceSpecifiers: 0: DefaultValue $ newVersion "
Chris Vasselli

2
Der Vollständigkeit halber ist hier ein anderer Ansatz mit PListBuddy, der für mich funktioniert hat: xcodehelp.blogspot.com/2012/05/…
koen

Der richtigste Weg ist/usr/libexec/PlistBuddy -c "Set :PreferenceSpecifiers:0:DefaultValue ${newVersion}" "${TARGET_BUILD_DIR}/${CONTENTS_FOLDER_PATH}/Settings.bundle/Root.plist"
Kambala

65

Die Lösung meines faulen Mannes bestand darin, die Versionsnummer aus meinem Anwendungscode zu aktualisieren. Sie könnten einen Standardwert (oder einen leeren Wert) in der Root.plist und dann irgendwo in Ihrem Startcode haben:

NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];
[[NSUserDefaults standardUserDefaults] setObject:version forKey:@"version_preference"];

Der einzige Haken ist, dass Ihre App mindestens einmal ausgeführt werden muss, damit die aktualisierte Version im Einstellungsfeld angezeigt wird.

Sie können die Idee weiterentwickeln und beispielsweise einen Zähler dafür aktualisieren, wie oft Ihre App gestartet wurde, oder andere interessante Informationen.


9
Dies funktioniert nur, wenn der Benutzer vor dem Starten Ihrer App die Einstellungen aufruft.
Moshe

9
@ Moshe True, aber um dies elegant zu handhaben, können Sie einfach einen Standardwert in der .plist-Datei angeben, möglicherweise so etwas wie "Noch nicht gestartet"
Carlos P

1
obwohl die meisten Entwickler wahrscheinlich gesetzt CFBundleShortVersionStringund CFBundleVersionden gleichen Wert, CFBundleShortVersionStringist eigentlich das, was Apple will Sie prüfen , veröffentlicht Version , die wäre, was Sie für die Nutzer zeigen. CFBundleVersionMöglicherweise handelt es sich um eine interne Versionsnummer, die Sie Benutzern wahrscheinlich nicht anzeigen sollten (sofern diese unterschiedlich ist).
Nate

3
Vermisse ich etwas Dies ist genau das, was ich tue, aber der Wert wird nicht geändert. Verwendet ihr keine Title-Eigenschaft, von der ich glaube, dass sie schreibgeschützt ist?
Samson

2
Es gibt auch ein anderes Problem beim Aktualisieren der Anwendung. Das Einstellungspaket zeigt weiterhin die alte Build-Version an, bis die aktualisierte Anwendung mindestens einmal gestartet wird.
Legoless

59

Basierend auf der Antwort von @ Quinn, hier der vollständige Prozess und Arbeitscode, den ich dazu verwende.

  • Fügen Sie Ihrer App ein Einstellungspaket hinzu. Benennen Sie es nicht um.
  • Öffnen Sie Settings.bundle / Root.plist in einem Texteditor

Ersetzen Sie den Inhalt durch:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"     "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>PreferenceSpecifiers</key>
    <array>
        <dict>
            <key>Title</key>
            <string>About</string>
            <key>Type</key>
            <string>PSGroupSpecifier</string>
        </dict>
        <dict>
            <key>DefaultValue</key>
            <string>DummyVersion</string>
            <key>Key</key>
            <string>version_preference</string>
            <key>Title</key>
            <string>Version</string>
            <key>Type</key>
            <string>PSTitleValueSpecifier</string>
        </dict>
    </array>
    <key>StringsTable</key>
    <string>Root</string>
</dict>
</plist>
  • Erstellen Sie eine Run Script- Erstellungsphase und verschieben Sie diese nach der Phase " Cople Bundle Resources" . Fügen Sie diesen Code hinzu:

    cd "${BUILT_PRODUCTS_DIR}"
    buildVersion=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "${INFOPLIST_PATH}" )
    /usr/libexec/PlistBuddy -c "Set PreferenceSpecifiers:1:DefaultValue $buildVersion" "${WRAPPER_NAME}/Settings.bundle/Root.plist"
  • Ersetzen Sie MyAppName durch den Namen Ihrer tatsächlichen App und die 1 nach PreferenceSpecifiers als Index für Ihren Versionseintrag in den Einstellungen. Das obige Root.plist-Beispiel hat es bei Index 1.


Ich denke, das ist der beste Weg
Tony

Ich habe dies versucht und sehe, dass sich der Titelwert in meinem Einstellungspaket ändert. Der Titel wird in InAppSettingsKit angezeigt, der Wert ändert sich jedoch nicht gegenüber der ursprünglichen Version. Der Titel wird in der App Einstellungen nie angezeigt. Ich gebe auf und werde nur einen Dialog
öffnen,

Bei Verwendung dieser Methode ist die Einstellung nicht schreibgeschützt. dh ich kann auf die Versionsnummerneinstellung in der settings.app tippen und sie kann bearbeitet werden.
Motionpotion

8
Das Bash-Skript @ Ben-Clayton Put hat bei mir nicht funktioniert, daher habe ich es basierend auf seiner Antwort neu erstellt. Hier ist es:buildVersion=$(/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${PROJECT_DIR}/${INFOPLIST_FILE}") /usr/libexec/PlistBuddy -c "Set PreferenceSpecifiers:3:DefaultValue $buildVersion" "${SRCROOT}/Settings.bundle/Root.plist"
Luis Ascorbe

1
Sie können ${INFOPLIST_PATH}für den Info-Plist-Pfad verwenden
Tomer Even

22

Verwenden der Plist von Ben Clayton https://stackoverflow.com/a/12842530/338986

Fügen Sie Run scriptmit folgendem Snippet nach hinzu Copy Bundle Resources.

version=$(/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "$PROJECT_DIR/$INFOPLIST_FILE")
build=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "$PROJECT_DIR/$INFOPLIST_FILE")
/usr/libexec/PlistBuddy -c "Set PreferenceSpecifiers:1:DefaultValue $version ($build)" "$CODESIGNING_FOLDER_PATH/Settings.bundle/Root.plist"

Anhängen CFBundleVersionzusätzlich zu CFBundleShortVersionString. Es gibt eine Version wie diese aus:

Durch das Schreiben an $CODESIGNING_FOLDER_PATH/Settings.bundle/Root.plist anstelle desjenigen in $SRCROOThaben einige Vorteile.

  1. Dateien in der Arbeitskopie des Repositorys werden nicht geändert.
  2. Sie müssen nicht zu Fall Pfad zu müssen Settings.bundlein $SRCROOT. Der Pfad kann variieren.

Testen mit Xcode 7.3.1


1
Dies ist die beste Antwort IMO, wenn Sie das Skript zum Abschnitt Erstellen, Voraktionen des Projektschemas hinzufügen. Schau dir Andys Antwort an.
Vahid Amiri

1
Das funktioniert bei mir. Denken Sie daran, "DefaultValue" so zu ändern, dass es für Sie spezifisch ist. Zum Beispiel wollte ich die Fußzeile ändern, also habe ich "FooterText" verwendet. Sie müssen auch die Nummer nach "PreferenceSpecifiers" ändern, damit sie mit dem Element in der Liste korreliert.
Richard Witherspoon

12

Anhand des Beispiels hier ist das Skript, mit dem ich die Versionsnummer des Einstellungspakets automatisch aktualisiere:

#! /usr/bin/env python
import os
from AppKit import NSMutableDictionary

settings_file_path = 'Settings.bundle/Root.plist' # the relative path from the project folder to your settings bundle
settings_key = 'version_preference' # the key of your settings version

# these are used for testing only
info_path = '/Users/mrwalker/developer/My_App/Info.plist'
settings_path = '/Users/mrwalker/developer/My_App/Settings.bundle/Root.plist'

# these environment variables are set in the XCode build phase
if 'PRODUCT_SETTINGS_PATH' in os.environ.keys():
    info_path = os.environ.get('PRODUCT_SETTINGS_PATH')

if 'PROJECT_DIR' in os.environ.keys():
    settings_path = os.path.join(os.environ.get('PROJECT_DIR'), settings_file_path)

# reading info.plist file
project_plist = NSMutableDictionary.dictionaryWithContentsOfFile_(info_path)
project_bundle_version = project_plist['CFBundleVersion']

# print 'project_bundle_version: '+project_bundle_version

# reading settings plist
settings_plist = NSMutableDictionary.dictionaryWithContentsOfFile_(settings_path)
  for dictionary in settings_plist['PreferenceSpecifiers']:
    if 'Key' in dictionary and dictionary['Key'] == settings_key:
        dictionary['DefaultValue'] = project_bundle_version

# print repr(settings_plist)
settings_plist.writeToFile_atomically_(settings_path, True)

Hier ist die Root.plist, die ich in Settings.bundle habe:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>PreferenceSpecifiers</key>
    <array>
        <dict>
            <key>Title</key>
            <string>About</string>
            <key>Type</key>
            <string>PSGroupSpecifier</string>
        </dict>
        <dict>
            <key>DefaultValue</key>
            <string>1.0.0.0</string>
            <key>Key</key>
            <string>version_preference</string>
            <key>Title</key>
            <string>Version</string>
            <key>Type</key>
            <string>PSTitleValueSpecifier</string>
        </dict>
    </array>
    <key>StringsTable</key>
    <string>Root</string>
</dict>
</plist>

Sehr nützlich - Ich habe Probleme beim Ausführen von PlistBuddy aus Python, und ich hätte nie daran gedacht, es zu verwenden NSDictionary(und wusste auch nicht, dass es Ihnen einen so einfachen Zugriff auf Plist-Dateien ermöglicht)
Dov

Danke dafür. Eine Änderung - wie Sie sie jetzt haben - ändert die Quelle und nicht das Build-Verzeichnis. Dies bedeutet, dass das, was Sie auf Ihrem Gerät oder im Simulator sehen, immer eine Build-Version hinter der tatsächlichen Build-Version ist. Um dies zu beheben, habe ich Ihr Skript so geändert, dass es zuerst über die Quelle und dann auch über das Build-Verzeichnis iteriert, d. H. settings_path_build = os.path.join (os.environ.get ('TARGET_BUILD_DIR'), settings_file_path_build)
xaphod

... und außerdem füge ich den Githash hinzu:gitHash = subprocess.check_output(["git", "rev-parse", "--short", "HEAD"]).rstrip()
Xaphod

8

Die anderen Antworten funktionieren aus einem Grund nicht richtig: Die Erstellungsphase des ausgeführten Skripts wird erst ausgeführt, nachdem das Einstellungspaket gepackt wurde. Wenn Ihre Info.plist-Version 2.0.11 ist und Sie sie auf 2.0.12 aktualisieren und dann Ihr Projekt erstellen / archivieren, wird im Einstellungspaket weiterhin 2.0.11 angezeigt. Wenn Sie das Einstellungspaket Root.plist öffnen, können Sie sehen, dass die Versionsnummer erst am Ende des Erstellungsprozesses aktualisiert wird. Sie können das Projekt WIEDER erstellen, um das Einstellungspaket korrekt zu aktualisieren, oder Sie können das Skript stattdessen einer Vorbereitungsphase hinzufügen ...

  • Bearbeiten Sie in XCode das Schema für Ihr Projektziel
  • Klicken Sie im BUILD-Schema auf den Offenlegungspfeil
  • Klicken Sie dann auf den Punkt "Voraktionen"
  • Klicken Sie auf das Pluszeichen und wählen Sie "New Run Script Action".
  • Setzen Sie den Shell-Wert auf / bin / sh
  • Stellen Sie "Projekteinstellungen bereitstellen von" auf Ihr Projektziel ein
  • Fügen Sie Ihr Skript zum Textbereich hinzu. Das folgende Skript hat bei mir funktioniert. Möglicherweise müssen Sie die Pfade an Ihr Projekt-Setup anpassen:

    versionString = $ (/ usr / libexec / PlistBuddy -c "CFBundleVersion drucken" "$ {PROJECT_DIR} / $ {INFOPLIST_FILE}")

    / usr / libexec / PlistBuddy "$ SRCROOT / Settings.bundle / Root.plist" -c "setzt PreferenceSpecifiers: 0: DefaultValue $ versionString"

Dadurch wird das Skript korrekt ausgeführt, BEVOR das Einstellungspaket während des Erstellungs- / Archivierungsprozesses gepackt wird. Wenn Sie das Einstellungspaket Root.plist öffnen und Ihr Projekt erstellen / archivieren, wird jetzt die Versionsnummer zu Beginn des Erstellungsprozesses aktualisiert und in Ihrem Einstellungspaket wird die richtige Version angezeigt.


Vielen Dank, nur Ihre Lösung zeigt die richtige Build-Version. Andere Lösungen müssen zweimal erstellt werden.
Boris Y.

Dies erforderte noch einen zweiten Build für mich mit Xcode 10.0
Patrick

@Patrick Die iOS-Einstellungs-App behält manchmal alte Informationen bei. Um die Änderung zu sehen, müssen Sie die Einstellungen-App beenden und neu starten.
Andy

1
Übrigens habe ich einen einfacheren Weg gefunden, dieses Skript hinzuzufügen: Gehen Sie zur Registerkarte Build-Phasen Ihres Projektziels und klicken Sie auf das Symbol "+". Wählen Sie "New Run Script Phase" und fügen Sie dort den Skriptcode hinzu. Dies ist der Schlüssel: Klicken Sie auf das neue Ausführungsskript und ziehen Sie es an den Anfang der Liste der Erstellungsphasen unter Zielabhängigkeiten, jedoch vor dem Kompilieren von Quellen. Dies verhält sich wie ein Pre-Build-Skript und ist leichter zu finden.
Andy

Dank @Andy hat Ihre Lösung zum Hinzufügen zur Registerkarte "Build-Phasen" perfekt funktioniert.
Patrick

4

Mit Xcode 11.4 können Sie die folgenden Schritte ausführen, um die App-Version im Einstellungspaket Ihrer Anwendung anzuzeigen.


Menge $(MARKETING_VERSION)und $(CURRENT_PROJECT_VERSION)Variablen

Hinweis: Wenn $(MARKETING_VERSION)und $(CURRENT_PROJECT_VERSION)Variablen für Bundle version string (short)und Bundle versionSchlüssel in Info.plist angezeigt werden , können Sie die folgenden Schritte überspringen und zum nächsten Abschnitt springen.

  1. Öffnen Sie das Xcode-Projekt.
  2. Öffnen Sie den Projektnavigator ( cmd1), wählen Sie Ihr Projekt aus, um die Einstellungen Ihres Projekts anzuzeigen, und wählen Sie dann das App-Ziel aus.
  3. Wählen Sie die Registerkarte Allgemein .
  4. Im Identität Abschnitt, die ändern Version Feldinhalt zu einem gewissen neuen Wert (zB 0.1.0) und die Änderung des Aufbaus Inhaltsfeld zu einem gewissen neuen Wert (zB 12). Diese beiden Änderungen erstellen $(MARKETING_VERSION)und $(CURRENT_PROJECT_VERSION)Variablen in der Datei Info.plist .

Erstellen und konfigurieren Sie das Einstellungspaket

  1. Im Projekt - Navigator , wählen Sie Ihr Projekt.
  2. Wählen Sie Datei > Neu > Datei… ( cmdN).
  3. Wählen Sie die Registerkarte iOS .
  4. Wählen Sie im Abschnitt Ressource die Option Einstellungspaket aus , klicken Sie auf Weiter und dann auf Erstellen .
  5. Wählen Sie Root.plist und öffnen Sie es als Quellcode. Ersetzen Sie den Inhalt durch den folgenden Code:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>PreferenceSpecifiers</key>
    <array>
        <dict>
            <key>DefaultValue</key>
            <string></string>
            <key>Key</key>
            <string>version_preference</string>
            <key>Title</key>
            <string>Version</string>
            <key>Type</key>
            <string>PSTitleValueSpecifier</string>
        </dict>
    </array>
    <key>StringsTable</key>
    <string>Root</string>
</dict>
</plist>

Fügen Sie ein Ausführungsskript hinzu

  1. Im Projekt - Navigator , wählen Sie Ihr Projekt.
  2. Wählen Sie das App-Ziel aus.
  3. Wählen Sie die Registerkarte Build-Phasen .
  4. Klicken Sie auf + > New Run Script Phase .
  5. Ziehen Sie die neue Phase per Drag & Drop über den Abschnitt " Bundle-Ressourcen kopieren ". Auf diese Weise wird das Skript vor dem Kompilieren der Anwendung ausgeführt.
  6. Öffnen Sie die neu hinzugefügte Phase " Skript ausführen" und fügen Sie das folgende Skript hinzu:
version="$MARKETING_VERSION"
build="$CURRENT_PROJECT_VERSION"
/usr/libexec/PlistBuddy -c "Set PreferenceSpecifiers:0:DefaultValue $version ($build)" "${SRCROOT}/Settings.bundle/Root.plist"

App starten

  1. Führen Sie das Produkt ( cmdR) auf einem Gerät oder Simulator aus.
  2. Öffnen Sie auf dem Gerät oder Simulator nach dem Start der App die App Einstellungen und wählen Sie Ihre App in der Liste der Apps von Drittanbietern aus. Die Version der App sollte wie folgt angezeigt werden:


Quellen


Dies wirft einen Fehler für michSet: Entry, "PreferenceSpecifiers:0:DefaultValue", Does Not Exist
Jordan H

2
Das hat bei mir funktioniert:/usr/libexec/PlistBuddy "$SRCROOT/AppName/Settings.bundle/Root.plist" -c "set PreferenceSpecifiers:0:DefaultValue $version"
Jordan H

Vielen Dank. Das ist was für eine Welt für mich. Aber meine hieß Settings-Watch.bundle und entfernte die($build)
Kurt Lane

3

Mit dem Open-Source-Projekt pListcompiler ( http://sourceforge.net/projects/plistcompiler ) konnte ich das tun, was ich wollte .

  1. Mit diesem Compiler können Sie die Eigenschaftendatei in eine .plc-Datei im folgenden Format schreiben:

    plist {
        dictionary {
            key "StringsTable" value string "Root"
            key "PreferenceSpecifiers" value array [
                dictionary {
                    key "Type" value string "PSGroupSpecifier"
                    key "Title" value string "AboutSection"
                }
                dictionary {
                    key "Type" value string "PSTitleValueSpecifier"
                    key "Title" value string "Version"
                    key "Key" value string "version"
                    key "DefaultValue" value string "VersionValue"
                    key "Values" value array [
                        string "VersionValue"
                    ]
                    key "Titles" value array [
                        string "r" kRevisionNumber
                    ]
                }
            ]
        }
    }
  2. Ich hatte eine eigene Skript BUILD - Phase ausführen , die meine Repository - Revision zu .h - Datei wurde extra wie brad-Larson beschrieben hier .

  3. Die plc-Datei kann Präprozessoranweisungen wie #define, #message, #if, #elif, #include, #warning, #ifdef, #else, #pragma, #error, #ifndef, #endif, xcode-Umgebungsvariablen enthalten. So konnte ich auf die Variable kRevisionNumber verweisen, indem ich die folgende Direktive hinzufügte

    #include "Revision.h"
  4. Ich habe meinem xcode-Ziel auch eine benutzerdefinierte Skript-Erstellungsphase hinzugefügt, um den plcompiler jedes Mal auszuführen, wenn das Projekt erstellt wird

    /usr/local/plistcompiler0.6/plcompile -dest Settings.bundle -o Root.plist Settings.plc

Und das war es!


Das klingt nach viel Arbeit, nur um einen einzelnen Wert in einer Plist-Datei zu ersetzen ... Es ist konzeptionell cool, beim Erstellen einer Plist auf eine Variable zugreifen zu können, aber es ist viel einfacher, ein Tool zu verwenden, das für eine Plist-Datei erstellt wird. Ich beschreibe PlistBuddy in meiner Antwort - probieren Sie es aus!
Quinn Taylor

3

Mein Arbeitsbeispiel basiert auf der Antwort von @Ben Clayton und den Kommentaren von @Luis Ascorbe und @Vahid Amiri:

Hinweis: Dieser Ansatz ändert die Datei Settings.bundle / Root.plist in der Arbeitskopie des Repositorys

  1. Fügen Sie Ihrem Projektstamm ein Einstellungspaket hinzu. Benennen Sie es nicht um

  2. Öffnen Sie Settings.bundle / Root.plist als SourceCode

    Ersetzen Sie den Inhalt durch:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
        <key>PreferenceSpecifiers</key>
        <array>
            <dict>
                <key>DefaultValue</key>
                <string></string>
                <key>Key</key>
                <string>version_preference</string>
                <key>Title</key>
                <string>Version</string>
                <key>Type</key>
                <string>PSTitleValueSpecifier</string>
            </dict>
        </array>
        <key>StringsTable</key>
        <string>Root</string>
    </dict>
    </plist>
  3. Fügen Sie dem Abschnitt Erstellen, Voraktionen des Projektschemas (Zielschemas) das folgende Skript hinzu

    version=$(/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "$PROJECT_DIR/$INFOPLIST_FILE")
    build=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "$PROJECT_DIR/$INFOPLIST_FILE")
    
    /usr/libexec/PlistBuddy -c "Set PreferenceSpecifiers:0:DefaultValue $version ($build)" "${SRCROOT}/Settings.bundle/Root.plist"
  4. Erstellen Sie das aktuelle Schema und führen Sie es aus


2

Die obigen Antworten haben bei mir nicht funktioniert, daher habe ich mein benutzerdefiniertes Skript erstellt.

Dadurch wird der Eintrag aus Root.plist dynamisch aktualisiert

Verwenden Sie unten das Ausführungsskript. Wir werden sicher in xcode 10.3 verifiziert arbeiten.

"var buildVersion" ist die Version, die im Titel angezeigt werden soll.

Der Name der Kennung lautet "var version" unten für den Titel in settings.bundle Root.plist

cd "${BUILT_PRODUCTS_DIR}"

#set version name to your title identifier's string from settings.bundle
var version = "Version"

#this will be the text displayed in title
longVersion=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "${INFOPLIST_PATH}")
shortVersion=$(/usr/libexec/PlistBuddy -c "Print :CFBundleShortVersionString" ${TARGET_BUILD_DIR}/${INFOPLIST_PATH})
buildVersion="$shortVersion.$longVersion"

path="${WRAPPER_NAME}/Settings.bundle/Root.plist"

settingsCnt=`/usr/libexec/PlistBuddy -c "Print PreferenceSpecifiers:" ${path} | grep "Dict"|wc -l`

for (( idx=0; idx<$settingsCnt; idx++ ))
do
#echo "Welcome $idx times"
val=`/usr/libexec/PlistBuddy -c "Print PreferenceSpecifiers:${idx}:Key" ${path}`
#echo $val

#if ( "$val" == "Version" )
if [ $val == "Version" ]
then
#echo "the index of the entry whose 'Key' is 'version' is $idx."

# now set it
/usr/libexec/PlistBuddy -c "Set PreferenceSpecifiers:${idx}:DefaultValue $buildVersion" $path

# just to be sure that it worked
ver=`/usr/libexec/PlistBuddy -c "Print PreferenceSpecifiers:${idx}:DefaultValue" $path`
#echo 'PreferenceSpecifiers:$idx:DefaultValue set to: ' $ver

fi

done

Beispieleintrag in Root.plist

    <dict>
        <key>Type</key>
        <string>PSTitleValueSpecifier</string>
        <key>Title</key>
        <string>Version</string>
        <key>DefaultValue</key>
        <string>We Rock</string>
        <key>Key</key>
        <string>Version</string>
    </dict>

Arbeitsbeispiel Root.plist-Eintrag


1

Ich glaube, Sie können dies auf eine Weise tun, die der Beschreibung in dieser Antwort (basierend auf diesem Beitrag ) ähnelt .

Zunächst können Sie VersionValue zu einer Variablen in Xcode machen, indem Sie sie in $ {VERSIONVALUE} umbenennen. Erstellen Sie eine Datei mit dem Namen versionvalue.xcconfig und fügen Sie sie Ihrem Projekt hinzu. Gehen Sie zu Ihrem Anwendungsziel und gehen Sie zu den Build-Einstellungen für dieses Ziel. Ich glaube, dass Sie VERSIONVALUE als benutzerdefinierte Build-Einstellung hinzufügen müssen. Ändern Sie in der unteren rechten Ecke dieses Fensters den Wert "Basierend auf" in "Versionswert".

Gehen Sie schließlich zu Ihrem Ziel und erstellen Sie eine Run Script Build-Phase. Überprüfen Sie die Phase "Skript ausführen" und fügen Sie sie in das Skriptfeld "Skript" ein. Mein Skript zum Kennzeichnen meiner BUILD_NUMBER-Einstellung mit dem aktuellen Subversion-Build lautet beispielsweise wie folgt:

REV=`/usr/bin/svnversion -nc ${PROJECT_DIR} | /usr/bin/sed -e 's/^[^:]*://;s/[A-Za-z]//'`
echo "BUILD_NUMBER = $REV" > ${PROJECT_DIR}/buildnumber.xcconfig

Dies sollte den Trick machen, die Variable zu ersetzen, wenn sich diese Werte in Ihrem Projekt ändern.


Dies funktioniert, wenn ich die Versionsnummer in die Datei Info.plist einbetten möchte. Aber ich kann es nicht für andere Plist-Dateien zum Laufen bringen, zum Beispiel für die Root.plist-Datei, die sich in der Settings.bundle befindet. Gibt es eine Build-Einstellung, mit der ich dies aktivieren kann?
Panagiotis Korros

0

Für mich war dies die einfachste Lösung:

Fügen Sie vor dem Schritt "Bundle-Ressourcen kopieren" eine neue Phase zum Erstellen von Skripten hinzu

Schale: /usr/bin/env python

Inhalt:

#! /usr/bin/env python
import os
from AppKit import NSMutableDictionary

# Key to replace
settings_key = 'version_preference' # the key of your settings version

# File path
settings_path = os.environ.get('SRCROOT') + "/TheBeautifulNameOfYourOwnApp/Settings.bundle/Root.plist"

# Composing version string
version_string = os.environ.get('MARKETING_VERSION') + " (" + os.environ.get('CURRENT_PROJECT_VERSION') + ")"

# Reading settings plist
settings_plist = NSMutableDictionary.dictionaryWithContentsOfFile_(settings_path)
for dictionary in settings_plist['PreferenceSpecifiers']:
    if 'Key' in dictionary and dictionary['Key'] == settings_key:
        dictionary['DefaultValue'] = version_string

# Save new settings
settings_plist.writeToFile_atomically_(settings_path, True)
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.