Friday, March 28, 2008

jQuery UI Tabs Callbacks

Somehow the jquery ui tabs callbacks as described on the website (and as described here) don't seem to work for me. So I took a look at the source code and this is how I got them to work:


$("#tabbook > ul").tabs().bind("show.ui-tabs",
function(event, ui) {
console.log(ui);
console.log('show tab');
if (ui.panel.id == 'id-of-some-tab-page') {
console.log('It is showing!');
}
}
);


These are the events you can register callbacks for:
  • load.ui-tabs
  • show.ui-tabs
  • select.ui-tabs
  • add.ui-tabs
  • remove.ui-tabs
  • enable.ui-tabs
  • disable.ui-tabs
The "ui" object that's passed into the callback function has lots of interesting properties (just dump it with Firebug's console.log or console.dir) but you'll probably be most interested in 'ui.panel.id' since that will hold the id of the tab page that the event has been triggered for.

Tuesday, March 25, 2008

OpenSocial explained by Chris Bissell

So I've been getting my feet wet with OpenSocial for a while now, both on MySpace and on Orkut. I've only signed up with MySpace because I needed an account to develop and test my OpenSocial application. But since then I've got to learn that - from a developer's perspective - MySpace is really cool. The guys there are very active in the forums to help developers and they actually listen to what we want. Oh, and they use Scrum, too.
Today I found this great series of videos about OpenSocial in general and OpenSocial on MySpace, presented by MySpace's own Chief Software Architect Chris Bissell. The videos are very interesting and entertaining. The way he talks reminds me a bit of the Comic Book Guy on the Simpsons. Notice the occasional random mad scientist "hee hee" laugh. Great stuff.

Monday, March 17, 2008

WWDC08, I'm coming!

So Apple finally announced the dates for this year's WWDC last week: June 9-13 2008. Last year's WWDC was great, the conference with the highest quality in content, organization and experience I've ever been to. With the release of the iPhone SDK and a whole track devoted to iPhone development this year's WWDC will be even more exciting, I'm sure. I've booked my ticket this weekend, so I'm pretty excited and I'll keep you and the other guy who's reading this updated.

Friday, March 14, 2008

OpenSocial Sample Code: Orkut UID and Viewer == Owner?

So I've been working on an OpenSocial app for a while. A lot of things come in quite handy and are needed relatively often. One of those things is checking if the current viewer is the owner of the application (if the viewer is the person that has added the application to his/her profile and is viewing the app on his/her profile or canvas page at the moment). On Facebook you have a tag for that:

<fb:visible-to-owner>  
Welcome back to your profile!
</fb:visible-to-owner>
How useful! Well, this doesn't exist on OpenSocial. So what you have to do is compare the OpenSocial ID for the current view to the ID of the owner. If both are the same, the viewer is the owner and the owner is the viewer and everyone is happy.
So what you do is get both IDs when the app is loaded and you remember them in a bunch of variables. I added one more thing, though: Getting the Orkut UID since the Orkut UID is not the same as the OpenSocial ID of the user. You need the Orkut UID to construct links to a person's canvas page. It's a really ugly hack, but that's how you're supposed to do it according to Google.
Having the Orkut UID, you can construct links to the canvas page of your app for a certain user. This is useful when you have a canvas page you want to link to for your friends to look at (showing the latest photos or videos you've uploaded or some other useless crap nobody will look at anyway).
Here's a little code sample (note: SAMPLE, you still need to add error checking and stuff) for constructing an Activity Stream update on Orkut that has a link to the canvas page of the person who's posting the activity:

const CANVAS_BASE_URL = 
'http://sandbox.orkut.com/Application.aspx'; //Orkut specific!

function postActivity(title, body) {
var params = {};
params[opensocial.Activity.Field.TITLE] = title;
if (body != null) {
params[opensocial.Activity.Field.BODY] = body;
}
var activity = opensocial.newActivity(params);
opensocial.requestCreateActivity(activity,
opensocial.CreateActivityPriority.HIGH,
postActivityCallback);
};

function postActivityCallback(data) {
if (DEBUG) console.log(data);
};

function createASampleActivity() {
var title = 'Something to waste 2 minutes of your life!';
var body = '<a href="' + CANVAS_BASE_URL +
'?uid=' + viewer_network_uid +
'&appId=' + stored_app_id +
'">Check them out!</a>';
postActivity(title, body);
}

Ok, and here's the code for getting all the IDs and a useful function to check if the viewer is the owner or not. Just call it during the initialization of your gadget with gadgets.util.registerOnLoadHandler(setupViewerOwnerIds);

const DEBUG = true;

/** not the opensocial uid, but the users
uid on the current social network, ie Orkut or MySpace */
var viewer_network_uid = '';
/** current viewer's opensocial id */
var viewer_os_id = null;
/** owner's opensocial id */
var owner_os_id = null;
var stored_app_id = '1111111111111'; //for orkut!

function setupViewerOwnerIds() {
var req=opensocial.newDataRequest();
req.add(req.newFetchPersonRequest("VIEWER"), "viewer");
req.add(req.newFetchPersonRequest("OWNER"), "owner");

req.send(setupViewerOwnerIdsCallback);
}

function setupViewerOwnerIdsCallback(data) {
if (data.hadError()) {
if (DEBUG) console.log("setupViewerOwnerIdsCallback had an error");

viewer_os_id = null;
owner_os_id = null;
} else {
var viewer = data.get("viewer").getData();
var owner = data.get("owner").getData();

viewer_os_id = viewer.getId();
owner_os_id = owner.getId();

//Orkut specific
if (opensocial.getEnvironment().getDomain() == 'orkut.com') {
var profile_url =
viewer.getField(opensocial.Person.Field.PROFILE_URL);
var regex = /uid=([^&#]+)/;
var result = profile_url.match(regex);
if (result.length == 2) {
viewer_network_uid = result[1];
/* uid now contains the viewer's orkut UID */
} else {
/* there was a problem getting the UID */
}
}

if (DEBUG) console.log('Viewer: ' + viewer_os_id);
if (DEBUG) console.log('Viewer Network UID: ' +
viewer_network_uid);
if (DEBUG) console.log('Owner: ' + owner_os_id);
}

if (DEBUG) console.log('isViewerOwner: ' + isViewerOwner());
}

function isViewerOwner() {
if (viewer_os_id != null &&
owner_os_id != null &&
viewer_os_id == owner_os_id) {
return true;
} else {
return false;
}
}

I can't take credit for most of this, since a lot of stuff is taken from the Orkut and OpenSocial wikis and mailing lists. My thanks go out to all the great people out there sharing their code and knowledge!
UPDATE: The code now also works when someone visits your app who doesn't have the app installed (produced an "unauthorized" error before while trying to fetch the viewer data).

Friday, March 7, 2008

Finally: the native iPhone SDK

I came back from the movies yesterday night (watched Michael Clayton, highly recommended!) and after putting together a piece of furniture from IKEA at 11:30 pm I remembered the iPhone Roadmap event that took place while I was at the movies. So I had to watch the Quicktime stream of the event. Very, very cool. VERY cool. The stuff EA and Sega got done in just 2 weeks is incredible. I've developed on the Mac with Cocoa before and it's just a joy to work with. Being able to use the same great XCode tools and even the debugging instruments for remote debugging is more I dared to hope for.
So I can't wait to start playing with it this weekend. I've already downloaded the SDK and checked out some of the tutorial videos on ADC on iTunes. I was laying awake in bed till 2 am thinking about the cool things I could build :). The only thing missing yesterday: An announcement of this years WWDC dates!

Tuesday, March 4, 2008

Developing Ruby on Rails on Mac OS X Leopard, or DRoRoMOSXL

I just received the new ADC newsletter and it had a link to a very nice tutorial for developing Ruby on Railsleopard applications on Leopard. There are heaps of RoR tutorials out there, but in my experience tutorials written by the Apple folks are of an above average quality.
Another interesting thing about this tutorial is that it uses XCode 3.0 instead of my (and I guess most people's) Mac text editor of choice, TextMate. It's the first of three parts. So to whom it may concern, it might be an interesting read.