Cómo obtener la versión y el número de compilación de la aplicación en Swift: explicación completa con código
\n\n¿Alguna vez te has preguntado por qué en App Store la misma aplicación puede llamarse «MiMensajero 3.2», pero en la configuración del teléfono aparece como «3.2.1 (45)»? ¿O por qué los desarrolladores piden que envíes el «número de compilación» cuando reportas un error? La respuesta es simple: dentro de cada aplicación iOS viven dos números ocultos: la versión de la aplicación y el número de compilación. Y hoy aprenderemos a extraerlos con Swift. Esta es una de las preguntas más populares en Stack Overflow (¡decenas de miles de visitas!), y no es para menos: conocer estas dos líneas de código puede ahorrarte horas de depuración y dolores de cabeza a los usuarios.
\n\nEn este artículo no solo copiaremos una respuesta del foro. Analizaremos qué son la versión y la compilación, para qué sirven, cómo obtenerlas correctamente y, lo más importante, cómo no pisar el rastrillo. ¡Allá vamos!
\n\n¿Qué es la versión y el número de compilación?
\n\nAntes de escribir código, aclaremos los términos. En Xcode, en el archivo Info.plist (o en la configuración del proyecto), hay dos claves:
- \n
- CFBundleShortVersionString — es lo que el usuario ve en App Store y en la configuración de la aplicación. Generalmente se ve como «1.0», «2.3.1», etc. Esta es la versión para el usuario. \n
- CFBundleVersion — es el número de compilación interno. Puede ser cualquier cosa: «42», «20240315», «1.0.0.123». Esta es la versión para el desarrollador, que ayuda a distinguir diferentes compilaciones de la misma versión. \n
¿Por qué separarlos? Imagina que lanzas la versión 1.0, pero encuentras un error crítico. Lo corriges sin cambiar la funcionalidad: sigue siendo la versión 1.0 para el usuario, pero aumentas el número de compilación (por ejemplo, de 1 a 2). Así no confundes al usuario y en Crashlytics puedes ver exactamente qué compilación falló.
\n\nLa forma más simple: Bundle.main
\n\nApple proporciona un acceso conveniente a estos datos a través del objeto Bundle.main. Aquí tienes la solución clásica que encontrarás en Stack Overflow:
import UIKit\n\nclass ViewController: UIViewController {\n\n override func viewDidLoad() {\n super.viewDidLoad()\n \n // Obtenemos la versión de la aplicación\n let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "Unknown"\n // Obtenemos el número de compilación\n let buildNumber = Bundle.main.infoDictionary?["CFBundleVersion"] as? String ?? "Unknown"\n \n print("Versión de la aplicación: \\(appVersion)")\n print("Número de compilación: \\(buildNumber)")\n \n // Ejemplo de uso en la UI\n versionLabel.text = "Versión \\(appVersion) (compilación \\(buildNumber))"\n }\n}\n\n\nTodo lo genial es simple. Pero analicemos cada línea:
\n- \n
Bundle.main— es el bundle principal de tu aplicación (archivo .app). \ninfoDictionary— es un diccionario que lee elInfo.plist. \n- Usamos la conversión opcional con
as? Stringy el operador??por si acaso la clave no existe (aunque es poco probable). \n
Enfoque avanzado: leer desde ProcessInfo
\n\n¿Quieres lucir como un profesional? Usa ProcessInfo. Esta clase sabe más sobre el sistema que solo el plist. Pero para la versión de la aplicación no aporta nada nuevo, aunque puede mostrar el sistema operativo. Sin embargo, hay un truco: si envuelves la obtención de datos en una extensión, el código se vuelve más limpio y reutilizable.
import Foundation\n\nextension Bundle {\n var appVersion: String {\n return infoDictionary?["CFBundleShortVersionString"] as? String ?? "Unknown"\n }\n \n var buildNumber: String {\n return infoDictionary?["CFBundleVersion"] as? String ?? "Unknown"\n }\n \n var fullVersion: String {\n return "Versión \\(appVersion) (compil