Wednesday, November 14, 2012

Making SCORM Calls from Flash (AS3)


If you are using a learning management system (LMS), chances are you can communicate with it using SCORM commands.  While many rapid development tools like Captivate and Articulate will automatically generate SCORM calls, they don’t provide you the flexibility and precision that can be necessary with eLearning module development.  In those situations, Flash is (still) a viable option.

If you are comfortable building a module in Flash, doing some light coding in ActionScript 3 (AS3), then the SCORM commands will simply be plug n play.  In this situation, it is more important to know when and how you should be making your SCORM calls as opposed to what the code will be. 

While there are a variety of calls that can be made (outlined in the ADL’s SCORM 1.2 Run-Time Environment), they fall into three primary categories: set, get, commit.  Some basic examples are detailed below, but the link above provides the full range of calls that can be made as well as specific keywords and values that are required for each type of variable used.

Set
To set a SCORM variable on the LMS:
fscommand(“LMSSetValue”, “cmi.core.lesson_status,completed”);
All set commands follow the same pattern.  The only thing that changes is the API call (cmi.core.lesson_status) and the value that you are looking to set (completed).  The fscommand has two variables.  The first string lets the LMS know you are interested in setting a variable.  The second string combines the API call and the value you are looking to set separated by a comma.  This can be done with a string (as defined above) or with a variable (intScore is the variable):
fscommand(“LMSSetValue”, “cmi.core.score.raw,”+intScore);
You can see in the example above that it is still two strings that are included in the fscommand, but the second string is concatenated between a literal and the variable intScore.

In addition to setting variables at the conclusion of a module, you should also potentially set the completion status at the beginning of the module.  However, rather than simply setting the variable, you will need to first get the completion status to ensure you aren’t overwriting a status of completed.  A module is initially ‘not attempted’, but once the learner begins the module, it should be modified to read ‘incomplete’.  Rather than making this SCORM call upon entry to the module, you would first get the current status to ensure it wasn’t previously completed before you reset it to incomplete. 

Another variable that is set throughout the module and retrieved at the beginning manages the bookmark.
fscommand(“LMSSetValue”, “cmi.suspend_data,”+stringBookmark);
The bookmark is a (maximum) 4096-byte string.  As such, you can include a variety of information about previous interactions with the module.  Leveraging a character within the string such as the pipe character (|), you can include a variety of information that can later be separated into an array and read in a logical way to return the module to the previous state. 

Get
A get API call works very similarly to the set call:
fscommand(“LMSGetValue”, “cmi.core.lesson_status,returnedStatus”);
In the case above, the LMS will return the status previously stored and set it as the value in the returnedStatus variable. 

While set variables are the simplest, get variables are the most powerful differentiator between a Flash module and a Captivate module.  While Captivate can set variables, it is very difficult to determine if the variable has successfully been set and to what value.  For example, at the conclusion of a module, you indicate that the completion status has been recorded.  However, in Captivate, you are making that statement based on an assumption.  Using Flash, you can set the completion status, then use a timed interval to check to ensure that you can get the same status that you believe should have been set by the LMS.  This will help to ensure you don’t have latency issues as you can refrain from communicating with the learner until you have confirmed (with a get call) that the LMS has the correct value stored. 

In addition to the fscommand, you also have to set up what happens when the variable is returned.  As such, you’ll need to add the following code:
ExternalInterface.addCallback(“SetVariable2”,mySetVariable);
function mySetVariable(varname:String, varvalue:String):void {
this[varname] = varvalue;

}
Here, the variable name that you set in the original fscommand is passed back with varvalue set to the value that is returned. 

this[varname] differs from this.varname in that whatever is the value of varname is the name of the variable name that is set.  For example:
varname = “returnedStatus”;
this[varname] = “completed”
// is the same as saying
this.returnedStatus = “completed”;

Here is a full example:
var returnedStatus:String;
// get the status at the beginning of the module
fscommand(“LMSGetValue”, “cmi.core.lesson_status,returnedStatus”);
// process the returned information from the javascript
ExternalInterface.addCallback(“SetVariable2”,mySetVariable);
function mySetVariable(varname:String, varvalue:String):void {
this[varname] = varvalue;
if(varname== “returnedStatus”) {
// only execute the code if we are getting the status
if(varvalue == “completed”) {
// already completed, so do nothing with the stauts
} else {
// set to incomplete since haven’t completed yet
fscommand(“LMSSetValue”, “cmi.core.lesson_status,incomplete”);
}
// we’ve successfully gotten something back, so show the next button
nextButton_btn.visible = true;
}
}

Commitment
When setting variables, depending on the LMS, they may or may not immediately perform an API call to the LMS.  The advantage of the call happening immediately is that the transaction has occurred.  The downside is that setting a handful of variables requires frequent calls between the module and the system.  Instead, many LMSs require a commitment statement to push all of the set variables to the LMS.
fscommand(“LMSCommit”, “”);
That simple statement tells the module to send everything that has been recently set to the LMS.  If you limit the amount of set calls, you can execute this command after each to ensure the variables aren’t waiting in the module in case of an unexpected termination of the program. 

How to Publish
While the fscommands are simple, there are a couple of other steps to ensure the javascript is properly placed in the html files associated with the module.  The most crucial part of publication is to tell Flash that you wish to publish the HTML as:
Flash with SCORM 1.2 Tracking
This will add the proper javascript functions to the HTML page to ensure that the fscommands are passing the information to something that will then interact with the LMS. 

The more difficult change is one that is required for the ability to get variables.  Flash, unfortunately, needs one of the HTML functions renamed in order for the return calls to function correctly.  By default, line 322 of the HTML page states
If ( cmd == “LMSGetValue”) {
SCORM_demoObj.SetVariable(arg2, SCOGetValue(arg1));
Here, you can see how the arguments passed through fscommand get placed into the function to make the actual call.  However, SetVariable is a function that is used twice.  As such, it should be renamed to SetVariable2(arg2… resulting in:
If ( cmd == “LMSGetValue”) {
SCORM_demoObj.SetVariable2(arg2, SCOGetValue(arg1));

Once you have mastered setting and getting SCORM variables, you will find that you can create valuable tracking that allow you to not only record how learners are interacting with your module, but also provide them a more positive, consistent experience where they know what is happening with the system and aren’t surprised that things didn’t get set as planned. 

No comments:

Post a Comment