Optimiser le chargement des flows et paywalls dans le SDK iOS
Un chargement fiable de flow ou de paywall sur iOS repose sur trois éléments : un rendu rapide, le retour de la variante ciblée selon l’audience, et un repli élégant en cas de réseau lent. Les règles ci-dessous couvrent le timing, la mise en cache et les stratégies de repli pour y parvenir.
Ces règles supposent que Adapty.activate() et Adapty.identify() ont déjà été résolus. Consultez Ordre des appels dans le SDK iOS.
Règles et pièges
| Faire | Ne pas faire | Pourquoi |
|---|---|---|
Récupérez le placement que vous êtes sur le point d’afficher, ou préchauffez le cache avec preloadFlows (SDK 4.1+). | Déclencher vos propres appels concurrents getFlow au lancement. | Une rafale de préchargement artisanale bloque le thread principal et produit un écran noir. preloadFlows est conçu pour ça et partage un seul budget de timeout sur tout le lot. |
Appelez getFlow après que l’attribution a eu le temps de se résoudre — par exemple, 1 à 2 secondes après activate ou après le déclenchement de didLoadLatestProfile. | Appeler getFlow dans App.init(). | L’attribution n’est pas encore arrivée. Le flow se résout sur l’audience par défaut et contourne silencieusement les segments et la personnalisation ASA. |
Définissez un loadTimeout et configurez un paywall de secours pour chaque placement. | Attendre getFlow indéfiniment. | Sans timeout, les utilisateurs avec une mauvaise connexion voient un écran vide jusqu’à ce que le réseau réponde — ou ferment l’application. |
Lorsque loadTimeout se déclenche sur n’importe quelle requête — y compris un simple getFlow — le SDK renvoie la variante mise en cache si elle existe, sinon il récupère la variante de l’audience par défaut (All Users) dans le temps restant. Le ciblage est perdu pour cette requête, pas simplement retardé : les segments et les audiences basées sur l’attribution ne s’appliquent pas au résultat.
Consultez Récupérer les paywalls et les produits pour la référence des paramètres fetchPolicy et loadTimeout, et Placements pour choisir le bon placement.
Précharger les placements
preloadFlows et preloadFlowsForDefaultAudience sont disponibles à partir de la version 4.1 du SDK.
preloadFlows met en cache le JSON du flow à l’avance — une requête par placement. Vous l’utilisez ensuite comme d’habitude : getFlow pour le flow, getFlowConfiguration pour sa configuration de vue.
fetchPolicy détermine quelle couche un getFlow ultérieur lit en premier, pas s’il peut accéder au cache :
.returnCacheDataElseLoadlit d’abord la copie préchargée et n’accède au réseau que si rien n’est en cache..returnCacheDataIfNotExpiredElseLoad(maxAge:)fait de même tant que la copie est plus récente quemaxAge.- La valeur par défaut,
.reloadRevalidatingCacheData, passe d’abord par le réseau et se rabat sur la copie préchargée en cas d’échec ou de timeout.
Le préchargement est utile dans les deux cas, mais différemment : une politique cache-first supprime la requête, tandis que la valeur par défaut la conserve tout en disposant d’une copie chaude en secours.
Utilisez cette méthode quand vous savez quels placements la session va nécessiter, mais que vous ne voulez pas les afficher tout de suite — par exemple, juste après la résolution de activate et identify, pour le flow derrière un bouton que l’utilisateur n’a pas encore tapé.
Paramètres :
placementIds(obligatoire) : les placements à précharger. Les IDs vides et en double sont ignorés.loadTimeout(optionnel) : délai d’expiration en secondes pour l’ensemble du lot, non par placement. Par défaut 5 secondes, et les valeurs inférieures à 1 seconde sont relevées à 1 seconde.
Ce qu’il faut savoir sur le comportement :
- La méthode ne lève une exception qu’après avoir essayé tous les placements, et l’erreur regroupe les échecs par placement. Un échec sur un placement n’interrompt pas les autres.
- Si un placement expire ou échoue avec une erreur réseau, le SDK bascule sur la variante d’audience par défaut pour ce placement. Les autres échecs sont rapportés tels quels.
- Si le délai expire avant que la récupération ciblée par audience soit terminée, le SDK tente quand même la variante d’audience par défaut dans le temps restant.
- Le préchargement sert uniquement à alimenter le cache. Il ne retourne pas de contenu — vous appelez toujours
getFlowpour l’afficher.
Ce que couvre un préchargement
Un flow s’affiche à l’écran par couches. Un préchargement couvre la première, exactement comme le fait getFlow :
| Couche | Récupérée par | Mise en cache par un préchargement |
|---|---|---|
| JSON du flow — la variante choisie, ses identifiants de produits et la Remote Config | getFlow | Oui |
| Mise en page de l’UI — structure, styles et textes de l’écran | getFlowConfiguration | Non |
| Images, y compris la première image fixe utilisée à la place d’un élément vidéo | getFlowConfiguration, en arrière-plan | Non |
| Fichiers vidéo | Le lecteur système, au moment du rendu de l’écran | Non mis en cache par le SDK |
getFlowConfiguration attend le layout, donc la première requête pour un layout donné coûte un aller-retour réseau, même après un préchargement. Le SDK conserve ensuite ce layout dans son propre cache disque, qui survit aux redémarrages de l’application et est lu avant tout appel réseau — le coût ne se répercute donc que sur la première requête, pas sur toutes. Une fois le layout disponible, le SDK commence à mettre les images en cache indépendamment de l’appel : il ne bloque pas l’affichage de l’écran, et aucun callback, méthode déléguée ou erreur ne signale la fin de cette opération.
Identifier quel placement a échoué
L’erreur levée est un AdaptyError unique couvrant tout le lot, avec le code networkFailed (2005). Pour voir les échecs individuels, consultez sa propriété preloadErrors — un dictionnaire indexé par ID de placement :
do {
try await Adapty.preloadFlows(placementIds: ["onboarding", "main_paywall"])
} catch {
for (placementId, placementError) in error.preloadErrors ?? [:] {
// log or retry the individual placement
}
}
preloadErrors est nil pour toute erreur ne provenant pas d’un appel de préchargement ; traitez donc une valeur nil comme « pas un échec de préchargement » plutôt que comme « aucune erreur ».
Ignorer la segmentation d’audience
Pour préchauffer le cache sans attendre la segmentation d’audience, utilisez la variante d’audience par défaut :
try await Adapty.preloadFlowsForDefaultAudience(placementIds: ["main_paywall"])
Afficher les médias du premier écran depuis le bundle de l’application
Un flow télécharge ses images et vidéos depuis Adapty. Pour afficher instantanément les médias du premier écran, servez-les depuis le bundle de l’application. C’est une bonne façon de réutiliser des médias déjà inclus dans l’app, comme les visuels d’un onboarding natif existant.
- Dans le Flow & Paywall Builder, définissez un identifiant de média personnalisé sur l’image ou la vidéo. Le fichier que vous y importez reste en tant que solution de secours.
- Ajoutez le fichier au bundle de l’application.
- Lorsque vous appelez
getFlowConfiguration, transmettez le fichier du bundle pour cet identifiant viaassetsResolver:
// "welcome_video" is the custom media ID set in the Flow & Paywall Builder
let bundledAssets: [String: AdaptyCustomAsset] = [
"welcome_video": .video(
.file(
url: Bundle.main.url(forResource: "welcome", withExtension: "mp4")!,
preview: .uiImage(value: UIImage(named: "welcome_poster")!),
resolution: CGSize(width: 1080, height: 1920)
)
),
]
let flowConfig = try await AdaptyUI.getFlowConfiguration(
forFlow: flow,
assetsResolver: bundledAssets
)
Les fichiers intégrés augmentent la taille de téléchargement de votre application, alors n’intégrez que les médias visibles en premier.
Les médias non intégrés s’affichent quand même immédiatement : la configuration de la vue contient une petite copie en basse résolution de chaque image, y compris l’image fixe d’une vidéo, et l’affiche jusqu’au chargement du fichier complet.
Pour la référence complète de assetsResolver, consultez Personnaliser les assets.
Optimiser pour une mauvaise connectivité
Pour les marchés où la connectivité est régulièrement mauvaise (zones rurales, transports, régions affectées par le routage) :
- Définissez
fetchPolicy: .returnCacheDataElseLoadsur chaque requête sauf la toute première. - Configurez un paywall de secours pour chaque placement dans l’Adapty Dashboard.
- Définissez
loadTimeoutentre 3 et 5 secondes et acceptez le paywall de secours quand le délai expire. - N’attendez pas
getProfile()pour afficher le flow. AppelezgetFlowindépendamment pour qu’un profil lent ne bloque pas l’interface.