Identité : utilisateurs anonymes et connectés

L'identité est portée par AppwinCore, pas par les produits. Un appareil, une session, un utilisateur : les modules Community, Support et Notifications lisent tous la même. C'est ce qui fait qu'une personne identifiée dans ton app est le même interlocuteur partout, sans que tu aies rien à recopier d'un produit à l'autre.

Trois états, dans cet ordre. Chacun est utilisable seul : tu peux t'arrêter au premier et avoir une intégration qui fonctionne.

1. Anonyme - rien à faire

Dès configure, le SDK reconnaît l'appareil : il génère un identifiant, le persiste, et ouvre une session authentifiée en tâche de fond. L'end-user peut lire et écrire sans inscription.

swift
AppwinCore.configure(projectAppId: "ton-app-id")
print(AppwinCore.deviceId ?? "-")   // stable d'un lancement à l'autre

L'identifiant est persisté dans le trousseau, donc il survit à une désinstallation. C'est ce qui évite qu'une personne perde son historique en changeant de version d'app.

Ce que voit cet end-user dépend du produit. Côté Community, son profil naît avec un pseudo généré stable (« Curious Otter 417 »), dérivé de son identifiant : s'il réinstalle l'app, il retrouve le même pseudo plutôt que de repartir avec une nouvelle identité aux yeux des autres. Côté Support, il ouvre une conversation comme visiteur.

Un membre anonyme peut se nommer lui-même depuis l'écran de profil du SDK. Il n'a pas besoin de toi pour ça.

2. Connecté - rattacher à ton utilisateur

Quand ton app sait qui est la personne, pousse ton identifiant, celui de ta base. Appwin ne l'interprète pas : il sert à reconnaître la même personne d'un appareil à l'autre et d'un produit à l'autre.

swift
AppwinCore.identify(externalId: user.id)
try await AppwinCore.bootstrapSession(externalId: user.id)

Deux gestes plutôt qu'un : identify inscrit l'externalId dans l'identité locale, bootstrapSession(externalId:) refrappe un jeton qui le porte. Sans le second, la session ouverte reste celle du profil anonyme jusqu'au prochain démarrage de l'app.

Les modules produit exposent un raccourci - AppwinCommunity.login(...), AppwinSupport.loginIdentifiedUser(...) - qui pousse la même valeur dans Core et rattache la personne côté serveur. C'est le chemin par défaut en React Native, où Core n'expose pas la variante à externalId.

C'est là que se joue le partage : après ce rattachement, cette personne est la même pour Support et pour Community. Ses conversations et son profil appartiennent au même individu, et ton équipe le voit comme un seul interlocuteur.

Déconnexion

swift
await AppwinCore.signOut()

signOut révoque la session côté serveur, vide le stockage local et repasse en profil anonyme. À appeler quand l'utilisateur se déconnecte de ton app - sinon la personne suivante sur le même appareil hériterait de son identité.

Il existe aussi clearIdentity(), qui oublie l'externalId localement sans rien révoquer. C'est un outil de test, pas une déconnexion.

3. Enrichi - pousser les attributs

Ton app connaît souvent déjà un pseudo, une photo, un email. Les pousser épargne une saisie. Cette passerelle est propre à chaque produit, parce que les attributs ne sont pas les mêmes : un profil communautaire n'est pas une fiche client.

ProduitMéthodeChamps
CommunityAppwinCommunity.setUser(...)nickname, avatarUrl, bio
SupportAppwinSupport.updateUser(...)name, email, avatarUrl, language, timezone, location
swift
try await AppwinCommunity.setUser(
  nickname: user.displayName,
  avatarUrl: user.photoURL?.absoluteString
)

Deux règles :

  • Tous les champs sont optionnels. Un champ omis n'est pas écrasé : une app qui ne connaît qu'un pseudo n'efface pas la bio saisie dans le SDK.
  • Fournir un nickname sort le profil communautaire de l'anonymat. C'est l'acte qui donne une identité visible. Le membre peut y revenir explicitement depuis son profil.

Ces méthodes ne changent pas l'identité : elles enrichissent le profil. Pour rattacher à ton utilisateur, c'est l'étape 2.


Quand appeler quoi

Texte brut
Démarrage de l'app        → AppwinCore.configure(...)          toujours
Connexion dans TON app    → identify + bootstrapSession        rattachement
                            (ou le login du produit)
Juste après               → setUser / updateUser               attributs
Profil modifié chez toi   → setUser / updateUser               mise à jour
Déconnexion dans TON app  → AppwinCore.signOut()               retour anonyme

L'ordre compte : le rattachement avant les attributs. Poussés dans l'autre sens, ils partent sur le profil anonyme et sont perdus au rattachement.

Ce qui est partagé, et ce qui ne l'est pas

Porté par Core, partagéPropre à chaque produit
Identifiant d'appareilProfil communautaire (pseudo, avatar, bio)
Session et jetonFiche client Support (email, langue, plan)
externalIdSanctions de modération
Métadonnées d'appareilJeton push et opt-in

Modération

Trois sanctions existent côté Community, décidées depuis le dashboard : avertissement, ban en lecture seule, et shadow ban - le membre continue de publier et voit ses propres contenus, personne d'autre ne les voit, et il n'en est jamais informé, ni par l'UI ni par une réponse d'API. Le SDK est conçu pour ne rien en laisser filtrer. Le détail est dans Piloter Community.

Vie privée

Ce que le SDK envoie, et rien de plus :

  • un identifiant d'appareil généré par le SDK - pas l'IDFA, pas l'IDFV, pas l'ID de publicité Android
  • la plateforme, le modèle, la version d'OS et d'app
  • la langue de l'appareil, pour la traduction des contenus
  • l'externalId que tu fournis, si tu en fournis un

Le SDK ne lit ni le carnet d'adresses, ni la localisation, ni les identifiants publicitaires. L'externalId étant choisi par toi, tu peux y mettre un identifiant opaque plutôt qu'un email si tu préfères.

Suite

  • Installation - dépendances, initialisation, API locale
  • Community - afficher le fil et le personnaliser