Charles Engelke's Blog

January 7, 2012

Chrome Web App Bookshelf – Part 6

Filed under: Uncategorized — Charles Engelke @ 3:52 pm

Note: this is part 6 of the Bookshelf Project I’m working on. Part 1 was a Chrome app “Hello, World” equivalent, part 2 added basic functionality, part 3 finally called an Amazon web service, part 4 parsed the web service result, and part 5 actually was somewhat useful. The series is almost done now. This post will cover packaging and privately publishing the app, and the next and final post will cover putting it in the Chrome Web Store.

There’s more functionality I want to add to the app eventually (updating the data on saved books, deleting books from the list, and even synchronizing the list of books between PCs) but the purpose of this series is to show how to create and publish Chrome web apps. My app is just barely functional enough now to publish, so I’m going to go ahead and do that.

Since my app contains software and images from others I’m going to have to add some acknowledgment of that fact. I want to be sure I’m complying with the license conditions when I distribute those pieces, and I should also specify whatever the license conditions are of my app. So I added a file called LICENSE to my project directory, spelling out my license terms. You can see the current version of that file here. As you can see, I chose the MIT license for my app because I feel that’s one that least encumbers the users.

One licensing issue I encountered was that the Stanford JavaScript Crypto Library includes patented code, and the conditions of its use apparently require either purchasing a license to the patent or using only the GPL, at least in the United States. I’m not a lawyer so I might not be understanding this clearly, but I don’t want to violate the terms or intent of that patent holder. Other than that issue the library can be licensed under the BSD license, which seems to be compatible with the MIT license I chose. That library includes tools to build subsets of the whole thing, so that’s what I did. The patented code is used in cipher algorithms, so I built a library without ciphers (in fact, it has the minimum functionality that I need) and am including only that. I believe that means I’m fine distributing it as part of my MIT licensed app.

I also added copyright notices to the files I created: main.html, main.js, aws.js, and main.css. I don’t think that the manifest file is actually a creative work, so didn’t put any copyright notice in it. I don’t even know where it could have gone had I wanted to add one.

I know a lot of people think that explicitly specifying copyright and license conditions aren’t really necessary unless you want to restrict use of your work, but as someone who builds commercial software for a living I can tell you that they’re very important even if you don’t want to restrict that use. Without clear indication of the conditions, nobody would risk reusing what you created in any professional or commercial endeavor.

Okay, the app has been slightly polished up, is (just barely) functional enough to actually use, and has clear claims and acknowledgment of ownership and licensing. I’m ready to publish it. But how?

I started by recognizing that once I publish it I will want to update it at times. Every update should have a higher version number. So far I’ve left that number as “1” in the manifest, but for publishing I’ll take advantage of the fact that Chrome allows that version number to be up to four integers, separated by periods, and start over at version “0.0.0.1”. With that done, I can package the app using any running copy of the Chrome web browser.

First, open the Extensions panel by choosing Tools/Extensions from the drop-down menu you get when you click the wrench icon in the upper right hand corner of the browser. When I do that, I see the unpacked version of the app I have been working on:

Extensions panel showing the unpacked app

When I click the Pack extension… button I get the following dialog box:

Pack Extension... dialog box

I enter the directory I have been working in, leave the Private key file field empty, and click Pack Extension. Chrome tells me what it has done now:

Message shown after packing

It created a Chrome extension file (ending in .crx) and a new key file for me to use (ending in .pem), and told me where they are. Next I opened the file in Chrome by dragging and dropping on to the browser, and was asked whether to install it. After I said yes, the Extensions panel showed the app twice:

Extensions panel showing two versions

The top one is the unpacked app I’ve been working on, and the lower one is the actual packaged application. I then removed the unpacked version and tried out the packed one. It worked!

But it’s still not really ready. If I create a new version there’s no way that Chrome will know about it. If I host the app on a web site I can configure the manifest so that Chrome will regularly check for updates and install them if they exist. But to make that happen I have to also create an XML file describing the current version of the app. I guess Chrome doesn’t want to have to download a whole app just to see if it’s updated, and prefers a small XML file for that. I have to put the URL for that XML file in the manifest. While I’m was at it I also added the URL of a home page for more information about the app and incremented the version number. The manifest file now looked like:

{
   "name": "Books to Buy",
   "description": "Keep a list of books to buy on Amazon, with their price and availability",
   "version": "0.0.0.2",
   "app": {
      "launch": {
         "local_path": "main.html"
      }
   },
   "icons": {
      "16":    "icon_16.png",
      "128":   "icon_128.png"
   },
   "homepage_url": "http://www.bibliote.ch/",
   "permissions": [
      "https://webservices.amazon.com/*"
   ],
   "update_url": "http://www.bibliote.ch/files/bookshelf.xml"
}

The homepage_url and update_url entries are new. Of course, since I’m referring to an XML file at a particular URL I’d better create that file and host it at the URL. The format of the XML file is pretty simple; I just copied an example and replaced values with the right ones for my app:

<?xml version='1.0' encoding='UTF-8'?>
<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>
  <app appid='mpcejinifahkdfhnfimbcckdllahpbmg'>
    <updatecheck codebase='http://www.bibliote.ch/files/bookshelf.crx' version='0.0.0.2' />
  </app>
</gupdate>

I had to fill in the correct codebase value with the URL I am hosting the app file itself at, the version value with the current version number, and appid with the correct value.

appid? What’s that?

Chrome assigns a unique ID to every application it creates. That’s the value needed here. To see it I just looked at the Extensions panel and clicked the gray arrow to the right of my application’s icon, then I cut and pasted it to here.

After I rebuilt the extension with the new manifest (I had to fill in the Private key file name this time, matching the one created the first time I packaged the app) I uploaded the XML and CRX files to the URLs shown in the manifest and XML file. I also set the Content-type of the CRX file to application/x-chrome-extension, though that’s probably not needed given that the file name ends in .crx. I uninstalled my app to get a clean environment and visited www.bibliote.ch/files/bookshelf.crx with Chrome. I was asked whether to install the app. When I agreed, it installed and worked file.

So, does auto-updating work? I changed the version numbers in the manifest and XML file, packaged the new version, and uploaded the new XML and CRX files. And, a little later, the new version showed up in my browser. Success!

If you want to try this yourself, the entire application directory I used for this is available here. You’ll have to create your own XML file by copying the one above and changing the values as needed.

I could stop here but there is one Chrome app feature I want and don’t yet have: synchronizing extensions across different browsers. From my reading of the documentation that should be working now, but it isn’t. Either applications like mine are treated special and not synchronized, or else you need to publish in the Chrome Web Store to get this functionality. I’d like to explore how that store works anyway, so I’ll try it out next time and see if synchronization starts working.

Advertisement

1 Comment

  1. […] web service, part 4 parsed the web service result, part 5 was useful enough to publish, and part 6 covered publishing it at my own website. This post finishes the series by publishing in the Chrome […]

    Pingback by Chrome Web App Bookshelf – Part 7 of 7 « Charles Engelke’s Blog — January 8, 2012 @ 1:37 pm


RSS feed for comments on this post.

Blog at WordPress.com.

%d bloggers like this: