Author Archive

10 links for Facebook developers

Facebook Keegan Street | 25 Aug. 2010 | 5 comments

These are the resources I most frequently refer to while developing Facebook apps. This is by no means an exhaustive list but hopefully it contains something that will help you out.

Official developer’s documentation

Googling for Facebook documentation will often bring you to outdated, incorrect information. Even the official looking wiki.developers.facebook.com contains information that is downright wrong, so stick with developers.facebook.com/docs. Here you can find documentation about everything Facebook: authentication, JavaScript SDK, Graph API, Open Graph protocol, social plugins, FQL, PHP SDK, XFBML and more.

Working examples of Javascript SDK methods and XFBML tags

The best way to learn how these things work is to see some working examples.

Console for testing Graph API queries

If you’re having trouble making Graph API queries from the JavaScript SDK, PHP SDK or some other method, this is a great tool that can help you determine whether the problem is in the query or your other code. It also contains an (almost) exhaustive list of the objects and properties available through the Graph API, but still needs to be updated to include checkins. You can browse through the list and see what information is available to you and the format that it is returned in.

If you see an error message saying "You must use https:// when passing an access token," then change the URL in the input text field from http to https. That’s a bug Apigee needs to fix in its console.

Console for testing FQL queries

FQL queries tend to be more complex than Open Graph queries, so it can be even more valuable to test them out in a console before trying to call them programatically.

URL Linter

If you want your web pages to be shared through Facebook, you will either add Open Graph protocol meta tags or basic meta tags to your pages. No matter which technique you use, the URL Linter can easily show you how Facebook will interpret this metadata when users share your pages.

Developers’ Forum

Draw from the knowledge and experience of over one hundred thousand Facebook developers. Just go easy on the Facebook reps – you can’t expect them to respond to every message or fix every bug. Unfortunately a lot of people tend to be quite disrespectful in the forums.

Bugzilla

The constant innovation of the Facebook platform comes with a price: there is a never-ending backlog of bugs. If you’re banging your head up against the wall because your app isn’t working, more often than not it will be a problem with Facebook’s code rather than yours. Search Bugzilla to find out if other developers are experiencing the same issues as you – and see if or when Facebook plan to fix it.

ThinkDiff.net tutorials

The blog of Md. Mahmud Ahsan contains some really useful tutorials for Facebook development – from getting started with the JavaScript SDK through to advanced topics like using the new iPhone SDK.

Facebook GUI PSD kit

A free set of vector images of Facebook GUI elements like the multi-friend selector and authentication dialogue. Really useful for wireframing and design. Thanks to SurgeWorks for providing this resource.

Publishing Facebook stories on browsers with popup blockers

Facebook Keegan Street | 11 Aug. 2010 | 2 comments

How to use Facebook’s Stream.Publish method on browsers with popup blockers. See a demo.

What is the problem?

Recently many Facebook developers have been frustrated by popup blockers preventing the Stream Publish dialogue box from being displayed. If a user hasn’t logged in and authorised the application, dialogue boxes are shown in a popup window instead of an iframe. That’s fine for some visitors, but for those who have a popup blocker enabled, it means that they won’t see the dialogue box and therefore can’t publish a post into the stream.

The Stream Publish dialogue being displayed in an iframe.
The Stream Publish dialogue being displayed in an iframe.

The Stream Publish dialogue being displayed in a popup window. Popup blockers will prevent this from opening.
The Stream Publish dialogue being displayed in a popup window. Popup blockers will prevent this from opening.

What causes it?

Previously popup blockers didn’t cause any problems for the Stream Publish method because all dialogue boxes were displayed with an iframe rather than a popup window. But in mid-May Facebook discovered that this exposed users to a clickjacking security vulnerability. To address the security problem, dialogue boxes are now shown in a popup window instead of an iframe for users who are not logged in or haven’t authorised the application making the request. According to Facebook, this change is here to stay.

Technically, popup blockers shouldn’t block popup windows that are opened intentionally by the user, for example by clicking on a link that says "Publish this to your profile". Unfortunately however, Facebook have implemented their Stream Publish method in such a way that the relationship between the user action and the popup window being opened is not direct enough. The onus is on Facebook to fix this, but in the meantime, there is a workaround.

The workaround

While not documented by Facebook, it is very easy to construct a URL for the Stream Publish dialogue box. To publish the news feed story, the user simply has to click a link pointing to this URL. Here’s one I prepared earlier. You can construct the URL with your programming language of choice, but I will demonstrate how it works with an ActionScript 3 example. (I have also provided a PHP example in the source download).

1. Defining the post parameters

First we define the parameters for the post, such as the title, link, caption and any media that we want to attach. The attachment and action_links objects follow exactly the same structure as the JSON objects used by the streamPublish method in the JavaScript SDK and the old REST API.

// An event handler which publishes a Facebook story when a button is clicked
private function clickPost(event : MouseEvent) : void {
    // Define the stream story parameters
    var attachment:Object = {
        'name' : "I've just played golf with Lexus at St Andrews.",
        'href' : 'http://apps.facebook.com/myapp',
        'caption' : "Win 2 x VIP tickets to the Open Golf Championships at St Andrews. Simply find the missing golf ball to win - it's quick and fun! Play now...",
        'media' : [ {'type' : 'image', 'src' : 'http://www.myapp.com/assets/share_image.jpg', 'href' : 'http://apps.facebook.com/myapp'}]
    };
    var action_links:Object = [
        {'text' : 'Find the Golf Ball', 'href' : 'http://apps.facebook.com/myapp'}
    ];
    var publishURL:URLRequest = StreamPublish.publishStoryLink('YOUR_API_KEY', attachment, action_links, TopGoals.APP_TAB_URL);
    // Open the URL and Facebook's dialogue box will be displayed
    navigateToURL(publishURL, "_blank");
}

2. Generating the URL

This static method takes the parameters we defined in the previous step and encodes them into a URL. It uses the JSON class from Mike Chambers’ as3corelib project.

package com.thesedays.facebook {
    import flash.net.URLRequest;
    import com.adobe.serialization.json.JSON;

    public class StreamPublish {
        
        /**
         * Generate a URL for displaying the Stream Publish dialogue.
         *
         * @param api_key The API key of your application - you must create an application to call this method.
         * @param attachment An object containing the post text, links, media, etc.
         * @param action_links An object containing actions links of text and hyperlinks.
         * @param next The URL to open after the user has published the post or cancelled it.
         * @param locale The locale code to display the Facebook interface with, for example en_US, fr_FR or nl_NL. It is generally best to leave this parameter as null because then Facebook will determine the language based on the user's browser and session.
         */
        public static function publishStoryLink(api_key:String, attachment:Object, action_links:Object, next:String, locale:String = null) : URLRequest {
            var url:String = 'http://www.facebook.com/connect/uiserver.php' +
            (locale ? '?locale=' + locale + '&' : '?') +
            'api_key=' + api_key +
            '&method=stream.publish' +
            '&channel=' + escape('http://www.facebook.com/xd_receiver_v0.4.php') +
            '&extern=1' +
            '&attachment=' + escape(JSON.encode(attachment)) +
            '&action_links=' + escape(JSON.encode(action_links)) +
            '&display=popup' +
            '&next=' + escape(next);
            return new URLRequest(url);
        }
    }
}

Download the source from this example.

An easy way to detect mobile devices

So you want to deploy a mobile version of your website? You’ve thought about what your target users would do with a mobile version, written your content, created your design and developed your Flash or HTML, CSS and Javascript (if you haven’t done that yet, read this post instead). Now for the task that can seem most daunting to new mobile web developers — detecting devices and serving the correct version of your site. How do you ensure that users with mobile phones will see the mobile version and vice versa?

The answer: WURFL. The Wireless Universal Resource File (WURFL) is an open source project which collects information about all of the different mobile devices in use. It is constantly being updated, so as long as you keep your WURFL definitions up-to-date you don’t have to worry about your detection scripts not recognising new devices. By querying a WURFL database with your visitor’s User Agent string, you can not only determine whether the device they are using is a mobile device, but whether it has a touch screen, can make phone calls, is a tablet (iPad) and more.

It is reasonably straightforward to install a Tera-WURFL service on your PHP enabled web server. If download speed is critical for your website, it would be best to install Tera-WURFL on the same web server. But if you would prefer to avoid the installation process, feel free to use our quick and easy These Days implementation of Tera-WURFL.

It can be as simple as this:

<?php
require_once ('TeraWurflRemoteClient.php');
$wurflObj = new TeraWurflRemoteClient(
    'http://wurfl.thesedays.com/webservice.php' );
$wurflObj->getCapabilitiesFromAgent(null, array('product_info'));
if ($wurflObj->getDeviceCapability("is_wireless_device")) {
    // Show mobile website
} else {
    // Show normal website
}
?>

Don’t forget to give your users a way of overriding automatic device detection. Even WURFL can get it wrong sometimes, and anyway some users prefer to view full sites on their mobile phones. The user is king!

10 tips for designing mobile websites

10 tips for web designers in 2010 – the year of the mobile.

1. Design with a fluid layout, min-width: 320px

There are two factors that make this a necessity. First, mobile device screens are so small that you really need to utilise all of the available space. Second, there are a lot of different screen resolutions out there. The only way to utilise all of the space available on different sized screens is with a fluid layout.

I have found websites with a minimum width of 320px will look good on most high-end mobile devices like the iPhone, Android and Nokia N97. Here are the screen resolutions of some of the most popular devices:

Device Screen res (height x width)
iPhone 320 x 480
iPhone 4 320 x 480 (scaled by a factor of 2)
Nokia N97 360 x 640
HTC Legend 320 x 480
LG eXpo 480 x 800


Technically, the retina display on the iPhone 4 has a screen resolution of 640 x 960 pixels but don’t worry, if you optimise your site for 320 x 480, the iPhone 4 will scale it up by a factor of two so it fits the whole screen. You will need to insert higher resolution images – but more on that in the next section!

2. Include high res images for the iPhone 4 retina display

The iPhone 4 display has four times the number of pixels as that of the original iPhone. To prevent mobile sites from looking tiny, it magnifies them by 200%. That works great on text and vector images like SVG. But its not so hot on bitmap images (or even the HTML5 canvas so it would seem). To avoid pixelation, you need to insert alternative high resolution images for the iPhone 4.

Designers should create their Photoshop documents with a width of 640 pixels. Developers should export the images at full res for iPhone 4 and 50% res for everything else.

Here’s how to use a CSS media query to insert a high resolution image for iPhone 4:

.myImage {
    height: 40px;
    width: 100px;
    -webkit-background-size: 100px 40px;
    background: url("images/myImage.jpg");
}

@media screen and (-webkit-device-pixel-ratio: 2) {
    .myImage {
        background: url("images/myImage@2x.jpg");
    }
}

The first line that might jump out at you as being a little unusual is probably -webkit-background-size: 100px 40px;. The -webkit-background-size CSS property takes two parameters: width and height. The parameters can be lengths, percentages or "auto", and can even be mixed, i.e. -webkit-background-size: 100% auto. This tells the browser to stretch the background image to a specific size.

The second interesting part is the media query @media screen and (-webkit-device-pixel-ratio: 2) {...}. This means that any styles contained within the curly braces only apply if the device has a pixel ratio of 2 (two physical pixels per measurement pixel). Inside the media query selector, we override the .myImage class, and replace the background image with the high resolution image myImage@2x.jpg.

The left half of this screenshot shows the pixelation that occurs on iPhone 4, and the right half shows how it looks when we insert with a high resolution image:

The left half of this screenshot shows the pixelation that occurs on iPhone 4, and the right half shows how it looks when we insert with a high resolution image

3. Turn off auto-scaling

Mobile devices will assume your website is optimised for desktop computers unless you tell them otherwise. Add a viewport meta tag to the head section of your HTML to set the width of your website to match the width of the display, render with a zoom level of 100% and prevent the user from zooming in/out.

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />

Mobile phones will also adjust text size when the screen orientation changes unless you include a special CSS parameter:

body {
    -webkit-text-size-adjust: none;
}

4. Make clickable elements big enough for a fingertip, ≈44px²

Your mobile visitors don’t have the accuracy of a mouse – they are often using their fingertips on a touch screen. Don’t make them put their fingers through a pencil sharpener just to click your button! Apple has said that the average finger tap on an iPhone is 44px by 44px (in your high res Photoshop doc that will be 88px by 88px), so aim to make clickable areas at least that size. This doesn’t mean you have to design gigantic looking buttons. Just add some padding to your small buttons to enlarge the clickable area.

5. Don’t use hover states

Today’s touch screens can’t detect when a finger is getting close to touching, so the concept of rollovers does not apply. On the iPhone your :hover style will actually display on click and then remain on screen even after the user takes their finger away, which can be really annoying. So the rule is – don’t use :hover in your CSS or mouseover in your JavaScript.

6. Create icons for your site

Hopefully users will really love your site and add it to their home screen for easy access. Don’t ruin the mood with an ugly default icon! Add these meta tags to the head section of your HTML to define icons.

<!-- 57 x 57 Android and iPhone 3 icon -->
<link rel="apple-touch-icon" media="screen and (resolution: 163dpi)" href="icon57x57.png" />
<!-- 114 x 114 iPhone 4 icon -->
<link rel="apple-touch-icon" media="screen and (resolution: 326dpi)" href="icon57.png" />
<!-- 57 x 57 Nokia icon -->
<link rel="shortcut icon" href="icon57x57.png" />

Note: The iPhone will automatically add rounded corners and a glossy effect to your icon. If you want to turn this off, change the rel attribute to apple-touch-icon-precomposed. Thanks to Jesse Dodds for discovering how to specify a seperate high res icon for the iPhone 4 retina display.

7. Reduce load time by using CSS3 instead of images for gradients, rounded corners, shadows, etc.

Depending on the devices you are targeting, CSS3 can be an excellent option for mobile design. With old school web design techniques, a button with a gradient and rounded corners might consist of 9 separate image slices, a bunch of nasty non-semantic markup and a hefty amount of CSS. With CSS3, you can create this:

CSS3 button

With this:

.redButton {
    color: #B91440;
    font-size: 19px;
    line-height: 25px;
    padding: 10px 30px;
    border: 1px solid #FFFFFF;
    background: -webkit-gradient(linear, left top, left bottom, from(#F2F2F2), to(#FFFFFF));
    -webkit-box-shadow: 0 0 2px #E4E3E3;
    -webkit-border-radius: 5px;
}

Go here for everything you need to know about CSS3.

But be careful! While the iPhone, Android and Nokia all have good CSS3 support, the Windows Mobile 6.5 browser is built on a version of IE6 (sigh…). Define, define, define your target devices before you begin design and development.

8. Use an HTML5 doctype

Not all browsers implement HTML5 features, but they will still accept an HTML5 doctype.

<!DOCTYPE html>

Using this doctype declaration will allow you to display HTML4 elements to all browsers, and then add in additional functionality for the browsers that support HTML5.

9. Make your site operate offline

Your visitors won’t always have a fast Internet connection. If you’re designing the type of site that will have return visitors, consider leveraging the client-side storage capabilities of HTML5. It can be as simple as creating a cache manifest file that tells the browser what files it needs to cache for offline access. A more advanced option is to create an SQLite database on the client with JavaScript.

10. Include an option for your mobile visitors to view the normal website

Detection scripts can get it wrong, or a user might simply prefer not to use the mobile optimised interface. So my final tip is, always offer users a way to switch back to ‘normal mode’.

So there’s a few mobile web tips I’ve picked up over the last few months. I’d love to hear yours too in the comments!

Logging in – a barrier to application uptake?

An analysis of the Facebook “Request for Permission” dialogue as a barrier to application uptake.

I have always wondered how much of a barrier the “Request for Permission” dialogue presents to uptake of Facebook applications. So two months ago I set up a simple one-page app to gather some statistics about user behavior.

My sample group consisted of 4000 unique visitors who spoke English, Dutch, Spanish or Portugese. Visitors came from 82 countries but the largest groups were from Portugal, Belgium, the Netherlands and Argentina.

The idea of the application was very simple. Users were asked to enter their birthday with one of two input methods, either (a) through a series of dropdown boxes or (b) with a button that gave the app access to the birthday on their Facebook profile. The app then calculated how many days, weeks and months the person had been alive for and allowed them to post the result to their Facebook profile.

This is what the input screen looked like:
Your Age in Days input screen

And the resulting profile story:

Your Age in Days result

So what were the results? For whatever reason, 96% of users chose method a – the dropdown boxes. That’s a pretty significant majority, but it doesn’t tell us why users chose this option. They probably had different reasons, but I think some would have been:

  • “The dropdown boxes look quicker and/or easier”
  • “I don’t want to give this application access to my personal information”
  • “I don’t know what will happen if I click the Facebook button”

Personally, I can understand people not wanting to grant the application permission to access their information. Even the lowest level of authorization gives an app access to the user’s name, profile picture, list of friends and other “public” parts of their profile.

Facebook permissions dialogue

Much of the time when we develop Facebook apps we can’t avoid asking users for authorization. But we need to be aware of the barrier this creates. We should delay the authorization request in our application flow until the point where we really need it. And hopefully by that time the user will be able to see the value of authorizing our app.