Monday, November 4, 2013

Tools for Developing on ChromeOS

I've been using my Chromebook Pixel as my primary machine ever since I got it for most of my work, with one crucial exception - development. Whenever I needed to do more than just edit a couple of individual files, I had to turn to my MacBook Pro with its trusty Sublime text editor and ability to run things like Node.

I'm happy to report, however, that things have changed dramatically just in the last several months, and it's now easier than ever to do real development on your Chromebook. In this post, I'm going to give an overview of some of the tools that I use when developing on my ChromeOS devices (In addition to my Pixel, I also have an HP 14, a Samsung 550 in developer mode, a Samsung Series 3, and an Acer C720).

Keep in mind that some of these tools are fairly new and still developing, so keep an eye on them as they get better over time. Also note that all the tools I talk about in this post are available for all the supported Chrome Apps platforms (Mac, Windows, Linux, and ChromeOS), but I'm focusing just on ChromeOS here.

The Basics - Offline Editing

Let's start with the basics - editing code. Obviously, having a great code editor that works locally on offline files is a prerequisite for any serious development on any computer. For ChromeOS, we have a couple of good options here.

Text App

Until recently, my go-to text editor was - not surprisingly - Text. It's pretty straightforward, works offline, has support for syntax highlighting, syncs with Google Drive, and can easily handle multiple open files.

Screen shot of the Text editor app from the Chrome Web Store
The Text app from the Chrome Web Store
As of this writing, though, Text has a few shortcomings. It doesn't remember the files I had open between sessions, it doesn't remember the window position or size, and it's not very customizable. All that said, though, it's a good editor for what it does, and I still use it all the time for various text editing tasks.

Caret

I'm a pretty big fan of Sublime Text, and it's one of the things I missed most when working on my Chromebook. I recently came across a new Chrome App called Caret that does a great job of code editing and gives me a user experience that's much more like Sublime:

screen shot of the Caret text editor application
The very Sublime-like "Caret" editor

Some of the things I really like about Caret are:
  • It remembers the files I had open between run sessions
  • It remembers the size and position of the window
  • Support for multiple carets and other Sublime-like features
  • Lots of color schemes, support for font sizes, etc.
  • Code completion
  • Very customizable - lots of user-editable settings
  • It's open source and has a Github project
Between these two tools, I think local code editing is pretty well covered. Caret in particular is in active development by the developer, so I'm looking forward to that app getting better over time and incorporating new features as they become available in the Chrome Apps API.

md everywhere

In addition to editing code, I find myself creating and editing Markdown content quite a bit, since it's how ReadMe files and such are represented in Github. 

The app that I usually reach for when I need to do this on my Chromebook is md everywhere, which - you guessed it - runs as an offline Chrome App. It has two main components: a window for editing markdown content, and a separate viewing window to see the HTML output, which can be shown or hidden separately from the editing window.

Editing Markdown on the left, with preview on the right

It's not perfect, and has a few quirks, but it gets the job done and greatly reduces the amount of guesswork involved. There are a couple of other MD editors in the store, but md everywhere seems to be the best of the bunch so far.

Cloud-Based IDEs

One of the more exciting trends of recent years has been the emergence of cloud-based IDEs. These are full-fledged development environments that work within your browser, giving you full access to a remote development box that can run all manner of environments, tools, etc.

Several of these IDE providers have existing apps in the Chrome Web Store, such as (but certainly not limited to): Koding, Cloud9, Nitrous.IOShiftEdit, and Codenvy. There are also collaborative cloud-based editors like Neutron Drive.

Each of these tools could take up an entire post on their own, and I'm planning to do a deeper dive into them at some point, but for the moment I'm going to focus on Nitrous.

Nitrous.IO

The Nitrous guys recently released their online IDE as a packaged Chrome App, so I've been using it a lot recently (which is not to say that any of the others are somehow lesser; to the contrary, they're all very good and have their own strengths). 

Cloud coding with Nitrous.IO

The Nitrous app is essentially a window that hosts the <webview> control, which displays the remote environment that you're connected to.

Setting up a remote Nitrous box is pretty easy, and you have your choice of Node, Ruby, Python, and Go environments. The Web IDE is straightforward, includes collaboration options, and lets you upload source files to the remote box. There's also a command shell for executing commands and such. The docs are pretty extensive, too.

I recently tried out Nitrous on a small NodeJS/MongoDB project, and the experience was about as easy as it could be. I just provisioned the box, uploaded some source files, and was working away within minutes. The Web IDE even provides a "Preview" function that launches the app within the local browser with the URL already set up.

Between working on source files locally and having a cloud IDE to test and deploy in, I can easily see how a setup like this could become the future of development.

Testing and Debugging

One of the greatest things about developing on a Chromebook is that you have access to the best Web developer tools in the business - the Chrome DevTools, naturally. You would be amazed at the number of people who don't yet realize this.

Chrome DevTools

Whether you are working on Chrome Apps, Extensions, or regular Web sites, the Chrome DevTools give you unparalleled features for debugging, profiling, logging, etc. Now, I'm not going to go deep into the Chrome DevTools here because all the information that you need to use them effectively is at that link that I've provided above, but here are some of the features you might not know about that you should definitely investigate:


Postman

If you do any work that requires transferring data to and from RESTful Web services (and who doesn't these days?), then you'll find that Postman is a great utility for testing REST based APIs.

Postman comes in two flavors - the original V1 Packaged App, and the newer Chrome App. I prefer the latter, since it works offline and in its own window. It also comes with a great set of online docs.

Postman makes working with REST APIs easy

Postman has some features that make working with REST services a breeze:

  • You can define collections of requests, and group them together to reflect your API
  • Adding headers and query parameters is quick and easy
  • You can set up different environments (such as "Production" vs. "Development") and then customize the way that requests are sent using variables
  • There are helpers for setting up various authentication schemes, such as OAuth2
  • The app adds each request to its History, which makes it easy to experiment
  • It is easy to customize the app's settings, and there are a lot of ways to tailor Postman to your particular needs
If your work involves REST APIs, then I highly recommend you download Postman.

Dimensions

Dimensions is a legacy, or "V1", Chrome Packaged App, but it's still useful and runs offline so I included it here (and hopefully the developer is working on updating it to be a Chrome App). Dimensions essentially does one thing - it shows you how your UI will lay out at different screen sizes.

Using Dimensions to view various layout sizes

Essentially, you start up the app, point it at a URL, and then slide the grab-handle left and right to simulate different screen widths. Assuming you've written your HTML to use responsive layout techniques, the page will change at various widths so you can gauge what it will look like on various devices.

Dimensions include pre-defined layout sizes for iPhone, Android, and Tablet sizes, and you can rotate each device to display different widths.

By default, the app will load in a browser tab, even if you're offline (that's what v1 Packaged Apps do). I usually set Dimensions to open as a regular window (just right-click on the app icon and choose the appropriate setting), which gives it a more app-like feel.

Useful Utilities

Editing and debugging get all the attention, but there are always those small utilities that developers use to make their lives somewhat easier when it comes to the workflow and other parts of development. Two of the utilities that I've found really useful so far are GistBox and HexReader.

GistBox

I've started using Github more and more to store things like code snippets (or "Gists", in their terms) because it's really easy to access them from everywhere, and GistBox makes organizing and working with Gists simple.

You can edit your Gists directly in the app, create new ones, apply labels, search Gists, and even share them via email or Twitter.

Organizing Gists with GistBox

Unfortunately, since it relies on Github access, it doesn't currently work offline, but given its purpose and usage scenario, I haven't found a situation where that has mattered for me yet.

HexReader

This one is pretty straightforward, and will be familiar to anyone who's ever had to manipulate binary files. Want to make sure that the file you're working with really is a proper PNG? Need to extract some embedded data from a PDF file? HexReader has you covered.

HexReader in action

It supports large files, you can copy data as text or hex, and it has bookmarks too.

Yes, it's a bit of niche app, and not exactly for everyone, but for those people who need it, HexReader is one of those developer utilities that you're glad is there.

Summing It All Up

ChromeOS has a come a very long way in a short period of time, and the developer story has improved right along with it. I find that I can do pretty much all of my every-day development tasks right from my Pixel (or, thanks to Chrome Sync, any one of my Chromebooks) while getting all the usual benefits of ChromeOS: speed, simplicity, and security.

And this is just the beginning - more developer tools are on their way, and the built-in Chrome DevTools continue to improve at a rapid rate.

App Links

I've included all the links to the apps I mentioned in this post here in one handy list for those of you looking to try some of these out:


Do you have any tools that you like to use to develop on ChromeOS? Be sure to let me know in the comments.

Happy Coding!

Monday, April 29, 2013

What jQuery 2.0 Means to Developers

On April 18, 2013, at long last, jQuery 2.0 emerged from Beta and was released to the public. The jQuery library has evolved a lot since it was first released, along with the way that developers use this iconic tool. The 2.0 release includes a couple of significant changes that affect how developers use jQuery, and in this post, I'll discuss what these changes mean to developers.

Dropping Support for Internet Explorer 6, 7, and 8

Many people seem to have overly focused mainly on what jQuery 2.0 does not do - that is, support older versions of Internet Explorer, 6 through 8. The jQuery team decided to split the library into two different versions: the 1.x line, which will continue to evolve and support older browsers, and the new 2.x line, which will remain feature compatible with 1.x while focusing on modern browsers.

This was absolutely the right decision by the jQuery team, for several reasons. Two of the most important reasons are:

  • The usage of IE 6-8 continues to decline, and according to the jQuery team, they were able to shrink the size of the library by 12% just by taking out the patches needed to support these older browsers.
  • The HTML5 development landscape is a lot more diverse than it was even just a few years ago, and continuing to support older browsers would have held jQuery back. I'll go into more detail about this below.

At first glance, this decision may seem a bit bold, especially since Windows XP still has a significant market share at the moment and IE8 is still in widespread use on that platform. However, since jQuery 1.x will continue to support these browsers, this essentially means that developers need to think in advance about where and how their app will be used, and consider the audience for their application.

HTML5 is No Longer Just About the Web

Notice that I didn't title this post "What jQuery 2.0 Means to Web Developers"? I did that very purposely, as a lot of development around HTML5 is increasingly no longer directly tied to Web browsers. Several application platforms have emerged that use HTML5 as their development language, and for these platforms, the notion of older browser support simply isn't very relevant.

In these and many other up-and-coming scenarios, support for older IE versions isn't needed and results in dead code that will never be executed. By removing this code from version 2.0, the jQuery team can spend more focus on modern development scenarios, which will help position the library for further growth and adoption in the scenarios I've listed above as well as newer ones that haven't even come along yet.

As a result of this change, jQuery 2.0 is just 82K when minified - and that's for the whole standard library. But jQuery introduced a modular build system back in 1.8. Use the custom build system to exclude things you don't need, and you can get it down to under 20K.

These two steps - dropping support for older IE versions and introducing a modular build system - are, in my opinion, two of the most important changes that jQuery has made in the past few versions. They make jQuery more attractive for application development beyond just web sites, which opens a whole new set of opportunities for the library, as well as additional potential sources of innovation and contribution.

So Which Version Should You Use?

The decision about which version of jQuery to use isn't really that complicated. If a project that you are working on needs to run on older browsers, then you should stick with jQuery 1.x. If the project doesn’t need to work on those older browsers, or you're building an app for one of the platforms I listed above, then you can move to the newer 2.x branch.

You can use IE Conditional Comments to make sure that the user's browser gets delivered the right version of the library by using the following code (from the jQuery blog):

<!--[if lt IE 9]>
<script src="/path/to/jquery-1.9.1.js"></script>
<![endif]-->
<!--[if gte IE 9]><!-->
<script src="/path/to/jquery-2.0.js"></script>
<!--<![endif]-->

Of course, Conditional Comments are going away in IE 10, but since IE10 is a much more capable, modern browser, that won’t matter and the above code will continue to work - IE10 will just get the 2.0 version.

When jQuery was first released, its two primary purposes were a) to abstract away differences among browser APIs and b) make manipulating the DOM a lot easier and more predictable. Since then, it has become far more useful and versatile, and the 2.0 release takes it a further step in the world beyond the web browser.

The decision to discontinue supporting older versions of IE may seem on the surface more about saving space and focusing on modern browsers, which are of course noble goals in themselves.

The real news here, however, is that with this decision, the jQuery team is clearly positioning the library to be relevant to development scenarios beyond web applications. That's a significant step in jQuery's evolution, and I'd expect to see the jQuery team flesh this out more as these scenarios become more and more prevalent.

Monday, February 25, 2013

Rich Notifications in Chrome Packaged Apps


Several modern application platforms provide mechanisms for notifying the user of interesting events. Android, iOS, Mac OSX, Windows - they all have a fairly common, standard way of organizing notifications and displaying them to the user.

With the release of Chrome Canary M27, the Chrome Packaged Apps platform joins that club by providing the Rich Notifications API on ChromeOS and Windows (Mac and Linux to follow soon). This API goes beyond the web-standard HTML notifications system by allowing more visually rich notifications to be displayed (since the official W3C spec recently removed support for HTML-based notifications). The API is fairly flexible, allowing developers to specify one of four basic layout templates and register for events that happen on individual notifications.

Note: although the API is fairly stable and will soon be exiting the experimental phase, it is still undergoing changes. Use with caution.


The API supports 4 types of notifications:

  • Simple - an icon and some text content
  • Basic - icon and text content, and up to two buttons
  • Image - icon, text, and image, and up to two buttons
  • List - icon and list content, and up to two buttons

Chrome Notifications User Experience

Chrome Notifications are displayed according to the underlying OS’s conventions. On Windows, for example, the notification appears as a “toast” pop-up in the lower right corner of the screen:


Notifications can contain images in addition to text:




In addition to the notifications themselves, the Chrome Notifications API provides a notifications center that organizes the notifications by criteria such as date, priority, etc.

The Notifications API

The API itself is fairly simple. Notifications can be created, updated, and deleted using straightforward methods:
function create(DOMString notificationId, NotificationOptions options, 
    CreateCallback callback);
function update(DOMString notificationId, NotificationOptions options, 
    UpdateCallback callback);
function delete(DOMString notificationId, DeleteCallback callback);

A few things to note when using the API:

  1. The notificationId parameter is a string of your choosing, as long as it is unique (which is required to keep the notifications center from becoming confused).
  2. The NotificationOptions structure defines the content of the notification - its type, title, message, buttons, and so on.
  3. Some of the NotificationOptions properties allow you to specify URLs for images; they currently do not accept data:// URLs (though this is planned). In addition, you can use the chrome.runtime.getURL() method to retrieve an app- or extension-relative path to an image resource included with your package.
  4. Although the API provides parameters such as priority, the API does not make any guarantees as to how such parameters will affect the display of notifications - they are just hints to the system (for example, the OS may decide that a low priority notification merely lights up the notification center icon instead of displaying it). Currently, normal priority notifications (0) are displayed for 7 seconds, higher priority (1 and 2) are displayed for 25 seconds.
  5. The update() method can be used to transform a notification from one type into another, such as from "simple" to "image". Very cool.
  6. As with many other Chrome APIs, this one is asynchronous - it uses callbacks to indicate to the calling program the result of each function.

Example:
var path = chrome.runtime.getURL("/images/myicon.png");
var options = {
   templateType : "simple",
   title: "Simple Notification",
   message: "Just a text message and icon",
   iconUrl : path,
   priority: 0
};

chrome.experimental.notification.create("id1", options, crCallback);

function crCallback(notID) {
   console.log("Succesfully created " + notID + " notification");
}

Notification Events

In addition to the API functions to create, update, and delete notifications, your program can register to listen for notification events. There are currently five such events.

  • onDisplayed - the notification was created and displayed to the user
  • onError - there was an error with the notification
  • onClosed - the notification was closed, either due to a system timeout or by the user (and it is possible to distinguish the difference)
  • onClicked - the body of the notification itself was clicked
  • onButtonClicked - the user clicked on one of the buttons in the notification (this event fires on the notification itself, and the index of the clicked button is a parameter).

Events are registered using the typical addListener() method for Chrome events:
chrome.experimental.notification.onDisplayed.addListener(fDisplayed);
chrome.experimental.notification.onClicked.addListener(notClicked);
chrome.experimental.notification.onButtonClicked.addListener(notBtnClk);

function fDisplayed(notID) {
   console.log("The notification '" + notID + 
       "' was displayed to the user");
}
function notClicked(notID) {
   console.log("The notification '" + notID + "' was clicked");
}
function notBtnClk(notID, iBtn) {
   console.log("The notification '" + notID + "' had button " + iBtn + " clicked");
}

Summary

The Chrome Rich Notifications API marks another step in the process of bringing native-app-like capabilities to Chrome Packaged Apps and Extensions. To get started, check out our example on the GoogleChromeGithub. Consider adding support for this API in your next project to give your users an experience that is more tightly integrated with their OS and in line with what they’ve come to expect from native applications!

Thursday, January 10, 2013

Best Practices for Marketing in the Chrome Web Store

One of the keys to success in the Chrome Web Store is to ensure that your app or extension stands out from the crowd of existing content. Now that the CWS has grown to encompass tens of thousands of items, developers can no longer just upload their products and wait for the world to beat a path to their doorstep. 

Of course, the best thing you can do is build a highly valuable product that meets the demands of as many users as possible, but it's not enough to just create a great product - you have to know how to market and promote it. Assuming you've already done that, I've listed here some of the more effective things you can do as a developer to differentiate yourself in the Chrome Web Store, as well as some things to avoid.

What to Do


1. Create high-quality graphic assets and promotional images. Users are much more likely to trust and feel good about installing a product that has high-quality, professional-looking images. Don't just fire up Photoshop and try to do this yourself unless you're really good at it - if you're serious about your product, invest in high-quality promotional materials. It will give your app/extension a sense of polish that will help it stand out. You're also far more likely to be selected for featuring in the store if you have high quality images.

2. Use inline installation. The Chrome Web Store makes it easy for users to install your product, but you can make the process even easier by implementing a feature called inline installation. It allows users to install your CWS item directly from your Web site without having to visit the store. You can do this in just a few lines of code, and can even see if the user already has your product installed. We've seen developers who implement this feature get very large jumps in installations - as much as 40% in some cases.

3. Create a dedicated page for your app or extension on your web site, and make sure it gets indexed by Google. Users find items in the CWS via regular Google search in addition to searching the store, and you want to make sure that your item appears at or near the top of these searches. When combined with #2 above, this can lead to many more installations.

4. Provide useful, meaningful screenshots. Users want to see your product in action before they spend effort on installing it and learning to use it. High-quality screen shots are your opportunity to show users what your product does even before they install it. Upload 4 to 5 images that clearly tell the story of what your product does and why it is valuable.

5. Include a YouTube video demonstration. In addition to static screen shots, you should upload one or two YouTube videos that show your product in action and clearly explain what it does. Keep the videos short - no more than 3 to 5 minutes. When combined with screen shots, this can be a very effective way to generate installations.

6. Create a good description entry. Short descriptions don't give the user enough information about what your item does. Think about the top 3-5 things you want users to know about your item and make sure to call them out here.

7. Supply a support link to your web site. Users want to know that they won't be stranded without help when they install a product. By providing a link to your support page, you can give them the reassurance that they need. It doesn't have to be a link to your site - if you prefer to use a support site like UserVoice, for example, that's fine too. Just don't leave people hanging.

8. Enable - and use - the CWS user feedback feature. In addition to leaving reviews, users can provide feature feedback and bug reports - but only if you enable this feature in your developer dashboard. This feature is a great way of encouraging an ongoing conversation with your users without polluting the Reviews section with bug reports and feature feedback.

9. Use Google Analytics. The CWS developer dashboard provides a place to enter your GA account ID. If you provide one, the CWS will tell you how many impressions your item's Details Dialog has received, as well as whenever the user clicks the Install button.

What Not To Do


In addition to the above tips, there are some things that you should avoid doing:

1. Don't try to out-smart the CWS search indexer by, for example, adding a whole bunch of keywords to your item's description. You will get flagged for this and taken down. It's a violation of our Terms of Service.

2. Don't use trademarks and copyrights that you don't own. If you want to indicate that your product works well with someone else's product, then give them proper attribution and use a phrase like "for GMail" (or whatever the product is). Starting off your product name with someone else's trademark will get you taken down (for example, "Gmail Awesomeness" is bad - use "Awesomeness for Gmail(tm)" instead).

3. Don't use permissions that you don't actually need. Users are less likely to grant all kinds of permissions to something that they don't highly value or trust. Make sure you are scoping your permissions to what you actually use.

Now, of course none of these tips will absolutely guarantee success. You still need to create a high-quality app. However, by following them you'll place yourself in top-tier of CWS items, and will position yourself well to get discovered and more likely to be installed.

Anything I missed? What else have you found to be an effective way to get attention for your store items?