The Core API is based on HTTP and OAuth and provides low-level calls to access and manipulate a user's Dropbox account.
If you want to follow along, first register a new app on the App Console. You'll need the app key to access the Core API. Then install the iOS SDK and you'll be ready to go.
The Core API uses OAuth v1, but the iOS SDK will take care of most of it so you don't have to start from scratch.
You'll need to provide your app key and secret as well as the permission you selected when creating the app. The permission will be represented by either the kDBRootAppFolder
or kDBRootDropbox
constants.
Once you have your app key and secret, you can create the DBSession
object for your app. To do this, add the following code in your application delegate's application:didFinishLaunchingWithOptions:
method:
#import <DropboxSDK/DropboxSDK.h> DBSession *dbSession = [[DBSession alloc] initWithAppKey:@"INSERT_APP_KEY" appSecret:@"INSERT_APP_SECRET" root:INSERT_ACCESS_TYPE]; // either kDBRootAppFolder or kDBRootDropbox [DBSession setSharedSession:dbSession];
Now we're all set to start the authentication flow. We'll start by calling the -[DBSession linkFromController:]
method which will ask the user to authorize your app. The linking process will switch to the Dropbox mobile app if it's installed so the user doesn't need to log in again. Otherwise, a Dropbox authorization view will be presented from the specified view controller.
- (IBAction)didPressLink { if (![[DBSession sharedSession] isLinked]) { [[DBSession sharedSession] linkFromController:self]; } }
The SDK coordinates with the Dropbox app (if it's installed) to simplify the auth process. But in order to smoothly hand the user back to your app, you need to add a unique URL scheme that Dropbox can call. You'll need to configure your project to add one:
Now that your app is registered for the correct scheme, you need to add the following code to your application delegate in order to complete the authentication flow:
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url sourceApplication:(NSString *)source annotation:(id)annotation { if ([[DBSession sharedSession] handleOpenURL:url]) { if ([[DBSession sharedSession] isLinked]) { NSLog(@"App linked successfully!"); // At this point you can start making API calls } return YES; } // Add whatever other url handling code your app requires here return NO; }
If you've made it this far, you have a simple app that uses the Core API to link to a Dropbox account. Next, we'll upload a file to Dropbox, get its metadata, and then download it back to our app.
Let's say we're building a text editing app and we want to use it to save your latest magnum opus to Dropbox. The DBRestClient
is your gateway to accessing Dropbox once the user has linked their account.
#import <DropboxSDK/DropboxSDK.h> @interface YourViewController () <DBRestClientDelegate> @property (nonatomic, strong) DBRestClient *restClient; @end ... - (void)viewDidLoad { [super viewDidLoad]; self.restClient = [[DBRestClient alloc] initWithSession:[DBSession sharedSession]]; self.restClient.delegate = self; }
Note that a DBSession
can be linked with more than one Dropbox, for example you could allow users to connect with both their work and personal Dropboxes. In that case, you'll want to use the -[DBRestClient initWithSession:userId:]
method to specify the account. You can get an array of all connected accounts from [DBSession sharedSession].userIds
.
Now that you've created a DBRestClient
object, you're ready to make requests. First, let's upload a file. -[DBRestClient uploadFile:toPath:withParentRev:fromPath:]
takes a local path pointing to a file and a path where we want the file on our Dropbox. For this example, let's upload a local copy of working-draft.txt:
// Write a file to the local documents directory NSString *text = @"Hello world."; NSString *filename = @"working-draft.txt"; NSString *localDir = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0]; NSString *localPath = [localDir stringByAppendingPathComponent:filename]; [text writeToFile:localPath atomically:YES encoding:NSUTF8StringEncoding error:nil]; // Upload file to Dropbox NSString *destDir = @"/"; [self.restClient uploadFile:filename toPath:destDir withParentRev:nil fromPath:localPath];
When calling this method, filename
is the name of the file and toPath
is the folder where this file will be placed in the user's Dropbox. If you are uploading a new file, set the parentRev
to nil
, which will prevent uploads from overwriting existing files. fromPath
is the full path of the file you are uploading on the device.
All the methods on DBRestClient
are asynchronous, meaning they don't immediately return the data they are meant to load. Each method has at least two corresponding DBRestClientDelegate
methods that get called when a request either succeeds or fails. The success callback will give you the data you requested and the failure callback will contain an NSError
object that has more details on why the request failed.
- (void)restClient:(DBRestClient *)client uploadedFile:(NSString *)destPath from:(NSString *)srcPath metadata:(DBMetadata *)metadata { NSLog(@"File uploaded successfully to path: %@", metadata.path); } - (void)restClient:(DBRestClient *)client uploadFileFailedWithError:(NSError *)error { NSLog(@"File upload failed with error: %@", error); }
Make sure you call DBRestClient methods from the main thread or a thread that has a run loop. Otherwise the delegate methods won't be called.
If all goes well, the data in your local working-draft.txt will now be in the root of your app folder (or Dropbox folder, depending on your app's access type). The variable metadata
will be an DBMetadata
object containing the metadata of the newly uploaded file. In this case, we're outputting the path of the newly uploaded file so the output in the console should look like this:
File uploaded successfully to path: /working-draft.txt
Now that your file is in Dropbox, let's glance at the metadata by invoking the metadata
method.
[self.restClient loadMetadata:@"/"];
The rest client will call your delegate with one of the following callbacks:
- (void)restClient:(DBRestClient *)client loadedMetadata:(DBMetadata *)metadata { if (metadata.isDirectory) { NSLog(@"Folder '%@' contains:", metadata.path); for (DBMetadata *file in metadata.contents) { NSLog(@" %@", file.filename); } } } - (void)restClient:(DBRestClient *)client loadMetadataFailedWithError:(NSError *)error { NSLog(@"Error loading metadata: %@", error); }
Metadata objects are how you get information on files and folders in a user's Dropbox. Calling loadMetadata:
on "/"
will load the metadata for the root folder, and since it's a folder the contents
property will contain a list of files and folders in that folder.
Each file's metadata will include its current revision. Every time a change is made to the file, the rev
field of the file's metadata changes as well. By saving the revision when you download the file, you'll be able to tell if that file has been updated by another computer or device and choose to download the newer revision of that file.
Some time has passed and you're ready to start editing that magnum opus of yours again. We'll need the -[DBRestClient loadFile:intoPath:]
method to download the file.
[self.restClient loadFile:dropboxPath intoPath:localPath];
Here, dropboxPath
is the path in the user's Dropbox (you probably got this from a metadata object), and localPath
is the location on the local device you want the file to be put after it has been downloaded. To find out when the file download either succeeds or fails implement the following DBRestClientDelegate
methods:
- (void)restClient:(DBRestClient *)client loadedFile:(NSString *)localPath contentType:(NSString *)contentType metadata:(DBMetadata *)metadata { NSLog(@"File loaded into path: %@", localPath); } - (void)restClient:(DBRestClient *)client loadFileFailedWithError:(NSError *)error { NSLog(@"There was an error loading the file: %@", error); }
You can now read the contents of the file from localPath
.
And with that you should be equipped with most everything you need to get started with the Core API. If you're still not sure about something, the developer forum is a great place to find information and get help from fellow developers. Good luck!