Versión vs compilación en Xcode

660

Tengo una aplicación que desarrollé con Xcode 3 y recientemente comencé a editar con Xcode 4. En el resumen de destino tengo el formulario de destino de la aplicación de iOS con campos: identificador, versión, compilación, dispositivos y objetivo de implementación. El campo de versión está en blanco y el campo de compilación es 3.4.0 (que coincide con la versión de la aplicación de cuando todavía estaba editando con Xcode 3).

Mis preguntas son:

  1. ¿Cuál es la diferencia entre la versión y los campos de compilación?

  2. ¿Por qué estaba en blanco el campo de versión después de actualizar a Xcode 4?

Chris
fuente
Por un lado, creo que es el número de compilación que aparece en la lista de archivos de Xcode Organizer. Aparte de eso, no estoy seguro de para qué se utiliza.
Daniel Dickison

Respuestas:

1224

Apple reorganizó / reutilizó los campos.

En el futuro, si busca en la pestaña Información el destino de su aplicación, debe usar la "Cadena de versiones de paquete, corta" como su Versión (por ejemplo, 3.4.0) y la "Versión de paquete" como su Compilación (por ejemplo, 500 o 1A500 ) Si no los ve a ambos, puede agregarlos. Esos se asignarán a la versión adecuada y crearán cuadros de texto en la pestaña Resumen; Son los mismos valores.

Al ver la pestaña Información, si hace clic con el botón derecho y selecciona Mostrar claves / valores sin formato , verá que los nombres reales son CFBundleShortVersionString(Versión) y CFBundleVersion(Compilación).

La versión se usa generalmente como parece que la has estado usando con Xcode 3. No estoy seguro de en qué nivel estás preguntando sobre la diferencia de Versión / Compilación, así que lo responderé filosóficamente.

Hay todo tipo de esquemas, pero uno popular es:

{MajorVersion}. {MinorVersion}. {Revisión}

  • Versión principal: cambios importantes, rediseños y cambios de funcionalidad
  • Versión menor: mejoras menores, adiciones a la funcionalidad
  • Revisión : un número de parche para corregir errores

Luego, la Compilación se usa por separado para indicar el número total de compilaciones para una versión o para toda la vida útil del producto.

Muchos desarrolladores comienzan el número de compilación en 0, y cada vez que construyen aumentan el número en uno, aumentando para siempre. En mis proyectos, tengo un script que aumenta automáticamente el número de compilación cada vez que construyo. Vea las instrucciones para eso a continuación.

  • La versión 1.0.0 podría ser la versión 542. Se necesitaron 542 versiones para llegar a la versión 1.0.0.
  • La versión 1.0.1 podría ser la compilación 578.
  • La versión 1.1.0 podría ser la compilación 694.
  • La versión 2.0.0 podría ser la compilación 949.

Otros desarrolladores, incluido Apple, tienen un número de compilación compuesto por una versión principal + versión secundaria + número de compilaciones para el lanzamiento. Estos son los números de versión de software reales, en oposición a los valores utilizados para el marketing.

Si va al menú Xcode > Acerca de Xcode , verá los números de Versión y Compilación. Si presiona el botón Más información ... verá un montón de versiones diferentes. Desde el Más información ... botón se retira en Xcode 5, esta información también está disponible en el software> desarrollador sección de la información del sistema de aplicaciones, disponible mediante la apertura de Apple menú> Acerca de este Mac > Informe del sistema ... .

Por ejemplo, Xcode 4.2 (4C139). La versión 4.2 de Marketing es Build versión principal 4, Build versión secundaria C y Build number 139. La próxima versión (presumiblemente 4.3) probablemente sea Build release 4D, y el número de Build comenzará de nuevo en 0 e incrementará a partir de ahí.

Los números de versión / compilación del simulador de iPhone son iguales, al igual que los iPhone, Mac, etc.

  • 3.2: (7W367a)
  • 4.0: (8A400)
  • 4.1: (8B117)
  • 4.2: (8C134)
  • 4.3: (8H7)

Actualización : a pedido, estos son los pasos para crear un script que se ejecuta cada vez que compila su aplicación en Xcode para leer el número de compilación, incrementarlo y volver a escribirlo en el {App}-Info.plistarchivo de la aplicación . Hay pasos adicionales opcionales si desea escribir sus números de versión / compilación en sus Settings.bundle/Root*.plistarchivos.

Esto se extiende desde el artículo de cómo hacerlo aquí .

En Xcode 4.2 - 5.0:

  1. Cargue su proyecto Xcode.
  2. En el panel izquierdo, haga clic en su proyecto en la parte superior de la jerarquía. Esto cargará el editor de configuración del proyecto.
  3. En el lado izquierdo del panel de la ventana central, haga clic en su aplicación debajo del encabezado OBJETIVOS . Deberá configurar esta configuración para cada objetivo del proyecto.
  4. Seleccione la pestaña Fases de construcción .
    • En Xcode 4, en la parte inferior derecha, haga clic en el botón Agregar fase de compilación y seleccione Agregar secuencia de comandos de ejecución .
    • En Xcode 5, seleccione el menú Editor > Agregar fase de compilación > Agregar fase de compilación de script de ejecución .
  5. Arrastre y suelte la nueva fase Ejecutar script para moverla justo antes de la fase Copiar recursos de paquete (cuando el archivo app-info.plist se incluirá con su aplicación).
  6. En el nuevo Ejecutar script fase, establecer Shell : /bin/bash.
  7. Copie y pegue lo siguiente en el área de script para números de compilación de enteros:

    buildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "$INFOPLIST_FILE")
    buildNumber=$(($buildNumber + 1))
    /usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "$INFOPLIST_FILE"
    

    Como señaló @Bdebeez, la herramienta de versiones genéricas de Apple ( agvtool) también está disponible. Si prefieres usarlo, primero debes cambiar un par de cosas:

    • Seleccione la pestaña Configuración de compilación .
    • En la sección Control de versiones , establezca la Versión del proyecto actual en el número de compilación inicial que desea usar, por ejemplo, 1 .
    • De vuelta en la pestaña Fases de compilación , arrastre y suelte la fase Ejecutar script después de la fase Copiar recursos de paquete para evitar una condición de carrera al intentar compilar y actualizar el archivo fuente que incluye su número de compilación.

    Tenga en cuenta que con el agvtoolmétodo aún puede obtener periódicamente compilaciones fallidas / canceladas sin errores. Por esta razón, no recomiendo usar agvtoolcon este script.

    Sin embargo, en la fase Ejecutar script , puede usar el siguiente script:

    "${DEVELOPER_BIN_DIR}/agvtool" next-version -all

    El next-versionargumento incrementa el número de compilación ( bumptambién es un alias para lo mismo) y se -allactualiza Info.plistcon el nuevo número de compilación.

  8. Y si tiene un paquete de configuración donde muestra la versión y la compilación, puede agregar lo siguiente al final del script para actualizar la versión y la compilación. Nota: Cambie los PreferenceSpecifiersvalores para que coincidan con su configuración. PreferenceSpecifiers:2significa mirar el elemento en el índice 2 debajo de la PreferenceSpecifiersmatriz en su archivo plist, por lo que para un índice basado en 0, esa es la tercera configuración de preferencia en la matriz.

    productVersion=$(/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "$INFOPLIST_FILE")
    /usr/libexec/PlistBuddy -c "Set PreferenceSpecifiers:2:DefaultValue $buildNumber" Settings.bundle/Root.plist
    /usr/libexec/PlistBuddy -c "Set PreferenceSpecifiers:1:DefaultValue $productVersion" Settings.bundle/Root.plist
    

    Si está utilizando en agvtoollugar de leer Info.plistdirectamente, puede agregar lo siguiente a su secuencia de comandos:

    buildNumber=$("${DEVELOPER_BIN_DIR}/agvtool" what-version -terse)
    productVersion=$("${DEVELOPER_BIN_DIR}/agvtool" what-marketing-version -terse1)
    /usr/libexec/PlistBuddy -c "Set PreferenceSpecifiers:2:DefaultValue $buildNumber" Settings.bundle/Root.plist
    /usr/libexec/PlistBuddy -c "Set PreferenceSpecifiers:1:DefaultValue $productVersion" Settings.bundle/Root.plist
    
  9. Y si tiene una aplicación universal para iPad y iPhone, también puede establecer la configuración para el archivo de iPhone:

    /usr/libexec/PlistBuddy -c "Set PreferenceSpecifiers:2:DefaultValue $buildNumber" Settings.bundle/Root~iphone.plist    
    /usr/libexec/PlistBuddy -c "Set PreferenceSpecifiers:1:DefaultValue $productVersion" Settings.bundle/Root~iphone.plist
    
nekno
fuente
17
"En mis proyectos, tengo un script que aumenta automáticamente el número de compilación cada vez que construyo". ¿Puedes compartir cómo lo haces? Gracias por los detalles y respuestas por la pregunta original.
Zsolt
2
@Andrews: actualicé mi respuesta con los detalles del script de compilación.
nekno
99
Para aumentar en números hexadecimales puede usarbuildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "$INFOPLIST_FILE") dec=$((0x$buildNumber)) buildNumber=$(($dec + 1)) hex=$(printf "%X" $buildNumber) /usr/libexec/PlistBuddy -c "Set :CFBundleVersion $hex" "$INFOPLIST_FILE"
Alon Amir
8
En resumen: HEX no está permitido en la AppStore.
Nicolas Miari
3
(Usuarios de Xcode 5) Es posible que deba cambiar el paso 5 para leer: "En la barra de menús, seleccione Editor -> Agregar fase de compilación -> Agregar fase de compilación de ejecución de script"
Greg M. Krsak
72

(Solo dejo esto aquí para mi propia referencia). Esto mostrará la versión y la compilación para los campos "versión" y "compilación" que ve en un objetivo de Xcode:

- (NSString*) version {
    NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"];
    NSString *build = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];
    return [NSString stringWithFormat:@"%@ build %@", version, build];
}

En veloz

func version() -> String {
    let dictionary = NSBundle.mainBundle().infoDictionary!
    let version = dictionary["CFBundleShortVersionString"] as? String
    let build = dictionary["CFBundleVersion"] as? String
    return "\(version) build \(build)"
}
Dan Rosenstark
fuente
2
OT: Tiene una fuga en su método: usted alloc/ initla cadena, que retiene la cadena, pero no la está liberando. En un objeto que devuelve de un método, generalmente debe usar un método conveniente para que la cadena se libere automáticamente o llame autorelease. O: return [NSString stringWithFormat:@"%@ build %@", version, build]; O return [[[NSString alloc] initWithFormat:@"%@ build %@", version, build] autorelease];
nekno
1
Gracias @nekno, cambió la respuesta por lo que es compatible con ARC o no ARC.
Dan Rosenstark
2
Probablemente sea mejor usar las constantes donde estén disponibles (por ejemplo, kCFBundleVersionKey), para evitar errores tipográficos. Sin embargo, no pude encontrar uno para "CFBundleShortVersionString" :)
DannyA
Tiene un error en el código rápido: está llamando a CFBundleShortVersionString dos veces
Yariv Nissim
Gracias @ yar1vn, lo arreglé y NO, no está al revés.
Dan Rosenstark
53

El número de compilación es un número interno que indica el estado actual de la aplicación. Se diferencia del número de versión en que normalmente no está dirigido al usuario y no denota ninguna diferencia / características / actualizaciones como lo haría normalmente un número de versión.

Piensa en esto, de esta manera:

  • Build ( CFBundleVersion): el número de la construcción. Por lo general, comienza esto en 1 y aumenta en 1 con cada compilación de la aplicación. Rápidamente permite comparaciones de qué compilación es más reciente y denota la sensación de progreso de la base de código. Estos pueden ser abrumadoramente valiosos cuando se trabaja con QA y necesitan asegurarse de que los errores se registren en las compilaciones correctas.
  • Versión de marketing ( CFBundleShortVersionString): el número de usuario que está utilizando para denotar esta versión de su aplicación. Por lo general, esto sigue un esquema de versión Major.minor (por ejemplo, MyAwesomeApp 1.2) para que los usuarios sepan qué versiones son actualizaciones de mantenimiento más pequeñas y cuáles son nuevas características importantes.

Para usar esto de manera efectiva en sus proyectos, Apple proporciona una gran herramienta llamada agvtool. Recomiendo encarecidamente usar esto, ya que es MUCHO más simple que crear scripts de cambios de plist. Le permite configurar fácilmente tanto el número de compilación como la versión de marketing. Es particularmente útil cuando se crean scripts (por ejemplo, actualizar fácilmente el número de compilación en cada compilación o incluso consultar cuál es el número de compilación actual). Incluso puede hacer cosas más exóticas como etiquetar su SVN por usted cuando actualiza el número de compilación.

Para usarlo:

  • Configure su proyecto en Xcode, en Control de versiones, para usar "Apple Generic".
  • En terminal
    • agvtool new-version 1 (establezca el número de compilación en 1)
    • agvtool new-marketing-version 1.0 (establezca la versión de Marketing en 1.0)

Vea la página de manual de agvtoolpara una tonelada de buena información

Bdebeez
fuente
otro artículo sobre agvtool Easy iPhone Application Versioning con agvtool
Gon
25

El script para aumentar automáticamente el número de compilación en la respuesta anterior no funcionó para mí si el número de compilación es un valor de coma flotante, por lo que lo modifiqué un poco:

#!/bin/bash    
buildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "$INFOPLIST_FILE")
buildNumber=`echo $buildNumber +1|bc`
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "$INFOPLIST_FILE"
ale84
fuente
21

El número de lanzamiento de marketing es para los clientes, llamado número de versión . Comienza con 1.0 y sube para actualizaciones importantes a 2.0 , 3.0 , para actualizaciones menores a 1.1 , 1.2 y para correcciones de errores a 1.0.1 , 1.0.2 . Este número está orientado sobre lanzamientos y nuevas características.

El número de compilación es principalmente el número interno de compilaciones que se han realizado hasta entonces. Pero algunos usan otros números como el número de sucursal del repositorio. Este número debe ser único para distinguir las diferentes compilaciones casi iguales.

Como puede ver, el número de compilación no es necesario y depende de usted qué número de compilación desea usar. Entonces, si actualiza su Xcodea una versión principal, el campo de compilación está vacío. ¡El campo de versión puede no estar vacío!


Para obtener el número de compilación como NSStringvariable:

NSString * appBuildString = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"];

Para obtener el número de versión como una NSStringvariable:

NSString * appVersionString = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"];

Si quieres ambos en uno NSString:

NSString * versionBuildString = [NSString stringWithFormat:@"Version: %@ (%@)", appVersionString, appBuildString];

Esto se prueba con Xcode versión 4.6.3 (4H1503) . El número de compilación a menudo se escribe entre paréntesis / llaves. El número de compilación está en hexadecimal o decimal.

versión incorporada


En Xcode , puede aumentar automáticamente el número de compilación como un número decimal colocando lo siguiente en la Run scriptfase de compilación en la configuración del proyecto

#!/bin/bash    
buildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "$INFOPLIST_FILE")
buildNumber=$(($buildNumber + 1))
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "$INFOPLIST_FILE"

Para el número de compilación hexadecimal, use este script

buildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "$INFOPLIST_FILE")
buildNumber=$((0x$buildNumber)) 
buildNumber=$(($buildNumber + 1)) 
buildNumber=$(printf "%X" $buildNumber)
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "$INFOPLIST_FILE"

configuración_proyecto

Binario
fuente
6

Gracias a @nekno y @ ale84 por sus excelentes respuestas.

Sin embargo, modifiqué el script de @ ale84 para aumentar poco los números de compilación para coma flotante.

el valor de incl puede cambiarse de acuerdo con sus requisitos de formato flotante. Por ejemplo: si incl = .01, el formato de salida sería ... 1.19, 1.20, 1.21 ...

buildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "$INFOPLIST_FILE")
incl=.01
buildNumber=`echo $buildNumber + $incl|bc`
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "$INFOPLIST_FILE"
iHS
fuente
1

Otra forma es establecer el número de versión en appDelegate didFinishLaunchingWithOptions:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
     NSString * ver = [self myVersion];
     NSLog(@"version: %@",ver);

     NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults];
     [userDefaults setObject:ver forKey:@"version"];
     return YES;
}

- (NSString *) myVersion {
    NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"];
    NSString *build = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];
    return [NSString stringWithFormat:@"%@ build %@", version, build];
}
Mark VanderWiele
fuente