Attribution

Attribution montre ce que ton budget publicitaire achète : le spend et le ROAS en face de tes revenus, les postbacks SKAdNetwork d'Apple sur ton propre endpoint, et tes événements de conversion renvoyés aux régies.

Le module s'appuie sur Appwin Core et Analytics : les conversions passent par les événements du SDK, tout le reste se règle dans le dashboard. Ses trois briques - comptes pub connectés, endpoint de postback, événements de conversion - sont indépendantes : chacune fonctionne sans les autres.

Installation

  1. 1

    Installe le SDK et initialise Analytics

    Attribution ne s'installe pas à part : il réutilise les événements d'Analytics. Le Quickstart génère l'installation d'Appwin Core et d'Analytics pour chaque plateforme. Vérifie qu'initialize() d'Analytics répond ready avant de suivre des conversions.

  2. 2

    Déclare l'endpoint de postback (iOS)

    Ajoute deux clés à ton Info.plist pour qu'iOS envoie ses postbacks d'attribution sur l'endpoint d'appwin :

    xml
    <!-- SKAdNetwork (toutes les versions d'iOS supportées) -->
    <key>NSAdvertisingAttributionReportEndpoint</key>
    <string>https://appwin.io</string>
    
    <!-- AdAttributionKit (iOS 17.4+) -->
    <key>AttributionCopyEndpoint</key>
    <string>https://appwin.io</string>
    

    Tu obtiens la colonne SKAN observé : les installs qu'Apple lui-même a attribuées à tes pubs. Ce sont des clés de build lues par iOS ; aucun SDK ne peut les poser à l'exécution. Les postbacks arrivent 24 à 144 h après l'install (ne les compare jamais jour à jour avec les chiffres des régies), et iOS normalise l'endpoint au domaine enregistrable : toute valeur en *.appwin.io livre sur appwin.io.

Connecter les comptes publicitaires

Réglages de l'app → Intégrations → Revenue : Meta, TikTok et Apple Search Ads, chacun en lecture seule et sans code (appwin n'écrit jamais sur un compte publicitaire). Meta et TikTok se connectent en OAuth ; pour Apple Search Ads, appwin génère une clé que tu colles dans un utilisateur API en lecture seule, puis toutes les organisations ASA qu'il voit sont connectées. Tu obtiens le spend quotidien par réseau, campagne, ad group et ad avec les vignettes des créas (page Campagnes), et les bénéfices croisés avec tes revenus (page Bénéfices).

Ces chiffres sont du Reported by network (ce que les plateformes revendiquent) : appwin ne les mélange jamais silencieusement avec ce qu'il observe lui-même.

Apple Search Ads remonte les installs, pas les essais ni les achats. Active l'intégration Apple Search Ads de RevenueCat et fais collecter le jeton AdServices par l'app (Purchases.enableAdServicesAttributionTokenCollection()) : les Essais et Achats de chaque campagne, groupe et mot-clé ASA comptent alors les abonnés que RevenueCat leur attribue, rapprochés par nom.

Sur Campagnes, les filtres Canal, Plateforme et Pays prennent une ou plusieurs valeurs. La plateforme est celle de l'app promue par la campagne (Apple Search Ads : toujours l'App Store ; Meta et TikTok : l'app de ses ad sets ou ad groups). Le pays vient des rapports des réseaux découpés par pays, sur les 90 derniers jours : les conversions SKAN n'ont pas de pays et disparaissent sous ce filtre, comme les installs de la ligne « Organique & non attribué ».

Suivre les conversions

Prérequis : SDK installé, Analytics initialisé. Toute l'étape tourne sur quatre noms d'événements :

ÉvénementQuand le déclencherProps
app_installJamais - le SDK l'émet-
start_trialUn essai gratuit démarre-
purchaseLe store confirme un paiement{ value, currency }
subscribeOptionnel : un abonnement s'active (vs vente one-shot){ value, currency }

Déclenche-les là où ton pipeline d'achat confirme la transaction, après le oui du store, jamais sur les restaurations. Sur purchase, le montant voyage en value (nombre) et currency (ISO 4217) ; toute autre prop reste à la maison.

Avec RevenueCat

swift
let result = try await Purchases.shared.purchase(package: package)
guard !result.userCancelled else { return }

let product = package.storeProduct
let isTrial = result.customerInfo.entitlements.active.values
  .contains { $0.periodType == .trial }

if isTrial {
  AppwinCore.track("start_trial")
} else {
  AppwinCore.track("purchase", props: [
    "value": Double(truncating: product.price as NSNumber),
    "currency": product.currencyCode ?? "USD",
  ])
}

Ton webhook RevenueCat (produit Revenue) et ces appels sont complémentaires : le webhook alimente les analytics de revenu côté serveur, track() s'exécute sur l'appareil - ce dont les conversion values et l'activation ont besoin.

Avec une autre stack d'achat

Même motif : un track dans le callback de succès.

swift
// StoreKit 2, sans SDK d'achat
let result = try await product.purchase()
if case .success(let verification) = result,
   case .verified(let transaction) = verification {
  AppwinCore.track("purchase", props: [
    "value": Double(truncating: product.price as NSNumber),
    "currency": product.priceFormatStyle.currencyCode,
  ])
  await transaction.finish()
}
swift
// Adapty
let result = try await Adapty.makePurchase(product: product)
if !result.isPurchaseCancelled {
  AppwinCore.track("purchase", props: [
    "value": Double(truncating: product.price as NSNumber),
    "currency": product.currencyCode ?? "USD",
  ])
}

Qonversion, Glassfy, Play Billing en direct : idée identique.

Sans rien coder de plus, tu obtiens :

  • Conversion values (iOS) - appwin gère la conversion value SKAdNetwork depuis tes événements. Schéma dans le dashboard ; défauts : essai = 32, achat = 63.
  • Sources d'install (Android) - le Play Install Referrer de chaque install, dans la vue d'ensemble.
  • Activation réseaux - tes événements renvoyés à Meta (côté serveur) et TikTok (adapter embarqué), gatés par le consentement.

Activer l'activation réseaux

Le consentement d'abord : l'activation est opt-in. Relaie le choix de l'utilisateur en un appel, typiquement branché sur la popup ATT côté iOS.

swift
let authorized = await AppwinAttribution.requestTrackingAuthorization()
AppwinAttribution.setAdvertisingConsent(authorized ? .granted : .denied)

Déclare NSUserTrackingUsageDescription dans ton Info.plist. Déjà une CMP ? Garde-la, relaie juste son verdict publicitaire.

Le consentement décide si les événements partent vers les régies ; l'ATT décide seulement si l'identifiant publicitaire les enrichit. Un ATT refusé active quand même, avec une qualité de match moindre.

Puis câble chaque réseau :

RéseauDans leur consoleDans appwin
MetaEvents Manager → votre dataset → Conversions API → générer un token system-userAttribution → Intégrations → Activation des signaux → Connecter Meta : coller dataset ID + token
TikTokEvents Manager → copier le TikTok App ID + l'access tokenAjouter le package AppwinTikTokEvents (iOS) / io.appwin:appwin-tiktok-events (Android) - sa présence EST l'intégration - puis coller les deux dans Connecter TikTok

Enfin, recopie ton schéma de conversion value (dashboard, Attribution → SKAN) dans la console de chaque réseau pour qu'ils décodent les postbacks de la même façon. Avec le schéma par défaut, c'est deux lignes : 32 = essai démarré (coarse : medium), 63 = achat (coarse : high).

Règles et limites

  • La source par install sur iOS n'existe pour personne : SKAN répond en agrégé, et c'est le principe. Appwin n'est pas un MMP certifié - il s'appuie sur les rails ouverts auxquels tout développeur a droit.
  • Le référent Play dit ce que l'annonceur a mis dans le lien du store ; les campagnes non taguées apparaissent en « other ».
  • La qualité de match dépend de ce que les utilisateurs consentent à partager. Le dashboard sépare toujours le Reported by network de l'Observed by appwin.

Suite