SCORM Runtime APIとは、eラーニング教材(SCO)とLMS(学習管理システム)がブラウザ上でデータをやり取りするためのJavaScript APIです。本記事では、SCORM 1.2およびSCORM 2004の全メソッドを、実際のコード例とともに体系的に解説します。

1. SCORM Runtime APIの全体像

SCORM Runtime APIは、教材側のJavaScriptからLMSが提供するAPIオブジェクトのメソッドを呼び出すことで動作します。SCORM 1.2と2004ではAPIオブジェクト名とメソッド名が異なりますが、基本的な役割は同じです。

役割SCORM 1.2SCORM 2004
APIオブジェクト名APIAPI_1484_11
通信開始LMSInitialize("")Initialize("")
値の取得LMSGetValue(element)GetValue(element)
値の設定LMSSetValue(element, value)SetValue(element, value)
データ保存LMSCommit("")Commit("")
通信終了LMSFinish("")Terminate("")
最終エラー取得LMSGetLastError()GetLastError()
エラー文字列取得LMSGetErrorString(code)GetErrorString(code)
診断情報取得LMSGetDiagnostic(code)GetDiagnostic(code)

すべてのメソッドは文字列を引数に取り、文字列を返すという点が共通しています。成功時は "true"、失敗時は "false" を返します(LMSGetValue / GetValue は値の文字列を返します)。

2. APIオブジェクトの探索(findAPI)

SCORM教材がLMS上で起動されると、LMSはブラウザのウィンドウ階層にAPIオブジェクトを配置します。教材はまずこのオブジェクトを探す必要があります。

SCORM 1.2用のfindAPI

function findAPI(win) {
  var attempts = 0;
  while (win.API == null && win.parent != null && win.parent != win) {
    attempts++;
    if (attempts > 10) return null;
    win = win.parent;
  }
  return win.API || null;
}

function getAPI() {
  var api = findAPI(window);
  if (api == null && window.opener != null) {
    api = findAPI(window.opener);
  }
  return api;
}

SCORM 2004用のfindAPI

function findAPI(win) {
  var attempts = 0;
  while (win.API_1484_11 == null && win.parent != null && win.parent != win) {
    attempts++;
    if (attempts > 10) return null;
    win = win.parent;
  }
  return win.API_1484_11 || null;
}

function getAPI() {
  var api = findAPI(window);
  if (api == null && window.opener != null) {
    api = findAPI(window.opener);
  }
  return api;
}

ポイントとして、LMSによってはAPIオブジェクトをwindow.parentではなくwindow.openerに配置する場合があります。両方を探索するようにしましょう。

3. Initialize / LMSInitialize——通信の開始

教材がロードされたら、最初に呼び出すメソッドです。これを呼ばないと、他のすべてのAPI呼び出しが失敗します。

// SCORM 1.2
var api = getAPI();
var result = api.LMSInitialize("");
if (result === "false") {
  var errorCode = api.LMSGetLastError();
  console.error("初期化失敗: " + api.LMSGetErrorString(errorCode));
}

// SCORM 2004
var api = getAPI();
var result = api.Initialize("");
if (result === "false") {
  var errorCode = api.GetLastError();
  console.error("初期化失敗: " + api.GetErrorString(errorCode));
}

注意: 引数は必ず空文字列 "" を渡します。これはSCORM仕様で定められており、他の値を渡すとエラーになるLMSがあります。

4. GetValue / LMSGetValue——データの取得

LMSに保存されている学習データを取得します。取得できるデータ項目(データモデル要素)はSCORMのバージョンによって異なります。

// SCORM 1.2 — 学習ステータスを取得
var status = api.LMSGetValue("cmi.core.lesson_status");

// SCORM 1.2 — 学習者名を取得
var learnerName = api.LMSGetValue("cmi.core.student_name");

// SCORM 1.2 — スコアを取得
var score = api.LMSGetValue("cmi.core.score.raw");

// SCORM 2004 — 完了ステータスを取得
var completionStatus = api.GetValue("cmi.completion_status");

// SCORM 2004 — 成功ステータスを取得
var successStatus = api.GetValue("cmi.success_status");

// SCORM 2004 — 学習者名を取得
var learnerName = api.GetValue("cmi.learner_name");

よく使うデータモデル要素の対応表

用途SCORM 1.2SCORM 2004
学習ステータスcmi.core.lesson_statuscmi.completion_status / cmi.success_status
スコア(素点)cmi.core.score.rawcmi.score.raw
スコア(最大値)cmi.core.score.maxcmi.score.max
スコア(最小値)cmi.core.score.mincmi.score.min
学習者名cmi.core.student_namecmi.learner_name
学習者IDcmi.core.student_idcmi.learner_id
中断位置cmi.core.lesson_locationcmi.location
自由データ領域cmi.suspend_datacmi.suspend_data
合計学習時間cmi.core.total_timecmi.total_time
セッション時間cmi.core.session_timecmi.session_time

5. SetValue / LMSSetValue——データの設定

学習データをLMSに書き込みます。教材の進捗やスコアを記録するために使用します。

// SCORM 1.2 — ステータスを「完了」にする
api.LMSSetValue("cmi.core.lesson_status", "completed");

// SCORM 1.2 — スコアを設定する
api.LMSSetValue("cmi.core.score.raw", "85");
api.LMSSetValue("cmi.core.score.max", "100");
api.LMSSetValue("cmi.core.score.min", "0");

// SCORM 1.2 — 中断位置を保存(レジューム用)
api.LMSSetValue("cmi.core.lesson_location", "page-5");
api.LMSSetValue("cmi.suspend_data", JSON.stringify({ currentPage: 5, answers: [1,3,2] }));

// SCORM 2004 — 完了と合格を設定
api.SetValue("cmi.completion_status", "completed");
api.SetValue("cmi.success_status", "passed");

// SCORM 2004 — スコアを設定(0〜1のスケール値が必須)
api.SetValue("cmi.score.raw", "85");
api.SetValue("cmi.score.max", "100");
api.SetValue("cmi.score.min", "0");
api.SetValue("cmi.score.scaled", "0.85");

SCORM 2004の注意点: cmi.score.scaled(-1.0〜1.0の小数)は必須項目です。cmi.score.raw だけ設定してもLMSによっては正しく記録されません。

6. Commit / LMSCommit——データの保存確定

SetValueで設定したデータをLMSに確実に保存させます。Commitを呼ばない場合、データがLMSに反映されないことがあります。

// SCORM 1.2
api.LMSSetValue("cmi.core.lesson_status", "completed");
api.LMSSetValue("cmi.core.score.raw", "90");
var result = api.LMSCommit("");
if (result === "false") {
  console.error("Commit失敗: " + api.LMSGetErrorString(api.LMSGetLastError()));
}

// SCORM 2004
api.SetValue("cmi.completion_status", "completed");
api.SetValue("cmi.score.scaled", "0.9");
var result = api.Commit("");
if (result === "false") {
  console.error("Commit失敗: " + api.GetErrorString(api.GetLastError()));
}

SetValueのたびにCommitを呼ぶ必要はありません。一連の値を設定し終わった後にまとめて1回呼ぶのが一般的です。ただし、ページ遷移のタイミングなど、データを失いたくないポイントではこまめにCommitすることを推奨します。

7. Finish / Terminate / LMSFinish——通信の終了

教材を閉じる前に呼び出します。これによりLMSはセッションを終了し、最終的なデータの保存処理を行います。

// SCORM 1.2
api.LMSSetValue("cmi.core.session_time", "0000:15:30.00");
api.LMSCommit("");
api.LMSFinish("");

// SCORM 2004
api.SetValue("cmi.session_time", "PT15M30S");  // ISO 8601形式
api.Commit("");
api.Terminate("");

セッション時間のフォーマットの違い: SCORM 1.2では HHHH:MM:SS.SS 形式、SCORM 2004ではISO 8601の期間表記(PT1H30M45S など)を使用します。

8. エラーハンドリングとエラーコード一覧

APIメソッドが "false" を返した場合、GetLastError でエラーコードを取得して原因を特定します。

SCORM 1.2 主要エラーコード

コード意味
0エラーなし
101一般的な例外
201引数エラー(無効な引数)
202要素は取得できない(書き込み専用)
203要素は設定できない(読み取り専用)
301初期化されていない
401未実装のデータモデル要素
402無効なSetValue引数(データ型不正)
403データモデル要素が読み取り専用

SCORM 2004 主要エラーコード

コード意味
0エラーなし
101一般的な例外
102初期化済み(二重Initialize)
103初期化されていない
104終了済み(Terminate後の呼び出し)
111Terminate前にTerminateが呼ばれた
201一般的な引数エラー
301一般的な取得エラー
351一般的なセットエラー
391一般的なCommitエラー
401未定義のデータモデル要素
403データモデル要素が読み取り専用
406データモデル要素のデータ型不正

エラーハンドリングのユーティリティ関数例

function scormSetValue(element, value) {
  var result = api.LMSSetValue(element, value);
  if (result === "false") {
    var code = api.LMSGetLastError();
    var msg = api.LMSGetErrorString(code);
    var diag = api.LMSGetDiagnostic(code);
    console.error("SetValue失敗 [" + element + "=" + value + "] code:" + code + " " + msg + " / " + diag);
  }
  return result;
}

9. 実装パターン——教材のライフサイクル全体

ここまでの内容を踏まえ、教材が起動してから終了するまでの一連の処理をまとめた実装例を示します(SCORM 1.2版)。

var api = null;

// 教材起動時
function initSCORM() {
  api = getAPI();
  if (api == null) {
    console.error("SCORM APIが見つかりません");
    return false;
  }
  var result = api.LMSInitialize("");
  if (result === "false") return false;

  // 前回の中断位置を復元
  var location = api.LMSGetValue("cmi.core.lesson_location");
  if (location !== "") {
    goToPage(location);
  }
  return true;
}

// ページ遷移時
function savePage(pageId) {
  api.LMSSetValue("cmi.core.lesson_location", pageId);
  api.LMSCommit("");
}

// テスト完了時
function reportScore(score, maxScore, passed) {
  api.LMSSetValue("cmi.core.score.raw", String(score));
  api.LMSSetValue("cmi.core.score.max", String(maxScore));
  api.LMSSetValue("cmi.core.lesson_status", passed ? "passed" : "failed");
  api.LMSCommit("");
}

// 教材終了時
function finishSCORM() {
  if (api == null) return;
  api.LMSSetValue("cmi.core.session_time", calculateSessionTime());
  api.LMSCommit("");
  api.LMSFinish("");
}

// ウィンドウを閉じる際に確実にFinishを呼ぶ
window.addEventListener("beforeunload", function() {
  finishSCORM();
});

10. よくある質問(FAQ)

Q1. InitializeとFinish(Terminate)は必ず呼ぶ必要がありますか?

はい。Initializeを呼ばないと他のAPI呼び出しがすべて失敗します。Finish/Terminateを呼ばないとLMS側でセッションが正常終了せず、学習データが保存されない場合があります。

Q2. Commitはどのタイミングで呼ぶべきですか?

SetValueで値を設定した後、データを失いたくないタイミングで呼びます。ページ遷移時やテスト完了時など、区切りのよいタイミングが一般的です。SetValueのたびに呼ぶ必要はありませんが、Finish前には必ず呼んでおきましょう。

Q3. SCORM 1.2と2004の両方に対応するにはどうすればよいですか?

APIオブジェクトの探索時に API(1.2)と API_1484_11(2004)の両方を探し、見つかった方に応じてメソッド名を切り替えるラッパー関数を作るのが一般的です。多くのSCORMラッパーライブラリがこの方式を採用しています。

Q4. suspend_dataの容量制限はありますか?

SCORM 1.2では最低4,096バイト、SCORM 2004(第4版)では最低64,000文字が保証されています。大量のデータを保存する場合は、JSON.stringifyで圧縮するなどの工夫が必要です。

Q5. beforeunloadイベントでFinish/Terminateを呼んでも大丈夫ですか?

ブラウザによっては beforeunload 内の非同期処理が完了しない場合があります。可能であれば教材内に「終了」ボタンを設け、そこでFinish/Terminateを呼ぶ設計を推奨します。beforeunload はあくまでフォールバックとして使いましょう。

11. まとめ

  • SCORM Runtime APIは、教材とLMSがブラウザ上でデータ通信するための8つのJavaScriptメソッドで構成される
  • Initialize → GetValue/SetValue → Commit → Finish/Terminate の順序を守ることがすべての基本
  • SCORM 1.2と2004ではAPIオブジェクト名・メソッド名・データモデルが異なるため、対応表を参照しながら実装する
  • エラーコードを活用したハンドリングを実装することで、問題の早期発見と対処が可能になる
  • 実装に不安がある場合は、実績あるSCORMラッパーライブラリの利用や専門家への相談が確実

SCORM APIの実装でお困りではありませんか?株式会社エレファンキューブはeラーニング専門18年・3,000件超のSCORM開発実績で、API実装のサポートからSCORM教材の制作・変換まで幅広く対応いたします。技術的なご相談もお気軽にお問い合わせください。

SCORMのことなら、何でもご相談ください

SCORM変換・教材制作・技術トラブルの解決まで、ワンストップで対応します。ご相談・お見積もりは無料です。

無料で相談する

株式会社エレファンキューブ

eラーニング教材制作の専門会社。2008年の創業以来、3,000件超の制作実績を持ち、SCORM 1.2 / SCORM 2004 / xAPI / cmi5など各種規格に精通。企画からLMS搭載まで、ワンストップで対応しています。

コーポレートサイト