I’ve discovered a handful of issues using the AS3 Flickr API in Flex 3 and AIR, and as a result I’ve made a number of tweaks, additions and bugfixes to the source code.

Aside from recompiling the SWC (see here), here are the bugs I’ve found and some of the changes I’ve made:


Auth.checkToken()
This method is used to return the credentials attached to an authentication token. If you’ve already gone through the login process in your application and are loading a saved auth token, this is the method you call to verify the token is still valid.

However there is a bug in the method parameters passed to the flickr.auth.checkToken API method.

Here’s the original method:

public function checkToken (token : String) : void
{
    MethodGroupHelper.invokeMethod (_service, checkToken_result,
        ”flickr.auth.checkToken”, false, new NameValuePair
        (”auth_token”, token));
}


The problem is the fourth parameter; a boolean that determines whether the method needs to be signed. The value here is false, when in fact it needs to be true.

The updated method:

public function checkToken (token : String) : void
{
    MethodGroupHelper.invokeMethod (_service, checkToken_result,
        ”flickr.auth.checkToken”, true, new NameValuePair
        (”auth_token”, token));
}



FlickrService, User Public Properties
These two classes contain a large number of public properties you’ll likely end up referencing in your application. For FlickrService, this includes the auth token and its associated permissions. For User, this includes the NSID, username and pro status of the authorized Flickr account.

While there’s nothing wrong with these classes, none of these properties are made [Bindable] by default. So if you reference any of these properties as a bindable value in a MXML component, you’ll need to modify the source code accordingly.


User.buddyIconUrl
This is a property I added to the User class. It points to the buddy icon URL of the authorized Flickr user.

You can implement this in one of two ways. First, you could add a basic getter/setter to User, and then set the property in the result handler for a FlickrService.people.getInfo() method call:

private function onGetInfo (event : FlickrResultEvent) : void
{
    if (event.success)
    {
        var user : User = event.data ["user"] as User;

        user.buddyIconUrl = “http://farm4.static.flickr.com/”
            + user.iconServer + “/buddyicons/” + user.nsid + “.jpg”;
    }
}


Second, you could make the property read-only by adding just the getter to User and building the URL directly in the method:

public function get buddyIconUrl () : String
{
    return “http://farm4.static.flickr.com/”
        + iconServer + “/buddyicons/” + nsid + “.jpg”;
}



I’ll update this post if I discover more bugs or make new tweaks to the API.

The AS3 Flickr API on Google Code (as3flickrlib) is a great tool for integrating Flickr into your Flex or Flash application.

But if you want to include the SWC in a Flex 3 or AIR project, you need to download the source code and recompile it as a Flex 3 Library. The SWC included in the zip file is compiled for Flex 2 and will generate a runtime error when you try to instantiate an instance of FlickrService.

Once you have the Flex 3 SWC in your project, using the actual Flickr API is pretty straightforward. As with all third-party Flickr apps, you first need to authenticate your application for a Flickr user.

Here’s a simplified version of the login process:

var flickr : FlickrService = new FlickrService (YOUR_FLICKR_API_KEY);
flickr.secret = YOUR_FLICKR_API_SECRET;

flickr.addEventListener (FlickrResultEvent.AUTH_GET_FROB, onGetFrob);

// starts the Flickr login process
flickr.auth.getFrob ();

private function onGetFrob (event : FlickrResultEvent) : void
{
    if (event.success)
    {
        var frob : String = event.data.frob as String;

        var authURL : String = flickr.getLoginURL (frob, AuthPerm.READ);

        navigateToURL (new URLRequest (authURL), “_blank”);
    }
}


The authURL is the page on Flickr where you authenticate your application. Your app needs to be authenticated before you can retrieve an auth token:

flickr.addEventListener (FlickrResultEvent.AUTH_GET_TOKEN, onGetToken);

flickr.auth.getToken (frob);

private function onGetToken (event : FlickrResultEvent) : void
{
    if (event.success)
    {
        var authResult : AuthResult = event.data as AuthResult;

        flickr.token = authResult.token;
        flickr.permission = authResult.perms;
    }
}


Once you have an auth token, you should have access to the private information in the user’s account, and depending on the permission level, the ability to add, edit and delete photos and metadata.

When you pass in parameters to a Flash or Flex application, you can include most special characters without URL encoding the values.

This includes the following characters:
; / ? : @ $ , # - _ . ! ~ * ' ( )

But as I recently discovered, this doesn’t apply to plus (+) signs.

If you pass in a plus sign as part of a parameter, it will automatically be converted into whitespace. To preserve the plus sign, you need to pass in %2b, which is the URL encoding for a plus sign.

To prevent your Flex app from running on certain domains, you’ll need to use JS to check the current domain, and then decide how to disable your application.

Here’s the sample code to retrieve the domain (you’ll notice it takes advantage of the getWindowLocation() method I defined in an earlier post last year):

private function getDomain () : String
{
    var domain : String = getWindowLocation ();

    if (domain != null)
    {
        // removes the “http://” or “https://” prefix
        domain = domain.substring (domain.indexOf (”//”) + 2);

        // removes the “www.” prefix
        if (domain.indexOf (”www.”) == 0)
        {
            domain = domain.substring (4);
        }

        // removes the rest of the URL minus the domain
        if (domain.indexOf (”/”) > 0)
        {
            domain = domain.substring (0, domain.indexOf (”/”));
        }
    }

    return domain;
}


There are several easy ways to disable your application. It all depends on how crafty you want to be about it.

You can check the current domain on preinitialize, for example, and simply never display the UI for a restricted domain (more on that here).

Or you can opt for the classic approach, and open an “undismissable” modal dialog to prevent the user from ever interacting with your application.

(or you can just translate everything into Japanese and invert all the colors… the sky’s the limit!) :-)

I recently discovered something interesting trying to implement a REST API call in an AIR application.

When you load a URL request in Flex, you usually listen for complete, I/O error and security error events on the loader. However, I’ve learned that it’s important to also listen for HTTP response status events when loading a URL request in AIR.

Otherwise you might not receive a response when the result is anything other than success (200). Instead, you’ll receive an I/O error: “Error #2032: Stream Error.”

Consider the following sample code:

var loader : URLLoader = new URLLoader ();

loader.addEventListener (Event.COMPLETE, onComplete);
loader.addEventListener (IOErrorEvent.IO_ERROR, onIOError);
loader.addEventListener (SecurityErrorEvent.SECURITY_ERROR,
    onSecurityError);

// AIR-only!
loader.addEventListener (HTTPStatusEvent.HTTP_RESPONSE_STATUS,
    onHTTPStatus);

loader.load (request);


No action is required in the onHTTPStatus() method above. As long as you are listening for the event, you will always receive a response.

Categories