Skip to Content

Chapitre 2.4 — Le cycle de vie d’un SCO

⏱️ TL;DR — Un SCO (Sharable Content Object) n’est pas une page web ordinaire : c’est un contenu qui dialogue avec le LMS pendant qu’il tourne. Son cycle de vie est toujours le même : le LMS le lance dans une iframe ou une fenêtre → le SCO trouve l’API dans la fenêtre parente → il appelle Initialize pour ouvrir la session → pendant la navigation, il lit et écrit des données CMI (statut, score, position, suspend_data) et appelle Commit pour demander l’enregistrement → à la sortie, il appelle Terminate → le LMS persiste statut et score. Un asset, lui, ne fait rien de tout ça : c’est un fichier passif (PDF, image) qui ne parle pas. Maîtriser ce cycle, c’est savoir un module casse quand « ça ne remonte pas ».

🎯 Objectifs

  • Décrire, dans l’ordre, les étapes de vie d’un SCO : lancement, découverte de l’API, Initialize, échanges CMI, Commit, Terminate.
  • Comprendre qui fait quoi : ce qu’initie le LMS, ce qu’initie le SCO.
  • Distinguer nettement un SCO (qui dialogue) d’un asset (passif).
  • Savoir placer un point d’arrêt mental quand un module « ne remonte rien ».
  • Lire un diagramme de séquence du cycle complet.

Un SCO, ce n’est pas une page web comme une autre

Ouvre une page HTML : elle s’affiche, point. Un SCO fait plus. Le LMS le lance dans une fenêtre ou une iframe dont il est le parent, et il attend que le SCO lui parle — qu’il ouvre une session, remonte un statut, un score, une position, puis referme proprement. Le SCO est donc un contenu actif : il a un cycle de vie rythmé par des appels d’API précis.

Ce cycle est identique dans les deux versions de SCORM ; seuls les noms changent. Pour rester lisible, ce chapitre décrit la logique avec les méthodes SCORM 2004 (Initialize, Commit, Terminate) ; les équivalents 1.2 sont LMSInitialize, LMSCommit, LMSFinish. Retiens la logique, pas seulement les mots.

ÉtapeSCORM 2004SCORM 1.2
Ouvrir la sessionInitialize("")LMSInitialize("")
Lire une valeurGetValue(elt)LMSGetValue(elt)
Écrire une valeurSetValue(elt, val)LMSSetValue(elt, val)
Demander l’enregistrementCommit("")LMSCommit("")
Fermer la sessionTerminate("")LMSFinish("")

Les six temps de la vie d’un SCO

1. Le LMS lance le SCO

Tout commence côté LMS. L’apprenant clique sur l’activité ; le LMS ouvre le SCO dans une iframe ou une fenêtre et se place comme fenêtre parente. À ce stade, le SCO est chargé, mais il n’a encore rien dit.

2. Le SCO trouve l’API (find the API)

Avant de parler, le SCO doit trouver l’objet API que le LMS a exposé. Il le cherche en remontant la hiérarchie des fenêtres : d’abord dans window.parent, puis, si besoin, via window.opener (cas d’une fenêtre pop-up). C’est le rituel du « find the API ».

// Recherche simplifiee de l'API SCORM 2004 dans les fenetres parentes. function findAPI(win) { var tries = 0; while (win.API_1484_11 == null && win.parent != null && win.parent != win) { tries++; if (tries > 50) return null; // garde-fou anti-boucle win = win.parent; } return win.API_1484_11 || null; // en 1.2, on chercherait "API" } var api = findAPI(window); if (api == null) { // Pas d'API : on n'est pas lance par un LMS conforme. On ne remontera rien. }

⚠️ Piège — Si le SCO ne trouve pas l’API, il n’y a aucun dialogue possible : le module s’affiche mais ne remonte rien. Causes classiques : le module a été ouvert hors LMS (double-clic sur le fichier local), une iframe cross-origin bloque l’accès à la fenêtre parente, ou le module cherche le mauvais objet (API alors qu’il est lancé en 2004, ou l’inverse — voir chapitre 2.2). Le tout premier réflexe de débogage : l’API a-t-elle été trouvée ?

3. Initialize — ouvrir la session

Une fois l’API en main, le SCO appelle Initialize("") (ou LMSInitialize("") en 1.2). C’est le « bonjour » obligatoire : il ouvre la session de communication. Tant qu’il n’est pas appelé, aucune lecture ni écriture de données n’est valide. C’est l’oubli n°1 des modules qui « ne remontent rien ».

4. La navigation — lire et écrire des données CMI

Pendant que l’apprenant progresse, le SCO lit (GetValue) et écrit (SetValue) des champs du modèle CMI :

  • au démarrage, il peut lire l’identité (cmi.core.student_name en 1.2) et relire son cmi.suspend_data pour reprendre où l’apprenant s’était arrêté ;
  • au fil de la progression, il écrit le statut, le score, la position, l’état de reprise.
// Reprise, puis progression (SCORM 2004). var repriseEtat = api.GetValue("cmi.suspend_data"); // relire l'etat sauvegarde // ... l'apprenant avance ... api.SetValue("cmi.completion_status", "incomplete"); api.SetValue("cmi.score.scaled", "0.62"); api.SetValue("cmi.suspend_data", "ecran=7;q3=B"); // memoriser l'etat

5. Commit — demander l’enregistrement

SetValue écrit dans le modèle en mémoire, mais ne garantit pas la persistance durable côté serveur. Pour demander au LMS d’enregistrer ce qui a été posé, le SCO appelle Commit("") (ou LMSCommit("")). On l’appelle typiquement régulièrement (à des jalons de progression) et avant de terminer.

⚠️ Piège — Écrire de belles valeurs avec SetValue sans jamais appeler Commit (ni Terminate, qui provoque en général un enregistrement final) : si l’apprenant ferme brutalement l’onglet, tout ce qui n’a pas été commité peut être perdu. Beaucoup de « le score du milieu de parcours a disparu » viennent de là.

6. Terminate — fermer proprement, le LMS persiste

À la sortie (fin du module, fermeture), le SCO appelle Terminate("") (ou LMSFinish("")). C’est le « au revoir » : il ferme la session et déclenche en général la persistance finale. Le LMS enregistre alors durablement le statut et le score dans son carnet de suivi. La boucle est bouclée : ce que le SCO a dit devient une donnée exploitable côté plateforme.

💡 Réflexe — Ordre canonique à ne jamais casser : trouver l’API → Initialize → (GetValue / SetValue + Commit) → Terminate. Toute écriture avant Initialize ou après Terminate est invalide. Quand « ça ne remonte pas », déroule cette chaîne dans l’ordre : c’est presque toujours un maillon manquant.

Le diagramme de séquence

SCO ou asset : dialoguer ou se taire

SCORM distingue deux types de ressources, et cette distinction structure tout ce chapitre :

  • Un SCO (Sharable Content Object) dialogue : il trouve l’API, s’initialise, remonte des données, se termine. Tout le cycle de vie ci-dessus le concerne. Dans le manifeste, sa ressource porte adlcp:scormType="sco".
  • Un asset est passif : une image, un PDF, une vidéo qu’on affiche mais qui ne parle pas au LMS. Il n’a pas de cycle de vie SCORM — pas d’API, pas d’Initialize, pas de statut remonté. Dans le manifeste, sa ressource porte adlcp:scormType="asset".
<resource identifier="RES-1" adlcp:scormtype="sco" href="module/index.html" /> <resource identifier="RES-2" adlcp:scormtype="asset" href="docs/fiche.pdf" />

⚠️ Piège — Déclarer en asset un contenu qui devrait remonter des résultats : le LMS l’affiche mais n’attend aucun statut, donc rien ne se trace, et c’est « normal ». Inversement, marquer sco un simple PDF n’a aucun sens : un asset ne sait pas dialoguer. Le typage scormType doit refléter la nature réelle de la ressource. C’est un contrôle à faire dès la lecture d’un manifeste.

🔌 Côté intégration — Côté LMS, un SCO est ce qui alimente le carnet de suivi ; un asset est un simple fichier servi. Quand un client dit « le suivi ne marche pas sur telle ressource », vérifie d’abord son type dans le manifeste : un contenu attendu comme traçable mais typé asset ne remontera jamais rien, quel que soit son code. Le problème n’est pas le runtime, c’est le CAM.

🧭 Sur FormaCampus — Chaque module de cours FormaCampus est un SCO unique : il trouve l’API API (SCORM 1.2), appelle LMSInitialize, écrit cmi.core.lesson_status et cmi.core.score.raw, commit à chaque jalon important, puis LMSFinish à la sortie. Les annexes (fiches PDF, modèles à télécharger) sont livrées comme assets dans le même paquet : l’école y accède, mais FormaCampus n’attend aucun suivi dessus — et c’est voulu. Résultat lisible côté client : un statut et un score par module dans le carnet Moodle, des annexes accessibles sans « faux » indicateurs de complétion.

✏️ Exercices

Exercice 1 — « Le module s’affiche mais rien ne remonte ». Un module SCORM 1.2 s’ouvre bien dans le LMS, l’apprenant le parcourt, mais le carnet reste vide. Donne trois causes possibles, dans l’ordre où tu les vérifierais.

✅ Solution

Dans l’ordre du cycle de vie :

  1. L’API n’est pas trouvée (« find the API » échoue) — le module cherche API dans les mauvaises fenêtres, une iframe cross-origin bloque l’accès, ou il a été ouvert hors LMS. Sans API, aucun dialogue.
  2. LMSInitialize n’est jamais appelé — sans l’ouverture de session, toute écriture est invalide.
  3. Aucun LMSCommit / LMSFinish — les valeurs sont posées en mémoire mais jamais persistées ; à la fermeture, elles sont perdues.

(Bonus : une valeur invalide dans cmi.core.lesson_status, comme "réussi" au lieu de passed, peut aussi faire échouer l’écriture.)

Exercice 2 — SCO ou asset ? Pour chacun, dis si tu le déclarerais sco ou asset : (a) un module interactif avec quiz noté ; (b) une fiche PDF de synthèse téléchargeable ; (c) une vidéo qui doit remonter « vue à 90 % » comme complétion.

✅ Solution

  • (a)sco. Il dialogue (score, statut), il a un cycle de vie complet.
  • (b)asset. Fichier passif, aucun suivi attendu. Le déclarer sco n’aurait aucun sens.
  • (c)sco. Dès qu’on veut tracer quelque chose (« vue à 90 % » = complétion remontée), il faut un contenu qui dialogue : donc un SCO (typiquement un lecteur vidéo enveloppé de code qui appelle l’API et écrit le statut). Une vidéo livrée en simple asset ne remontera jamais de complétion.

Exercice 3 — Remettre le cycle dans l’ordre. On te donne ces appels en désordre : Commit, Terminate, SetValue, Initialize, « trouver l’API ». Remets-les dans l’ordre canonique et dis lesquels peuvent se répéter.

✅ Solution

Ordre canonique :

  1. trouver l’API (une fois, au démarrage) ;
  2. Initialize (une fois, ouvre la session) ;
  3. SetValue (répétable, autant de fois que nécessaire pendant la navigation ; souvent précédé/entrelacé de GetValue) ;
  4. Commit (répétable, à des jalons de progression et avant de terminer) ;
  5. Terminate (une fois, ferme la session et déclenche la persistance finale).

Répétables : SetValue, GetValue, Commit. Uniques : trouver l’API, Initialize, Terminate. Toute écriture avant Initialize ou après Terminate est invalide.

🧠 Quiz de révision

1. Qui lance le SCO, et où ?

Le LMS lance le SCO dans une iframe ou une fenêtre dont il est la fenêtre parente. Le SCO devra ensuite y retrouver l’API exposée par le LMS pour pouvoir dialoguer.

2. Que signifie « find the API » et pourquoi est-ce critique ?

C’est la recherche de l’objet API par le SCO, en remontant les fenêtres parentes (window.parent, puis window.opener). C’est critique parce que sans API trouvée, aucun dialogue n’est possible : le module s’affiche mais ne remonte rien. C’est le premier point à vérifier en débogage.

3. À quoi servent Initialize, Commit et Terminate ?

Initialize ouvre la session (obligatoire avant toute écriture). Commit demande au LMS d’enregistrer durablement ce qui a été posé par SetValue. Terminate ferme la session à la sortie et déclenche en général la persistance finale du statut et du score. (En 1.2 : LMSInitialize, LMSCommit, LMSFinish.)

4. Quelle est la différence entre un SCO et un asset ?

Un SCO dialogue avec le LMS (trouve l’API, Initialize, remonte statut/score, Terminate) : il a un cycle de vie. Un asset est passif (PDF, image, vidéo simple) : il s’affiche mais ne parle pas au LMS, donc ne trace rien. Le manifeste les distingue via adlcp:scormType (sco ou asset).

5. Pourquoi un score écrit avec SetValue peut-il ne jamais arriver dans le carnet ?

Parce que SetValue écrit en mémoire, pas durablement. Sans Commit (et sans Terminate, qui déclenche la persistance finale), une fermeture brutale de l’onglet perd les valeurs non enregistrées. Il faut Commit aux jalons et terminer proprement pour que le LMS persiste les données.


Chapitre suivant : Forces & limites de SCORM — pourquoi il domine encore, ce qu’il ne sait pas faire, et pourquoi xAPI et cmi5 ont dû naître.

Last updated on