How can I authorize more than one Dropbox account in an app?

cocoa-touch, dropbox-api, ios, ios6

Solution

I found this to be a challenge but finally made it work after lots of experimentation. Here are some bits of information that should help:

Each Dropbox (DB) account has a userid (uid) associated with it once the user has been authorized. In your own app's model for an account, you need to keep track of the uid. Initially, before the user links their DB account, this uid will be `nil`.

When the user wants to access their DB account, you get your associated uid for the account. If the uid isn't nil you setup the `DBRestClient` as follows:

_client = [[DBRestClient alloc] initWithSession:[DBSession sharedSession] userId:uid];

If the uid isn't set yet, you need to present the login screen.

[[DBSession sharedSession] linkFromController:someController];

This, of course, launches the DB app to present the login (or presents a web interface if the DB app isn't installed). Either way, your app will be launched again by DB when the user finishes the authorization process.

In your app delegate's `application:openURL:sourceApplication:annotation:` method you do something like:

if ([[DBSession sharedSession] handleOpenURL:url]) {
    NSString *query = url.query;
    if ([[url absoluteString] rangeOfString:@"cancel"].location == NSNotFound) {
        NSDictionary *urlData = [DBSession parseURLParams:query];
        NSString *uid = [urlData objectForKey:@"uid"];
        if ([[[DBSession sharedSession] userIds] containsObject:uid]) {
            // At this point we know the login succeeded and we have the newly linked userid
            // make a call to process the uid
        }
    } else {
        // user cancelled the login
    }
}

In the code that processes the newly linked uid, you can store the uid in your own account data model. Then you use the uid to create the `DBRestClient` like I showed earlier.

If you have a uid, you can determine if the uid is properly linked with a simple check:

if ([[[DBSession sharedSession] userIds] containsObject:uid]) {
    // the uid is linked
}

To unlink a user based on their uid you can do:

[[DBSession sharedSession] unlinkUserId:uid];

At that point I would also clear out the saved uid from your own account model.

Hopefully that is enough pieces to build the puzzle. Good luck.

Problem

I'm looking to update one of my apps (which is a Dropbox client) to have support for multiple accounts, but I can't seem to find a way to do it. I have analyzed the SDK many times and no matter how many times I look at, it looks like an account using the official SDK can only support one account at a time. Although I'm sure it can support more as I know of many apps that allow you to link more than one. Any pointers on doing this will be highly appreciated. I can't even find a way to fetch tokens to store them separately later.

Original source