Developer Overview

The RSOfflinePlayer is an iOS and Android SDK designed to allow playback of SCORM content from the Rustici Engine on your mobile device. It allows your native mobile app to playback and sync SCORM content with a specially designed player package. When you are offline, with no connection, the results are saved locally. When you are online, and can connect to the Rustici Engine server, your results are synced back and appear just like other desktop browser attempts in the reporting.

The following is a quick overview of what it looks like to integrate with Engine's offline player. You can refer to the platform-specific instructions in the table of contents for a more detailed explanation of either platform's integration.

Exporting Content

In order for the content to be able to be played on a mobile device while offline, the content package must be all inclusive. That is, it must contain all the resources required within the content directory. Any links to external files or documents will not work when launched offline. Engine will take your content directory and wrap our SCORM player around it so that it is a self-contained SCORM player that can play in a WebView instance.

To export your content from Engine as a ZIP file, you will use the OfflineExporter included with Engine. After exporting your package, the OfflineExporter will return the path to the newly created ZIP file. The offline package will be stored on Engine's local file system, or it can alternatively be pushed to a S3 bucket for later download. This ZIP file is user agnostic and can be downloaded to any number of devices for any number of users. If a new version of a package is loaded into Engine, the new version must also be re-exported and the mobile app will need to know to re-download it for users. Your call to the OfflineExporter will look like this (for .NET customers, replace the .jsp with .aspx):

https://[your.server]/RusticiEngine/offline/OfflineExporter.jsp?package=[course_id]&configuration=[tenant name, if not default]

Aside from the required package and configuration query parameters, there are a few other parameters than you can specify:

  • filename - If specified, Engine will save the exported offline package with the given name. By default, Engine will choose a sensible file name on its own.
  • uiFileDir - This value should be the directory that contains Engine's player files. If unspecified, Engine will construct a default path based on the value you have configured as FilePathToEngineRoot.
  • pathToContent - Can be used to specify where the course's contents are located. If you have configured a value for FilePathToContentRoot or OfflineFilePathToContentRoot, then the value should be relative to the FilePathToContentRoot that you have configured. Otherwise, the value should be an absolute path.

    It is usually not necessary to use this parameter, as Engine can determine the location of most courses automatically. If you want to provide this parameter, you will also to configure a value for the setting OfflineContentPathAcceptedRegex. The value specified by pathToContent will have to match the regex specified by OfflineContentPathAcceptedRegex.

Keeping Application State

Your application is responsible for keeping track of what packages have been exported and what course IDs are associated with them. The usual process is for your app's central server to have a listing of available content to a user. For each piece of content, the server should provide your mobile app with a download link, the package/course ID, and the registration ID for the user from Engine. Using this information, the user can select an available course and your application can download that package for later offline consumption.

Each registration ID is created for a user taking a course. You can either create the registration preemptively so it already exists when the learner downloads their course, or you can create the registration as part of delivering the offline package to the learner. Registrations can be created via Engine's API by POSTing the following JSON object to the URL https://[your.server]/RusticiEngine/api/v2/registrations:

{
    "courseId": "golf",
    "learner": {
        "id": "testLearnerId",
        "firstName": "Last",
        "lastName": "First"
    },
    "registrationId": "test1"
}

You must have a registration created in Engine for each user that will launch your content. You will get an error when trying to retrieve the player configuration if the registration ID does not exist.

Downloading a Package

Your app should have been provided a download link for the course and can download the package to the device while a connection is available. Remember that when a new version of a course is imported into Engine, it needs to be re-exported and re-downloaded to the device for users to see the changes. There is no automated process for this in Engine. How you implement this will depend upon your platform.

Getting Ready to Launch

Before a user can launch the offline package, you need to make a quick call to get the player configuration for this registration ID from Engine. This needs to be done while the user is online, so we recommend doing it right after the package is downloaded and they are still connected.

The result of the player configuration call is saved to the local database and the file system for launching the course without a connection. The URL of the PlayerConfiguration page is the following (for .NET customers, replace the .jsp with .aspx):

https://[your.server]/RusticiEngine/PlayerConfiguration.jsp?registration=[registration_id]&forOffline=true&configuration=[tenant name, if not default]

Your registration_id will need to be in a particular serialized format that includes the instance ID of your registration. The instance ID of a registration defaults to a value of 0. However, if you use Engine's course versioning feature, the instance ID may be incremented when a learner launches online after a new version has been imported (based on your WhenToRestartRegistration setting).

For the majority of customers, that format will look like this: ApiRegistrationId|xxxx!InstanceId|x (depending on your server configuration, the | character may need to be URL-encoded). If you are a customer with a custom integration layer, please reach out to Rustici support for assistance with this format.

Launching Content

After you download the offline package to the device, you'll need to extract the ZIP file locally. The location for this depends upon the platform for which you are developing. This directory will contain all the content files and the player files as well as an index.html file in the root that is the central launch page for the content.

To present the content to the user, you simply create a WebView in your app and navigate to the index.html of the course being launched. When the user exits the course, the WebView will be directed to offline-results.html. You'll need to setup a watch on the WebView's page load event to watch for that page. When offline-results.html is loaded, you can pull the attempt info and runtimeXML from the WebView's localStorage. This attempt info and runtimeXML is then saved to the local DB and the file system for the next launch. This allows the course to be synced back with Engine or resumed upon relaunch locally.

The process for all of this varies upon the platform used. You can refer to one of our sample applications for an example, and we can provide further assistance for several platforms.

Sync with Engine

When you are ready to sync your user's attempt info back to Engine and they are back online, you will need to pull the registration's runtimeXml that we saved at exit previously. This XML will be posted to the RecordResults endpoint in Engine with the proper registration ID and flags set on the path. (for .NET customers, replace the .jsp with .aspx)

https://[your.server]/RusticiEngine/RecordResults.jsp?registration=[registration_id]&isExitScormPlayer=true&configuration=[tenant name, if not default]&package=[course_id]

Once you get a successful response from this POST, you can mark the data as synced in the local DB on the device.

If you need to batch sync courses for many users, you can send this runtimeXML to another backend server for processing and posting to Engine from there. Simply loop all the desired unsynced records and iterate through them until you get success messages for each one from Engine.

After a few seconds of processing, Engine will have your rolled up course registration data ready for reporting.

Recording Results

If you have configured Engine with a value for ApiRollupRegistrationPostBackUrl, then Engine will automatically send the registration's data to your application after you have synced the data back to Engine just like it will for online launched.

If you need to get further results from Engine at a later date, then you will need to call the /api/v2/registration/{registrationId}/progress endpoint in Engine while passing the proper registration ID. This will return various levels of information depending upon the flags passed in on the API call.

Sample App

We can provide an example application for iOS, Android and Xamarin (C#) upon request. If you need to do offline SCORM in another platform, let us know, and maybe we can help.

results matching ""

    No results matching ""