← Todos los articulos

On Demand Resources queda obsoleto: lo que cuesta Background Assets

Apple retiró un sistema de entrega de contenido con una década encima en 13 palabras: «On Demand Resources y la API NSBundleResourceRequest quedan obsoletos. Usa Background Assets en su lugar».1

Esa frase es la entrada completa. Lleva el radar 170066290, aparece bajo el apartado Deprecations y se repite palabra por palabra en tres notas de versión distintas.123 Apple no publicó una versión de eliminación, ni una guía de migración asociada a la obsolescencia, ni una nota equivalente en las notas de versión de macOS o watchOS.

El trabajo se esconde en las últimas cuatro palabras. Background Assets no es una sola cosa: se bifurca en tres configuraciones con modelos de alojamiento distintos, objetivos de despliegue mínimos distintos y costos de migración separados por aproximadamente un orden de magnitud. La elección ocurre antes de que escribas una línea de código, y equivocarse ahí es el error caro.

En resumen

  • Apple declaró obsoletos On Demand Resources y NSBundleResourceRequest en las notas de versión de iOS e iPadOS 27, tvOS 27 y visionOS 27.123 ODR sigue funcionando: Apple no fijó fecha de eliminación, y las APIs obsoletas siguen incluidas y siguen resolviendo etiquetas.
  • Los propios datos de disponibilidad de la API la declaran obsoleta en seis plataformas, dos más de las que menciona cualquier nota de versión: Mac Catalyst y watchOS.4 Background Assets no publica disponibilidad alguna para watchOS, así que watchOS recibe una obsolescencia sin reemplazo documentado.56
  • «Usa Background Assets en su lugar» se bifurca en tres caminos: gestionado con alojamiento de Apple, gestionado con alojamiento propio y no gestionado. Ambas rutas gestionadas exigen iOS 26.0 como objetivo de despliegue mínimo.78 Por debajo de 26.0 solo queda abierta la ruta no gestionada, que te obliga a alojar los archivos, inventar el formato del manifiesto y analizarlo tú mismo.9
  • La gestión de disco se invierte. ODR dejaba que el sistema purgara los recursos etiquetados sin usar y tomaba setPreservationPriority(_:forTags:) como una pista sobre el orden.410 Background Assets conserva en el dispositivo todos los paquetes descargados hasta que tu código llame a remove(assetPackWithID:).11
  • Apple aloja hasta 200 GB de paquetes de recursos (asset packs) comprimidos y hasta 200 paquetes por registro de app, compartidos entre todas las plataformas que ofrece tu app, subidos a App Store Connect y revisados por separado de las compilaciones.1213

Qué declaró obsoleto Apple, exactamente

Tres detalles de la nota pesan, y la nota no menciona ninguno.

El alcance es más amplio que las notas de versión. La entrada aparece en tres documentos: iOS e iPadOS 27, tvOS 27 y visionOS 27, cada uno bajo un encabezado On Demand Resources con un subencabezado Deprecations y citando el mismo radar.123 Las notas de macOS 27 y watchOS 27 no dicen nada al respecto.

La anotación de disponibilidad de la API cuenta una historia más amplia. NSBundleResourceRequest figura como introducida en iOS 9.0 y obsoleta en 27.0, con la misma obsolescencia en 27.0 para iPadOS 9.0, Mac Catalyst 13.1, tvOS 9.0, visionOS 1.0 y watchOS 2.0.4 Seis plataformas en los metadatos, cuatro nombradas en las notas. Los dos métodos de prioridad de conservación de Bundle llevan la misma anotación de seis plataformas.10 Una auditoría guiada solo por las notas de versión pasa por alto por completo las entradas de Mac Catalyst y watchOS.

La entrada de Mac Catalyst es nominal. Apple documenta que NSBundleResourceRequest «ignora las llamadas de las apps de Mac creadas con Mac Catalyst», de modo que la obsolescencia retira una API que allí nunca hizo nada.4 La entrada de watchOS no es nominal. Background Assets declara disponibilidad para iOS 16.0, iPadOS 16.0, Mac Catalyst 16.0, macOS 13.0, tvOS 18.4 y visionOS 2.4, sin fila para watchOS.5 Apple afirma sin rodeos que los paquetes de recursos alojados por Apple están «disponibles para apps distribuidas a través de la App Store en todas las plataformas excepto watchOS».6 Una app de watchOS que use ODR recibe una advertencia de obsolescencia y ningún reemplazo al que migrar.

La fuerza de este cambio es la más débil de los tres del ciclo 27 que he cubierto. Obsoleto significa obsoleto. Apple no publicó versión de eliminación, ni bloqueo en el envío, ni fallo en tiempo de ejecución. Compáralo con el mandato del ciclo de vida de escenas del mismo ciclo, donde las apps compiladas con el nuevo SDK «no se inician», o con el requisito de pantalla de inicio, donde la App Store rechaza la compilación de plano. ODR no hace ni lo uno ni lo otro. Las etiquetas existentes se siguen resolviendo, las llamadas existentes siguen devolviendo recursos y los binarios ya publicados siguen funcionando. Lo que llega es una advertencia del compilador y un reloj que nadie puede leer.

El momento se lee como una decisión, no como una limpieza. Apple declaró obsoleta la API en cuatro plataformas a la vez, un lanzamiento después de que se publicara el nivel gestionado de su reemplazo. Trata la obsolescencia como la apertura de una ventana de migración cuya duración Apple no ha publicado, no como una emergencia.

La bifurcación que eliges antes de escribir código

La descripción general del framework que publica Apple menciona dos modelos de alojamiento y un modo gestionado por defecto que «se encarga por ti de las descargas, las actualizaciones, la compresión y más». Con el alojamiento de Apple, «subes tus recursos a App Store Connect y los mantienes ahí, igual que las compilaciones de la app».5 La plantilla de extensión Background Download de Xcode nombra dos tipos directamente: gestionado con alojamiento de Apple y no gestionado con alojamiento propio.911 Una tercera combinación vive en las claves del property list: BAHasManagedAssetPacks en YES sin BAUsesAppleHosting selecciona paquetes de recursos gestionados que alojas tú mismo, y su documentación te dirige al protocolo ManagedDownloaderExtension en lugar del StoreDownloaderExtension de StoreKit.7814

Gestionado, alojado por Apple Gestionado, alojamiento propio No gestionado, alojamiento propio
iOS mínimo 26.0715 26.0714 16.19
Quién aloja los archivos Apple, vía App Store Connect6
Formato del manifiesto Esquema JSON de Apple11 Esquema JSON de Apple11 El tuyo: te toca inventarlo y analizarlo9
Protocolo de la extensión StoreDownloaderExtension716 ManagedDownloaderExtension714 BADownloaderExtension9
Descargas, actualizaciones, compresión El sistema5 El sistema5 9
Claves del property list 311 Sin documentar de principio a fin7 4 de nivel superior, una con 3 más dentro9

Para la mayoría de los equipos, la decisión la toma el objetivo de despliegue. Todo punto de entrada gestionado exige iOS 26.0 como mínimo, desde AssetPackManager y ManagedDownloaderExtension hasta las tres claves del property list.781415 Una app que dé soporte a iOS 18 no puede adoptar el nivel gestionado en absoluto, y sus opciones se reducen a la ruta no gestionada, que llega hasta iOS 16.1, o a seguir con el ODR obsoleto hasta que suba el objetivo de despliegue.9

La ruta no gestionada es otro trabajo distinto. En la secuencia de Apple, el sistema descarga un manifiesto desde BAManifestURL antes de que tu app se inicie, le entrega el archivo a tu extensión y recibe de vuelta un conjunto de solicitudes de descarga.9 Apple plantea el reparto sin matices: «Es tu responsabilidad crear los archivos de manifiesto de tus recursos autoalojados y no gestionados (con el formato que elijas) para que tu código los analice y entregue al sistema las URL y los tamaños de archivo».9 Tú pones el alojamiento, un CDN, un esquema de manifiesto, un analizador y una lista de dominios permitidos. Quien lea «usa Background Assets en su lugar» como un simple cambio de API está mirando el nivel gestionado y citando la factura del no gestionado.

Lo que ODR te daba y ahora reconstruyes a mano

Tres comportamientos de ODR no tienen equivalente directo.

Las etiquetas se convierten en paquetes de recursos. ODR identificaba el contenido con etiquetas de texto asignadas en Xcode, y NSBundleResourceRequest(tags:) reservaba una o varias.4 Background Assets sustituye las etiquetas por paquetes de recursos: carpetas de archivos descritas por un manifiesto JSON y comprimidas en un archivo .aar mediante una herramienta de línea de comandos. La unidad de granularidad crece, y la asignación sale del catálogo de recursos de Xcode para vivir en un archivo que mantienes tú.

El alojamiento de Apple se convierte en un tren de publicación aparte. El contenido de ODR viajaba con la compilación. Los paquetes de recursos alojados por Apple se suben de forma independiente mediante Transporter, altool, iTMSTransporter o la API de App Store Connect, y los envías a App Review por separado de la app.1113 El desacoplamiento es justamente la ventaja: publicas contenido nuevo sin publicar una compilación. El costo es un segundo canal de envío, una segunda cola de revisión y un segundo conjunto de estados que vigilar.

La purga automática pasa a ser tarea tuya, y esa inversión es el cambio más brusco. ODR trataba el contenido descargado como una caché que pertenecía al sistema. Apple documentaba que el sistema «no intentará purgar del almacenamiento del dispositivo los recursos marcados con una etiqueta mientras al menos un objeto NSBundleResourceRequest esté gestionando esa etiqueta», lo cual es una promesa sobre cuándo ocurre la purga, no sobre si ocurre.4 setPreservationPriority(_:forTags:) existía precisamente para dar «una pista al sistema sobre el orden relativo para purgar conjuntos de recursos etiquetados dentro del bundle».10 Terminabas tu reserva, el sistema recuperaba el espacio a su propio ritmo y lidiar con la falta de almacenamiento era problema de Apple.

Background Assets invierte la propiedad. El sistema mantiene los paquetes actualizados de forma automática, y checkForUpdates() elimina los que quedaron obsoletos en el servidor.15 Ninguno de los dos mecanismos desaloja un paquete con el que simplemente terminaste. La instrucción de Apple es explícita: «el sistema no eliminará automáticamente tus paquetes de recursos mientras tu app esté instalada. Por lo tanto, cuando termines con un paquete de recursos, llama al método remove(assetPackWithID:)».11

El patrón acotado y con conteo de referencias se reduce a un borrado explícito que tienes que decidir invocar:

// ODR: claim a tag, use the file, release the claim.
// The system reclaims the space afterward on its own schedule.
let request = NSBundleResourceRequest(tags: ["Tutorial"])
try await request.beginAccessingResources()
let url = Bundle.main.url(forResource: "Introduction", withExtension: "m4v")
request.endAccessingResources()
import System  // url(for:) and contents(at:) take a FilePath

// Background Assets: ensure the pack, read the file, delete the pack.
// Nothing reclaims the space if you skip the last line.
let manager = AssetPackManager.shared
guard let pack = try await manager.manifest.assetPack(withID: "Tutorial") else { return }
try await manager.ensureLocalAvailability(of: pack, requireLatestVersion: false)
let url = try manager.url(for: "Videos/Introduction.m4v")
try await manager.remove(assetPackWithID: "Tutorial")

Toda app que arrastre la suposición de desalojo de ODR necesita una política de almacenamiento escrita a propósito. El modo de fallo es silencioso: nada se cae, nada avisa y el almacenamiento del dispositivo sube hasta que alguien ve tu app en la lista de almacenamiento.

La superficie de migración, punto por punto

Para la ruta gestionada con alojamiento de Apple, los propios pasos de Apple producen esta lista de verificación.

Agrupa los archivos en paquetes de recursos y elige una política de descarga para cada uno. Existen tres. essential se descarga durante la instalación y alimenta la barra de progreso que la gente mira en la App Store, en TestFlight y en la pantalla de inicio. prefetch arranca durante la instalación y continúa en segundo plano una vez terminada. onDemand se descarga solo cuando tu código lo pide.11 Para essential y prefetch, un array anidado installationEventTypes acepta firstInstallation, subsequentUpdate o ambos, de modo que un paquete de tutorial puede descargarse en la primera instalación y saltarse todas las actualizaciones posteriores.11

Escribe un manifiesto por paquete. Xcode genera una plantilla comentada:

xcrun ba-package template -o Manifest.json
{
  "assetPackID": "Tutorial",
  "downloadPolicy": {
    "essential": {
      "installationEventTypes": ["firstInstallation"]
    }
  },
  "fileSelectors": [
    { "file": "Videos/Introduction.m4v" },
    { "directory": "Textures/Tutorial" }
  ],
  "platforms": ["<identifiers from the generated template comments>"]
}

Las rutas de archivo se resuelven en relación con la carpeta desde la que ejecutas el comando de empaquetado, algo que vuelve a importar más adelante, cuando leas los archivos por ruta.11 Archiva cada paquete:

xcrun ba-package Manifest.json -o Tutorial.aar

Agrega un target de extensión Background Download dentro de Application Extension y elige como tipo el gestionado con alojamiento de Apple. Agrega la capacidad App Groups tanto a la app como a la extensión, y pon ambas en el mismo grupo. Después añade tres claves del property list al target de la app: BAAppGroupID, BAHasManagedAssetPacks en YES y BAUsesAppleHosting en YES. Apple indica que omitas cualquier otra clave de Background Assets en los proyectos alojados por Apple.11 Hay una restricción con la que es fácil tropezar: adoptar AssetPackManager sin adoptar también el protocolo de extensión correspondiente es, en palabras de Apple, «un error de programación».15

La lectura de archivos funciona a través de un espacio de nombres unificado. Apple «fusiona automáticamente todos tus paquetes de recursos en un espacio de nombres compartido, reconstruyendo en la práctica la carpeta raíz de tus recursos como si estuviera pegada en el dispositivo de la persona», así que el código direcciona los archivos por ruta sin llevar cuenta de qué paquete los contiene.11 Las lecturas devuelven por defecto un Data mapeado en memoria, con una variante de descriptor de archivo para carga procedural que debes cerrar tú.11

Las pruebas locales traen un costo de configuración que conviene presupuestar aparte. Background Assets usa HTTPS en todas las descargas, así que el servidor simulado necesita un certificado. El camino documentado por Apple pasa por Acceso a Llaveros para crear una CA raíz autofirmada, Apple Configurator para armar un perfil que lleve esa CA, instalar ese perfil y marcarlo como de confianza en cada dispositivo de prueba, emitir un certificado SSL de hoja cuyo nombre coincida exactamente con la dirección IP o el nombre de host del servidor, iniciar el servidor y fijar una URL de sustitución en los ajustes de Developer de cada dispositivo.17

xcrun ba-serve --host localhost Tutorial.aar HighQualityTextures.aar

Presupuesta esa secuencia como una tarea propia. On Demand Resources no necesitaba en ningún momento un servidor tuyo: Apple lo describe como un gestor de «contenido alojado en la App Store», y los recursos que faltan en el dispositivo «se solicitan a la App Store».4 Migrar implica levantar alojamiento, o una imitación local en la que el dispositivo confíe, antes de poder ejercitar una sola descarga. Al leer los dos flujos de trabajo uno junto al otro, espero que sea la cadena de certificados, y no la adopción de la API, lo que consuma el primer día de una migración.

Las cifras con las que planificar

Apple publica dos topes duros para los paquetes alojados por Apple: 200 GB en total y 200 paquetes de recursos por registro de app. Ambos están «compartidos entre todas las plataformas que ofrece tu app».12 Apple calcula el total a partir del tamaño máximo entre las versiones aptas para distribución en TestFlight o en la App Store, excluyendo las que están en Awaiting Upload, Processing, Failed y las totalmente Superseded, y te envía un correo al llegar al 80 % del límite. Archivar un paquete recupera espacio eliminando todas sus versiones, incluidas las que están publicadas en la App Store.12

La ruta no gestionada sustituye esos topes por cuatro claves de nivel superior del property list que fijas tú, una de ellas un diccionario que contiene tres más, y la división entre comprimido y sin comprimir es una trampa de verdad. BADownloadAllowance y BAEssentialDownloadAllowance limitan los tamaños de descarga y toman valores comprimidos. BAMaxInstallSize y BAEssentialMaxInstallSize limitan los tamaños instalados y toman valores sin comprimir.9 Apple acompaña las claves de tamaño de instalación con una advertencia que en realidad es una advertencia de producto: «La App Store usa esta clave para mostrar el tamaño de tu app en la página del producto, así que proporciona un valor exacto… No exageres el espacio en disco que necesitas».18 BADownloadDomainAllowList completa el conjunto y acepta dominios en formato DNS, con un asterisco inicial opcional para comodines.9

Falta una cifra más en el plan, y sale de los metadatos de disponibilidad antes que de la prosa. AssetPackManager llegó con iOS 26.0, y cuatro de sus miembros ya están marcados como obsoletos: ensureLocalAvailability(of:) y status(ofAssetPackWithID:) en 26.4, y luego assetPack(withID:) y allAssetPacks en 27.0.19 La búsqueda, el estado y la llamada de descarga se movieron una vez cada uno, en dos versiones menores. La ruta a la que Apple apunta ahora, a través de la propiedad manifest del gestor, lleva anotación de beta en el SDK de 27.0, igual que la variante por lotes ensureLocalAvailability(of:requireLatestVersions:).19 El propio tutorial de Apple sobre paquetes alojados por Apple todavía muestra dos de las llamadas obsoletas.11 El piso práctico, por lo tanto, queda por encima del 26.0 nominal de ese nivel. Escribir la ruta de descarga que se mostró antes sin llevarte una advertencia de obsolescencia significa apuntar a 27.0 y aceptar símbolos anotados como beta para lograrlo. El reemplazo que te dicen que adoptes es más joven y se mueve más rápido que la API a la que sustituye.

A quién alcanza realmente la obsolescencia

La población afectada es reducida, y no la encontré en mi propio código. Busqué en siete proyectos publicados NSBundleResourceRequest, beginAccessingResources, setPreservationPriority, cualquier ajuste de compilación ON_DEMAND_RESOURCES, knownAssetTags y la configuración de etiquetas del catálogo de recursos. Cero coincidencias, en los siete, con todos los patrones. Un barrido de todos los archivos Swift, Objective-C, property list y pbxproj bajo mi carpeta de proyectos no devolvió nada para ningún símbolo de ODR, y tampoco nada para Background Assets.20

El resultado nulo tiene una causa que vale la pena nombrar, porque se generaliza. ODR existe para apps cuyo contenido empequeñece su código. Mi catálogo de recursos más grande es el de Return, con 66,6 MB, y todas las demás apps están por debajo de 8 MB, con Water y Yawara por debajo de 100 KB.20 A esos tamaños, partir el contenido en paquetes añade modos de fallo de red, una política de almacenamiento y un segundo canal de revisión, y a cambio ahorra una descarga de la que nadie se queja. Las apps que de verdad necesitan Background Assets son los juegos con contenido por niveles, las apps que distribuyen modelos grandes de machine learning y cualquier cosa con video por idioma, que es exactamente la población a la que apunta el soporte de paquetes de recursos localizados que Apple añadió en iOS 27.21

Los objetivos de despliegue afinan el panorama, y son la cifra que hay que revisar primero en cualquier código base. Cinco de mis seis apps de iOS ya están en iOS 26.0 o posterior, así que el nivel gestionado estaría disponible para ellas hoy mismo. Ace Citizenship todavía declara 17.0 y 17.5 en algunos de sus targets, lo que descartaría el nivel gestionado y dejaría solo la ruta no gestionada o el ODR obsoleto.20 Haz esa comprobación antes de diseñar nada: el objetivo de despliegue mínimo, y no el peso de los recursos, es lo que decide qué migración te están ofreciendo en realidad.

Preguntas frecuentes

¿On Demand Resources deja de funcionar en iOS 27?

No. Apple marcó ODR y NSBundleResourceRequest como obsoletos y no publicó versión de eliminación, ni bloqueo en el envío, ni fallo en tiempo de ejecución.1 Las APIs obsoletas siguen funcionando y las etiquetas existentes se siguen resolviendo. Lo que obtienes es una advertencia del compilador. El contraste con los otros cambios incompatibles del mismo ciclo es instructivo: el mandato del ciclo de vida de escenas hace que las apps «no se inicien», y el requisito de pantalla de inicio hace que la App Store rechace la compilación. La obsolescencia de ODR pone en marcha un reloj; no cierra una puerta.

¿Qué plataformas abarca la obsolescencia?

Las notas de versión nombran cuatro plataformas repartidas en tres documentos: iOS e iPadOS 27, tvOS 27 y visionOS 27, todos citando el radar 170066290.123 Los metadatos de disponibilidad de la API son más amplios: marcan como obsoletos en 27.0 tanto NSBundleResourceRequest como los métodos de prioridad de conservación de Bundle en seis plataformas, sumando Mac Catalyst y watchOS.410 Mac Catalyst es un caso teórico, porque Apple documenta que la clase ignora las llamadas de las apps de Catalyst.4 watchOS no es teórico: Background Assets no publica disponibilidad para watchOS, y los paquetes alojados por Apple están disponibles «en todas las plataformas excepto watchOS», así que una app de watchOS se queda con una API obsoleta y ningún sucesor documentado.56

¿Puedo migrar si mi app da soporte a iOS 18?

Al nivel gestionado, no. AssetPackManager, ManagedDownloaderExtension, BAHasManagedAssetPacks y BAUsesAppleHosting exigen todos iOS 26.0.781415 Por debajo de ese piso quedan dos opciones. La ruta no gestionada funciona desde iOS 16.1, y te pide alojar los recursos, definir tu propio formato de manifiesto, analizarlo en una extensión y declarar los límites de descarga y una lista de dominios permitidos en tu property list.9 Si no, sigue usando el ODR obsoleto hasta que tu objetivo de despliegue llegue a 26.0, algo que la ausencia de una fecha de eliminación por parte de Apple permite hoy por hoy.

¿Qué se rompe en silencio si porto el código de ODR tal cual?

El almacenamiento. ODR dejaba que el sistema purgara el contenido etiquetado sin usar, y setPreservationPriority(_:forTags:) solo sugería un orden.410 Background Assets nunca elimina un paquete con el que ya terminaste mientras tu app siga instalada, así que el espacio es tuyo hasta que llames a remove(assetPackWithID:).11 El código que imita el viejo patrón de beginAccessingResources y endAccessingResources sin añadir un borrado explícito filtra disco de forma indefinida, sin caídas ni advertencias que lo delaten durante las pruebas. Escribe la política de eliminación antes de escribir el código de descarga.

Puntos clave

Para quienes desarrollan en iOS: - Revisa el objetivo de despliegue mínimo antes que nada. Por debajo de iOS 26.0 el nivel gestionado no existe para ti, y «usa Background Assets en su lugar» significa construir alojamiento, un formato de manifiesto y un analizador en la ruta no gestionada.79 - Escribe una política de eliminación como parte de la migración. remove(assetPackWithID:) no tiene contraparte automática, y la vieja costumbre de ODR de soltar la reserva y confiar en el sistema deja el almacenamiento creciendo en silencio.11

Para equipos que distribuyen contenido pesado: - Presupuesta la configuración de pruebas locales aparte del código. El camino documentado por Apple pasa por una CA raíz autofirmada, un perfil de Apple Configurator instalado y marcado como de confianza en cada dispositivo, un certificado SSL de hoja que coincida con el nombre de host del servidor y una URL de sustitución por dispositivo.17 - Planifica contra 200 GB y 200 paquetes por registro de app, compartidos entre todas las plataformas en las que publicas, y está atento al correo que Apple envía al 80 %.12 Archivar para recuperar espacio elimina versiones que están publicadas en la App Store.12

Para quienes gestionan lanzamientos: - Los paquetes alojados por Apple implican un segundo canal de envío: se suben con Transporter o con la API de App Store Connect, se versionan de forma independiente de las compilaciones y se envían a App Review por su cuenta.1113 Asigna personal al ciclo de revisión en consecuencia. - Nada obliga a migrar en este ciclo. Pon ODR después del mandato del ciclo de vida de escenas y del requisito de pantalla de inicio, que sí traen sanción real, y vuelve a evaluarlo cuando Apple publique una versión de eliminación.


El ciclo 27 sigue clasificando sus rupturas de compatibilidad según cuántos dientes tienen: el ciclo de vida de escenas impide que las apps se inicien, la pantalla de inicio impide que las compilaciones se publiquen y ODR apenas pone en marcha un reloj. Saber cuál es cuál es lo que te permite aprovechar bien el ciclo. Para el mismo patrón en una superficie más pequeña, mira la eliminación de ImageCreator de Image Playground. El centro de la serie completa es la serie sobre el ecosistema de Apple.

Referencias


  1. Apple, iOS & iPadOS 27 Release Notes, sección On Demand Resources, apartado Deprecations (radar 170066290): «On Demand Resources y la API NSBundleResourceRequest quedan obsoletos. Usa Background Assets en su lugar». Verificado contra el JSON de documentación de Apple el 25 de julio de 2026. La entrada es el texto completo; las notas de versión no contienen versión de eliminación, ni requisito de envío, ni lenguaje de fallo en tiempo de ejecución para On Demand Resources. 

  2. Apple, tvOS 27 Release Notes, sección On Demand Resources, apartado Deprecations (radar 170066290). Redacción idéntica a la nota de iOS e iPadOS. 

  3. Apple, visionOS 27 Release Notes, sección On Demand Resources, apartado Deprecations (radar 170066290). Redacción idéntica. Las notas de versión de macOS 27 y watchOS 27 no contienen una entrada equivalente, verificado mediante una búsqueda en su JSON de documentación el 25 de julio de 2026. 

  4. Apple, NSBundleResourceRequest, Foundation. Disponibilidad: iOS 9.0, iPadOS 9.0, Mac Catalyst 13.1, tvOS 9.0, visionOS 1.0 y watchOS 2.0, todas obsoletas en 27.0. Fuente del modelo de etiquetas («Identificas los recursos bajo demanda durante el desarrollo creando identificadores de texto conocidos como etiquetas»), del comportamiento de purga («El sistema no intentará purgar del almacenamiento del dispositivo los recursos marcados con una etiqueta mientras al menos un objeto NSBundleResourceRequest esté gestionando esa etiqueta»), de la nota sobre Mac Catalyst («Esta clase ignora las llamadas de las apps de Mac creadas con Mac Catalyst») y de la restricción de un solo uso. Las APIs miembro init(tags:), beginAccessingResources(completionHandler:) y endAccessingResources() llevan la misma obsolescencia en 27.0 para seis plataformas. 

  5. Apple, Background Assets, descripción general del framework. Disponibilidad: iOS 16.0, iPadOS 16.0, Mac Catalyst 16.0, macOS 13.0, tvOS 18.4 y visionOS 2.4, sin fila para watchOS. Fuente de «La implementación por defecto de Managed Background Assets se encarga por ti de las descargas, las actualizaciones, la compresión y más» y de «Si eliges Apple-Hosted Background Assets, subes tus recursos a App Store Connect y los mantienes ahí, igual que las compilaciones de la app». 

  6. Apple, Creating managed asset packs, Background Assets. Fuente de «Apple-Hosted Background Assets puede alojar hasta 200 GB de recursos comprimidos y está disponible para apps distribuidas a través de la App Store en todas las plataformas excepto watchOS». 

  7. Apple, BAHasManagedAssetPacks, referencia de Information Property List. Booleano; iOS 26.0, iPadOS 26.0, macOS 26.0, tvOS 26.0 y visionOS 26.0. Fuente del enrutamiento del protocolo de extensión: «usa el protocolo StoreDownloaderExtension de StoreKit si fijas la clave BAUsesAppleHosting en YES; de lo contrario, usa el protocolo ManagedDownloaderExtension de Background Assets». Ese enrutamiento documenta la combinación gestionada con alojamiento propio que los artículos guía no cubren de principio a fin. 

  8. Apple, BAUsesAppleHosting y BAAppGroupID, referencia de Information Property List. Ambas indican iOS 26.0, iPadOS 26.0, macOS 26.0, tvOS 26.0 y visionOS 26.0. Ten en cuenta que BAAppGroupID, BAHasManagedAssetPacks y BAUsesAppleHosting llevan cada una una fila anómala de Mac Catalyst 16.0 junto a sus filas de 26.0 para el resto de plataformas; el piso de iOS 26.0 del nivel gestionado descansa en AssetPackManager, ManagedDownloaderExtension y BAHasManagedAssetPacks, y no en BAAppGroupID, que la ruta no gestionada también exige. 

  9. Apple, Configuring an unmanaged Background Assets project, Background Assets. Fuente del tipo de extensión Self-Hosted, Unmanaged, del requisito de App Groups en ambos targets, de la secuencia de descarga durante la instalación y la actualización, y de la declaración de responsabilidad: «Es tu responsabilidad crear los archivos de manifiesto de tus recursos autoalojados y no gestionados (con el formato que elijas) para que tu código los analice y entregue al sistema las URL y los tamaños de archivo». También es la fuente de BAManifestURL, BAInitialDownloadRestrictions, BADownloadAllowance y BAEssentialDownloadAllowance (tamaños comprimidos), BAMaxInstallSize y BAEssentialMaxInstallSize (tamaños sin comprimir), y BADownloadDomainAllowList (dominios en formato DNS, con asterisco inicial opcional para comodines). BADownloaderExtension está disponible desde iOS 16.1, iPadOS 16.1, Mac Catalyst 16.1, macOS 13.0, tvOS 18.4 y visionOS 2.4; BAManifestURL, desde iOS 16.1. 

  10. Apple, setPreservationPriority(_:forTags:) y preservationPriority(forTag:), Foundation. Ambos introducidos en iOS 9.0 y obsoletos en 27.0 en iOS, iPadOS, Mac Catalyst, tvOS, visionOS y watchOS. Fuente de «Una pista para el sistema sobre el orden relativo para purgar conjuntos de recursos etiquetados dentro del bundle». 

  11. Apple, Downloading Apple-hosted asset packs, Background Assets, junto con Creating managed asset packs. Fuente de la plantilla de extensión Background Download y su tipo Apple-Hosted, Managed; del requisito de app group compartido; de la configuración de tres claves en el property list con la instrucción de «omitir todas las demás claves de la lista de propiedades de Background Assets»; de los comandos xcrun ba-package template y xcrun ba-package; de las claves del manifiesto (assetPackID, downloadPolicy, installationEventTypes con firstInstallation y subsequentUpdate, fileSelectors con file y directory, y platforms); de las tres políticas de descarga (essential, prefetch y onDemand) y su comportamiento durante la instalación; de la regla de rutas relativas a la carpeta de empaquetado; del espacio de nombres unificado («El sistema fusiona automáticamente todos tus paquetes de recursos en un espacio de nombres compartido, reconstruyendo en la práctica la carpeta raíz de tus recursos como si estuviera pegada en el dispositivo de la persona»); de las lecturas de Data mapeado en memoria y de su variante con descriptor de archivo; de los canales de subida (Transporter, altool, iTMSTransporter y la API de App Store Connect); y de la instrucción sobre almacenamiento: «el sistema no eliminará automáticamente tus paquetes de recursos mientras tu app esté instalada. Por lo tanto, cuando termines con un paquete de recursos, llama al método remove(assetPackWithID:)». Los ejemplos de descarga del artículo llaman tanto a assetPack(withID:), que los datos de disponibilidad de Apple marcan como obsoleto en 27.0, como a ensureLocalAvailability(of:), obsoleto en 26.4 (véase la nota 19). 

  12. Apple, Apple-hosted asset pack size limits, Ayuda de App Store Connect. Total de paquetes de recursos: 200 GB; número de paquetes: 200. Fuente de «La suma total del uso de tamaño de todos los paquetes de recursos subidos a un registro de app en App Store Connect», del método de cálculo (tamaño máximo entre las versiones aptas para distribución en TestFlight o en la App Store, excluyendo las versiones en Awaiting Upload, Processing, Failed y las totalmente Superseded), de la notificación por correo al 80 %, de «Estos límites se comparten entre todas las plataformas ofrecidas para tu app» y del comportamiento del archivado, que «elimina de App Store Connect todas las versiones de un paquete de recursos, incluidas las que se están probando en TestFlight y las publicadas en la App Store». 

  13. Apple, Overview of Apple-hosted asset packs, Ayuda de App Store Connect. Fuente del flujo de cuatro pasos (empaquetar, subir, probar con TestFlight, enviar a App Review), de la independencia de los paquetes de recursos respecto de las compilaciones de la app, y de la lista de plataformas compatibles con recursos gestionados alojados por Apple: iOS 26+, iPadOS 26+, macOS 26+, tvOS 26+ y visionOS 26+. 

  14. Apple, ManagedDownloaderExtension, Background Assets. Protocolo; iOS 26.0 o posterior en las seis plataformas listadas. Ofrece implementaciones por defecto para todos los requisitos heredados de BADownloaderExtension, con la advertencia de no implementar esos requisitos heredados salvo, opcionalmente, backgroundDownload(_:didReceive:)

  15. Apple, AssetPackManager, Background Assets. Actor; iOS 26.0, iPadOS 26.0, Mac Catalyst 26.0, macOS 26.0, tvOS 26.0 y visionOS 26.0. Fuente de la nota sobre la adhesión («La primera vez que tu código hace referencia al gestor compartido, Background Assets considera que tu app se está adhiriendo a la gestión automática de tus paquetes de recursos por parte del sistema») y del requisito de emparejamiento: adoptar el gestor sin el protocolo de extensión gestionada correspondiente es «un error de programación». También es la fuente de checkForUpdates(), que «obtiene del servidor la información más reciente de los paquetes de recursos, actualiza los desactualizados y elimina los obsoletos», y de remove(assetPackWithID:), url(for:) (nonisolated, que recibe un FilePath y devuelve una URL) y statusUpdates(forAssetPackWithID:), ninguno de los cuales está marcado como obsoleto. AssetPack y ManagedBackgroundAssetsError tienen la misma disponibilidad desde iOS 26.0. Para los miembros del gestor que sí están obsoletos, véase la nota 19. 

  16. Apple, StoreDownloaderExtension, StoreKit. Protocolo que refina ManagedDownloaderExtension, disponible en iOS 26.0, iPadOS 26.0, macOS 26.0, tvOS 26.0 y visionOS 26.0. 

  17. Apple, Testing asset packs locally, Background Assets. Fuente del requisito de HTTPS, de la secuencia de creación de la CA raíz en Acceso a Llaveros, de la creación del perfil en Apple Configurator y de los pasos de instalación y confianza en cada dispositivo, del certificado SSL de hoja cuyo nombre debe ser «una dirección IP, un nombre de host o un nombre de dominio válido» que coincida con el servidor, del comando xcrun ba-serve y de la URL de sustitución en los ajustes de Developer (Ajustes > Developer > Development Overrides en iOS, iPadOS, tvOS y visionOS; xcrun ba-serve url-override en macOS). 

  18. Apple, BAEssentialMaxInstallSize y BAMaxInstallSize, referencia de Information Property List. BAEssentialMaxInstallSize desde iOS 18.0; BAMaxInstallSize desde iOS 16.0. Ambas incluyen: «La App Store usa esta clave para mostrar el tamaño de tu app en la página del producto, así que proporciona un valor exacto. Si comprimes los recursos, usa el tamaño sin comprimir de los archivos para este valor. No exageres el espacio en disco que necesitas». Ambas están marcadas como obligatorias para usar Background Assets. 

  19. Metadatos de disponibilidad de Apple para los miembros de AssetPackManager, leídos del JSON de documentación de Apple el 25 de julio de 2026. Miembros obsoletos, todos introducidos en iOS 26.0: ensureLocalAvailability(of:) obsoleto en 26.4; status(ofAssetPackWithID:) obsoleto en 26.4 en favor de status(relativeTo:); assetPack(withID:) obsoleto en 27.0 con la nota «Llama a assetPack(withID:) sobre el valor de la propiedad manifest del gestor»; y allAssetPacks obsoleto en 27.0 en favor de la propiedad assetPacks del manifiesto. Símbolos de reemplazo introducidos en iOS 27.0 y marcados como beta en el SDK actual: manifest, AssetPackManifest.assetPack(withID:) (síncrono, que devuelve un AssetPack opcional) y ensureLocalAvailability(of:requireLatestVersions:). ensureLocalAvailability(of:requireLatestVersion:) llegó en 26.4 y no está obsoleto. La observación de que el tutorial de Apple sobre paquetes alojados por Apple todavía muestra dos llamadas obsoletas, assetPack(withID:) y ensureLocalAvailability(of:), es del autor, a partir de comparar el texto de ese artículo con la disponibilidad de los símbolos en esa misma fecha. 

  20. Revisión del autor sobre siete proyectos publicados, el 25 de julio de 2026: Reps, Return, Banana List, Ace Citizenship, Water, ResumeGeni y Yawara. Se buscaron en todos los archivos Swift, Objective-C, de cabecera, property list y project.pbxproj, excluyendo build, DerivedData, .build, Pods y .git, los términos NSBundleResourceRequest, beginAccessingResources, setPreservationPriority, On Demand Resources, cualquier ajuste de compilación ON_DEMAND_RESOURCES, knownAssetTags y los ajustes ASSETCATALOG_COMPILER_*TAG. Cero coincidencias con todos los patrones en todos los proyectos, y cero coincidencias con símbolos de Background Assets. Totales de los catálogos de recursos medidos con du sobre todas las carpetas .xcassets, excluyendo salida de compilación, capturas de fastlane y carpetas de informes: Return 66,62 MB, Ace Citizenship 7,81 MB, Banana List 2,04 MB, Reps 1,66 MB, Water 0,04 MB y Yawara 0,01 MB. Valores de IPHONEOS_DEPLOYMENT_TARGET leídos de cada project.pbxproj: Reps 26.0 y 26.2, Return 26.1, Banana List 26.0, Water 26.0, Yawara 26.5, y Ace Citizenship 17.0, 17.5 y 26.1 entre sus targets. 

  21. Apple, Reducing download and storage demands with localized asset packs, Background Assets. Fuente de la designación language añadida a los paquetes de recursos en macOS 27, iOS 27, tvOS 27 y visionOS 27, de las reglas de los identificadores BCP-47 (solo subetiquetas de idioma, región y escritura, sin variantes ni extensiones) y de la clave language de la plantilla de Xcode 27. 

Artículos relacionados

canOpenURL quedó obsoleto: qué llamar en su lugar

Apple declaró obsoleto canOpenURL y redujo la lista de esquemas permitidos a 25 entradas. El reemplazo y la única compro…

27 min de lectura

La casilla de redes sociales de la App Store y lo que cuesta

La App Store obliga a declarar funciones de redes sociales en cada envío; la excepción para menores de 13 cuesta un enti…

27 min de lectura