SCORM on Google Trends

Interesting stats from Google: SCORM is clearly on the decline, as is AICC, but both still much stronger than xAPI (aka Tin Can), which is barely registering.

2004-present (10 years)

2009-present (5 years)

2012-2014 (2 years)

“experience api, tin can api weren’t searched for often enough to appear on the chart. Try selecting a longer time period.”

Does this mean anything? I dunno. But it’s interesting to see SCORM’s steady decline over the last 10 years. Also, please forgive the un-responsiveness of the graphs, Google hard-codes the width in px.

Convert “localhost” to your Mac’s current IP address

When developing web pages, I use MAMP.app or my Mac’s built-in Apache. Viewing the page means using an address such as http://localhost/mypage.html. If you use custom host names (especially easy with the excellent VirtualHostX.app), you may wind up with a localhost address such as http://projectname/mypage.html.

This works great when you’re just testing the pages on your Mac’s browsers. However, once you cross boundaries into Windows testing (via VMs or separate laptops), localhost will no longer resolve. Why? Because localhost is local to your machine.

If you want to view the page in a VM or on another machine, just swap the domain name with your machine’s IP address. For example http://localhost/mypage.html becomes http://10.0.1.14/mypage.html. (Note: you must be on the same network or have a public IP address.)

This works very well, but it’s tiresome to manually grab the IP address anytime you want to use a VM or share the page with coworkers, especially if you’re on DHCP and don’t have a static IP address.

I decided to make my life a little easier by writing an AppleScript that looks at the open tabs in Chrome and Safari then replaces “localhost” (or custom domain) with my current IP address. Saving this as a service enables me to go to Chrome > Services to run the script.

Chrome > Services

If you’d like to give it a try, the AppleScript is available as a Gist on GitHub.

AppleScript for generating SCORM manifest nodes

SCORM requires all of the course assets to be listed as a <file> item in the <resource> node. This is not evenly enforced — some LMSs don’t care of you do it or not — but is still a good practice.

If you’re anything like me, you find it to be a major pain and try to avoid it.

Today I decided to whip up an AppleScript that automates the generation of the <file> nodes to make my life a little easier. If you’re on a Mac, you may find it useful, too. I’ve posted it on GitHub as gist:

https://gist.github.com/pipwerks/9179518

Note that it doesn’t include the name of the root folder. Let’s say you have a root folder named content. If needed, you can simply specify the root using the “xml:base” attribute of the resource node, like so:


<resource identifier="reosurceID" adlcp:scormType="sco" href="index.html" type="webcontent" xml:base="content/">
   <file href="index.html" />
   <file href="Lesson01/index.html" />
</resource>

Clean out the root of your SCORM 2004 package

Anyone who works with SCORM 2004 has seen something like this:

Image of file directory with all schema files at root of directory

With just a little effort, you can make it look like this, and still be perfectly valid:

Image of file directory with all schema files placed in subfolder

SCORM manifests are required to specify a slew of schema files via the schemaLocation attribute. Here’s what you’d typically see:


<manifest identifier="pipwerks-schema-example" version="1.0"
          xmlns="http://www.imsglobal.org/xsd/imscp_v1p1" 
          xmlns:adlcp="http://www.adlnet.org/xsd/adlcp_v1p3" 
          xmlns:adlseq="http://www.adlnet.org/xsd/adlseq_v1p3" 
          xmlns:adlnav="http://www.adlnet.org/xsd/adlnav_v1p3" 
          xmlns:imsss="http://www.imsglobal.org/xsd/imsss" 
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
          xsi:schemaLocation="http://www.imsglobal.org/xsd/imscp_v1p1 imscp_v1p1.xsd 
                              http://www.adlnet.org/xsd/adlcp_v1p3 adlcp_v1p3.xsd 
                              http://www.adlnet.org/xsd/adlseq_v1p3 adlseq_v1p3.xsd 
                              http://www.adlnet.org/xsd/adlnav_v1p3 adlnav_v1p3.xsd 
                              http://www.imsglobal.org/xsd/imsss imsss_v1p0.xsd">

Notice the structure of the data in the schemaLocation attribute: external URL followed by a space then the local (relative) URL. For example:


http://www.imsglobal.org/xsd/imscp_v1p1 imscp_v1p1.xsd

In this example, imscp_v1p1.xsd is at the root of the package, in the same folder as the imsmanifext.xml file. The trick is to create a subfolder in the root of the package, then update schemaLocation to point to the subfolder. I created a subfolder named SCORM-schemas, which you can see in the following code exerpt:


<manifest identifier="pipwerks-schema-example" version="1.0"
          xmlns="http://www.imsglobal.org/xsd/imscp_v1p1" 
          xmlns:adlcp="http://www.adlnet.org/xsd/adlcp_v1p3" 
          xmlns:adlseq="http://www.adlnet.org/xsd/adlseq_v1p3" 
          xmlns:adlnav="http://www.adlnet.org/xsd/adlnav_v1p3" 
          xmlns:imsss="http://www.imsglobal.org/xsd/imsss" 
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
          xsi:schemaLocation="http://www.imsglobal.org/xsd/imscp_v1p1 SCORM-schemas/imscp_v1p1.xsd 
                              http://www.adlnet.org/xsd/adlcp_v1p3 SCORM-schemas/adlcp_v1p3.xsd 
                              http://www.adlnet.org/xsd/adlseq_v1p3 SCORM-schemas/adlseq_v1p3.xsd 
                              http://www.adlnet.org/xsd/adlnav_v1p3 SCORM-schemas/adlnav_v1p3.xsd 
                              http://www.imsglobal.org/xsd/imsss SCORM-schemas/imsss_v1p0.xsd">

Test, test, test! I’ve tested this in SCORM Cloud as well as a couple of real-world LMSs and haven’t encountered any issues. Your mileage may vary depending on your LMS’s SCORM implementation, but this is perfectly valid XML and shouldn’t break in any LMSs — unless the LMS is poorly coded, but that’s a rarity, right? (LOL)

I guess there’s no such thing as a secure PDF

I was reading the SCORM 1.2 reference docs today. I wanted to copy a passage for my notes, but the PDF is password-protected and prevents anyone from copying text. (REALLY irritating, considering the ADL is a quasi-government organization and the docs should be open to all.)

What to do? Well, turns out there are at least two super easy ways to bypass the password protection: Upload it to Google Drive or import it to Evernote.

Google Drive

The Google Drive site includes a built-in PDF reader; when I opened the PDF in the web viewer, I was able to copy text freely. Better yet, I was able to save the PDF as an unlocked file by selecting “Print” then choosing “Save as PDF” in the print options.

Evernote

When dragging the file onto the Evernote app (Mac), the PDF shows up in a preview window. I was able to copy text freely. No need to save as a PDF since it’s already stored in Evernote!

Security, schmescurity

So I guess there’s no such thing as a secure PDF. I’m sure there are other services like to Google Drive and Evernote, and there are definitely other techniques for defeating protection, including screen captures, OCR, and the old fashioned approach of printing to paper then scanning the prints. If you truly need a document to be secure, don’t distribute it electronically.

On Converting Flash to HTML

I received a question from Bob (no, really), who wrote:

I have a question about the newest version of Flash and its HTML publishing option using CreateJS. What do you think of that approach going forward?

I started to write an email response but figured I should probably post it here.

I haven’t been paying much attention to Flash, so I don’t know what the ‘HTML export’ is capable of these days. In general, I’m very wary of converting Flash-based projects to HTML. When Adobe Captivate first released a “publish to HTML5″ feature, all it did was convert the SWF animation to a video file, losing all interactivity along the way.

The limitations of the browsers and the HTML5 spec mean you can’t expect a fully 1:1 conversion from Flash to HTML, regardless of libraries like CreateJS. Some of the features found in Flash are still not quite supported in browsers, or might not work quite the way you’d expect. For example, CSS transitions, CSS gradients, and SVG/Canvas support vary widely from browser to browser (though it’s getting better, and there are workarounds aka ”polyfills”). Streaming video, which is a breeze in Flash, is not part of the HTML5 Video spec (yet) and is unsupported in browsers. Video and audio codec support is inconsistent. In some cases, devices add new limitations — last time I checked, iOS devices wouldn’t autoplay audio or video in Safari. ‘Play’ couldn’t be scripted, it required the user to press a button.

Publishing to HTML (with the aid of JavaScript libraries like CreateJS) is definitely the way of the future, but I would flip the workflow: use a tool that’s “HTML first”. For my workflow, I always start in HTML then only fall back to Flash if I absolutely have to. I hand-code, but if you want to stick to a WYSIWYG editor, maybe try some of the Adobe Edge products, or go with a third-party product such as Tumult Hype.

If you continue to use Flash as an HTML development tool, temper expectations and test widely, as some things might not work the way you expect when converted to HTML.

And regardless of whether you publish to Flash or HTML, always test the accessibility of your project. Just because it’s HTML doesn’t mean it’s accessible; HTML by nature is more accessible than Flash, but libraries like CreateJS add a lot of complexity to the page, which can easily impact accessibility.

iTunes, TV Shows and Apple TV

iTunes vexes me. For better or for worse, we’re an Apple household and own an Apple TV, so I’m kind of stuck with iTunes for managing my media files.

My wife and I have also purchased a significant amount of DVDs over the years, which I ripped to iTunes using the trusty old Handbrake (love you, Handbrake!). These DVDs include a lot of TV shows, such as Doctor Who and Magnum PI.

My workflow has always been: rip via Handbrake, then import into iTunes by dragging the m4v files onto the iTunes window. By default, the TV shows don’t have any metadata (no proper titles, descriptions, episode numbers, or artwork), and iTunes automatically files them under Movies. This means they’ll show up in Apple TV with no description, no preview picture (such as DVD box art), and no sequence information.

I recently heard someone mention iDentify, a Mac app that adds metadata to movie files. It’s not free, so I had reservations about buying it. However, $10 is a small price to pay for cleaning up such a big mess, especially if you’re a bit OCD like me. I decided to give it a try, and it works very well, especially for TV shows — if you manually specify each file’s season and episode number, iDentify will take care of the rest by performing lookups at thetvdb.com. Sweet.

iDentify took care of the metadata and artwork problem, but the files were still cluttering my Movies menu, making it very hard to navigate with a remote control. For example, Magnum PI went eight seasons and has over 150 episodes, so we’d have to navigate past 150 Magnum PI titles to get to any videos whose name began with N-Z. Very annoying.

For a long time my workaround was to create custom genres and shove the TV shows there, then stick to genres when navigating Apple TV. This always felt kludgy, and I wondered why I couldn’t just drag the TV show episodes onto the TV Shows section in iTunes. This weekend I decided to look into it, and stumbled onto a MacWorld article containing a solution so simple I had to do a double face-palm: change the Media Kind from Movie to TV Show.

iTunes file properties dialog, 'Options' tab

Once set, the video is automagically moved from the iTunes Media/Movies folder to the iTunes Media/TV Shows folder, and shows up in the TV Shows menu!

Be sure to input the show’s name in the Video section so the episodes will be properly grouped.

iTunes file properties dialog, 'Video' tab

The MacWorld article pointed out that this technique can be extended to group ANY videos. This piqued my interest — my wife and I own a lot of DVDs that contain high-quality special features, including the entire James Bond collection, Star Wars collection, and classic films like Lawrence of Arabia. As I mentioned, I’m partially OCD, so I’ve ripped quite a few of these special features. Until now, they’ve all cluttered up my Movies menu just like the TV shows did.

TV Show grouping to the rescue! By changing the videos’ Media Kind to TV Show, they get moved to the TV Show section and can then be grouped. For example, I grouped all of my James Bond special features under the heading “James Bond Featurettes”. Now when I navigate the TV Shows section of iTunes or Apple TV, I only see ONE listing for James Bond Featurettes and no longer need to sift through 100+ titles.

iTunes still leaves a lot to be desired, but I’m a happy camper now that my files are well-organized and have proper metadata.

Setting OS X Desktop Picture Based on Time of Day

I recently changed jobs (Hello, FireEye!) and was issued a new MacBook Air. I spend a lot of time looking at the screen and was getting bored with the supplied desktop pictures. I also start work very early most days (7am-ish), and thought it would be nice to have a desktop picture that matches the mellow-ness of such an early hour.

Of course, this leads to daydreaming — “scope creep” in professional parlance — and next thing you know, I started thinking “well, maybe I could also set it to show a nice evening-themed picture at night”. Then “maybe I can get it to change both screens” (I use a laptop with an external display).

I also liked the challenge of putting together a script as quickly as possible. (In my off-hours, of course!)

I downloaded some nice wallpaper images from National Geographic, then created six folders that correspond to the major periods of the day: morning (early and late), afternoon (early and late), and evening (early and late). I organized my National Geographic photos into those six folders, based on the mood each photo evokes. For example, this one is an early morning photo.

Then I rolled up my sleeves and got out the trusty old AppleScript Editor. The resulting AppleScript is posted on GitHub, if you’d like to take a gander.

The gist:

  • It selects a folder based on the time of day.
  • It randomly selects an image from within that folder and displays it as the desktop picture.
  • It supports more than one monitor, with an option to either display the same image on all monitors, or display different images on each monitor.

The resulting AppleScript must be run at a regularly scheduled interval. I’m currently using GeekTool to run the script every 15 minutes, but I might eventually switch to a crontab job for less overhead.

Regardless, I’m quite happy with the way it turned out, and have already started daydreaming about other things I can hack together with AppleScript.

Flash support is increasingly a minefield

Back in 2011, I mentioned that Microsoft was about to halt development of the Silverlight plugin, that Flash mobile was being discontinued, and that Adobe recommended HTML5 for enterprise RIA development instead of Flex, which was being open-sourced. My post was a little long-winded, but the short version was: whoa, the times-are-a-changin’, it’s getting dangerous to rely on browser plugins.

Over the last year, the situation has evolved in an interesting way — browser support for plugins (especially Flash Player) has been considerably restricted by browser vendors due to repeated security vulnerabilities in Flash Player and Java.

Automatically disabling Flash Player

In May 2012, Apple’s Safari browser began automatically disabling outdated versions of Flash Player: “Out-of-date versions of Adobe Flash Player do not include the latest security updates and will be disabled to help keep your Mac secure.” If a webpage contains a SWF but the installed edition of Flash Player is deemed out of date, Safari will display a “blocked plugin” message and inform the user they need to download the latest edition of Flash Player at adobe.com. This change came with Adobe’s blessing.

In January 2013, Mozilla introduced a global “click to play” mechanism that disables ALL plugins in Firefox by default, except the latest edition of Flash Player:  ”Our plan is to enable Click to Play for all versions of all plugins except the current version of Flash.”

To Adobe’s credit, Flash Player updates are being released at a fast clip to address known security vulnerabilities. Unfortunately, this has a nasty side effect: you’re very likely to have an outdated edition of Flash Player when you try to view Flash content on a website. (By my unofficial count, there have been at least 13 updates over the past calendar year, averaging about once a month.)

At a recent job, I managed a small network of Macs in classrooms. The Macs were set up to use Adobe’s ‘automatic updates’ feature for Flash Player, but they never seemed to update fast enough — we received numerous complaints from classroom users who couldn’t view Flash content because Safari blocked it.

Internet Explorer’s on-again, off-again relationship with Flash Player

I previously mentioned that Microsoft’s Windows 8 ‘Metro’ mode disabled all plugins, including Flash Player; Microsoft said Internet Explorer in Windows 8 Metro mode ”provides an add-on–free experience, so browser plugins don’t load and dependent content isn’t displayed“.

In May 2012 Microsoft changed their minds and enabled Flash in Metro mode. BUT… Microsoft will ship Flash Player as a component of IE 10 (much like Google Chrome does), and will restrict which sites are allowed to run Flash! “While any site can play Flash content in IE10 on the Windows desktop, only sites that are on the Compatibility View (CV) list can play Flash content within Metro style IE.”

In other words, if you don’t have Microsoft’s blessing, your Flash site will not work when viewed in Metro mode.

Update: @chris_sage pointed me to a post by Microsoft written just three days ago where they apparently changed their minds again — almost a year after saying they’d require a whitelist, they now say they support Flash Player by default in Metro mode without requiring sites to be whitelisted.

What it boils down to…

If you develop Flash-based content, it will be more and more of a challenge to provide a smooth, problem-free user experience. For e-learning developers, one of the original lures of Flash was the ubiquity of Flash Player; Flash made it easy to provide the same e-learning experience across browsers and platforms. Due to fragmentation in Flash support, this no longer appears possible.

  • Adobe says: No Flash Player for mobile devices.
  • Microsoft says: No Flash Player on Surface tablets (or other Windows 8/RT tablets) unless the user switches to desktop mode OR gets on our whitelist for Metro mode. We love us some Flash! But we’ll manage the security updates ourselves, thank-you.
  • Mozilla says: Only the latest edition of Flash Player for Firefox.
  • Apple says: No Flash Player on Apple iOS devices, and only the latest edition of Flash Player for desktop Safari.
  • Opera says: Flash Player on desktop editions of Opera? No problem. Flash Player in Opera Mobile? Don’t get mad at us, Adobe stopped providing Flash Player for mobile devices!
  • Google says: We control Flash Player for Chrome (desktop) ourselves. No worries. Flash Player in Chrome on mobile devices? Don’t get mad at us, Adobe stopped providing Flash Player for mobile devices!

The browser vendors are enforcing their will. You don’t have to be a Flash-hater to see that building Flash-dependent sites is a minefield.

For those of you in e-learning who depend almost completely on Flash-based courseware, it’s a good idea to start looking for alternatives.

 

 

E-Learning and Web Development