iOS Deployment Target (también iOS Target, Deployment Target) es la versión mínima del sistema operativo Apple en la que se puede ejecutar una aplicación. Este parámetro se establece en el proyecto de Xcode y define el límite de compatibilidad: al seleccionar iOS 16.0, la aplicación solo se instala en dispositivos con iOS 16.0 o superior. Según Apple Developer Documentation, elegir el Deployment Target correcto afecta tanto al alcance de la audiencia como al acceso a nuevas API de frameworks Swift y Objective-C.
Puntos Clave
iOS Deployment Target es un parámetro de configuración de Xcode que especifica la versión más temprana de iOS, iPadOS, tvOS, watchOS o visionOS en la que puede ejecutarse una aplicación. Cada proyecto de Xcode contiene esta configuración para cada plataforma por separado. Por ejemplo, una app de iOS puede tener Deployment Target 16.0, mientras que una extensión de watchOS — 9.0. Si el dispositivo del usuario ejecuta iOS 15.0, una app con Target 16.0 no aparecerá en App Store y no podrá instalarse mediante distribución directa.
El mecanismo de Deployment Target se basa en la verificación de la versión del SO durante la instalación. App Store de iOS compara el valor del Deployment Target de Info.plist (clave MinimumOSVersion) con la versión del SO en el dispositivo del usuario. Si la versión del dispositivo es inferior — el botón "Descargar" se bloquea y la API de App Store no devuelve la aplicación en los resultados de búsqueda para ese dispositivo. El mismo comportamiento aplica para TestFlight, distribución ad-hoc y enterprise.
Según datos de StatCounter de junio de 2025, iOS 16 representa aproximadamente el 48% de los dispositivos iPhone activos, iOS 17 — 35%, iOS 18 — 12%, versiones más antiguas — alrededor del 5%. Elegir Deployment Target 16.0 cubre el 83% de los dispositivos, Target 17.0 — 35% (solo iOS 17+). Estas cifras son críticas para la toma de decisiones: cuanto mayor es el Target, menor es la audiencia, pero más accesibles son las API más recientes de SwiftUI y UIKit.
| Deployment Target | Participación de dispositivos (junio 2025) | Funciones disponibles |
|---|---|---|
| iOS 15.0 | ~90% | Swift Concurrency, async/await, Focus State |
| iOS 16.0 | ~83% | SwiftUI NavigationStack, Layout, Live Activities |
| iOS 17.0 | ~35% | Observation, SwiftData, TipKit, Reactive Editing |
| iOS 18.0 | ~12% | Nuevas API de Apple Intelligence, SwiftUI mejorado |
Cada nueva versión de iOS añade no solo funciones para el usuario, sino también API para desarrolladores. Nuevos modificadores de SwiftUI, métodos de UIKit, frameworks como SwiftData y Observation solo están disponibles con un Deployment Target específico. El desarrollador debe equilibrar entre el alcance de la audiencia y la disponibilidad de herramientas modernas.
iOS Deployment Target y minSdkVersion de Android realizan la función idéntica — establecer la versión mínima del SO para una aplicación. Sin embargo, los mecanismos de implementación y las herramientas asociadas difieren. Comprender estas diferencias es útil para los desarrolladores que trabajan en ambas plataformas y ayuda a evitar confusiones al cambiar entre ecosistemas.
En iOS, la versión mínima se establece mediante la configuración de compilación de Xcode (IPHONEOS_DEPLOYMENT_TARGET) y se almacena en Info.plist (MinimumOSVersion). En Android — mediante build.gradle (minSdkVersion) y AndroidManifest.xml (<uses-sdk android:minSdkVersion>). iOS no tiene equivalentes de targetSdkVersion y compileSdkVersion — los cambios de comportamiento en iOS se gestionan mediante el SDK con el que se compila la aplicación (Base SDK) y la versión del SO en el dispositivo.
| Parámetro | iOS | Android |
|---|---|---|
| Versión mínima | Deployment Target (IPHONEOS_DEPLOYMENT_TARGET) | minSdkVersion |
| Dónde se indica | Xcode Build Settings → Info.plist | build.gradle → AndroidManifest.xml |
| Comprobación en código | @available / #available / if #available | Build.VERSION.SDK_INT |
| Versión objetivo | Base SDK (siempre la última) | compileSdkVersion + targetSdkVersion |
| Filtrado en la tienda | App Store: MinimumOSVersion | Google Play: minSdkVersion |
La diferencia clave es que Base SDK en iOS es siempre la última versión instalada en Xcode. El desarrollador no puede elegir compileSdkVersion como en Android — la aplicación siempre se compila contra el último SDK disponible. Los nuevos cambios de comportamiento en iOS se aplican a todas las aplicaciones compiladas con el nuevo Base SDK, independientemente del Deployment Target. En Android, targetSdkVersion proporciona control sobre los cambios de comportamiento; iOS no tiene tal separación.
A diferencia de Android, donde los cambios de comportamiento están vinculados a targetSdkVersion, iOS aplica cambios de comportamiento a todas las aplicaciones compiladas con la nueva versión de Xcode y Base SDK. Por ejemplo, iOS 13 introdujo el Modo Oscuro — todas las aplicaciones compiladas con Xcode 11 y iOS 13 SDK recibieron automáticamente soporte para el tema oscuro, independientemente del Deployment Target. En Android, un cambio similar (Scoped Storage) se aplica solo cuando targetSdk >= 29. Los desarrolladores de iOS deben estar preparados para cambios de comportamiento con cada nuevo Xcode, sin posibilidad de aplazamiento.
El conocimiento de ambas plataformas permite predecir las consecuencias de elegir una versión mínima y planificar actualizaciones de código para nuevas API. En IT Sectr, hemos estado utilizando ambos ecosistemas desde 2017 — la práctica muestra que el iOS Deployment Target debe elegirse 2–3 versiones por debajo de la actual para un equilibrio entre cobertura y funcionalidad.
La configuración del iOS Deployment Target se realiza en varios lugares del proyecto: el Target principal, el proyecto Pods (si se usa CocoaPods), las dependencias de Swift Package Manager y los targets de Widget/Extension. Si los valores difieren entre la aplicación principal y las extensiones, App Store utiliza el máximo de todos — es decir, una extensión no puede tener un Target inferior al de la aplicación principal.
Abra el proyecto de Xcode → seleccione el Target → pestaña General → sección Minimum iOS Deployment. El menú desplegable muestra todas las versiones disponibles del SDK de iOS instaladas en Xcode. El cambio se aplica a todos los esquemas de compilación. Alternativamente — pestaña Build Settings → iOS Deployment Target (IPHONEOS_DEPLOYMENT_TARGET). Si el proyecto tiene varios targets de extensión (Widget, Watch), cada uno tiene su propio Deployment Target.
Para bibliotecas distribuidas a través de SPM, el Deployment Target se especifica en Package.swift en el parámetro platforms. Una biblioteca con platforms: [.iOS(.v16)] solo estará disponible para aplicaciones con Deployment Target iOS 16.0+. Al agregar dicha biblioteca a un proyecto con Target 15.0, Xcode mostrará un error de incompatibilidad. En CocoaPods, el Deployment Target se establece en el Podfile: platform :ios, '16.0'.
// Package.swift — Deployment Target para bibliotecas SPM
import PackageDescription
let package = Package(
name: "MyLibrary",
platforms: [
.iOS(.v16),
.macOS(.v13),
.watchOS(.v9),
.tvOS(.v16)
],
products: [
.library(
name: "MyLibrary",
targets: ["MyLibrary"]
)
],
dependencies: [],
targets: [
.target(
name: "MyLibrary",
swiftSettings: [
.enableUpcomingFeature("ConciseMagicFile")
]
)
]
)
// Verificación de compatibilidad en código
#if swift(>=5.9)
// Funciones de Swift 5.9+ (Xcode 15+)
#endifEn el ejemplo, Package.swift establece las plataformas iOS 16+, macOS 13+, watchOS 9+, tvOS 16+. Cualquier proyecto con Deployment Target inferior a iOS 16.0 no podrá agregar esta biblioteca. El parámetro swiftSettings incluye próximas funciones para una versión específica de Swift. SPM verifica automáticamente la compatibilidad de platforms al agregar una dependencia.
El Podfile utiliza la directiva platform :ios, '16.0'. Después de pod install, CocoaPods verifica el Deployment Target de cada biblioteca pod: si al menos una tiene un Target superior al del proyecto, la instalación fallará con el error "The iOS deployment target 'IPHONEOS_DEPLOYMENT_TARGET' is set to 17.0, but the range of supported deployment target versions is 16.0 to 17.0". La solución es reducir el Target del pod problemático o aumentar el Target del proyecto.
# Podfile — ejemplo con Deployment Target
platform :ios, '16.0'
# Ignorar advertencias de Deployment Target
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '16.0'
end
end
endEl hook post_install en el Podfile establece forzosamente el Deployment Target 16.0 para todas las bibliotecas pod. Esto es útil cuando uno de los pods especifica un Target superior al necesario para su funcionalidad. Úselo solo si está seguro de que el pod no utiliza API de una versión superior de iOS.
@available y #available son directivas de Swift y Objective-C para llamar de forma segura a API que solo están disponibles en ciertas versiones del SO. Si el Deployment Target del proyecto es iOS 16.0 y un método requiere iOS 17.0, una llamada directa provocará un fallo en tiempo de ejecución en dispositivos con iOS 16.0–16.x. Las comprobaciones de disponibilidad son una herramienta obligatoria para soportar múltiples versiones de iOS.
La directiva @available se aplica a clases, métodos o archivos completos. Si @available(iOS 17.0, *) se especifica antes de una clase, toda la clase solo está disponible en iOS 17.0+. Intentar llamar a la clase en iOS 16.0 provocará un error en tiempo de ejecución. Use @available para aislar módulos completos de funcionalidad específicos de una versión particular del SO. Para métodos dentro de una clase, @available permite ocultar funciones individuales.
La directiva #available (if #available) verifica la versión del SO en tiempo de ejecución y ejecuta el código solo cuando coincide. Se usa dentro de funciones para elegir entre implementaciones nuevas y antiguas. En Objective-C, el equivalente es @available(iOS 17.0, *) dentro de if. Para comprobaciones más complejas, use ProcessInfo.processInfo.isOperatingSystemAtLeast para comparar componentes de versión (major, minor, patch).
import UIKit
import SwiftUI
// 1. @available — clase completa solo para iOS 17+
@available(iOS 17.0, *)
class ObservationViewModel: ObservableObject {
@Published var name: String = "User"
// Usa Observation framework — disponible solo iOS 17+
func updateWithObservation() {
let newName = "Updated via Observation"
name = newName
}
}
// 2. #available — llamada condicional dentro de función
func configureLiveActivity() {
if #available(iOS 16.1, *) {
// API de Live Activities — disponible desde iOS 16.1
let activity = Activity<MyAttributes>(
attributes: MyAttributes(name: "Live"),
contentState: MyContentState(value: 42)
)
Task {
await activity.activate()
}
} else {
// Alternativa: notificación push o nada
print("Live Activities no disponible")
}
}
// 3. ProcessInfo — verificación precisa de versión
func checkOSVersion() {
let osVersion = ProcessInfo.processInfo.operatingSystemVersion
print("iOS \(osVersion.majorVersion).\(osVersion.minorVersion).\(osVersion.patchVersion)")
// Comparación de componentes
if osVersion.majorVersion >= 17 {
print("iOS 17+ detectado")
}
}
// 4. Objective-C @available
// Objective-C usa @available:
// if (@available(iOS 17.0, *)) { }
// 5. @available con argumento unavailable
@available(*, unavailable, message: "Use configureWithSwiftUI instead")
func legacyConfigureMethod() { }La clase ObservationViewModel usa @available para aislar la funcionalidad de iOS 17. La función configureLiveActivity usa #available para verificar Live Activities (iOS 16.1+) con una implementación de respaldo. ProcessInfo verifica la versión exacta del SO. @available(*, unavailable) marca un método como no disponible en todas las versiones — para migrar a una nueva API. Sin estas comprobaciones, una aplicación con Deployment Target 16.0 fallará en dispositivos con iOS 16.0 al llamar a API de iOS 17.
Objective-C usa @available(iOS 17.0, *) con la misma semántica que Swift #available. La diferencia: Objective-C verifica en tiempo de ejecución, Swift #available también es en tiempo de ejecución pero con sugerencias del compilador para optimización de ramas. Para código Objective-C que interactúa con Swift, las comprobaciones de disponibilidad son necesarias del lado de Objective-C — el puente de Swift no agrega comprobaciones automáticas.
Elegir el iOS Deployment Target es una decisión estratégica que afecta tres aspectos: alcance de la audiencia, API disponibles y complejidad del mantenimiento del código. No existe un valor correcto único — la elección depende de la audiencia objetivo de la aplicación, las funciones mínimas requeridas y los recursos del equipo para el soporte de compatibilidad hacia atrás.
El primer factor — estadísticas de uso de versiones de iOS. Apple publica datos de instalación de iOS en WWDC y en Apple Developer Dashboard. En junio de 2025, la distribución es: iOS 15 — ~7%, iOS 16 — ~48%, iOS 17 — ~35%, iOS 18 — ~10%. Elegir Target 16.0 proporciona una cobertura del 83%, Target 17.0 — 35%. Para aplicaciones masivas (redes sociales, mensajería, e-commerce), se recomienda Target 16.0. Para aplicaciones B2B de nicho con API específicas — Target 17.0.
El segundo factor — API requeridas. Si la función clave de la aplicación requiere SwiftData (iOS 17+), Observation (iOS 17+) o Live Activities (iOS 16.1+), el Target no puede ser inferior a la versión requerida. Analizar las API requeridas en la etapa de diseño previene la situación en la que a mitad del desarrollo se descubre que se necesita un Target más alto. Use las comprobaciones de disponibilidad como plan de respaldo, no como estrategia principal.
El tercer factor — recursos de prueba. El soporte de versiones antiguas de iOS requiere pruebas en simuladores y dispositivos reales con esas versiones. iOS 15 se prueba en iPhone 6s/7, iOS 16 — en iPhone 8/X, iOS 17 — en iPhone XS/XR. Cada versión adicional de compatibilidad hacia atrás aumenta el tiempo de QA. Si el equipo es pequeño, es razonable elegir un Target 2–3 versiones por debajo de la actual (16.0) — un equilibrio entre cobertura y esfuerzo.
| Tipo de aplicación | Target recomendado | Cobertura | Justificación |
|---|---|---|---|
| Masiva (social, marketplace) | iOS 16.0 | ~83% | Máxima audiencia |
| Enterprise / B2B | iOS 16.0 | ~83% | Los dispositivos corporativos se actualizan lentamente |
| Startup / MVP | iOS 17.0 | ~35% | Desarrollo rápido con nuevas API |
| Juegos (Metal 3+) | iOS 17.0 | ~35% | Requieren nuevas API gráficas |
| Biblioteca/SDK | iOS 15.0 | ~90% | Máxima compatibilidad para clientes |
Las bibliotecas y SDK deben tener el Deployment Target más bajo posible (15.0 o incluso 14.0) — los consumidores de la biblioteca pueden tener cualquier Target superior al suyo. Si una biblioteca requiere iOS 17.0, la mitad de los proyectos no podrán usarla. Para las aplicaciones, por otro lado, puede permitirse un Target más alto para acceder a nuevas API.
Reducir el iOS Deployment Target es una tarea que surge cuando se necesita expandir la audiencia o al publicar una biblioteca con compatibilidad para proyectos antiguos. A diferencia del aumento, la reducción requiere trabajo activo con el código: debe reemplazar todas las llamadas directas a API que no están disponibles en el nuevo Target (más bajo) con comprobaciones #available e implementaciones de respaldo.
El primer paso — inventario de API. Xcode no muestra errores de compilación al reducir el Target — solo advierte con advertencias amarillas. Debe encontrar todos los métodos y clases marcados con @available(iOS N+, *) donde N sea superior al nuevo Target. Use la búsqueda en el proyecto (Cmd+Shift+F) con el patrón "available(iOS". Cada una de estas llamadas es candidata para refactorización.
El segundo paso — reemplazo con comprobaciones #available. Cada llamada a API de una versión superior se envuelve en if #available(iOS N+, *) { } else { }. Para clases completas, use #if os(iOS) con @available a nivel de tipo. Si una API no tiene un respaldo razonable (por ejemplo, Live Activities), la funcionalidad se desactiva para versiones antiguas con notificación al usuario.
import UIKit
import SwiftUI
// Reducción del Deployment Target de 17.0 a 16.0
// ANTES (@available iOS 17.0):
@available(iOS 17.0, *)
func setupObservation() {
// Observation framework — solo iOS 17+
let model = ObservationViewModel()
// ...
}
// DESPUÉS (comprobación #available):
func setupObservationCompatible() {
if #available(iOS 17.0, *) {
// iOS 17+: Observation framework
let model = ObservationViewModel()
// ...
} else {
// iOS 16.x: ObservableObject con @Published
let model = LegacyObservableViewModel()
// ...
}
}
// Para API UIKit iOS 17+:
@available(iOS 17.0, *)
class ModernViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Usa UIKit TraitChanges (iOS 17+)
registerForTraitChanges([UITraitVerticalSizeClass.self]) { _, _ in }
}
}
// Alternativa para iOS 16:
class LegacyViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Sin registerForTraitChanges — usando traitCollectionDidChange
}
override func traitCollectionDidChange(_: UITraitCollection?) {
super.traitCollectionDidChange(nil)
// Manejo de cambios de traits para iOS 16
}
}
// Fábrica para seleccionar implementación según versión de iOS
func makeViewController() -> UIViewController {
if #available(iOS 17.0, *) {
return ModernViewController()
} else {
return LegacyViewController()
}
}El código demuestra la reducción del Target de iOS 17.0 a 16.0. La función setupObservation se reemplaza por setupObservationCompatible con una comprobación #available. El ViewController se divide en Modern (iOS 17+) y Legacy (iOS 16) con una fábrica makeViewController que selecciona la implementación según la versión del SO. Esta arquitectura permite soportar dos Deployment Targets sin duplicar toda la base de código — solo módulos versionados.
Después de reducir el Deployment Target, Xcode resaltará en amarillo todas las llamadas a API no disponibles en el nuevo Target. La advertencia "In iOS 16.0 and later" significa que el método requiere una versión superior. Soluciones: agregar @available o if #available (recomendado), suprimir mediante @available(*, deprecated) para migración gradual, o eliminar la llamada. Activar "Treat Warnings as Errors" en el proyecto convertirá estas advertencias en errores de compilación — active esta opción para tener control.
Preguntas Frecuentes
iOS Deployment Target es la versión mínima de iOS en la que puede ejecutarse una aplicación. Se especifica en Xcode Project → Info → iOS Deployment Target. Una app con Target 16.0 no puede instalarse en iOS 15.0 o inferior. App Store filtra las aplicaciones según este parámetro — los usuarios con versiones no compatibles no ven la aplicación. El equivalente en Android es minSdkVersion.
Ambos parámetros establecen la versión mínima del SO para instalar una aplicación. iOS Deployment Target se almacena en Info.plist (MinimumOSVersion), minSdkVersion — en AndroidManifest.xml. iOS no tiene equivalentes de targetSdkVersion y compileSdkVersion — todos los cambios de comportamiento se aplican al compilar con el nuevo Base SDK. En Android, los cambios de comportamiento se controlan mediante targetSdkVersion. Comprobaciones en código: @available en Swift vs Build.VERSION.SDK_INT en Android.
Se recomienda elegir iOS 16.0 para aplicaciones masivas (83% de dispositivos) e iOS 17.0 para startups y proyectos que usan SwiftUI Observation/SwiftData (35% de dispositivos). iOS 16.0 es compatible con iPhone 8 y versiones posteriores, incluye SwiftUI Layout, NavigationStack, Live Activities. iOS 17.0 proporciona Observation, SwiftData, TipKit. Para bibliotecas y SDK — iOS 15.0 para máxima compatibilidad.
En Swift, use #available(iOS 17.0, *) dentro de funciones para ejecución condicional de código o @available(iOS 17.0, *) a nivel de clase/método para comprobación declarativa. Para la versión exacta — ProcessInfo.processInfo.operatingSystemVersion, que devuelve OperatingSystemVersion. En Objective-C, use @available(iOS 17.0, *) dentro de if. Sin comprobaciones, llamar a una API por encima del Deployment Target provoca un fallo en tiempo de ejecución.
Puede reducir el iOS Deployment Target, pero requiere reemplazar todas las llamadas directas a API de versiones superiores con comprobaciones #available e implementaciones de respaldo. Xcode advertirá con advertencias amarillas pero no mostrará un error. Las API sin un respaldo razonable (Live Activities, SwiftData) se desactivan en versiones antiguas. Se recomienda comenzar con un Target 2 versiones por debajo de la actual para evitar una migración compleja.
Resumen
Desarrollaremos una aplicación móvil llave en mano
IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.
Lea también