Resuming an articulate story
Nov 15, 2013
By
fbs 419
When you launch an Articulate story (at least via SCORM Cloud), the question "Would you like to resume where you left off?" pops up. This must come from the state API, specifically the GET call on activities/state. Looking at the response from that, you get something like:
25245060ji1001111a010110111100~2C1~2w1cb101001a1a113te1M6Ai00H06Ai00I26Ai0000jDi3000m1118_default6Ai0012pn02Dkfe720118_default0000001000
What format is that in? How can I use that data to know which slide to go to? And even if you know, how do you get the browser to go to that slide? Articulate must be getting (or giving) some information about that.
None of this is documented anywhere.
18 Replies
The data is compressed, the player uncompresses it and decides where to go this is not user editable.
There is no jump to slide API, you cannot jump into a slide
So what is this data? Is it some kind of bookmark? What am I supposed to store via the TinCan state API's /activities/state/?method=PUT, and when I get whatever comes back in /activities/state/?method=GET, what am I supposed to do with it? How does that get the Articulate story to go to where we left off?
This is the resume data, are you building your own LMS I have no idea where you need to put it sorry
It didn't start out that way, but yes -- it looks like I'm building my own LMS, or at least trying to implement a lot of the Tin Can stuff myself. I've implemented services for launching stories, and for storing and retrieving Tin Can statements, and all that's working fine. I figured I would implement the state API, but there is no documentation on what the format of state data is, and especially, how you actually communicate with Articulate to get it to use the resume data. I guess since I'm using an LMS, I wouldn't be dealing with Flash cookies. So all I have is this weird compressed data with no idea what to do with it. I wish this were documented somewhere.
Hi Frank,
As Phil mentioned, suspend data is compressed to allow for more robust storage, the suspend_data string in an LMS debug log isn't human-readable. That is, you won't be able to decipher it. Since you're building your own LMS, I'm not sure this information will help, but figured I'd share here the information on an LMS and Flash cookies:
If you choose Always or Prompt, and if you'll be hosting your content in an LMS, do one of the following:
So I'm not sure what "if your LMS supports bookmarking" means. Does that mean that the LMS has implemented the State API, and is dealing with this compressed resume data? And if it doesn't support bookmarking, I assume that means the state API wasn't implemented, and we would use the Flash cookie so Flash would take care of it.
There seems to be no documentation on what the state API is supposed to return, and how to use this data to influence the Articulate player.
Hi Frank,
Yes, if the LMS supports bookmarking it is tracking the resume data itself. If it doesn't, the flash cookies will do this. That data is compressed, so I don't have information on what it's returning, but for more information about how it's handled within Storyline I wanted to point you to this kb article.
Thanks
Happy to help Frank, and please let us know if you need anything else.
Well -- since nobody knows how this data is compressed, and therefore what I should store and retrieve, it seems like it's impossible for me to implement the State API in my LMS, and I will just have to rely on the Flash cookies. I suppose Rustici probably knows about this, but it seems weird that nobody documents it. The spec talks about LMS's having to implement the State API, but they then make it impossible to do so.
Frank, just return that content parameter by itself.
So its a json return that should just say :
2h145040981001111000$Xa91010310103xe1C1414e720118_default1414e770158_default00010000
Or whatever your bookmark looks like.
hi,finally were you able to solve the problem. I have been dealing with the same problem for 2 weeks.could you please help me
Hey there, Ati.
Just in case Frank is no longer subscribed to this discussion, feel free to use the Contact Me button on his profile page to reach out about his comment. And if there's anything we can help answer, please let us know!
Hey Ati,
Look at my reply. You have to send the JSON string in your payload call..
what have you tried so far?
thanks alot. finally it worked. my problem was that I didnt have any idea about payload, but now I get it,store it and at the next Get from State Api retrieve it
to get the payload: StreamReader(HttpContext.Current.Request.InputStream).ReadToEnd()
This post was removed by the author
This post was removed by the author
This is an old thread, but I am revisiting it now since we finally need this capability. I have this method which is called if I have chosen the resume option in my Articulate story:
[OperationContract, WebInvoke(Method = "*", UriTemplate = "{appId}/activities/state", ResponseFormat = WebMessageFormat.Json)]
public void activitiesstate(string appId, Stream theStream)
With this code:
var method = WebOperationContext.Current.IncomingRequest.Method;
string m = method.ToString();
I can tell whether it's a GET or a PUT. The framework seems fine -- GET only happens when the course is started, and for every question, I see a PUT, and the parameter "theStream" has the resume data, so I store it. On the next GET, when I resume the course, I read that data. It is not working.
My questions come from these statements from a couple of other related posts:
https://community.articulate.com/discussions/articulate-storyline/resume-tin-can-state
https://community.articulate.com/discussions/articulate-storyline/resuming-an-articulate-story#reply-737844
The first one has this statement:
You just need to save the "Content" string which is the bookmark. And then when its requesting that info back, just return that content string by itself and Articulate will resume to that specific spot it saved at.
I'm sure this advice is correct, but I'm not sure how to implement this. How do I just return that content string by itself? The method is a void, which I assume the Tin Can framework wants.
The second one has this statement:
Frank, just return that content parameter by itself. So its a json return that should just say 2h145040981001111000$Xa91010310103xe1C1414e720118_default1414e770158_default00010000 Or whatever your bookmark looks like
Again, how do I just return that content parameter by itself?
Should the code for GET send this data back? Like I said, the activitiesstate method is a void. I figured if maybe the GET sent this data back, that when the statements method executes, it would go to the place I want to resume. But I don't know how to send it back.
I do this in the GET code. resumeData has the proper string.
WebOperationContext.Current.OutgoingRequest.ContentType = "application/octet-stream";
WebOperationContext.Current.OutgoingResponse.ContentLength = resumeData.Length;
I read that I need to set the ContentType to application/octet-stream.
But this doesn't work yet. Perhaps I need another line of code to include that data? I don't quite see how to do that, and since the method is a void, I can't return anything.
Or am I totally off about how this is supposed to work? I guess my question is:
What do I do in the GET part of this code to get this to work?
Thanks
OK -- starting to figure this out and I've proved the concept. I changed my activities/state method to return a string, and for GET, it now returns that JSON string of the resume data. I am using application/json as the ContentType and that seems to be working. Not totally working yet, but I've gotten past the issue that was bugging me.
Thanks to Trip Levine and Nelson Cheng for info in their posts.
Any progress on this?