TJDropbox is designed to be pretty flexible when it comes to authentication. Once can simply use TJDropboxAuthenticationViewController
as a catch-all, but I'd suggest doing the following for the best user experience.
- Try to authenticate using the Dropbox app
- Use
ASWebAuthenticationSession
if available (iOS 12+) - Use
SFAuthenticationSession
if available (iOS 11+) - Use
SFSafariViewController
if available (iOS 9+) - Use the Safari app or
TJDropboxAuthenticationViewController
The reasoning for this suggestion is that users are likely already authenticated in the Dropbox app or in Safari, so they don't need to re-enter their credentials. Here's a breakdown of how to implement these.
TJDropbox provides two methods for authenticating users using the Dropbox app, if installed.
First, you'll need to get the URL you'll use to authenticate and check if the OS can open in. You'll need to add dbapi-2
to your info plist's LSApplicationQueriesSchemes
array in order for this to work in iOS 9 and aboe.
NSString *clientIdentifier = /* fill this in */;
NSURL *authURL = [TJDropbox dropboxAppAuthenticationURLWithClientIdentifier:clientIdentifier];
if ([[UIApplication sharedApplication] canOpenURL:authURL]) {
[[UIApplication sharedApplication] openURL:authURL];
} else {
// Use another authentication method...
}
You'll then need to register your app with a URL scheme that the Dropbox app is capable of handling, outlined in the 'Set up a URL scheme' section here.
Once this is done, you need to intercept URLs coming from the Dropbox app back into yours, like so.
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
BOOL didHandle = NO;
NSString *accessToken = [TJDropbox accessTokenFromDropboxAppAuthenticationURL:url];
if (accessToken) {
// Success! You've authenticated. Store the token and use it.
didHandle = YES;
} else {
// Handle other incoming URLs if need be
}
return didHandle;
}
Using ASWebAuthenticationSession
(iOS 12+) or SFAuthenticationSession
(iOS 11+) to authenticate users via TJDropbox is very easy. You should register a URL scheme for your app as described here (also needed to authentication with the Dropbox app) then use the following snippet.
NSString *clientIdentifier = /* fill this in */;
NSURL *authURL = [TJDropbox tokenAuthenticationURLWithClientIdentifier:clientIdentifier];
NSStringr *callbackScheme = [NSString stringWithFormat:@"db-%@", clientIdentifier];
// or SFAuthenticationSession
[[[ASWebAuthenticationSession alloc] initWithURL:authURL callbackURLScheme:callbackScheme completionHandler:^(NSURL *callbackURL, NSError *error) {
NSString *accessToken = [TJDropbox accessTokenFromURL:callbackURL withClientIdentifier:clientIdentifier];
if (accessToken) {
// Completed with token!
} else {
// Completed without token, something went wrong.
}
}] start];
Using SFSafariViewController
for Dropbox authentication is useful if the user is already signed in within their browser. It is superseded by ASWebAuthenticationSession
/SFAuthenticationSession
in later iOS versions, but useful for older OSes. You should register a URL scheme for your app as described here (also needed to authentication with the Dropbox app) then use the following snippet.
NSURL *authURL = [TJDropbox tokenAuthenticationURLWithClientIdentifier:clientIdentifier];
SFSafariViewController *safariViewController = [[SFSafariViewController alloc] initWithURL:authURL];
// Present safariViewController modally
Then you'll need to intercept URLs coming into your app from this SFSafariViewController
redirecting to your app's URL scheme.
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
BOOL didHandle = NO;
NSString *accessToken = [TJDropbox accessTokenFromURL:url withClientIdentifier:/*client identifier*/];
if (accessToken) {
// Success! You've authenticated. Store the token and use it.
didHandle = YES;
} else {
// Handle other incoming URLs if need be
}
return didHandle;
}
You can also used similar steps to perform auth with Safari.app by calling -openURL:
with authURL
.
Using TJDropboxAuthenticationViewController
is outlined here.
Here's sample code for using all three of these methods.
In the place where you initiate authentication.
- (void)authenticate
{
NSString *clientIdentifier = /* your client identifier */;
NSURL *appAuthURL = [TJDropbox dropboxAppAuthenticationURLWithClientIdentifier:clientIdentifier];
if ([[UIApplication sharedApplication] canOpenURL:appAuthURL]) {
[[UIApplication sharedApplication] openURL:appAuthURL];
} else if ([SFAuthenticationSession class]) {
[[[SFAuthenticationSession alloc] initWithURL:authURL callbackURLScheme:callbackScheme completionHandler:^(NSURL *callbackURL, NSError *error) {
NSString *accessToken = [TJDropbox accessTokenFromURL:callbackURL withClientIdentifier:clientIdentifier];
if (accessToken) {
// Completed with token!
} else {
// Completed without token, something went wrong.
}
}] start];
} else if ([SFSafariViewController class]) {
NSURL *authURL = [TJDropbox tokenAuthenticationURLWithClientIdentifier:clientIdentifier];
SFSafariViewController *safariViewController = [[SFSafariViewController alloc] initWithURL:authURL];
// Present safariViewController modally
} else {
TJDropboxAuthenticationViewController *authViewController = [[TJDropboxAuthenticationViewController alloc] initWithClientIdentifier:clientIdentifier delegate:self];
// Push authViewController onto the nav stack or embed in a nav controller and present modally
}
}
- (void)dropboxAuthenticationViewController:(TJDropboxAuthenticationViewController *)viewController didAuthenticateWithAccessToken:(NSString *)accessToken
{
// Huzzah! You're authenticated.
// Store the token and dismiss your view controller
}
In your app delegate
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
BOOL didHandle = NO;
NSString *dropboxAppAccessToken = [TJDropbox accessTokenFromDropboxAppAuthenticationURL:url];
NSString *dropboxWebAccessToken = [TJDropbox accessTokenFromURL:url withClientIdentifier:/*client identifier*/];
if (dropboxAppAccessToken) {
// Success! You've authenticated. Store the token and use it.
didHandle = YES;
} else if (dropboxWebAccessToken) {
// Success! You've authenticated. Store the token and use it.
// Also, dismiss your SFSafariViewController.
didHandle = YES;
} else {
// Handle other incoming URLs if need be
}
return didHandle;
}