View in English

  • Global Nav Open Menu Global Nav Close Menu
  • Apple Developer
Search
Cancel
  • Apple Developer
  • News
  • Discover
  • Design
  • Develop
  • Distribute
  • Support
  • Account
Only search within “”

Quick Links

5 Quick Links

Videos

Abrir menú Cerrar menú
  • Colecciones
  • Temas
  • Todos los videos
  • Información

Volver a WWDC25

  • Información
  • Resumen
  • Transcripción
  • Código
  • Novedades de widgets

    WidgetKit mejora tu app con actualizaciones de widgets, Actividades en Vivo y controles. Descubre cómo llevar tus widgets a visionOS, usarlos en carretera con CarPlay y hacer que se vean lo mejor posible con modos de renderizado acentuados. Además, descubre cómo se pueden mostrar widgets relevantes en la Pila Inteligente (en watchOS) y descubre cómo se pueden usar las notificaciones push para mantener tus widgets actualizados.

    Capítulos

    • 0:00 - Introducción
    • 1:03 - Widgets en nuevos lugares
    • 15:31 - Widgets de relevancia
    • 18:12 - Actualizaciones del widget Push

    Recursos

    • Increasing the visibility of widgets in Smart Stacks
    • Optimizing your widget for accented rendering mode and Liquid Glass
    • RelevanceKit
    • Updating widgets with WidgetKit push notifications
    • Updating your widgets for visionOS
      • Video HD
      • Video SD

    Videos relacionados

    WWDC25

    • Novedades de watchOS 26
    • Turbocarga tu app para CarPlay
    • Widgets de diseño para visionOS

    WWDC24

    • Design Live Activities for Apple Watch
    • Extend your app’s controls across the system

    WWDC23

    • Bring widgets to new places
    • Meet Push Notifications Console

    WWDC20

    • The Push Notifications primer
  • Buscar este video…

    Hola, mi nombre es Tanner Oakes y soy un ingeniero del equipo de Experiencia del Sistema. Los widgets son una excelente forma de mostrar información y acciones oportunas en todo el sistema, manteniendo tu app útil incluso cuando no está en primer plano. WidgetKit continúa expandiéndose, haciendo que tus widgets sean más capaces y llevándolos a nuevos lugares. Mi amigo Luca tiene una app para registrar la cafeína. Lo he estado ayudando a actualizarla. A lo largo de esta charla, te mostraré cómo aprovecha todo lo nuevo en widgets. En este video, cubriré widgets, Actividades en Vivo y controles en nuevos lugares en nuestras plataformas. También cubriré una nueva forma de mostrar contenido de widgets relevante en la Pila Inteligente de watchOS. Y finalmente, te mostraré cómo mantener tus widgets actualizados en todos los dispositivos con notificaciones push. Los widgets, las Actividades en Vivo y los controles están en muchos lugares nuevos. Pero primero, abordaré el nuevo aspecto de los widgets en los lugares donde comenzaron. En iOS 26, la pantalla de inicio se puede configurar para presentar íconos y widgets en una presentación de vidrio transparente, o personalizarse aún más seleccionando un color específico, como el azul en este caso. Se pueden configurar para los widgets en el escritorio y también en el Centro de Notificaciones en macOS Tahoe. Estas nuevas presentaciones están construidas de manera similar en iOS y macOS. En primer lugar, el contenido de los widgets se genera utilizando el modo de representación acentuado, tiñendo todo el contenido de blanco. Luego, se elimina el fondo del widget y se reemplaza con un vidrio temático o un efecto de color. Mi widget de seguimiento de cafeína se ve genial en modo acentuado, sin tener que hacer nada. Es posible que algunos widgets necesiten ajustes para lucir lo mejor posible en modo acentuado. Agregué un widget a mi app que me muestra la bebida que consumo con más frecuencia. En mi caso, es un té matcha con leche. Mi widget tiene una imagen que representa la bebida, un título abajo y un degradado detrás, lo que lo hace más legible cuando está encima de la imagen. Cuando se aplica la representación acentuada, todo el contenido del widget se tiñe de blanco. Para el contenido opaco, como mi taza de leche, todo es de un solo color blanco. El contenido parcialmente transparente, como mi degradado, está teñido de blanco pero mantiene su opacidad. Este no es realmente el aspecto que busco. Ya no puedo distinguir la imagen y el texto es difícil de leer. Te mostraré cómo puedo actualizar mi widget para manejar mejor la representación acentuada. Aquí está mi vista de widgets. Tengo una ZStack con la imagen de la bebida, el degradado y luego la vista de texto. Primero, agregaré la variable de entorno widgetRenderingMode a mi vista del widget. Mostraré condicionalmente la imagen grande y el degradado lineal, solo si el widget se representa a todo color. Luego traeré mi imagen nuevamente sobre el texto, la agregaré en una VStack y mostraré condicionalmente mi imagen si el widget está en modo acentuado. Creo que mi diseño se ve bastante bien. Ahora solo necesito mejorar el aspecto de mi imagen. Agregaré el modificador widgetAccentedRenderingMode a mi imagen y lo configuraré como desaturado. widgetAccentedRenderingMode es un modificador de SwiftUI que se puede aplicar a las imágenes en los widgets. El argumento que paso me da un control preciso sobre cómo debe mostrarse mi imagen cuando está en Modo acentuado. Hay cinco opciones diferentes que acepta widgetAccentedRenderingMode. Te mostraré cómo cada modo afecta la presentación de imágenes, mediante la comparación de iOS y macOS con un modo acentuado en la carátula.

    Para widgetAccentedRenderingMode, pasarlo en nil es lo mismo que no aplicar el modificador en absoluto. Aplica el color del contenido principal a la imagen. Tanto para mi widget de iOS como para el de watchOS, esto hace que mi imagen sea completamente blanca. Al pasarlo como acentuado, la imagen se inclina hacia el color acentuado. En iOS y macOS, tanto los colores principales como los de acento son blancos, lo que hace que mi imagen sea blanca. En watchOS, el color de acento coincide con el color de la carátula, lo que hace que la imagen de mi widget de watchOS sea azul. Al pasarlo como desaturado, se desaturará el color de la imagen. Este efecto se ve igual en los estilos de presentación de iOS y watchOS. Al pasar a accentedDesaturated se aplicarán ambos efectos, desaturará los colores de la imagen y aplicará el color de acento del tema seleccionado. En iOS, esto significa que la imagen es un poco más blanca, mientras que en watchOS, mi imagen desaturada ahora adquiere el color de acento azul del tema. Al pasar a fullColor se muestra la imagen completa y sin modificaciones en el modo de representación acentuado. Para combinar mejor con la carátula, esta opción no se utiliza en watchOS. Con varios widgets, usa una imagen desaturada o desaturada acentuada para ayudar a que el contenido de la imagen combine con la pantalla de inicio. Utilice fullColor para imágenes que representen contenido multimedia, como la portada de un álbum o de un libro. A continuación, me entusiasma mostrarte cómo llevar los widgets a una dimensión completamente nueva. Con visionOS 26, tus apps de visionOS ahora pueden incluir widgets. Y si ya tienes una app de iPhone o iPad compatible con widgets, estos estarán disponibles automáticamente en visionOS. Se admiten todos los tamaños de la familia de sistemas iOS y macOS. Y los widgets en visionOS tienen capacidad de interacción y animación, al igual que otras plataformas. Te mostraré cómo funcionan los widgets en visionOS y las nuevas opciones que ofrece WidgetKit. En visionOS, se pueden agregar widgets a la sala y luego fijarlos a una superficie. De forma predeterminada, adoptarán un aspecto Elevado y se ubicarán directamente sobre la superficie. Los widgets también pueden empotrarse, haciendo que parezca que están integrados directamente en la superficie. Si estos estilos no son adecuados para el widget, usa supportedMountingStyles en la configuración para especificar qué opciones se deben proporcionar. Este modificador está disponible para los widgets de visionOS y iOS. De forma predeterminada, todos los widgets se mostrarán debajo de una textura de vidrio. Para las apps de visionOS, se puede especificar una textura de papel alternativa, lo que le da al widget un aspecto de póster. Aquí, a la izquierda, tengo mi widget de bebida frecuente configurado con vidrio y a la derecha estoy probando el mismo pero con la textura de papel aplicada. Usa el modificador widgetTexture en la configuración para especificar si debe representarse con una textura de papel o detrás de un panel de vidrio. Para completar el aspecto de los widgets estilo póster, en visionOS se encuentra disponible una nueva familia de widgets systemExtraLargePortrait. Esta es una versión orientada verticalmente de la familia de widgets systemExtraLarge horizontal existente.

    Agrega esto a la configuración de tu widget usando el modificador supportedFamilies. En visionOS, el tema de color del widget también se puede personalizar. De forma predeterminada, el widget aparecerá en una presentación a todo color. Si selecciono este tema verde, el contenido del widget se muestra utilizando el modo de representación acentuado. La estructura y el contenido del widget se tiñen con el color seleccionado. Luego se elimina el fondo y se reemplaza con un color sólido que complementa el tema de color seleccionado. Este estilo aplica el mismo enfoque de representación analizado anteriormente para iOS y macOS. Usa las mismas técnicas que mencioné para que tu widget se vea lo mejor posible en estos temas de color. Usa el modificador widgetAccentedRenderingMode para personalizar la presentación de tus imágenes. Y usa la variable de entorno widgetRenderingMode para aplicar condicionalmente modificaciones más sustanciales.

    En visionOS, los widgets pueden incorporarse a tu entorno y colocarse en múltiples superficies. A medida que te muevas por el espacio, los widgets permanecen en su posición fija. Incluso si un widget está lejos, en una pared al otro lado de la habitación, permanecerá visible. Al igual que los objetos físicos reales, los widgets que están más lejos son más pequeños y más difíciles de ver. A diferencia de los objetos físicos, los widgets en visionOS pueden adaptarse según su distancia mediante una nueva API LevelOfDetail. Te mostraré cómo puedo agregar LevelOfDetail a mi widget de seguimiento de cafeína.

    Aquí tengo mi widget existente que muestra mi cafeína total del día, lo último que bebí, así como un botón práctico para agregar otra bebida al registro. Cuando este widget esté más lejos de mí, me gustaría que el valor total de cafeína sea más grande y más fácil de leer. También me gustaría ocultar el botón, ya que será más difícil presionarlo desde más lejos. Aquí está mi widget de seguimiento de cafeína. Quiero actualizar mi TotalCaffeineView, cambiar su tamaño y mostrar u ocultar condicionalmente mi LogDrinkView en la parte inferior. Primero, agregaré esta propiedad de entorno, LevelOfDetail, a mi vista. LevelOfDetail puede ser uno de dos valores. El valor predeterminado es el nivel normal de detalle esperado de los widgets. En visionOS, los widgets se muestran con el nivel de detalle predeterminado cuando están a una distancia cómoda. Si está lo suficientemente lejos, el nivel de detalle cambia a simplificado, para poder mostrar una representación más simple y más fácil de ver del widget. Agregaré esta condición a mi LogDrinkView para que solo se muestre si LevelOfDetail es el predeterminado. Ahora necesito actualizar la cantidad de cafeína.

    En mi TotalCaffeineView, se muestra el título y la cantidad total de cafeína formateada. Primero, agregaré la propiedad de entorno LevelOfDetail a mi vista. Para hacerlo más grande, cambiaré condicionalmente la fuente de la cantidad de cafeína de título a título grande según el nivel de detalle.

    Ahora, cada vez que el widget está lo suficientemente lejos, mi widget cambia para mostrar una versión más simple y más fácil de ver. Y al igual que los cambios en la línea de tiempo dentro de tu widget, los cambios de nivel de detalle también se animan. Para saber más sobre cuándo personalizar tu estilo espacial, recomendaciones sobre el nivel de detalle y otras consideraciones para integrar tus widgets en esta nueva plataforma, consulta “Diseño de Widgets para visionOS”. Cambiando de tema, ahora los widgets y las Actividades en Vivo llegan a la carretera con CarPlay. En CarPlay Ultra, los widgets aparecen en una o más pilas a la izquierda del tablero. Y a partir de iOS 26, esta funcionalidad llega a todos los autos con CarPlay. Los widgets se pueden configurar en la app Configuración en CarPlay. En CarPlay, la información visible, la tipografía grande y la legibilidad son importantes para que tu widget sea fácil de leer en la pantalla del automóvil. Para respaldar esto, CarPlay muestra los widgets en un estilo StandBy, utilizando la familia systemSmall en fullColor y con el widget sin fondo. Las interacciones de los widgets son compatibles con las pantallas táctiles y puedes usar el simulador de CarPlay disponible en el sitio del desarrollador para probar tu widget. Obtén más sugerencias sobre cómo adaptar tu widget para una presentación en StandBy en “Llevar widgets a nuevos lugares” de la WWDC 23. Las Actividades en Vivo también se pueden mostrar en la pantalla de inicio en CarPlay. De forma predeterminada, se mostrarán las vistas principales y secundarias de Dynamic Island de Actividades en Vivo. Aquí tengo el seguimiento de la Actividad en Vivo de mi pedido de café que se muestra en CarPlay. Este es un buen comienzo, pero con algunos códigos adicionales, puedo hacerlo aún mejor. Aquí está el código para mi Actividad en Vivo. Actualmente, se muestran mis vistas principales y secundarias. Para personalizar esta presentación de Actividad en Vivo para CarPlay, agregaré el modificador supplementalActivityFamilies, en small como argumento para mi Configuración de Actividad. Ahora, en lugar de utilizar las vistas principal y secundaria, CarPlay mostrará mi ActivityView, la misma vista que se usa en la pantalla de bloqueo del iPhone. Para algunas Actividades en Vivo, esto puede verse genial, pero el mío está un poco apretado y parte de mi contenido está cortado. Afortunadamente, puedo personalizarlo aún más.

    Aquí está mi ActivityView. Agregaré la variable de entorno activityFamily a mi vista. Con eso agregado, en el cuerpo de mis vistas, puedo mostrar contenido diferente de manera condicional o ajustar el diseño para brindar una excelente experiencia. Cuando activityFamily sea pequeño, proporcionaré una vista ShopOrderView optimizada para un diseño más pequeño. De lo contrario, mostraré mi vista OrderView predeterminada. Con este código adicional, mi Actividad en Vivo ahora se ve genial en CarPlay. Ahora puedo echar una mirada rápida y ver cuánto falta para que mi pedido esté listo. Al adoptar supplementalActivityFamily, también he mejorado enormemente el aspecto de mi Actividad en Vivo cuando se presenta en un Apple Watch enlazado. Tu app de iPhone obtiene esto automáticamente, sin la necesidad de una app de watchOS separada. Para saber más sobre cómo optimizar tu Actividad en Vivo en la Pila Inteligente de watchOS, consulta “Diseñar Actividades en Vivo para el Apple Watch”. Y consulta “Turbocarga tu app para CarPlay” para saber cómo optimizar tus widgets en CarPlay. CarPlay no es el único lugar nuevo para Actividades en Vivo. Las Actividades en Vivo de un iPhone enlazado ahora aparecerán en macOS Tahoe. Al igual que en Dynamic Island del iPhone, la Actividad en Vivo del rastreador de pedidos de café presenta las vistas principales y posteriores juntas en la barra de menú. Cuando se selecciona la Actividad en Vivo, aparecerá la presentación de la pantalla de bloqueo del iPhone. Al hacer clic en la presentación de la pantalla de bloqueo, se iniciará la app asociada que utiliza la duplicación de iPhone. Las Actividades en Vivo en macOS se pueden proporcionar en iPhone con iOS 18 y posterior. No se requieren cambios en el código y, al igual que los widgets de iPhone en macOS, admiten interacción y enlaces directos. Ahora cubriré nuevos lugares para los controles en macOS y watchOS. En macOS, los controles pueden ser proporcionados por apps que se ejecutan en la Mac, ya sea que estén creadas con el SDK de macOS, Catalyst o desde apps de iOS que se ejecutan en las Mac con el chip de Apple. Se pueden agregar controles en el Centro de Control. Las mismas presentaciones pequeñas, medianas y grandes disponibles en iOS también se pueden configurar en macOS. Los controles también se pueden colocar directamente en la barra de menú. Ahora que he agregado un control de seguimiento de café a mi app en macOS, puedo actualizar fácilmente mi registro de café directamente desde la barra de menú. En watchOS 26, los controles pueden aparecer en tres lugares. Se pueden configurar en el Centro de Control, accesible desde el botón lateral. Los controles también se pueden ejecutar al presionar el botón de acción en el Apple Watch Ultra. Y se pueden configurar en la Pila Inteligente, donde aparecen junto con otros widgets que muestran el símbolo, el título y el valor actual del control. Los controles se pueden proporcionar desde una app de watchOS o desde una app de iPhone en un dispositivo enlazado. Para obtener una guía detallada sobre cómo crear controles, consulta Amplía los controles de tu app en todo el sistema de la WWDC24. A continuación, te mostraré los widgets de relevancia en la Pila Inteligente de watchOS 26. He agregado un widget a mi app de seguimiento de cafeína en watchOS que me ayuda a realizar un seguimiento de cuándo mis cafeterías favoritas tienen horas felices con mitad de precio. Hay dos cosas que me gustaría mejorar en mi widget. En primer lugar, dado que estoy haciendo un seguimiento de la hora feliz de varias cafeterías, a menudo las horas felices se superponen, lo que significa que el contenido de mi widget en la Pila Inteligente está bastante apretado. En segundo lugar, las horas felices tienden a ocurrir aproximadamente a la misma hora. Así que durante el resto del día, mi widget no es muy útil. Realmente me gustaría que mi widget de la hora feliz solo apareciera en la Pila Inteligente si fuera relevante y mostrara información más detallada para cada hora feliz activa. Con los widgets de relevancia en watchOS 26, puedo hacer precisamente eso. Te mostraré cómo puedo configurar mis horas felices como un widget de relevancia. Para definir un widget de relevancia, crea un tipo de widget y, en lugar de una configuración StaticConfiguration o AppIntent, proporciona una RelevanceConfiguration. Al igual que otras configuraciones, se necesita una cadena kind, un objeto proveedor y el cierre para transformar tu entrada personalizada en una vista SwiftUI. El tipo de proveedor es RelevanceEntriesProvider. Los métodos placeholder y relevance son similares al TimelineEntriesProvider. Para placeholder, puedo devolver una entrada simple para que se muestre mientras se prepara mi contenido. Para relevance, primero busco una colección de objetos de configuración que he definido.

    Para mi widget de la hora feliz, es relevante una configuración entre la hora de inicio y la hora de finalización de esa hora feliz. Definiré el atributo de relevance con este contexto utilizando el intervalo de fechas para cada hora feliz. Luego implemento el método de entrada. A diferencia de un widget de Timeline, un RelevanceEntriesProvider solo proporciona una única entrada para una configuración. Tengo todos los datos que necesito para esta entrada en mi configuración, los datos de la tienda y el rango de tiempo para la hora feliz, así que puedo crearlo inmediatamente. Si necesitara otros datos o recursos, podría obtenerlos aquí ya que este método está marcado como asíncrono. Ahora, con mi widget de relevancia configurado, mi widget de horas felices solo se muestra en mi Pila Inteligente cuando es relevante. Además, si tengo varias configuraciones que son relevantes al mismo tiempo, puedo ver múltiples instancias de mi widget en la Pila Inteligente. Los widgets de relevancia son una nueva y poderosa funcionalidad de watchOS 26 que le brinda la posibilidad de conectar directamente el contenido del widget con su relevancia. Estos widgets son un gran complemento por sí solos o junto con los widgets existentes basados en Timeline. Para obtener más información sobre los widgets de relevancia, consulta las novedades de watchOS 26 con Anne. Ahora que hay muchos más lugares y plataformas donde pueden aparecer los widgets, me gustaría mantener mis widgets siempre actualizados dondequiera que estén. Recientemente agregué un servidor para poder mantener mis datos de registro de cafeína sincronizados en mis dispositivos. Cubriré qué opciones están disponibles para actualizar mi widget, comenzando con las recargas programadas del widget. En este diagrama, a la izquierda tengo mi paquete de apps, que contiene mi app así como mi extensión de widget. En el lado derecho, tengo un cuadro que representa a WidgetKit. Cuando se configura un widget en un dispositivo, como en la pantalla de inicio del iPhone o en la carátula de un reloj, WidgetKit solicita una línea de tiempo de la extensión del widget. La extensión responde con una línea de tiempo del widget, que incluye un TimelineReloadPolicy. WidgetKit utiliza esto para determinar el próximo momento apropiado para recargar ese widget. Usar TimelineReloadPolicy es una excelente opción para los widgets que necesitan actualizarse a intervalos regulares, como un widget que muestra el horario de una cafetería, un widget del clima o un widget de acciones. El sistema calcula el tiempo de recarga programado para ayudar a mantener el rendimiento y la vida útil de la batería.

    La API WidgetCenter es otra opción disponible para las apps. Dentro de una app, si ocurre un cambio de datos que debería reflejarse en su widget, se puede usar el método reloadAllTimelines o reloadTimelines(ofKind:) de WidgetCenter. Esto le dice a WidgetKit que el contenido del widget está desactualizado y necesita ser recargado. Luego, WidgetKit solicita una línea de tiempo de la extensión de widget para actualizar el widget. Esta es una excelente opción si el contenido del widget cambia principalmente dentro de la app, como actualizar un registro de cafeína, cambiar una nota o marcar un recordatorio. Dado que la app se está ejecutando cuando se llama a esta API, el sistema no calcula esta solicitud. ¿Pero qué sucede si se produce un cambio de datos en el servidor o en otro dispositivo? Aquí es donde entran en juego las actualizaciones push del widget. Un servidor que rastrea los cambios de datos puede enviar una notificación push a APNs, que le indicará a WidgetKit que recargue los widgets de esa app. Y, al igual que otras actualizaciones, WidgetKit solicitará una línea de tiempo actualizada del widget. Las actualizaciones push de widgets son una gran herramienta si los datos pueden cambiar externamente a ese dispositivo. Al igual que TimelineReloadPolicy, las actualizaciones de notificaciones push del widget también se calculan para mantener el rendimiento y la duración de la batería. Con esta capacidad, los widgets ahora tienen un conjunto completo de opciones de recarga para manejar una variedad de situaciones. Estas no son mutuamente excluyentes. Es posible que algunos widgets quieran utilizar dos o incluso las tres opciones. Gracias a las actualizaciones push de widgets, el registro de cafeína de mi widget puede mantenerse actualizado en todos los dispositivos, ya sea que registre una actualización en mi app para iPad, mi widget de Vision Pro o mi control de la barra de menú de macOS. Te mostraré cómo puedo agregar esto a mi widget. Crearé un WidgetPushHandler y lo agregaré a mi configuración de widget, agregaré el derecho de notificación push a mi extensión de widget y construiré una solicitud push de actualización de widget. Primero, crearé una estructura que se ajuste al protocolo del WidgetPushHandler. Este tipo es cómo le notificamos cuando su Token push cambia o cuando cambia el conjunto de widgets configurados. Utilice el método pushTokenDidChange como una oportunidad para enviar su Token push y la información del widget a su servidor. A continuación, necesito actualizar la configuración de mi widget. Aquí tengo la configuración de mi widget rastreador de cafeína. Agregaré el modificador pushHandler a mi widget para registrar su soporte para notificaciones push. Para este modificador, paso el tipo de pushHandler del widget que implementé.

    Finalmente, en Xcode, iré a la pestaña de firma y capacidades para mi extensión de widget. Aquí agregaré el derecho de notificación push para que pueda comunicarse con APNs. Ahora que mi widget está configurado para actualizaciones push, te mostraré cómo enviar una notificación push de actualización de widget. Para actualizar su widget a través de notificaciones push, envía una solicitud HTTPS POST al servidor Apple Push. Usa el token push del widget proporcionado en tu WidgetPushHandler como la última parte de la ruta de solicitud. Para los encabezados, usa el tipo push de APNs de los widgets y configura el encabezado del tema APNs usando el ID del paquete de la app, con el sufijo .push-type.widgets. En el cuerpo de la solicitud en el diccionario APS, establece el valor de la clave de contenido modificado a true. Para obtener más información sobre las notificaciones push, ve el artículo “Introducción a las notificaciones push”. Y consulta “Conoce la consola de notificaciones push”, para ver cómo puedes probar fácilmente las solicitudes de notificaciones push. Las actualizaciones push de los widgets ayudan a mantener el contenido de los widgets más actualizado, pero se realizan de manera oportunista y no son un reemplazo directo de otras experiencias de notificación. Si tienes una actualización urgente o importante para mostrar, proporciona una notificación al usuario. Si tienes actualizaciones que ocurren periódicamente durante un período limitado, como un pedido de bebida, actualización de resultados deportivos o actualizaciones de vuelos, usa una Actividad en Vivo. Usa las actualizaciones push del widget para mantener el contenido del widget actualizado. Las actualizaciones push de widgets están disponibles en todas las plataformas que admiten widgets. Cuando envías una notificación push de widget, esto actualizará todos los widgets habilitados para push configurados en el dispositivo. Recuerda que estas recargas de widgets están calculadas. Intenta mantener el envío de actualizaciones limitado, por ejemplo, limitando las actualizaciones en el servidor. Y durante el desarrollo y la prueba, puedes usar el modo de desarrollador de WidgetKit en la configuración para ignorar los cálculos push y de recarga de tu app. He hablado de mucho hoy. Tómate un tiempo para explorar estas nuevas plataformas para widgets. Echa una mirada algunos de los videos mencionados anteriormente para inspirarte. Asegúrate de que tus widgets se vean geniales en las nuevas apariencias en iOS y macOS. Y finalmente, si los datos de tus widgets pueden actualizarse desde fuentes externas u otros dispositivos, considera agregar notificaciones push para mantenerlos actualizados. Estoy muy entusiasmado con todas las nuevas capacidades y lugares para los widgets. No puedo esperar a llevar tus widgets conmigo dondequiera que vaya. Gracias por acompañarnos.

    • 2:44 - Observe .widgetRenderingMode

      struct MostFrequentBeverageWidgetView: View {
          @Environment(\.widgetRenderingMode) var renderingMode
          
          var entry: Entry
          
          var body: some View {
              ZStack {
                  if renderingMode == .fullColor {
                      Image(entry.beverageImage)
                          .resizable()
                          .aspectRatio(contentMode: .fill)
                  
                      LinearGradient(gradient: Gradient(colors: [.clear, .clear, .black.opacity(0.8)]), startPoint: .top, endPoint: .bottom)
                  }
                  
                  VStack {
                      if renderingMode == .accented {
                          Image(entry.beverageImage)
                              .resizable()
                              .widgetAccentedRenderingMode(.desaturated)
                              .aspectRatio(contentMode: .fill)
                      }
                      
                      BeverageTextView()
                  }
              }
          }
      }
    • 6:08 - visionOS Widget Configuration

      struct CaffeineTrackerWidget: Widget {
          var body: some WidgetConfiguration {
              StaticConfiguration(
                  kind: "BaristaWidget",
                  provider: Provider()
              ) { entry in
                  CaffeineTrackerWidgetView(entry: entry)
              }
              .configurationDisplayName("Caffeine Tracker")
              .description("A widget tracking your caffeine intake during the day.")
              .supportedMountingStyles([.elevated])
              .widgetTexture(.paper)
              .supportedFamilies([.systemExtraLargePortrait])
          }
      }
    • 8:56 - LevelOfDetail - CaffeineTrackerWidgetView

      struct CaffeineTrackerWidgetView : View {
          @Environment(\.levelOfDetail) var levelOfDetail
          
          var entry: CaffeineLogEntry
      
          var body: some View {
              VStack(alignment: .leading) {
                  TotalCaffeineView(entry: entry)
      
                  if let log = entry.log {
                      LastDrinkView(log: log)
                  }
      
                  if levelOfDetail == .default {
                      LogDrinkView()
                  }
              }
          }
      }
    • 9:46 - LevelOfDetail - TotalCaffeineView

      struct TotalCaffeineView: View {
          @Environment(\.levelOfDetail) var levelOfDetail
          
          let entry: CaffeineLogEntry
      
          var body: some View {
              VStack {
                  Text("Total Caffeine")
                      .font(.caption)
      
                  Text(totalCaffeine.formatted())
                      .font(caffeineFont)
              }
          }
          
          var caffeineFont: Font {
              if levelOfDetail == .simplified {
                  .largeTitle
              } else {
                  .title
              }
          }
          
          var totalCaffeine: Measurement<UnitMass> {
              entry.totalCaffeine
          }
      }
    • 11:49 - Add .supplementalActivityFamilies

      struct ShopOrderLiveActivity: Widget {
          var body: some WidgetConfiguration {
              ActivityConfiguration(for: Attributes.self) { context in
                  ActivityView(context: context)
              } dynamicIsland: { context in
                  DynamicIsland {
                      DynamicIslandExpandedRegion(.leading) {
                          ExpandedView(context: context)
                      }
                  } compactLeading: {
                      LeadingView(context: context)
                  } compactTrailing: {
                      TrailingView(context: context)
                  } minimal: {
                      MinimalView(context: context)
                  }
              }
              .supplementalActivityFamilies([.small])
          }
      }
    • 12:27 - Add .activityFamily

      struct ActivityView: View {
          @Environment(\.activityFamily) var activityFamily
          var context: ActivityViewContext<Attributes>
          
          var body: some View {
              switch activityFamily {
              case .small:
                  ShopOrderSmallView(context: context)
              default:
                  ShopOrderView(context: context)
              }
          }
      }
    • 16:20 - Define relevance widget with RelevanceConfiguration

      struct HappyHourRelevanceWidget: Widget {
          var body: some WidgetConfiguration {
              RelevanceConfiguration(
                  kind: "HappyHour",
                  provider: Provider()
              ) { entry in
                  WidgetView(entry: entry)
              }
          }
      }
    • 16:41 - Implement RelevanceEntriesProvider

      struct Provider: RelevanceEntriesProvider {
          func placeholder(context: Context) -> Entry {
              Entry()
          }
          
          func relevance() async -> WidgetRelevance<Configuration> {
              let configs = await fetchConfigs()
              var attributes: [WidgetRelevanceAttribute<Configuration>] = []
              
              for config in configs {
                  attributes.append(WidgetRelevanceAttribute(
                      configuration: config,
                      context: .date(interval: config.interval, kind: .default)))
              }
              
              return WidgetRelevance(attributes)
          }
          
          func entry(configuration: Configuration,
                     context: RelevanceEntriesProviderContext) async throws -> Entry {
              Entry(shop: configuration.shop, timeRange: configuration.timeRange)
          }
      }
    • 21:13 - Handle push token and widget configuration changes

      struct CaffeineTrackerPushHandler: WidgetPushHandler {
          func pushTokenDidChange(_ pushInfo: WidgetPushInfo, widgets: [WidgetInfo]) {
              // Send push token and subscription info to server
          }
      }
    • 21:30 - Add pushHandler to WidgetConfiguration

      struct CaffeineTrackerWidget: Widget {
          var body: some WidgetConfiguration {
              StaticConfiguration(
                  kind: Constants.widgetKind,
                  provider: Provider()
              ) { entry in
                  CaffeineTrackerWidgetView(entry: entry)
              }
              .configurationDisplayName("Caffeine Tracker")
              .pushHandler(CaffeineTrackerPushHandler.self)
          }
      }
    • 22:29 - Push Notification Request Body

      {
          "aps": {
              "content-changed": true
          }
      }
    • 0:00 - Introducción
    • Obtén información sobre las actualizaciones de WidgetKit, incluidas nuevas formas de incorporar tu app al sistema, mostrar contenido relevante en Pila Inteligente y mantener la app actualizada.

    • 1:03 - Widgets en nuevos lugares
    • Los widgets tienen nuevas opciones de estilo y están disponibles en nuevos lugares. Consulta algunos consejos para que tus widgets se vean geniales con el modo de renderizado acentuado. Los widgets están disponibles en más lugares, incluidos visionOS 26 y CarPlay. Los widgets en visionOS 26 se pueden agregar a salas y fijar a superficies. Estos widgets se pueden personalizar para admitir diferentes estilos de montaje, texturas y niveles de detalle según la proximidad. CarPlay y macOS 26 ya admiten actividades en vivo. Los controles están disponibles en macOS Tahoe y watchOS 26.

    • 15:31 - Widgets de relevancia
    • Los widgets relevantes aparecen en Pila Inteligente en watchOS 26 cuando son más relevantes según las rutinas de las personas, la ubicación y más. Estos widgets aparecen en Pila Inteligente solo cuando son relevantes y pueden aparecer varias instancias al mismo tiempo, como en el caso de eventos de calendario superpuestos o happy hours. Crea widgets relevantes especificando cuándo el widget es más relevante, como en un momento particular o en un tipo de ubicación.

    • 18:12 - Actualizaciones del widget Push
    • Los widgets en todas las plataformas WidgetKit se pueden actualizar mediante actualizaciones push a través de APNS. Existen múltiples herramientas para mantener los widgets actualizados y la mejor herramienta para cada caso de uso está determinada por cómo se actualizan los datos de su widget. Las líneas de tiempo son buenas para actualizar datos periódicamente. Los cambios impulsados por la interacción en una app deben recargar AllTimelines. Para la sincronización entre dispositivos o cambios de datos externos, como desde un servidor, utilice actualizaciones push del widget. Las actualizaciones push de los widgets ayudan a mantener los widgets más actualizado, pero no son un reemplazo directo de otras experiencias de notificación. Considera si una notificación de usuario, una actividad en vivo o un widget es lo mejor para cada caso de uso.

Developer Footer

  • Videos
  • WWDC25
  • Novedades de widgets
  • Open Menu Close Menu
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • visionOS
    • watchOS
    Open Menu Close Menu
    • Swift
    • SwiftUI
    • Swift Playground
    • TestFlight
    • Xcode
    • Xcode Cloud
    • Icon Composer
    • SF Symbols
    Open Menu Close Menu
    • Accessibility
    • Accessories
    • App Store
    • Audio & Video
    • Augmented Reality
    • Business
    • Design
    • Distribution
    • Education
    • Fonts
    • Games
    • Health & Fitness
    • In-App Purchase
    • Localization
    • Maps & Location
    • Machine Learning & AI
    • Open Source
    • Security
    • Safari & Web
    Open Menu Close Menu
    • Documentation
    • Sample Code
    • Tutorials
    • Downloads
    • Forums
    • Videos
    Open Menu Close Menu
    • Support Articles
    • Contact Us
    • Bug Reporting
    • System Status
    Open Menu Close Menu
    • Apple Developer
    • App Store Connect
    • Certificates, IDs, & Profiles
    • Feedback Assistant
    Open Menu Close Menu
    • Apple Developer Program
    • Apple Developer Enterprise Program
    • App Store Small Business Program
    • MFi Program
    • News Partner Program
    • Video Partner Program
    • Security Bounty Program
    • Security Research Device Program
    Open Menu Close Menu
    • Meet with Apple
    • Apple Developer Centers
    • App Store Awards
    • Apple Design Awards
    • Apple Developer Academies
    • WWDC
    Get the Apple Developer app.
    Copyright © 2025 Apple Inc. All rights reserved.
    Terms of Use Privacy Policy Agreements and Guidelines