Come impedire a Xcode 11 di modificare CFBundleVersion e CFBundleShortVersionString in $ (CURRENT_PROJECT_VERSION) e $ (MARKETING_VERSION)?


14

Dalla versione 11, Xcode imposta il mio CFBundleVersionvalore su $(CURRENT_PROJECT_VERSION)e il mio CFBundleShortVersionStringvalore $(MARKETING_VERSION)ogni volta che inserisco i valori Versione o Build nelle impostazioni di destinazione (scheda "Generale").

La versione effettiva e i valori di build che inserisco sono ora memorizzati nel file project.pbxproj. Non voglio o mi piace questo comportamento, poiché utilizzo gli script di shell per modificare i valori in fase di compilazione.

Posso impostare manualmente i valori corretti nel file Info.plist, ma non appena cambio i numeri Versione o Build nelle impostazioni di destinazione, il file Info.plist viene nuovamente modificato da Xcode.

Come posso impedire a Xcode 11 di farlo?

Quando modifico il mio script di build per modificare il file di progetto stesso, Xcode annulla immediatamente la build non appena il file di progetto viene modificato.


Perché vorresti che Xcode 11 smettesse di farlo, invece di modificare lo script della shell per recuperare il valore?
Manuel,

1
@Manuel Penso che modificare un plist usando plistbuddysia piacevole e pulito, mentre modificare il file di progetto è molto più disordinato, inaffidabile e incline a cambiamenti inattesi nel formato del file.
Mr. Zystem,

1
La manipolazione del file project.pbxproj non è disordinata quando si comprende il formato del file. È solo un plist di stile Next ben documentato. Puoi anche modificare il file con plistbuddy, è compatibile con questo formato.
Manuel,

Ho aggiornato la mia risposta con un suggerimento per il tuo caso d'uso.
Manuel,

Risposte:


1

La strada finora

Il mio caso d'uso è stato quello:

  1. Sto sincronizzando la versione e costruisco numeri attraverso diversi target.
  2. Sto sincronizzando la versione e costruendo i numeri con quelli del target Settigns.bundle
  3. Sto leggendo e modificando il numero di build da un server CI.

In passato eseguivo i punti 1 e 2 come script di build di destinazione e il punto 3 come script personalizzato sull'elemento della configurazione stesso.

Il nuovo modo di archiviare la versione e la compilazione nelle impostazioni di compilazione di Xcode causava problemi con gli script, poiché non erano più in grado di modificare efficacemente i valori. Almeno la lettura era possibile.

Sfortunatamente non sono stato in grado di scoprire un modo legittimo per impedire a Xcode di archiviare la versione e creare numeri nelle impostazioni di creazione del progetto, tuttavia sono riuscito a creare una soluzione alternativa.

Si scopre che quando viene creata una build o un archivio, viene utilizzato il valore scritto in Info.plist. Ciò significa che il valore viene sostituito durante il tempo di compilazione, il che non ci consente di modificarlo durante lo stesso tempo di compilazione.

Ho anche provato a modificare il progetto usando xcodeprojcli, tuttavia qualsiasi modifica al progetto stava causando l'arresto di qualsiasi build, quindi questa soluzione non funzionava.

Alla fine, dopo molti approcci diversi che ho provato, sono finalmente riuscito a trovare un compromesso che non stava violando il nuovo comportamento dell'Xcode.

Risposta breve:

Come pre-azione del bersaglio, viene eseguito uno script che scrive i rispettivi valori su CFBundleShortVersionStringe CFBundleVersionsul bersaglioInfo.plist

Come fonte di verità, utilizzo le impostazioni di build di Xcode per leggere i valori di MARKETING_VERSIONe CURRENT_PROJECT_VERSIONdel target desiderato.

In questo modo, quando modifichi i valori dalle impostazioni del progetto - al prossimo build / archivio - verranno scritti in Info.plist, consentendo a qualsiasi se la tua logica di scripting esistente continui a funzionare.

Risposta dettagliata

L'unico modo per modificare una risorsa su un'azione di compilazione è utilizzare uno pre-actionscript. Se provi a farlo da uno script di compilazione, le modifiche non avranno effetto immediato e non saranno presenti alla fine della compilazione / dell'archivio.

Per aggiungere un'azione pre-build, vai a modifica schema.

inserisci qui la descrizione dell'immagine

Quindi espandere le sezioni Build and Archive. Sotto Pre-action, fai clic sul Provide build and settings frommenu a discesa e seleziona l'origine della verità target da cui desideri leggere i valori.

inserisci qui la descrizione dell'immagine

Aggiungi il seguente script:

# 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

Le linee di script effettuano le seguenti operazioni:

  1. Vai alla directory in cui si trova lo script di sincronizzazione per eseguirlo
  2. Consente di scrivere un registro durante l'azione preliminare, altrimenti qualsiasi output viene silenziato per impostazione predefinita
  3. Eseguire lo script di sincronizzazione fornendo il MARKETING_VERSIONeCURRENT_PROJECT_VERSION

Il passaggio finale è quello di scrivere il tuo script di sincronizzazione che legge i valori del fornito MARKETING_VERSIONe CURRENT_PROJECT_VERSIONdei rispettivi target e quando lo desideri.

Nel mio caso lo script è il seguente:

#!/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

Uso condiviso Info.pliste Settings.bundletra entrambi i target delle mie app, quindi devo aggiornarlo una volta.

Inoltre, utilizzo un'estensione del servizio di notifica BadgeCounter, che deve avere la stessa versione esatta e compilare come destinazione in cui è incorporato. Quindi aggiorno anche questo.


1

Non farlo.

Presumibilmente c'è un motivo per cui questo comportamento è cambiato. Se le funzionalità Xcode successive si basano su questo comportamento, le cose diventano sempre più "costruite" lungo la linea.

Invece di provare a piegare Xcode, cambia il modo in cui lo script di build recupera questi valori:

Come leggere la versione attuale dell'app in Xcode 11 con script

Se è necessario manipolare il project.pbxprojfile, è un plist di stile Next ben documentato. Puoi usare plistbuddyquale è compatibile con questo vecchio formato. Puoi anche usare awkpiù script se hai manipolazioni più complesse.

Se capisco il tuo caso d'uso, potresti scrivere uno script che ottiene i numeri di versione più alti con awke quindi aggiorna tutti i numeri di versione inferiori che può trovare nel file con sed.


la stampa dei valori con PlistBuddy sembra funzionare bene, ma quando uso il setcomando l'intero project.pbxproj viene convertito in un file XML .plist e non può più essere letto da Xcode. esempio:PlistBuddy -c "Set :objects:$configurationId:buildSettings:CURRENT_PROJECT_VERSION $newProjectVersion" "$projectFile"
Mr. Zystem

A seconda di cosa esattamente vuoi ottenere, potresti dover usare una combinazione di strumenti
Manuel,

Il riavvio di Xcode ha risolto il problema XML. Als ha scoperto che quando si esegue uno script di build che modifica il pbxprojfile verrà annullata la build. Quindi questo non funzionerà davvero, temo.
Mr. Zystem,

Ho aggiornato la mia domanda originale con le informazioni sopra.
Mr. Zystem,

1
Ad esempio - il mio caso d'uso è sincronizzare la versione e costruire su più target - vorrei impostare la versione e costruire sul primo target e questo si aggiorna automaticamente a tutti gli altri. Funzionava bene prima, perché hai appena modificato una risorsa. Ora non riesco a modificare il progetto durante la fase di compilazione di alcun target, perché la compilazione viene annullata.
KoCMoHaBTa
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.