Me gustaría incluir la versión de la aplicación y la revisión interna, algo así como 1.0.1 (r1243), en el paquete de configuración de mi aplicación.
El archivo Root.plist contiene un fragmento como este ...
<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>
y me gustaría reemplazar la cadena "VersionValue" en el momento de la compilación.
Tengo un script que puede extraer el número de versión de mi repositorio, lo que necesito es una forma de procesar (preprocesar) el archivo Root.plist, en el momento de la compilación, y reemplazar el número de revisión sin afectar el archivo fuente.
fuente
/usr/libexec/PlistBuddy -c "Set :PreferenceSpecifiers:0:DefaultValue ${newVersion}" "${TARGET_BUILD_DIR}/${CONTENTS_FOLDER_PATH}/Settings.bundle/Root.plist"
La solución de mi vago fue actualizar el número de versión del código de mi aplicación. Podría tener un valor predeterminado (o en blanco) en Root.plist y luego, en algún lugar de su código de inicio:
NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"]; [[NSUserDefaults standardUserDefaults] setObject:version forKey:@"version_preference"];
El único inconveniente es que su aplicación tendría que ejecutarse al menos una vez para que la versión actualizada aparezca en el panel de configuración.
Puede llevar la idea más allá y actualizar, por ejemplo, un contador de cuántas veces se ha lanzado su aplicación u otra información interesante.
fuente
CFBundleShortVersionString
yCFBundleVersion
con el mismo valor,CFBundleShortVersionString
es en realidad lo que Apple quiere que usted considere que su lanzado la versión , que sería lo que muestran a los usuarios.CFBundleVersion
potencialmente podría ser un número de versión interno, que probablemente no debería mostrar a los usuarios (si es diferente).Según la respuesta de @ Quinn, aquí el proceso completo y el código de trabajo que utilizo para hacer esto.
Reemplaza el contenido con:
<?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>
Cree una fase de construcción de Ejecutar script , muévala después de la fase Copiar recursos del paquete . Agrega este código:
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"
Reemplace MyAppName con el nombre real de su aplicación, y el 1 después de PreferenceSpecifiers para ser el índice de su entrada de Versión en la Configuración. El ejemplo anterior de Root.plist lo tiene en el índice 1.
fuente
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}
para la ruta de información plistUsando plist de Ben Clayton https://stackoverflow.com/a/12842530/338986
Agregue
Run script
con el siguiente fragmento despuésCopy 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"
Añadiendo
CFBundleVersion
además deCFBundleShortVersionString
. Emite una versión como esta:Escribiendo a en
$CODESIGNING_FOLDER_PATH/Settings.bundle/Root.plist
lugar de uno en$SRCROOT
tiene algunos beneficios.Settings.bundle
en$SRCROOT
. El camino puede variar.Prueba en Xcode 7.3.1
fuente
Según el ejemplo aquí , aquí está el script que estoy usando para actualizar automáticamente el número de versión del paquete de configuración:
#! /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)
Aquí está el Root.plist que tengo en 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>
fuente
NSDictionary
(y tampoco me di cuenta de que le brindaba un acceso tan fácil a los archivos plist)gitHash = subprocess.check_output(["git", "rev-parse", "--short", "HEAD"]).rstrip()
Las otras respuestas no funcionan correctamente por una razón: la fase de ejecución del script no se ejecuta hasta DESPUÉS de que se haya empaquetado el paquete de configuración. Por lo tanto, si su versión de Info.plist es 2.0.11 y la actualiza a 2.0.12, luego compile / archive su proyecto, el paquete de Configuración seguirá diciendo 2.0.11. Si abre el paquete de configuración Root.plist, puede ver que el número de versión no se actualiza hasta el FINAL del proceso de compilación. Puede compilar el proyecto OTRA VEZ para actualizar correctamente el paquete de configuración, o puede agregar el script a una fase previa a la compilación en su lugar ...
Agregue su secuencia de comandos al área de texto. El siguiente guión funcionó para mí. Es posible que deba modificar las rutas para que coincidan con la configuración de su proyecto:
versionString = $ (/ usr / libexec / PlistBuddy -c "Imprimir CFBundleVersion" "$ {PROJECT_DIR} / $ {INFOPLIST_FILE}")
/ usr / libexec / PlistBuddy "$ SRCROOT / Settings.bundle / Root.plist" -c "set PreferenceSpecifiers: 0: DefaultValue $ versionString"
Esto ejecutará correctamente el script ANTES de empaquetar el paquete de configuración durante el proceso de compilación / archivo. Si abre el paquete de configuración Root.plist y compila / archiva su proyecto, ahora verá que el número de versión se actualiza al comienzo del proceso de compilación y su paquete de configuración mostrará la versión correcta.
fuente
Con Xcode 11.4, puede utilizar los siguientes pasos para mostrar la versión de la aplicación en el paquete de configuración de su aplicación.
Conjunto
$(MARKETING_VERSION)
y$(CURRENT_PROJECT_VERSION)
variablesNota: si las variables
$(MARKETING_VERSION)
y$(CURRENT_PROJECT_VERSION)
aparecen para las teclasBundle version string (short)
yBundle version
en Info.plist , puede omitir los siguientes pasos y pasar a la siguiente sección.0.1.0
. Ej. ) Y cambie el contenido del campo Construir a algún valor nuevo (p12
. Ej .). Estos 2 cambios crearán$(MARKETING_VERSION)
y$(CURRENT_PROJECT_VERSION)
variables en el archivo Info.plist .Crear y configurar el paquete de ajustes
<?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>
Agregar un script de ejecución
version="$MARKETING_VERSION" build="$CURRENT_PROJECT_VERSION" /usr/libexec/PlistBuddy -c "Set PreferenceSpecifiers:0:DefaultValue $version ($build)" "${SRCROOT}/Settings.bundle/Root.plist"
Ejecutar aplicación
Fuentes
fuente
Set: Entry, "PreferenceSpecifiers:0:DefaultValue", Does Not Exist
/usr/libexec/PlistBuddy "$SRCROOT/AppName/Settings.bundle/Root.plist" -c "set PreferenceSpecifiers:0:DefaultValue $version"
($build)
Logré hacer lo que quería usando el proyecto de código abierto pListcompiler ( http://sourceforge.net/projects/plistcompiler ).
Con este compilador puede escribir el archivo de propiedades en un archivo .plc usando el siguiente formato:
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 ] } ] } }
Tuve una fase de compilación de script de ejecución personalizada que extraía la revisión de mi repositorio al archivo .h como lo describe brad-larson aquí .
El archivo plc puede contener directivas de preprocesador, como #define, #message, #if, #elif, #include, #warning, #ifdef, #else, #pragma, #error, #ifndef, #endif, xcode variables de entorno. Entonces pude hacer referencia a la variable kRevisionNumber agregando la siguiente directiva
#include "Revision.h"
También agregué una fase de compilación de script personalizado a mi destino xcode para ejecutar el compilador plcompiler cada vez que el proyecto se está compilando
/usr/local/plistcompiler0.6/plcompile -dest Settings.bundle -o Root.plist Settings.plc
¡Y eso fue todo!
fuente
Mi ejemplo de trabajo basado en la respuesta de @Ben Clayton y los comentarios de @Luis Ascorbe y @Vahid Amiri:
Agregue un paquete de configuración a la raíz de su proyecto. No le cambie el nombre
Abra Settings.bundle / Root.plist como SourceCode
Reemplaza el contenido con:
<?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>
Agregue la siguiente secuencia de comandos a la sección Compilación, acciones previas del esquema del proyecto (objetivo)
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"
Construye y ejecuta el esquema actual
fuente
Las respuestas anteriores no funcionaron para mí, por lo tanto, creé mi script personalizado.
Esto actualiza dinámicamente la entrada de Root.plist
Utilice ejecutar el script a continuación. Funcionará con seguridad verificado en xcode 10.3.
"var buildVersion" es la versión que se mostrará en el título.
Y el nombre del identificador es "versión var" a continuación para el título en 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
Entrada de ejemplo en 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>
fuente
Creo que puede hacer esto de una manera similar a la que describo en esta respuesta (basada en esta publicación ).
Primero, puede hacer de VersionValue una variable dentro de Xcode cambiándola de nombre a $ {VERSIONVALUE}. Cree un archivo llamado versionvalue.xcconfig y agréguelo a su proyecto. Vaya al destino de su aplicación y vaya a la configuración de compilación para ese destino. Creo que debe agregar VERSIONVALUE como configuración de compilación definida por el usuario. En la esquina inferior derecha de esa ventana, cambie el valor Basado en a "versionvalue".
Finalmente, vaya a su objetivo y cree una fase de construcción Ejecutar script. Inspeccione la fase Ejecutar script y pegue su script dentro del campo de texto Script. Por ejemplo, mi secuencia de comandos para etiquetar mi configuración BUILD_NUMBER con la compilación actual de Subversion es la siguiente:
REV=`/usr/bin/svnversion -nc ${PROJECT_DIR} | /usr/bin/sed -e 's/^[^:]*://;s/[A-Za-z]//'` echo "BUILD_NUMBER = $REV" > ${PROJECT_DIR}/buildnumber.xcconfig
Esto debería hacer el truco de reemplazar la variable cuando estos valores cambian dentro de su proyecto.
fuente
Para mí, esta fue la solución más fácil:
Agregue una nueva fase de compilación del script antes del paso Copiar recursos del paquete
Cáscara:
/usr/bin/env python
Contenido:
#! /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)
fuente