Pregunta

Me gustaría incluir la versión de la aplicación y revisión interna, algo así como 1.0.1 (r1243), en la configuración de haz de mi aplicación.

El archivo contiene un fragmento Root.plist 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 tiempo de compilación.

Tengo un script que puede extraer el número de versión de mi repositorio, lo que necesito es una manera de procesar (pre-proceso) el archivo Root.plist, en tiempo de compilación, y sustituir el número de revisión sin afectar el archivo de origen .

¿Fue útil?

Solución 7

Me las arreglé para hacer lo que quería con la pListcompiler ( http://sourceforge.net/projects/plistcompiler ) Porject de código abierto.

  1. El uso de este compilador puede escribir el archivo de propiedades en un archivo del plc con 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
                    ]
                }
            ]
        }
    }
    
  2. tuve una fase de construcción script personalizado de gestión que se extraía de mi revisión del repositorio de archivos .h como se describe por Brad Larson- aquí .

  3. El archivo PLC puede contener directivas del preprocesador, como #define, #message, #if, #elif, # include, #warning, #ifdef, #else, #pragma, #error, #ifndef, #endif , variables de entorno Xcode. Así que pude hacer referencia a la variable kRevisionNumber añadiendo la siguiente directiva

    #include "Revision.h"
    
  4. También he añadido una fase de acumulación script personalizado para mi objetivo Xcode para ejecutar el plcompiler cada vez que el proyecto esta en buen estado la construcción

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

Y eso fue todo!

Otros consejos

Hay otra solución que puede ser mucho más simple que cualquiera de las respuestas anteriores. Manzana lía una herramienta de línea de comandos llamada PlistBuddy en el interior de la mayoría de sus instaladores, y lo ha incluido en Leopard en /usr/libexec/PlistBuddy.

Desde que desea reemplazar VersionValue, suponiendo que tiene el valor de versión se extrae en $newVersion, podría utilizar este comando:

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

No hay necesidad de tocar el violín con expresiones regulares o de sed, este método es bastante sencillo. Vea la página para obtener instrucciones detalladas. Puede utilizar PlistBuddy para agregar, eliminar o modificar cualquier entrada en una lista de propiedades. Por ejemplo, un amigo mío escribió sobre incrementar los números de compilación en Xcode usando PlistBuddy.

Nota: Si proporciona sólo la ruta de acceso al plist, PlistBuddy entra en modo interactivo, para que pueda emitir varios comandos antes de decidir para guardar los cambios. Sin duda, recomiendo hacer esto antes de dejarse en su escritura de la estructura.

La solución de Mi hombre perezoso fue actualizar el número de versión de mi código de la aplicación. Usted podría tener un defecto (o en blanco) en el valor 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 problema es que su aplicación tendría que ser ejecutado al menos una vez para la versión actualizada que aparezca en el panel de configuración.

Usted podría tomar la idea y actualización, por ejemplo, un contador del número de veces que su aplicación se ha puesto en marcha, u otras cosas interesantes de información.

Sobre la base de la respuesta de @ Quinn, aquí el proceso completo y el código de trabajo que utilizo para hacer esto.

  • Añadir un paquete de configuración para su aplicación. No cambie su nombre.
  • Settings.bundle Abrir / Root.plist en un editor de texto

Reemplazar 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>
  • Crear un Ejecutar script fase de construcción, pasar a ser después de la Copiar Recursos Bundle fase. Agregue 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"
    
  • Reemplazar MyAppName con el nombre de su aplicación real, y el 1 después PreferenceSpecifiers ser el índice de la entrada de la versión en la configuración. El ejemplo Root.plist anteriormente tiene en el índice 1.

https://stackoverflow.com/a/12842530/338986

Añadir Run script con siguiente fragmento después 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"

Al añadir CFBundleVersion además de CFBundleShortVersionString. Se emite la versión de esta manera:

Al escribir a $CODESIGNING_FOLDER_PATH/Settings.bundle/Root.plist en lugar de la de $SRCROOT tener algunos beneficios.

  1. dosis no modificar los archivos de copia de repositorio de trabajo.
  2. Usted no necesita a la caja camino hacia Settings.bundle en $SRCROOT. La ruta puede variar.

Pruebas en Xcode 7.3.1

Con base en el ejemplo aquí , aquí está el guión I' m utilizando para actualizar automáticamente la configuración del número de versión del paquete:

#! /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á la Root.plist 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>

Las otras respuestas no funcionan correctamente por una razón: La fase de despliegue ejecución de script no se ejecuta hasta que el paquete de configuración ha sido empaquetado. Por lo tanto, si su versión es Info.plist 2.0.11 y 2.0.12 para actualizarlo, y luego construir / archivar su proyecto, el paquete de configuración seguirá diciendo 2.0.11. Si abre los ajustes del lote Root.plist, se puede ver que el número de versión no se actualiza hasta el final del proceso de construcción. Se puede construir el proyecto de nuevo para obtener el paquete de configuración actualiza correctamente, o puede agregar el guión a una fase de pre-construcción en su lugar ...

  • En XCode, Editar el esquema para su objetivo del proyecto
  • Haga clic en la flecha de la divulgación en el esquema de la creación
  • A continuación, haga clic en la opción "Pre-acciones"
  • Haga clic en el signo más y seleccione "Nueva Ejecutar comandos de acción"
  • Establecer el valor shell a / bin / sh
  • Ajuste "Proporcionar configuración de generación de" a su objetivo del proyecto
  • Añada su secuencia de comandos para el área de texto. La siguiente secuencia de comandos que funcionó para mí. Puede que tenga que modificar las rutas para que coincida 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: ValorPredeterminado $ versionString"

Esto ejecutará correctamente el guión antes el paquete de configuración se envasa durante el proceso de construcción / Archivo. Si abre los ajustes del lote y construir Root.plist / archivar su proyecto, ahora verá el número de versión se actualiza al comienzo del proceso de construcción y su paquete Ajustes mostrará la versión correcta.

Creo que se puede hacer esto utilizando una manera que es similar a lo que describo en esta respuesta (basado en este post ).

En primer lugar, puede hacer VersionValue una variable dentro de Xcode renombrándolo a $ {} VersionValue. Crear un archivo llamado versionvalue.xcconfig y añadirlo a su proyecto. Vaya a su objetivo de aplicación y vaya a la configuración construir para ese objetivo. Creo que es necesario agregar VersionValue como escenario de construcción definido por el usuario. En la esquina inferior derecha de la ventana, cambiar el basado en el valor de "VersionValue".

Por último, vaya a su destino y crear una secuencia de comandos Ejecutar construir fase. Inspeccionar la fase de ejecución de secuencias de comandos y pegar en el script dentro del campo de texto Script. Por ejemplo, mi script para etiquetar mi entorno con la actual acumulación de Subversion BUILD_NUMBER es el 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 la sustitución de la variable cuando estos valores cambian dentro de su proyecto.

Mi ejemplo de trabajo basado en la respuesta @Ben Clayton y los comentarios de @Luis Ascorbe y @Vahid Amiri:

  

Nota: Este enfoque modifica el Settings.bundle / Root.plist en el archivo de copia de repositorio de trabajo

  1. Añadir un paquete de ajustes a la raíz de su proyecto. No cambie el nombre
  2. Settings.bundle Abrir / Root.plist como Código Fuente

    Reemplazar 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>
    
  3. Añadir la siguiente secuencia de comandos para la construcción, la sección Pre-acciones 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"
    
  4. Generar y ejecutar el esquema actual

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top