We love Dropbox: free storage space, simple enough for our grandma to use and responsive customer service. Speaking of which, long live Brian S.!

If you are working on an AIR mobile app and want to integrate Dropbox, you may have noticed that there isn’t an official Dropbox Actionscript SDK. There is however an independent solution, kindly provided by grossopa, which wraps around OAuth and JSON and does most of the hard work talking to the Dropbox API for you: dropbox-as3.

Responding to changes in the Dropbox API

These happen, as the API evolves or has to be modified for… well, political reasons. Keeping up with the changes, while using a third party SDK isn’t always easy.

I’ll walk you through the bigger changes that have happened so far and what we’ve done to keep up with them.

In the beginning there were username and password

Initially, an app could link to a user’s Dropbox account by asking for username and password and using these to make a request to the Dropbox API.

Then came OAuth

Later Dropbox switched to OAuth authentication: instead of handling usernames and passwords itself, an app would switch to a browser, where the user would log in to Dropbox to authorize the link, then the browser would switch back to the app, telling it whether the linking was authorized.

Then Apple took umbridge…

A few weeks ago there was a wave of rejections of iOS apps from the App Store, which were using browser authentication. The story was all over the web, but the dialog on the Dropbox forum captured it best:
Apple rejecting applications which use Dropbox. The horror.

At DiaDraw we were gutted, but decided to release version 1.0 of IdeaDraw out without its Dropbox feature, while Dropbox and Apple were trying to agree a solution.

In the end the Dropbox iOS SDK was changed, so switching to an external browser is no longer required. The two ways of autorhizing your app to link with Dropbox are as follows.

If the user has the Dropbox app installed, it handles the authorization for you and shares credentials with your app – this is not new:

What is new is that if the user doesn’t have the Dropbox app installed, instead of switching to an external browser, the Dropbox log-in and authorization page is now shown in a view inside your app:

What happens if you use ActionScript?

For developers of native apps the change meant that they had to download the latest Dropbox iOS SDK and rebuild.

With ActionScript however we were faced with the need to somehow replicate the changes. Not massive fans of repeating work, we thought we’d have the best of both worlds:

  • use the Dropbox iOS SDK for the autorization step;
  • stick with dropbox-as3 for doing everything else.

In order to take advantage of the Dropbox iOS SDK (and the credential sharing, which in ActionScript would be trickier) we wrote a native extension that takes care of the authorization. It’s yours to use and modify.

The native extension – code and binaries

Can be downloaded here:
https://code.google.com/p/diadraw-air-dropbox-native-extension-example/

There is also an example app and detailed instructions on how to set it up and run it to demo the extension – check out the Wiki pages:

https://code.google.com/p/diadraw-air-dropbox-native-extension-example/wiki/ExampleApp

How to use the extension

0. Download the latest Dropbox iOS SDK

from
https://www.dropbox.com/developers/reference/sdk  and copy DropboxSDK.framework into your iPhoneOSx.x.sdk Frameworks folder, typically in

[sourcecode language=”actionscript3″]
/Developer/Xcode.app/Contents/Developer/
Platforms/iPhoneOS.platform/Developer/SDKs/
iPhoneOS6.0.sdk/System/Library/Frameworks
[/sourcecode]

if you use iOS 6.0 SDK

or in

[sourcecode language=”actionscript3″]
/Developer/Xcode.app/Contents/Developer/
Platforms/iPhoneOS.platform/Developer/SDKs
/iPhoneOS5.1.sdk/System/Library/Frameworks
[/sourcecode]

if you use iOS 5.1 SDK.

1. Create an instance of NativeDropboxLogin

and make sure you listen for the event, which will tell you when your app has linked to Dropbox:

[sourcecode language=”actionscript3″]
private var m_loginExt : NativeDropboxLogin;
m_loginExt = new NativeDropboxLogin();
m_loginExt.addEventListener( "DROPBOX_EXT_LINKED", handleDropboxLinked );
[/sourcecode]

2. Call linkWithDropbox()

on that instance and pass it your app’s key, secret and how it will access Dropbox (“kDBRootDropbox” or “kDBRootAppFolder“):

[sourcecode language=”actionscript3″]
m_loginExt.linkWithDropbox( APP_KEY, APP_SECRET, "kDBRootDropbox" );
[/sourcecode]

3. Add CFBundleURLSchemes to your application descriptor file

(yourApp-app.xml) in the
<iPhone> section and make sure it has this format: db-YOUR-APP-DROPBOX-KEY

[sourcecode language=”xml”]

<![CDATA[

<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>db-bsrweprjfs</string>
</array>
</dict>
</array>
]]>

[/sourcecode]

This URL scheme is used by the Dropbox app to invoke your application and let it know whether the user authorized linking or not.

4. Wait for the com.diadraw.extensions.dropbox.NativeDropboxLinkEvent event

Once you receive it, make a request for the access secret and access token, which you can then use to make requests for browsing, uploading, etc. file management on Dropbox.

This one is dispatched with or without additional information:

  • if the app has already been linked previously, the event will come back with its userId, token and tokenSecret all null; in this case make a request for the access secret and access token, which you can then use to make requests for browsing, uploading, etc. file management on Dropbox.
  • if the app has just been authorised to link with Dropbox, the event will contain the userId, token and tokenSecret, which you can use to start making requests.

[sourcecode language=”actionscript3″]
m_loginExt.addEventListener( NativeDropboxLinkEvent.DROPBOX_LINKED, handleDropboxLinked );

private function handleDropboxLinked( _event : NativeDropboxLinkEvent ) : void
{
if ( null != _event.token && null != _event.tokenSecret )
{
m_dropboxAPI.config.accessTokenKey = _event.token;
m_dropboxAPI.config.accessTokenSecret = _event.tokenSecret;

signalLoginComplete( _event.token, _event.tokenSecret );
}
else
{
getRequestToken();
}
}
[/sourcecode]

[Note: This is only relevant if you build with Adobe AIR 3.2 or lower] Orientation – beware

Since the extension potentially creates a native view, this can cause the rest of your app to spontaneously reorient itself in strange ways once the native view comes into play.

This has been taken care of with the UIViewController (Orientation) category in the native code.

If you are curious why and how this works, have a look at this post:
Native extensions for mobile AIR apps – getting round the orientation issue

About the Author

Radoslava is co-founder of DiaDraw. Prefers to communicate with images. Verbal communication always caused trouble with her parents. Started speaking Basic early on, followed by four years of Delphi, six years of C++, four years of ActionScript, lately converses in Objective-C. Her mum and dad hope she'll start speaking human at some point.