row
row

Reputation: 141

Easiest way to convert SCORM package to run on an external server?

I have created a SCORM package (without an authoring tool) where the ismmanifest.xml points to the content on an external server.

However, the LMS used (Cornerstone) does not support external content in SCORM!

Is there an easy way to convert the SCORM package to xAPI, AICC, cmi5, whatever that can run the content on an external server, outside the LMS?

In a first attempt I wanted to use xAPI, but failed because it requires user authentication, but I have neither access to the LMS nor to the external server on which the content should run. I only created the content and the package.

Thanks for any help

Upvotes: 0

Views: 58

Answers (1)

pipwerks
pipwerks

Reputation: 4581

You can't point to external content via the imsmanifest file, because the external HTML file will be on a different domain and unable to communicate with the LMS via JavaScript due to cross-domain security restrictions.

What I've done in similar situations is create a relay system where I load a single HTML file in my course ZIP, and load external content into this HTML file via iframe. The index.html file handles all SCORM/JS interactions with the LMS because it's on the same domain as the LMS. The trick is to use postMessage (or similar) to enable the child pages to instruct the index.html file to fire JS commands on their behalf.

Assuming you have the ability to modify the course files and SCORM ZIP, here's a general overview of how it works:

Create an index.html file that goes in the SCORM package. Have the imsmanifest point to this file as the launch file for the course.

Within the index.html file, create an iframe that fills the viewport 100%. This makes the iframe feel invisible to the end user.

Use JS to dynamically load the external files into the iframe as needed per your course's logic.

Add your SCORM support code (e.g. a SCORM wrapper) to the index.html file. It will handle the SCORM connection and all the commands for you (init, get, set, terminate, etc.). The external files will NOT use any SCORM code and will never interact with the LMS -- the external pages will only interact with the index.html file via postMessage.

When a course page needs to make a SCORM call, have it relay the command to your index.html file via postMessage, such as

const message = JSON.stringify({ bookmark: 2 });
//Replace lms.com with the domain of your LMS for security purposes
window.parent.postMessage(message, 'https://lms.com');

In your index.html file, you'd listen for messages and handle accordingly. (Sample code, untested -- needs error handling)

window.addEventListener('message', function(event) {
    //Replace example.com with the domain of your external files for security purposes
    if (event.origin === 'https://example.com') {
        const data = JSON.parse(event.data);
        switch(Object.keys(data)[0]){
            case "bookmark":
               //In this example I'm using my pipwerks SCORM wrapper
               pipwerks.SCORM.set("cmi.core.lesson_location", data[0]);
               break;
            case "exit":
               pipwerks.SCORM.exit();
               break;
            // etc.
        }
    }
});

I've used this approach successfully for years on multiple LMS platforms. There are a lot of added benefits to this approach, including:

  1. The SCORM package is extremely lightweight
  2. The SCORM package never needs to be touched again -- no messing with versioning in the LMS
  3. You can send the SCORM packages to as many LMSs as you want, while maintaining just a single copy of course files on your external server. If you ever need to update the course, make the change in one place and it's instantly reflected everywhere.

Upvotes: 1

Related Questions