Droga do tej pory
Mój przypadek użycia był taki:
- Synchronizuję wersję i numery wersji między kilkoma celami.
- Synchronizuję wersję i numery kompilacji z celami
Settigns.bundle
- Czytam i modyfikuję numer kompilacji z serwera CI.
Kiedyś wykonywałem punkt 1 i 2 jako docelowy skrypt kompilacji, a punkt 3 jako skrypt niestandardowy w samym CI.
Nowy sposób przechowywania wersji i kompilacji w ustawieniach kompilacji Xcode powodował problemy ze skryptami, ponieważ nie były one już w stanie skutecznie modyfikować wartości. Możliwe było przynajmniej czytanie.
Niestety nie byłem w stanie odkryć prawidłowego sposobu zapobiegania przechowywaniu przez Xcode wersji i numerów kompilacji w ustawieniach kompilacji projektu, jednak udało mi się stworzyć obejście.
Okazuje się, że przy tworzeniu kompilacji lub archiwum Info.plist
używana jest wartość zapisana w . Oznacza to, że wartość jest zastępowana w czasie kompilacji, co nie pozwala nam jej modyfikować w tym samym czasie kompilacji.
Próbowałem również zmodyfikować projekt przy użyciu xcodeproj
cli, jednak wszelkie zmiany w projekcie powodowały zatrzymanie wszelkich kompilacji, więc to rozwiązanie nie działało.
W końcu, po wielu różnych podejściach, które wypróbowałem, w końcu udało mi się znaleźć kompromis, który nie naruszał nowego zachowania Xcode.
Krótka odpowiedź:
Jako cel przed działaniem wykonywany jest skrypt, który zapisuje odpowiednie wartości do CFBundleShortVersionString
i CFBundleVersion
do celuInfo.plist
Jako źródło prawdy używam ustawień kompilacji Xcode do odczytywania wartości MARKETING_VERSION
i CURRENT_PROJECT_VERSION
pożądanego celu.
W ten sposób, gdy zmodyfikujesz wartości z ustawień projektu - przy następnym kompilacji / archiwum - zostaną one zapisane w Info.plist
, pozwalając na dowolne, jeśli twoja logika skryptowa będzie dalej działać.
Szczegółowa odpowiedź
Jedynym sposobem modyfikacji zasobu po akcji kompilacji jest użycie pre-action
skryptu. Jeśli spróbujesz to zrobić ze skryptu kompilacji - zmiany nie zostaną zastosowane natychmiast i nie będą obecne na końcu kompilacji / archiwum.
Aby dodać akcję przed kompilacją - przejdź do schematu edycji.
Następnie rozwiń sekcje Kompilacja i Archiwum. Poniżej Pre-action
kliknij Provide build and settings from
menu rozwijane i wybierz źródło prawdy, z którego chcesz odczytać wartości.
Dodaj następujący skrypt:
# 1)
cd ${PROJECT_DIR}
# 2)
exec > Pruvit-Int.prebuild.sync_project_version_and_build_with_info_plists.log 2>&1
# 3)
./sync_project_version_and_build_with_info_plists.sh $MARKETING_VERSION $CURRENT_PROJECT_VERSION
Linie kreski wykonują następujące czynności:
- Przejdź do katalogu, w którym znajduje się skrypt synchronizacji, aby go wykonać
- Pozwala na zapisanie dziennika podczas akcji wstępnej, w przeciwnym razie dane wyjściowe są domyślnie wyciszane
- Uruchom skrypt synchronizacji, podając
MARKETING_VERSION
iCURRENT_PROJECT_VERSION
Ostatnim krokiem jest napisanie własnego skryptu synchronizacji, który odczytuje wartości podanego MARKETING_VERSION
i CURRENT_PROJECT_VERSION
odpowiedniego celu / ów i kiedy tylko chcesz.
W moim przypadku skrypt jest następujący:
#!/bin/bash
#IMPORTANT - this script must run as pre-action of each target's Build and Archive actions
version_number=$1
build_number=$2
echo "version_number is $version_number"
echo "build_number is $build_number"
#update Pruvit/Info.plist
pruvitInfoPlist="Pruvit/Info.plist"
/usr/libexec/PlistBuddy -c "Set CFBundleShortVersionString $version_number" $pruvitInfoPlist
/usr/libexec/PlistBuddy -c "Set CFBundleVersion $build_number" $pruvitInfoPlist
#update Pruvit/Settings.bundle
settingsPlist="Pruvit/Settings.bundle/Root.plist"
/usr/libexec/PlistBuddy -c "Set PreferenceSpecifiers:0:DefaultValue $version_number" $settingsPlist
/usr/libexec/PlistBuddy -c "Set PreferenceSpecifiers:1:DefaultValue $build_number" $settingsPlist
#update BadgeCounter/Info.plist
badgeCounterInfoPlist="BadgeCounter/Info.plist"
/usr/libexec/PlistBuddy -c "Set CFBundleShortVersionString $version_number" $badgeCounterInfoPlist
/usr/libexec/PlistBuddy -c "Set CFBundleVersion $build_number" $badgeCounterInfoPlist
Używam współdzielonych Info.plist
i Settings.bundle
między dwoma celami mojej aplikacji, więc muszę to zaktualizować raz.
Używam również rozszerzenia usługi powiadomień BadgeCounter
, które musi mieć tę samą wersję i kompilację, co obiekt docelowy, w którym jest osadzone. Więc aktualizuję to również.