iOS 16 LockScreen Widget — Journée innovation Frianbiz
Mise en place de widgets sur le lock screen d’iOS 16.
Au cours de la journée innovation de Frianbiz du vendredi 07 Octobre 2022, j’ai pu mettre en place des widgets pour l’écran de verrouillage d’iOS 16.
Qu’est-ce qu’un Widget
Un Widget est un élément que l’on peut ajouter sur l’écran de verrouillage d’iOS 16 qui permet d’afficher différentes informations en provenance d’une application. (Les widgets peuvent aussi être présents sur l’écran d’accueil et dans la section dédiée au widget.)
Limite des Widgets
L’affichage
Les widgets sont limités dans leurs affichages par leur taille et doivent donc présenter les informations importantes de manière claire et concise.
La mise à jour
En plus d’afficher les informations, le widget doit pouvoir les mettre à jour afin de garantir leur exactitude.
Mettre à jour un widget consomme en effet des ressources système.
C’est pourquoi Apple va, en fonction de différents paramètres, allouer un budget à votre widget pour qu’il se mette à jour. Celui-ci est calculé dynamiquement et prend en compte différents facteurs (Source: Apple Documentation) :
- La fréquence et les heures auxquelles le widget est visible par l’utilisateur.
- L’heure du dernier rechargement du widget
- L’état de l’application lié au widget
Chacune des mises à jour consommera une part du budget, sauf dans certains cas :
- Si l’application est au premier plan
- Si l’application a une session audio ou une session de navigation en cours
- La “local” du système change
- Si des paramètres dynamiques ou d’accessibilité sont modifiés
Mise en place d’un widget
La mise en place d’un widget dans une application iOS est relativement simple pour ce faire, une fois votre projet ouvert avec xCode, il suffit de suivre ce cheminement:
File -> New -> Target
Puis dans l’écran de choix d’un template pour la nouvelle target, il faut choisir: “Widget Extension”
Une fois l’extension créée, différents fichiers seront générés dans la section dédiée à l’extension du widget.
Dans un premier temps, le fichier qui nous intéresse est le fichier swift MyWidget_widget.swift
Mise en place des previews
Nous allons créer trois previews avec un contexte chacun, pour ce faire, il suffit d’ajouter cette ligne a chacune des preview
.previewContext(WidgetPreviewContext(family: .accessoryInline))
Il est possible de nommer chaque preview afin de les retrouver plus simplement :
.previewDisplayName("InLine")
Widgets Previews:
Une fois les previews configurés, le canvas des previews affichera ceci:
Trois boutons présents en haut à gauche permettent de naviguer entre les trois différents widgets circular
rectangular
in line
Mise en place des views
des widgets
Dans la section EntryView
afin de conditionner l’affichage en fonction du type de widget, il nous faut ajouter la variable d’environnement widgetFamily
@Environment(\.widgetFamily) var widgetFamily
Cette variable nous permet de connaître le contexte d’affichage du widget et donc d’adapter la vue à ce contexte. widgetFamily
est un enum (Documentation d’Apple) ce qui permet via un switch d’accéder au différents états possibles du contexte du widget.
Voici un exemple de vue simple pour les widgets sur le lock screen:
Rendu des vues
Mise à jour des widgets
Une fois ce premier widget simple mis en place, j’ai décidé d’aller un peu plus loin en ayant un widget qui afficherait un vol en cours et sa progression.
Voici les vues mises en place pour ce widget
Timeline pour des événements prévisibles
Certains widgets ont des points prévisibles dans le temps où il est logique de mettre à jour les informations. (exemple: Une application météo qui affiche la température actuelle devrait mettre à jour sont contenu régulièrement ou un widget donnant des informations boursières pourra être mis à jour durant les heures d’ouverture de la bourse, etc.)
Pour ce faire, nous utilisons un TimelineProvider
Pour cette journée innovation, j’ai choisi de stocker les informations via une API. Je n’ai donc pas eu à utiliser d’ IntentTimelineProvider
offrant une approche différente pour mettre à jour un widget (Source: Apple documentation)
Mise en place du TimelineProvider
Pour ce faire, il suffit de créer un Provider qui suit le protocole TimelineProvider
Dans ce code, nous avons deux premières fonctions qui ont pour but de créer un placeholder et l’autre de crée un snapshot depuis un contexte.
Dans cette journée innovation, je me suis concentré uniquement sur la mise à jour via la timeline.
Dans cette timeline, je fais appel à un NetworkManager qui permet de faire appel à l’API et de retrouver les données du vol. Une fois les données retrouvées, je construis l’entrée du vol et crée une timeline qui est renvoyée via la complétion.
Cette timeline est configurée pour se mettre à jour toutes les 30 minutes.
Forcer la mise à jour
Il est aussi possible pour l’application, liée au widget, de forcer la mise à jour d’une timeline ou de toutes les timelines si nécessaire.
Pour ce faire, il faut importer WidgetKit et d’appeler les méthodes suivantes:
WidgetCenter.shared.reloadAllTimelines()
// Force l'update de toutes les timelinesWidgetCenter.shared.reloadTimelines(ofKind: "com.exemple.myapp.timelineIdentifier")
// Force l'update de la timeline identifier
Confidentialité des données
Lorsque des données sensibles sont affichées via un widget, il est possible de définir quelles informations sont sensibles et de masquer ces données tant que le téléphone est verrouillé.
Pour mettre en place cette protection, il faut ajouter la “Capability” Data protection dans les réglages de votre application.
Une fois fait, il suffit d’ajouter le modifier de vue .privacySensitive(true)
aux vues contenant des informations sensibles.
Dans mon exemple, j’ai ajouté cette ligne sur l’intégralité du Vstack
ce qui cache entièrement le widget tant que le téléphone est verrouillé.
Conclusion
La mise en place de widget est relativement rapide et simple. En quelques heures, un widget peut être créé.
Bien que la mise à jour reste claire et simple à mettre en place, le système d’iOS gère le budget alloué à un widget selon beaucoup de critères qui change continuellement.