SproutCore 1.0: UserDefaults

Here’s a fun new bit of code I added to SproutCore for 1.0 over the holiday. The SC.UserDefaults objects that comes with SproutCore 1.0 can be used to store user preferences for your application. It’s terribly easy to use.

First, you will want to set your application and user domains at the top of your main() function like so:

function main() {
  SC.userDefaults.set('appDomain', 'MyCompany:MyApp');  // unique for your application
  SC.userDefaults.set('userDomain', 'charles'); // set to user name
  // ... setup the rest of your app here
};

Next, you will want to setup some reasonable defaults.  The defaults are used if you have not overridden them.  I usually put this into a file on their own called defaults.js, but you could also load these defaults dynamically from a server and fill them in:

SC.userDefaults.defaults("MyCompany:MyApp", {
  "mainTab:nowShowing": "welcome",
  "calendarPane:isVisible": YES
});

Finally, you can get/set attributes like normal:

// determine which pane to show on app load
  SC.page.mainTabs.set('nowShowing', SC.userDefaults.get('mainTab:nowShowing'));

// ..elsewhere, when the tab changes, save the updated view
  nowShowingTabDidChange: function(tabView) {
    SC.userDefaults.set('mainTab:nowShowing', tabView.get('nowShowing'));
    //... other observer code
  }.observes('nowShowing')

All well and good, but so far this looks like syntactic sugar.  Well, here’s the kicker:  if you are using a browser that supports localStorage, including Safari or Firefox, or you have Google Gears installed, userDefaults will automatically save your user preferences locally.  These will override the defaults you write in using the SC.UserDefaults.defaults() method above.  If you are on a browser that does not support client-side storage, things will still work; the preferences will simply reset when you reload.

This new API makes it terribly easy to help your application use client-side storage to remember its last state when you reload the app.  In fact, it’s so easy to use I’ve gone ahead and added support for user defaults to some of the built in views as well.  The SC.TabView, for example, now supports a property called userDefaultKey.  Set this property to some key name, and the tab view will automatically save its last showing tab in user defaults.

Installing SproutCore on Ubuntu

To install SproutCore you can’t just do sudo gem install sproutcore because it lacks some preliminary components you need. Thankfull, cdivilly has figured it out for you:

Installing SproutCore on Intrepid Ibex (Ubuntu)

SproutCore 1.0: Mixins

There are a lot of little refinements going into SproutCore 1.0.  One of those refinements is better support for Mixins.  A mixin is simply a collection of properties that can be applied to your object or class.  It’s a more flexible way of adding functionality than through class inheritance.   Mixins are supported in SproutCore today, but they get some additional love in SproutCore 1.0 through the addition of initMixin() and destroyMixin().  I’ve added some basic documentation here:

SproutCore Wiki: About Mixins

(Bonus link: draft docs on creating objects and classes)

SproutCore @ GTUG

A few weeks ago we had a great meetup at Google. If you didn’t get to attend, now you can enjoy the meeting vicariously through YouTube! This video starts with a presentation from Matt on the Google AppEngine team, followed by five minutes of futzing with a technical problem, and finally the SproutCore presentation starts.

During this presentation I actually built and deployed a small application on stage but the most interesting thing, I think, is the part where I talk about how thick client frameworks like SproutCore change the way you build your server side as well.  It’s a model I call “microservices.”

Skip to about 20min in to see the SproutCore goods. Thanks again to SV-GTUG for hosting us.

Let me know your thoughts (especially on microservices) in the comments below!

SproutCore & Microservices @ Google

SproutCore Objectives...

We had a great SproutCore Meetup at Google a few nights ago in cooperation with our friends at SV-GTUG. Nearly 100 people attended, Peter showed his great SproutCore app, Ryan gave a talk on Google AppEngine, and I built an entire application, including the backend, and deployed it on stage. That was fun.

Google AppEngine is interesting, but I think it’s especially interesting when you combine it with a web-client style technology like SproutCore. It makes AppEngine apps easier to build and delivers outstanding performance.

We’ll have a full video up in a few days as I understand it. I’ll post a link here when we get it, but until then here are some photos to tide you over.

Thanks again to the fine folks at SV-GTUG and Google for hosting the event.

SproutSightings: PaperCube

Peter Bergstrom has been working on a really interesting paper citation visualization tool called PaperCube for the last few months and its powered by SproutCore. Today he posted a detailed writeup on the app and how to use it, that you can check out for yourself.

PaperCube is a great example of using SVG and advanced CSS rendering to create a rich graphical experience. It’s a bit shocking when you use this app to realize that he has created this entire experience using only JavaScript and native web technologies. Who says you need Flash or Silverlight for a great visual experience!

PaperCube will be one of the example apps listed on our samples page soon also.

» Read Peter’s Instructions
» Try the app

SproutCore 1.0: Platforms

Mobile is a really interesting area for any web developer.  With the iPhone and Android, there are finally phones with serious browsers that can run actual app-like code.  Very exciting.

Of course, developing an application for a phone has its own unique limitations.  Bandwidth is an issue of course.  As is memory constraints and the UI has to look completely different.

Nevertheless, I believe that the thick-client model that SproutCore is based upon holds great promise for the phone.  Precisely because of the bandwidth constrained, memory limited environment, downloading and installing code that runs right in the web browser can produce a dramatically better experience than forcing the user to wait on regular HTTP or even Ajax requests to complete.  All you need is the framework.

SproutCore was originally designed for desktop applications, where you can potentially display large amounts of data.  Neither the UI controls nor some of the large-data technologies we use on the desktop make sense on the phone.  This is why we are working on creating a mobile version of the framework.

Starting with SproutCore 1.0, you will have a few new options in the SproutCore build tools to let you output a version of your application just for the mobile phone.  Rather than force you to create an entirely new app for mobile devices, SproutCore treats platforms a bit like creating multiple languages.  That is, you simply add a “foo.platform” folder to your project.  Anything you place in that folder will only be included in the build for that platform.

For example, let’s say you were designing a Contacts application.  You might create some models and controllers for your app.  These will live in the models and controllers folder just like before.  But now you could also create a “desktop.platform” folder and a “mobile.platform” folder.  Inside of these folders, you can add the views and view-level resources needed to build the unique UI for that platform.  Here is how that folder structure would look:

contacts
  core.js <-- namespace
  models/
    contact.js  <-- Contact model object
  controllers/
    master.js  <-- typical controllers
    detail.js
  desktop.platform  <-- for the desktop browsers
    main.js <-- this main() is run when loading the app in the desktop
    english.lproj
      body.rhtml <-- view helpers for desktop
  mobile.platform <-- for the mobile browsers
    main.js <-- this main() is run when loading the app on the phone
    english.lproj
      body.rhtml <-- view helpers for mobile

When you run a build, SproutCore will output both the desktop and mobile directories in your bundles.  Once your app is deployed, you can visit your two apps by going to either:

Desktop: http://www.example.com/contacts/en/desktop
Mobile: http://www.example.com/contacts/en/mobile

There is also a facility to add auto-detection code at the top of your template page so you can redirect to the correct version of your app whenever a user visits your app’s main URL.

Of course, this means that the SproutCore JavaScript itself will also come in desktop and mobile flavors.  More on that as it develops.

This new feature in the build tools is still fairly primitive.  I’m sure we’ll be adding many more features to it once we get into your hands, but in general this opens up a new and very exciting area for SproutCore.  I can’t wait to see what you all do with it!

SproutCore 1.0: SC.Enumerable and SC.Array

One of the trickier aspects of making SproutCore DOM-library independent is dealing with enhancements these libraries make to built-in JavaScript objects.

For example, Prototype adds some very useful iterator methods - such as uniq() and compact() - to Array.prototype that we use frequently.  These helpers reduce our code size and make it easier to read.  On the other hand, depending on them limits your ability to use other libraries.  What if you want to load a library that defines these methods in a conflicting way?   For example, the way each() (or forEach() in the JavaScript standard) is implemented by Prototype, jQuery, and built-in by Firefox each pass different parameters to your callback.  Not pretty.

Some libraries, like jQuery, avoid modifying built-in objects altogether to work around this problem.  I didn’t think we needed to be that dogmatic about it, because some of these are so useful.  So I decided on a few simple rules:

  1. Never, ever, modify Object.prototype.  This breaks too many things.
  2. Many of the more useful enhancements that libraries add, such as forEach(), map(), and reduce() on Arrays, are actually part of the new JavaScript standard but just unevenly implemented.  SproutCore will provide implementations of these on all browsers that do not have them consistent with the standard.  You can basically use any of the iterators described in JavaScript 1.8 on any browser with SproutCore.
  3. A few of the more useful helpers defined by Prototype, such as compact() and uniq(), which have common, unambiguous functions, are provided by SproutCore as well.  They are implemented in the same way as Prototype so that if you do not want to.
  4. We will also enhance Array and String as needed to support property observing and localization.  For these methods, we try to name them in a way that is unlikely to conflict with other libraries.

While I was at it, I decided to make these enhancements available as mixins as well.  The SC.Enumerable and SC.Array mixins in SproutCore provide our uniform enumeration API.  They are applied automatically to Array, but you can apply them to any other object as well to make it “array-like”.   This opens up lots of possibilities for creating sets, sparse arrays, and other complex collection-oriented data structures that you can essentially pass in anywhere you might normally expect an Array.

Overall, I’m pretty happy with the results.  SC.Enumerable implements common iterators such as forEach(), map(), filter(), every(), some() and reduce().  These methods are all implemented natively in Firefox and some are in WebKit.  For all other browsers, SproutCore provides a generic implementation for you.  In addition, we’ve come up with some really useful extra features, such as:

SC.Enumerator

Sometimes you don’t want to just iterate through an array.  Instead, it is easier to pass around an “iterator” that can simply return the next value until you are done.  For example, let’s say you are going to process a bunch of data to produce some graph results.  This would potentially lock up the browser if you have a large data set.  It would be better to schedule a timer and then process them one or two at a time.  Here is how you could do this:

function processData(array) {
  var enumerator = array.enumerator(); // get an SC.Enumerator instance
  var process = function() {
    var next = enumerator.nextObject() ;
    if (next) {
      processItem(next);
      process.invokeLater(); // schedule to fire again
    } else process = enumerator = null; // cleanup closure
  };
  process(); // start processing
} ;

processData(aBigArrayOfData);

The nice thing about this is the enumerator will work even if you edit the array of data, whereas keeping a simple index would be more difficult to keep in line.  Note how you can call nextObject() on the enumerator until it reaches the end of the array, afterwhich it will return undefined.

Content Observing

One other benefit SC.Enumerable brings is it makes your array observable.  All arrays have a ‘[]‘ property which you can observe to be notified whenever the membership of the array changes.  For this to work, you must use the SproutCore-specific API for manipulating the array instead of the native methods, but this is cheap and yields huge wins.  Here is a banking example:

MyApp.account = SC.Object.create({
  ledger: [],

  ledgerDidChange: function() {
    console.log('account ledger changed!');
  }.observes('.ledger.[]')
});

With this controller, you could now insert or remove items like so:

MyApp.account.ledger.pushObject(newDeposit);
> "account ledger changed!"

MyApp.account.ledger.popObject();  // this is probably stealing. :-)
> "account ledger changed!"

MyApp.controller.records.insertAt(3, newWithdrawl);
> "account ledger changed!"

This makes it incredibly easy to observe changes on an array when you care about the member of the array itself.

Reduced Properties

Of course, we didn’t stop there.  Observing when an array value has changed is nice, but often times you don’t care about the array itself, only a summary of its contents.  For example, consider the ledger above.  Maybe what you really care about are not the specific transactions, but the sum total of the account.    You can get this with something called a “reduced property”.  A reduced property is simply a value that is computed dynamically by evaluating all of the items in an array and combining their results.  You can write your own reduced properties, but SproutCore comes with a couple of useful ones built in as well.

To get the value of a reduced property, you just use get() on the array with the property name.  All reduced properties begin with an @ symbol and may contain a parameter identifying a specific property on the array contents you are interested in.  For example, assuming all of the objects in the ledger above have an “amount” property that tells you their value, you could get a sum of the transactions with:

MyApp.account.ledger.get('@sum(amount)');
> (returns total amount)

Best of all, reduced properties are observable as well.  So you can bind to them.  If you wanted to show this account balance in a label view, for example, you could just bind the “value” property to "MyApp.account.ledger.@sum(amount)".

And so much more…

SC.Enumerable opens up a wide array (no pun intended) of possibilities for working with collections of objects in SproutCore.  Best of all, these features are available TODAY in the SproutCore version you probably have installed on your machine.  Checkout the SC.Enumerable and SC.Array mixins today.  They both get a minor facelift for 1.0, but for the most part they work now.  Get to know them.

SproutCore 1.0: SC.Builder

Over the past few months, I’ve worked more and more with jQuery while investigating removing our dependency on Prototype.  By far, my favorite part of the library is its API.  jQuery’s design genius is to use chained methods to operate on a result set.  This both makes your code very compact and it makes the API itself easily hackable as you can always add new helper methods at runtime.

This API-model makes a lot of sense for features where you need to configure a bunch of JavaScript (or DOM elements).  For example, let’s say you want to quickly find all of the headings on your page, turn them red and change their text.  It’s easy to do this in jQuery like so:

$('h1').title('Hello World!').css('color','red');

Pretty nice.  Of course, you can do a lot more complicated things with this as well, but you get the point.

Of course, this kind of API lends itself quite well to the DOM layer, but it got me to thinking about what other pieces of an API might be better expressed this was as well.  Take for example, Ajax requests.  When you think about it, an Ajax request is a one time action.  It’s really pretty clunky to have to create a Request instance and configure it just to send off a request.  We could do better.

In SproutCore 1.0, we will have a new SC.Request API that you can use to make low-level requests to a server. (This will sit beneath SC.Server, for example, replacing what you would do now with Prototype).  We’re still putting the finishing touches on this API, but its here is an example of how you might send a request to a server to get a resource:

SC.Request.get('/twitter/feeds').format(SC.JSON_FORMAT)
  .notify(Twitter.feedController, 'feedDidLoad').send();

Not bad huh?  This would request the named twitter feed, expecting a JSON format, and then notify your the Twitter.feedController when the request is finished.  Request object’s have a response property that contains either the retrieved JSON or an Error object depending on the result.

The nice thing about this model also is that you can hold onto the builder object and use it over and over again.  For example, this is how you would setup a controller so you can send the same request over and over again:

Twitter.feedController = SC.Object.create({
  feedRequest: SC.Request.get('/twitter/feeds').format(SC.JSON_FORMAT),
  refreshFeedThenNotify: function(target, method) {
    this.feedRequest.notify(target,method).send();
  }
});

You can call refreshFeedThenNotify() as often as you want and each time it will initiate a new request.  Pretty powerful for a few lines of code.

SC.Request is just one example of how we are thinking of using this DOM-builder-like API.  We are also planning API’s for configuring views, menus, and even models.  This is starting to look like a new design pattern, so we got to thinking: maybe we should provide some support for it.  So that’s what we’ve done.

Introducing SC.Builder

SC.Builder is a simple class that makes it terribly easy to create jQuery-like builders for any kind of content you want.  For example, to create your own jQuery all you need to do is:

jQuery = SC.Builder.create({
  init: function() { .. setup ... },

  // other helper methods you want here
});

Out of the box, this builder can do method chaining, supports plugins, and implements SC.Enumerable, which means you can iterate over it using typical Array methods like getEach().  All you need to do is to fill in the content-specific helper methods you want to add.

As we finalize some of these new API’s over the coming few weeks I’ll post more details about them, but I’m very excited about what SC.Builder makes possible.  Configuring your SproutCore app has never been so easy.

If only…

Microsoft considers adopting WebKit for Internet Explorer

I have no idea if this is true or not, but I can say that Microsoft has to get the JavaScript performance up to speed (pun intended) for the next generation of IE or risk becoming totally irrelevant.

People will spend thousands of dollars to buy a new computer so they can run the latest software that is important to them. They are far more willing to switch to a free brwoser to get the best experience for their web-based software. You would be surprised how quickly people will switch browsers for apps.

Apps !== content sites. The rules have changed.