Chciałbym dołączyć wersję aplikacji i wewnętrzną rewizję, np. 1.0.1 (r1243), do pakietu ustawień mojej aplikacji.
Plik Root.plist zawiera taki fragment ...
<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>
i chciałbym zastąpić ciąg „VersionValue” w czasie kompilacji.
Mam skrypt, który może wyodrębnić numer wersji z mojego repozytorium, potrzebuję sposobu na przetworzenie (wstępne przetworzenie) pliku Root.plist w czasie kompilacji i zastąpienie numeru wersji bez wpływu na plik źródłowy.
źródło
/usr/libexec/PlistBuddy -c "Set :PreferenceSpecifiers:0:DefaultValue ${newVersion}" "${TARGET_BUILD_DIR}/${CONTENTS_FOLDER_PATH}/Settings.bundle/Root.plist"
Rozwiązaniem mojego leniwca było zaktualizowanie numeru wersji z kodu mojej aplikacji. Możesz mieć domyślną (lub pustą) wartość w Root.plist, a następnie gdzieś w kodzie startowym:
NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"]; [[NSUserDefaults standardUserDefaults] setObject:version forKey:@"version_preference"];
Jedyny haczyk polega na tym, że Twoja aplikacja musiałaby zostać uruchomiona co najmniej raz, aby zaktualizowana wersja pojawiła się w panelu ustawień.
Możesz pójść dalej i zaktualizować na przykład licznik, ile razy Twoja aplikacja została uruchomiona, lub inne interesujące informacje.
źródło
CFBundleShortVersionString
iCFBundleVersion
na taką samą wartość,CFBundleShortVersionString
to rzeczywiście to, co Apple chce, aby rozważyć swoją wydaną wersję , która byłaby co pokazują użytkowników.CFBundleVersion
może potencjalnie być wewnętrznym numerem wersji, którego prawdopodobnie nie powinieneś pokazywać użytkownikom (jeśli jest inny).W oparciu o odpowiedź @ Quinn, oto pełny proces i działający kod, którego używam do tego.
Zastąp zawartość:
<?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>
Utwórz fazę kompilacji Run Script , przejdź do fazy Copy Bundle Resources . Dodaj ten kod:
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"
Zastąp MyAppName rzeczywistą nazwą aplikacji i 1 po PreferenceSpecifiers, aby być indeksem wpisu wersji w Ustawieniach. Powyższy przykład Root.plist ma go pod indeksem 1.
źródło
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"
${INFOPLIST_PATH}
do ścieżki informacji plistKorzystanie z plist Bena Claytona https://stackoverflow.com/a/12842530/338986
Dodaj
Run script
z następującym fragmentem poCopy 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"
Dołączanie
CFBundleVersion
dodatkowoCFBundleShortVersionString
. Emituje wersję następującą:Pisząc do
$CODESIGNING_FOLDER_PATH/Settings.bundle/Root.plist
zamiast tego w$SRCROOT
ma pewne korzyści.Settings.bundle
w$SRCROOT
. Ścieżka może się różnić.Testowanie na Xcode 7.3.1
źródło
Opierając się na przykład tutaj , oto skrypt używam, aby automatycznie aktualizować ustawienia wiązki numer wersji:
#! /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)
Oto lista Root.plist, którą mam w Settings.bundle:
<?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>
źródło
NSDictionary
(i nie zdawałem sobie sprawy, że daje to tak łatwy dostęp do plików plist)gitHash = subprocess.check_output(["git", "rev-parse", "--short", "HEAD"]).rstrip()
Inne odpowiedzi nie działają poprawnie z jednego powodu: Faza kompilacji skryptu uruchamiania nie jest wykonywana, dopóki nie zostanie spakowany pakiet ustawień. Tak więc, jeśli twoja wersja Info.plist to 2.0.11 i zaktualizujesz ją do 2.0.12, a następnie skompiluj / zarchiwizuj swój projekt, pakiet ustawień nadal będzie zawierał 2.0.11. Jeśli otworzysz pakiet ustawień Root.plist, zobaczysz, że numer wersji nie zostanie zaktualizowany do zakończenia procesu kompilacji. Możesz skompilować projekt PONOWNIE, aby pakiet ustawień został poprawnie zaktualizowany, lub możesz zamiast tego dodać skrypt do fazy przed kompilacją ...
Dodaj swój skrypt do pola tekstowego. Poniższy skrypt zadziałał dla mnie. Może zajść potrzeba zmodyfikowania ścieżek, aby pasowały do konfiguracji projektu:
versionString = $ (/ usr / libexec / PlistBuddy -c "Print CFBundleVersion" "$ {PROJECT_DIR} / $ {INFOPLIST_FILE}")
/ usr / libexec / PlistBuddy "$ SRCROOT / Settings.bundle / Root.plist" -c "set PreferenceSpecifiers: 0: DefaultValue $ versionString"
Spowoduje to prawidłowe uruchomienie skryptu PRZED pakowaniem pakietu ustawień podczas procesu budowania / archiwizacji. Jeśli otworzysz pakiet ustawień Root.plist i skompilujesz / zarchiwizujesz swój projekt, zobaczysz teraz, że numer wersji jest aktualizowany na początku procesu kompilacji, a pakiet ustawień wyświetli poprawną wersję.
źródło
W przypadku Xcode 11.4 możesz wykonać następujące kroki, aby wyświetlić wersję aplikacji w pakiecie ustawień aplikacji.
Zbiór
$(MARKETING_VERSION)
i$(CURRENT_PROJECT_VERSION)
zmienneUwaga: jeśli zmienne
$(MARKETING_VERSION)
i$(CURRENT_PROJECT_VERSION)
pojawiają się dla kluczyBundle version string (short)
iBundle version
w Info.plist , możesz pominąć następujące kroki i przejść do następnej sekcji.0.1.0
) I zmień zawartość pola Kompilacja na jakąś nową wartość (np12
.). Te 2 zmiany będą tworzyć$(MARKETING_VERSION)
i$(CURRENT_PROJECT_VERSION)
zmienne w Info.plist pliku.Utwórz i skonfiguruj pakiet ustawień
<?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>
Dodaj skrypt uruchamiania
version="$MARKETING_VERSION" build="$CURRENT_PROJECT_VERSION" /usr/libexec/PlistBuddy -c "Set PreferenceSpecifiers:0:DefaultValue $version ($build)" "${SRCROOT}/Settings.bundle/Root.plist"
Uruchom aplikację
Źródła
źródło
Set: Entry, "PreferenceSpecifiers:0:DefaultValue", Does Not Exist
/usr/libexec/PlistBuddy "$SRCROOT/AppName/Settings.bundle/Root.plist" -c "set PreferenceSpecifiers:0:DefaultValue $version"
($build)
Udało mi się zrobić to, co chciałem, używając porject open source pListcompiler ( http://sourceforge.net/projects/plistcompiler ).
Za pomocą tego kompilatora możesz zapisać plik właściwości w pliku .plc w następującym formacie:
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 ] } ] } }
Miałem fazę budowania niestandardowego skryptu uruchamiania, która polegała na wyodrębnianiu mojej wersji repozytorium do pliku .h, jak opisał tutaj Brad-Larson .
Plik plc może zawierać dyrektywy preprocesora, takie jak #define, #message, #if, #elif, #include, #warning, #ifdef, #else, #pragma, #error, #ifndef, #endif, zmienne środowiskowe xcode. Więc mogłem odwołać się do zmiennej kRvisionNumber, dodając następującą dyrektywę
#include "Revision.h"
Dodałem również fazę kompilacji skryptu niestandardowego do mojego celu xcode, aby uruchamiać plcompiler za każdym razem, gdy projekt jest budowany
/usr/local/plistcompiler0.6/plcompile -dest Settings.bundle -o Root.plist Settings.plc
I to było to!
źródło
Mój przykład roboczy oparty na odpowiedzi @Ben Clayton i komentarzach @Luis Ascorbe i @Vahid Amiri:
Dodaj pakiet ustawień do katalogu głównego projektu. Nie zmieniaj jej nazwy
Otwórz Settings.bundle / Root.plist jako SourceCode
Zastąp zawartość:
<?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>
Dodaj następujący skrypt do sekcji Kompiluj, Działania wstępne schematu projektu (celu)
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"
Zbuduj i uruchom bieżący schemat
źródło
Powyższe odpowiedzi nie zadziałały, dlatego stworzyłem własny skrypt.
To dynamicznie aktualizuje wpis z Root.plist
Użyj skryptu uruchamiania poniżej. Na pewno będzie działać zweryfikowany w Xcode 10.3.
„var buildVersion” to wersja, która ma być wyświetlana w tytule.
A nazwa identyfikatora to „wersja zmienna” poniżej dla tytułu w 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
Przykładowy wpis w 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>
źródło
Uważam, że możesz to zrobić w sposób podobny do tego, co opisuję w tej odpowiedzi (na podstawie tego postu ).
Po pierwsze, możesz ustawić VersionValue jako zmienną w Xcode, zmieniając jej nazwę na $ {VERSIONVALUE}. Utwórz plik o nazwie versionvalue.xcconfig i dodaj go do swojego projektu. Przejdź do celu aplikacji i przejdź do ustawień kompilacji dla tego celu. Uważam, że musisz dodać VERSIONVALUE jako ustawienie kompilacji zdefiniowane przez użytkownika. W prawym dolnym rogu tego okna zmień wartość Na podstawie na „versionvalue”.
Na koniec przejdź do celu i utwórz fazę kompilacji Run Script. Sprawdź tę fazę Uruchom skrypt i wklej skrypt w polu tekstowym Skrypt. Na przykład mój skrypt oznaczający moje ustawienie BUILD_NUMBER bieżącą kompilacją Subversion wygląda następująco:
REV=`/usr/bin/svnversion -nc ${PROJECT_DIR} | /usr/bin/sed -e 's/^[^:]*://;s/[A-Za-z]//'` echo "BUILD_NUMBER = $REV" > ${PROJECT_DIR}/buildnumber.xcconfig
Powinno to załatwić sprawę polegającą na zastąpieniu zmiennej, gdy te wartości zmienią się w projekcie.
źródło
Dla mnie to było najłatwiejsze rozwiązanie:
Dodaj nową fazę kompilacji skryptu przed krokiem Kopiuj zasoby pakietu
Muszla:
/usr/bin/env python
Zadowolony:
#! /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)
źródło