I want to integrate Google+ sign in functionality to my app. I have used Google+ sdk , but it redirect to safari to sign in to google , I want to open that web dialog within my application. Can anybody help me on that thing?
I did it. By inheriting UIApplication class and then handling url in web view. Here is code:
Add Google+ FrameWork to your project.
Now, on authentication call, catch that URL by inhereting UIAPPLICATION Class.
- (IBAction)btnGooglePlusTap:(id)sender
{
[[GPPSignIn sharedInstance] authenticate];
}
SubClassUIApplication.h
#import <UIKit/UIKit.h>
#define ApplicationOpenGoogleAuthNotification #"GoogleFriendInvitationPosted"
#interface SubClassUIApplication : UIApplication
#end
#import "SubClassUIApplication.h"
#implementation SubClassUIApplication
- (BOOL)openURL:(NSURL *)url
{
if([[url absoluteString] hasPrefix:#"googlechrome-x-callback:"])
{
return NO;//This will prevent call to Google Chrome App if installed.
}
else if([[url absoluteString] hasPrefix:#"https://accounts.google.com/o/oauth2/auth"])
{
[[NSNotificationCenter defaultCenter] postNotificationName:ApplicationOpenGoogleAuthNotification object:url];
return NO;// Here we will pass URL to notification and from notification observer , we will load web view.
}
else if ([[url absoluteString] hasPrefix:#"com.google"])
{
return NO;
}
return [super openURL:url];
}
#end
Set this subclass as principal class in info.plist file.
Now open URL to web view
- (void)catchNotificationforGooglePlusSharing:(NSNotification *)notiofication
{
NSURL *u=(NSURL *)notiofication.object;
UINavigationController *navWebView =(UINavigationController *) [self.storyboard instantiateViewControllerWithIdentifier:#"WebViewNavController"];
WebViewController *vcWebView = navWebView.viewControllers[0];
vcWebView.webURL = u;
[self.navigationController presentViewController:navWebView animated:YES completion:Nil];
}
Now in webviewcontroller.m
- (void)viewDidLoad
{
[super viewDidLoad];
NSURLRequest *req= [[NSURLRequest alloc]initWithURL:webURL];
[webvGoogle loadRequest:req];
}
#pragma mark - UIWebViewDelegate method
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
BOOL canHandle = [GPPURLHandler handleURL:request.URL sourceApplication:#"com.apple.mobilesafari" annotation:nil];
if(canHandle == YES)
{
[self dismissViewControllerAnimated:YES completion:^
{
}];
}
return YES;
}
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
{
NSLog(#"Error in loading : %#",error.description);
}
Don't forget to register your class for ApplicationOpenGoogleAuthNotification notification.
You can use GTMOAuth2ViewControllerTouch from Google Toolbox for Mac - OAuth 2 Controllers.
#import <GTMOAuth2ViewControllerTouch.h>
GTMOAuth2ViewControllerTouch *googleAuthViewController = [[GTMOAuth2ViewControllerTouch alloc]
initWithScope:#"https://www.googleapis.com/auth/userinfo#email"
clientID:kClientId
clientSecret:kSecretId
keychainItemName:#"GooglePlus_Sample_App"
delegate:self
finishedSelector:#selector(viewController:finishedWithAuth:error:)];
[self.navigationController pushViewController:googleAuthViewController animated:YES];
This is a sample found here http://blog.krzyzanowskim.com/2015/02/22/google-sign-on-with-1password/ where you can find full sample project.
Related
While trying to integrate Azure AD B2C, I am stuck with an error "oauthConnection Error: Bad Request". Following their given sample app it all works fine. But after integrating the same copy paste code from the working sample app, and trying to log in with Facebook or Google Plus, it throws an error! I am pretty sure that every credential that I used in the sample app is the same for my app. Any idea about this will be highly appreciated. Here is my code, AppDelegate.m
#import "AppData.h"
#import "NXOAuth2.h"
#import "AppDelegate.h"
#interface AppDelegate ()
#end
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[self setupOAuth2AccountStore];
// Override point for customization after application launch.
return YES;
}
- (void)setupOAuth2AccountStore {
AppData *data = [AppData getInstance]; // The singleton we use to get the settings
NSDictionary *customHeaders =
[NSDictionary dictionaryWithObject:#"application/x-www-form-urlencoded"
forKey:#"Content-Type"];
// Azure B2C needs
// kNXOAuth2AccountStoreConfigurationAdditionalAuthenticationParameters for
// sending policy to the server,
// therefore we use -setConfiguration:forAccountType:
NSDictionary *B2cConfigDict = #{
kNXOAuth2AccountStoreConfigurationClientID : data.clientID,
kNXOAuth2AccountStoreConfigurationSecret : data.clientSecret,
kNXOAuth2AccountStoreConfigurationScope :
[NSSet setWithObjects:#"openid", data.clientID, nil],
kNXOAuth2AccountStoreConfigurationAuthorizeURL :
[NSURL URLWithString:data.authURL],
kNXOAuth2AccountStoreConfigurationTokenURL :
[NSURL URLWithString:data.tokenURL],
kNXOAuth2AccountStoreConfigurationRedirectURL :
[NSURL URLWithString:data.bhh],
kNXOAuth2AccountStoreConfigurationCustomHeaderFields : customHeaders,
// kNXOAuth2AccountStoreConfigurationAdditionalAuthenticationParameters:customAuthenticationParameters
};
[[NXOAuth2AccountStore sharedStore] setConfiguration:B2cConfigDict
forAccountType:data.accountIdentifier];
}
LoginViewController.m
#import "AppData.h"
#import "LoginViewController.h"
#import "NXOAuth2.h"
#interface LoginViewController ()
#end
#implementation LoginViewController {
NSURL *myLoadedUrl;
bool isRequestBusy;
}
// Put variables here
- (void)viewDidLoad {
[super viewDidLoad];
// OAuth2 Code
self.loginView.delegate = self;
[self requestOAuth2Access];
[self setupOAuth2AccountStore];
NSURLCache *URLCache =
[[NSURLCache alloc] initWithMemoryCapacity:4 * 1024 * 1024
diskCapacity:20 * 1024 * 1024
diskPath:nil];
[NSURLCache setSharedURLCache:URLCache];
}
- (void)resolveUsingUIWebView:(NSURL *)URL {
// We get the auth token from a redirect so we need to handle that in the
// webview.
if (![NSThread isMainThread]) {
[self performSelectorOnMainThread:#selector(resolveUsingUIWebView:)
withObject:URL
waitUntilDone:YES];
return;
}
NSURLRequest *hostnameURLRequest =
[NSURLRequest requestWithURL:URL
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:10.0f];
isRequestBusy = YES;
[self.loginView loadRequest:hostnameURLRequest];
NSLog(#"resolveUsingUIWebView ready (status: UNKNOWN, URL: %#)",
self.loginView.request.URL);
}
- (BOOL)webView:(UIWebView *)webView
shouldStartLoadWithRequest:(NSURLRequest *)request
navigationType:(UIWebViewNavigationType)navigationType {
AppData *data = [AppData getInstance];
NSLog(#"webView:shouldStartLoadWithRequest: %# (%li)", request.URL,
(long)navigationType);
// The webview is where all the communication happens. Slightly complicated.
myLoadedUrl = [webView.request mainDocumentURL];
NSLog(#"***Loaded url: %#", myLoadedUrl);
// if the UIWebView is showing our authorization URL or consent URL, show the
// UIWebView control
if ([request.URL.absoluteString rangeOfString:data.authURL
options:NSCaseInsensitiveSearch]
.location != NSNotFound) {
self.loginView.hidden = NO;
} else if ([request.URL.absoluteString rangeOfString:data.loginURL
options:NSCaseInsensitiveSearch]
.location != NSNotFound) {
// otherwise hide the UIWebView, we've left the authorization flow
self.loginView.hidden = NO;
} else if ([request.URL.absoluteString rangeOfString:data.bhh
options:NSCaseInsensitiveSearch]
.location != NSNotFound) {
// otherwise hide the UIWebView, we've left the authorization flow
self.loginView.hidden = YES;
[[NXOAuth2AccountStore sharedStore] handleRedirectURL:request.URL];
} else {
self.loginView.hidden = NO;
}
return YES;
}
#pragma mark - UIWebViewDelegate methods
- (void)webViewDidFinishLoad:(UIWebView *)webView {
// The webview is where all the communication happens. Slightly complicated.
}
- (void)handleOAuth2AccessResult:(NSURL *)accessResult {
// parse the response for success or failure
if (accessResult)
// if success, complete the OAuth2 flow by handling the redirect URL and
// obtaining a token
{
[[NXOAuth2AccountStore sharedStore] handleRedirectURL:accessResult];
} else {
// start over
[self requestOAuth2Access];
}
}
- (void)setupOAuth2AccountStore {
[[NSNotificationCenter defaultCenter]
addObserverForName:NXOAuth2AccountStoreAccountsDidChangeNotification
object:[NXOAuth2AccountStore sharedStore]
queue:nil
usingBlock:^(NSNotification *aNotification) {
if (aNotification.userInfo) {
// account added, we have access
// we can now request protected data
NSLog(#"Success!! We have an access token.");
} else {
// account removed, we lost access
}
}];
[[NSNotificationCenter defaultCenter]
addObserverForName:NXOAuth2AccountStoreDidFailToRequestAccessNotification
object:[NXOAuth2AccountStore sharedStore]
queue:nil
usingBlock:^(NSNotification *aNotification) {
NSError *error = [aNotification.userInfo
objectForKey:NXOAuth2AccountStoreErrorKey];
// Always got stuck here while trying to login with any credentials
NSLog(#"Error!! %#", error.localizedDescription);
}];
}
- (void)requestOAuth2Access {
AppData *data = [AppData getInstance];
[[NXOAuth2AccountStore sharedStore]
requestAccessToAccountWithType:data.accountIdentifier
withPreparedAuthorizationURLHandler:^(NSURL *preparedURL) {
NSURLRequest *r = [NSURLRequest requestWithURL:preparedURL];
[self.loginView loadRequest:r];
}];
}
ViewController.m
#import "ViewController.h"
#import "AppData.h"
#import "LoginViewController.h"
#import "NXOAuth2.h"
// Login Action
- (IBAction)login:(id)sender {
LoginViewController *userSelectController =
[self.storyboard instantiateViewControllerWithIdentifier:#"login"];
[self.navigationController pushViewController:userSelectController
animated:YES];
}
In case if anybody stumbles in this, Here is the solution
Go to pod, NXOAuth2Client.m and replace the method
- (void)requestTokenWithAuthGrant:(NSString *)authGrant redirectURL:(NSURL *)redirectURL; with the below code
- (void)requestTokenWithAuthGrant:(NSString *)authGrant redirectURL:(NSURL *)redirectURL;
{
NSAssert1(!authConnection, #"authConnection already running with: %#", authConnection);
NSMutableURLRequest *tokenRequest = [NSMutableURLRequest requestWithURL:tokenURL];
[tokenRequest setHTTPMethod:self.tokenRequestHTTPMethod];
[authConnection cancel]; // just to be sure
self.authenticating = YES;
NSMutableDictionary *parameters = [NSMutableDictionary dictionaryWithObjectsAndKeys:
#"authorization_code", #"grant_type",
clientId, #"client_id",
// clientSecret, #"client_secret",
[redirectURL absoluteString], #"redirect_uri",
authGrant, #"code",
nil];
if (self.desiredScope) {
[parameters setObject:[[self.desiredScope allObjects] componentsJoinedByString:#" "] forKey:#"scope"];
}
if (self.customHeaderFields) {
[self.customHeaderFields enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSString *obj, BOOL *stop) {
[tokenRequest addValue:obj forHTTPHeaderField:key];
}];
}
if (self.additionalAuthenticationParameters) {
[parameters addEntriesFromDictionary:self.additionalAuthenticationParameters];
}
authConnection = [[NXOAuth2Connection alloc] initWithRequest:tokenRequest
requestParameters:parameters
oauthClient:self
delegate:self];
authConnection.context = NXOAuth2ClientConnectionContextTokenRequest;
}
Commenting clientSecret solved the issue
I'm working with a UIWebView and am already using webViewDidFinishLoad: method with an optional block that gets executed after loading complete:
-(void)webViewDidFinishLoad:(UIWebView *)webView
{
[super webViewDidFinishLoad:webView];
//... bunch of other code
if(self.webViewFinishLoadBlock != nil)
{
self.webViewFinishLoadBlock();
}
}
Now I'm working with an even more complicated sequence of loading pages and redirects that makes the logic above not sufficient. I don't want to register myself as a delegate of dummyWebView and have to juggle multiple completion blocks stored in my view controller's properties:
dummyWebView = [[UIWebView alloc] initWithFrame:CGRectZero];
[dummyWebView loadRequest:[NSURLRequest requestWithURL:logoutURL]];
//Ideally here I would know when dummyWebView finishes loading, because there's some code I want to execute once it is done
My question is:
Is there some kind of third party framework that would allow me to use loadRequest:withCompletion: to simplify writing callback code?
You can just:
Subclass UIWebView with a property to hold the webViewDidFinish completion block;
Make sure it specifies its delegate;
Implement the webViewDidFinish much like you wrote it (though I'd suggest the block return both the web view as well as the NSError object, if any); and
Implement the webView:didFailLoadWithError:, too.
Thus:
// MyWebView.h
#import <UIKit/UIKit.h>
typedef void(^WebViewFinishLoadBlock)(UIWebView *, NSError *);
#interface MyWebView : UIWebView
#property(nonatomic, copy) WebViewFinishLoadBlock webViewFinishLoadBlock;
- (void)loadRequest:(NSURLRequest *)request withCompletionHandler:(WebViewFinishLoadBlock)completionHandler;
#end
And
// MyWebView.m
#import "MyWebView.h"
#interface MyWebView () <UIWebViewDelegate>
#end
#implementation MyWebView
- (void)loadRequest:(NSURLRequest *)request withCompletionHandler:(WebViewFinishLoadBlock)completionHandler
{
self.delegate = self;
self.webViewFinishLoadBlock = completionHandler;
[self loadRequest:request];
}
#pragma mark - UIWebViewDelegate
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
if (self.webViewFinishLoadBlock) {
self.webViewFinishLoadBlock(webView, nil);
self.webViewFinishLoadBlock = nil;
}
}
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
{
if (self.webViewFinishLoadBlock) {
self.webViewFinishLoadBlock(webView, error);
self.webViewFinishLoadBlock = nil;
}
}
#end
And then:
MyWebView *webView = [[MyWebView alloc] init];
webView.frame = self.view.bounds;
[self.view addSubview:webView];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[webView loadRequest:request withCompletionHandler:^(UIWebView *webView, NSError *error) {
if (error) {
NSLog(#"failed: %#", error);
} else {
NSLog(#"succeeded");
}
}];
- (void)webViewDidFinishLoad:(UIWebView *)webView
is a delegate method. By convention delegate methods require the object pass itself back to the delegate:
(UIWebView*)webView
Through a parameter.
If we want to get last request parameter using property request: that means webView.request.URL
The parent object can be the delegate for multiple objects, and it can identify which it is getting a response from though that parameter. Either switch on what responds to you or build some infrastructure to handle it more elegantly.
I am a beginner in making iOS applications. I have made a simple webview showing my web page. The problem is that every link that is pressed in my web page opens in the webview. I want some links to open in safari. I would like links starting with "..something" to be opened inside the webview and every other link to be opened in safari. I also have a button for email and dial which i want to open in the dial app and email app on the phone. Is this a possibility? please explain simple.
ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
#property (nonatomic, strong) IBOutlet UIWebView *webView;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize webView;
- (void)viewDidLoad
{
NSURL *url = [NSURL URLWithString:#"http://MyWebPage"];
NSURLRequest *requestURL = [NSURLRequest requestWithURL:url];
[webView loadRequest:requestURL];
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
I made the same application for android using java with this code below
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
try{
System.out.println("url called:::" + url);
if (url.startsWith("tel:")) {
Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse(url));
startActivity(intent);
} else if (url.startsWith("http:")
|| url.startsWith("https:")) {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(intent);
} else if (url.startsWith("mailto:")) {
MailTo mt=MailTo.parse(url);
send_email(mt.getTo());
}
else {
return false;
}
}catch(Exception e){
e.printStackTrace();
}
return true;
}
}
You'll need to make your controller a UIWebViewDelegate and implement the webView: shouldStartLoadWithRequest:navigationType: method.
#interface ViewController () <UIWebViewDelegate>
viewDidLoad should look like this:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSURL *url = [NSURL URLWithString:#"http://MyWebPage"];
NSURLRequest *requestURL = [NSURLRequest requestWithURL:url];
webView.delegate = self;
[webView loadRequest:requestURL];
}
- (BOOL)webView:(UIWebView *)inWeb shouldStartLoadWithRequest:(NSURLRequest *)inRequest navigationType:(UIWebViewNavigationType)inType {
if ( inType == UIWebViewNavigationTypeLinkClicked && [self shouldOpenInSafari:[inRequest URL]]) {
[[UIApplication sharedApplication] openURL:[inRequest URL]];
return NO;
}
return YES;
}
- (BOOL)shouldOpenInSafari:(NSURL*)url
{
if ([url.scheme isEqualToString:#"mailto"]) {
return YES;
}
else if ([url.scheme isEqualToString:#"tel"]) {
return YES;
}
else if (([url.scheme isEqualToString:#"http"] || [url.scheme isEqualToString:#"https"]) && [url.host isEqualToString:#"example.com"]) {
return YES;
}
return NO;
}
Then you'll need to implement the shouldOpenInSafari: method. The openURL: method can also handle tel: and mailto: links.
Some code from here.
For the urls which you want to open in web view, use the same code which you have.
For opening in safari, use this
NSString* launchUrl = #"URL to open in safari";
[[UIApplication sharedApplication] openURL:[NSURL URLWithString: launchUrl]];
I'm trying to login to Tumblr via OAuth and a Mac App I begin to code.
I donwloaded gtm-oauth source code, everything is fine.
I just began with this code inside a view controller :
- (GTMOAuthAuthentication *)myCustomAuth {
GTMOAuthAuthentication *auth;
auth = [[[GTMOAuthAuthentication alloc] initWithSignatureMethod:kGTMOAuthSignatureMethodHMAC_SHA1
consumerKey:kConsumerKey
privateKey:kConsumerSecret] autorelease];
auth.serviceProvider = #"Custom Auth Service";
return auth;
}
- (void)viewController:(GTMOAuthViewControllerTouch *)viewController
finishedWithAuth:(GTMOAuthAuthentication *)auth
error:(NSError *)error {
NSLog(#"finishedWithAuth");
if (error != nil) {
NSLog(#"failed");
} else {
NSLog(#"done");
}
}
- (void)signInToCustomService {
GTMOAuthAuthentication *auth = [self myCustomAuth];
if (auth == nil) {
NSLog(#"A valid consumer key and consumer secret are required for signing in to Tumblr");
}
else
{
NSLog(#"Ok auth");
}
NSURL *requestURL = [NSURL URLWithString:#"http://www.tumblr.com/oauth/request_token"];
NSURL *accessURL = [NSURL URLWithString:#"http://www.tumblr.com/oauth/access_token"];
NSURL *authorizeURL = [NSURL URLWithString:#"http://www.tumblr.com/oauth/authorize"];
NSString *scope = #"http://api.tumblr.com"; // HERE I DON'T KNOW WHAT TO WRITE
GTMOAuthViewControllerTouch *viewController;
viewController = [[[GTMOAuthViewControllerTouch alloc] initWithScope:scope
language:nil
requestTokenURL:requestURL
authorizeTokenURL:authorizeURL
accessTokenURL:accessURL
authentication:auth
appServiceName:#"My App: Custom Service"
delegate:self
finishedSelector:#selector(viewController:finishedWithAuth:error:)] autorelease];
[self presentModalViewController:viewController animated:YES];
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self signInToCustomService];
}
But nothing happens.
- (void)viewController:(GTMOAuthViewControllerTouch *)viewController
finishedWithAuth:(GTMOAuthAuthentication *)auth
error:(NSError *)error;
This method is never called.
Perhaps this is my scope variable. I don't know which value I have to write for it.
Thanks for your help !
I have started exploring the Dropbox API for an app that I have where I would like the user to be able to back up the database file. The problem I have run into is that after the user links the app with their account (similar to logging in via Facebook) the app doesn't return to the foreground. When I manually go back to the app it is still on the backups screen, but the account has not been linked (as best as I can tell) and the handleOpenUrl app delegate method is not called.
Any ideas? or maybe someone knows a good tutorial for this. The sample Dropbox app works fine, and I'm doing my best to use it as a guide but obviously i've messed something up.
App Delegate:
#import "AppDelegate_iPad.h"
#import <DropboxSDK/DropboxSDK.h>
#interface AppDelegate_iPad () <DBSessionDelegate>
#end
#implementation AppDelegate_iPad
#synthesize window,viewController;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.viewController = [[mainMenuViewController alloc]init];
[window addSubview:viewController.view]; //< this is a main menu viewcontroller for my app
[self.window makeKeyAndVisible];
// Set these variables before launching the app
NSString* appKey = #"XXXX";
NSString* appSecret = #"XXX";
NSString *root = kDBRootAppFolder;
NSString* errorMsg = nil;
if ([appKey rangeOfCharacterFromSet:[[NSCharacterSet alphanumericCharacterSet] invertedSet]].location != NSNotFound) {
errorMsg = #"Make sure you set the app key correctly in DBRouletteAppDelegate.m";
} else if ([appSecret rangeOfCharacterFromSet:[[NSCharacterSet alphanumericCharacterSet] invertedSet]].location != NSNotFound) {
errorMsg = #"Make sure you set the app secret correctly in DBRouletteAppDelegate.m";
} else if ([root length] == 0) {
errorMsg = #"Set your root to use either App Folder of full Dropbox";
} else {
NSString *plistPath = [[NSBundle mainBundle] pathForResource:#"Info" ofType:#"plist"];
NSData *plistData = [NSData dataWithContentsOfFile:plistPath];
NSDictionary *loadedPlist =
[NSPropertyListSerialization
propertyListFromData:plistData mutabilityOption:0 format:NULL errorDescription:NULL];
NSString *scheme = [[[[loadedPlist objectForKey:#"CFBundleURLTypes"] objectAtIndex:0] objectForKey:#"CFBundleURLSchemes"] objectAtIndex:0];
if ([scheme isEqual:#"db-APP_KEY"]) {
errorMsg = #"Set your URL scheme correctly in DBRoulette-Info.plist";
}
}
DBSession* session =
[[DBSession alloc] initWithAppKey:appKey appSecret:appSecret root:root];
session.delegate = self; // DBSessionDelegate methods allow you to handle re-authenticating
[DBSession setSharedSession:session];
[session release];
if (errorMsg != nil) {
[[[[UIAlertView alloc]
initWithTitle:#"Error Configuring Session" message:errorMsg
delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil]
autorelease]
show];
}
NSURL *launchURL = [launchOptions objectForKey:UIApplicationLaunchOptionsURLKey];
NSInteger majorVersion =
[[[[[UIDevice currentDevice] systemVersion] componentsSeparatedByString:#"."] objectAtIndex:0] integerValue];
if (launchURL && majorVersion < 4) {
// Pre-iOS 4.0 won't call application:handleOpenURL; this code is only needed if you support
// iOS versions 3.2 or below
[self application:application handleOpenURL:launchURL];
return NO;
}
return YES;
}
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url { /// this is never called
if ([[DBSession sharedSession] handleOpenURL:url]) {
if ([[DBSession sharedSession] isLinked]) {
NSLog(#"App linked successfully!");
// At this point you can start making API calls
}
return YES;
}
return NO;
}
#end
From the main Menu, the user pressed a backup button and that opens the following view controller:
#import "BackupManagerViewController.h"
#import <DropboxSDK/DropboxSDK.h>
#import <stdlib.h>
#interface BackupManagerViewController () <DBRestClientDelegate>
//#property (nonatomic, readonly) DBRestClient* restClient;
#end
#implementation BackupManagerViewController
#synthesize itemsArray,delegate;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
//[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orientation
{
return (orientation != UIDeviceOrientationLandscapeLeft) &&
(orientation != UIDeviceOrientationLandscapeRight);
}
- (IBAction)didPressLink {
if (![[DBSession sharedSession] isLinked]) {
[[DBSession sharedSession] link];
} else {
[[DBSession sharedSession] unlinkAll];
[[[[UIAlertView alloc]
initWithTitle:#"Account Unlinked!" message:#"Your dropbox account has been unlinked"
delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil]
autorelease]
show];
}
}
-(DBRestClient *)restClient{
if (restClient == nil) {
restClient = [[DBRestClient alloc]initWithSession:[DBSession sharedSession]];
restClient.delegate = self;
}
return restClient;
}
-(IBAction) closeButtonPressed {
[delegate closeBackupManager];
}
#end
Things to check are
Make sure you don't have two applications with same db-APP_KEY
Make sure only one of these is implemented (not both) in your application delegate.
(a)
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
(b)
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
Option (b) is deprecated so please go with the option (a) in your new applications
You have entered correct APP_KEY in the URL scheme .
I ran into the same problem, but got it working after deleting the sample app DBRoulette from the simulator. I also deleted my own app and restarted the simulator, but I am not sure if those steps were necessary.
Did you add the drop box URL schema to your app's info.plist?
I believe this problem had to do with running in the simulator. I ran it on a device and it worked fine.