I'm unable to get my app to link to dropbox on iOS.
I create the session and ask if it's linked... if no, it opens up Dropbox to get authorization. I say yes, and it returns to my app and sends a notification to start the upload.
But isLinked is still NO, so the file fails to upload if I try. Any advice is appreciated.
Interestingly, the -sessionDidReceiveAuthorizationFailure: userId: delegate method is never called.
-(void)connectToDropbox{
if (!dbSession) {
dbSession = [[DBSession alloc] initWithAppKey:#"key"
appSecret:#"secret"
root:kDBRootDropbox];
dbSession.delegate = self;
[DBSession setSharedSession:dbSession];
}
if ([[DBSession sharedSession] isLinked]) {
[self beginUpload:nil];
} else {
[[DBSession sharedSession] linkFromController:self.currentViewController];
}
}
- (void)beginUpload:(NSNotification *)note {
if (![[DBSession sharedSession] isLinked]) {
NSError * error = [NSError errorWithDomain:#"myApp"
code:0
userInfo:#{NSLocalizedDescriptionKey : #"Could not link to Dropbox"}];
[[NSNotificationCenter defaultCenter] postNotificationName:kErrorDidOccurNotification object:error];
NSLog(#"File upload failed with error: %#", error);
return;
}
///do the upload if we make it here.
}
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation NS_AVAILABLE_IOS(4_2){
if ([sourceApplication isEqualToString:#"com.getdropbox.Dropbox"]) {
[[NSNotificationCenter defaultCenter] postNotificationName:#"beginDropboxUpload" object:nil];
}
/// more code
}
Your code in the app delegate isn't correct. You need something like this:
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation NS_AVAILABLE_IOS(4_2) {
if ([[DBSession sharedSession] handleOpenURL:url]) {
NSString *query = url.query;
if ([[url absoluteString] rangeOfString:#"cancel"].location == NSNotFound) { // NO_I18N
[[NSNotificationCenter defaultCenter] postNotificationName:#"beginDropboxUpload" object:nil];
} else {
// Link cancelled
}
} else {
// Something other than Dropbox
}
}
Related
I am beginner in IOS and want to invite friend via facebook for used my application. I used new framework of the facebook(4.0) and i found that for invite i need to used FBSDKAppInvite.
I setup the deep link in "Quick Start for App Links Hosting API".
I used following code for application invite
#pragma mark
#pragma mark - Share via facebbok
- (IBAction)btnShare:(id)sender
{
FBSDKAppInviteContent *content =[[FBSDKAppInviteContent alloc] init];
content.appLinkURL = [NSURL URLWithString:#"https://fb.me/863075563772717"];
//optionally set previewImageURL
// present the dialog. Assumes self implements protocol `FBSDKAppInviteDialogDelegate`
[FBSDKAppInviteDialog showWithContent:content
delegate:self]; // Do any additional setup after loading the view, typically from a nib.
}
-(void)appInviteDialog:(FBSDKAppInviteDialog *)appInviteDialog didCompleteWithResults:(NSDictionary *)results
{
NSLog(#"result::%#",results);
}
-(void)appInviteDialog:(FBSDKAppInviteDialog *)appInviteDialog didFailWithError:(NSError *)error
{
NSLog(#"error::%#",error);
}
And handle callback in following method
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
// Check if the handler knows what to do with this url
BFURL *parsedUrl = [BFURL URLWithInboundURL:url sourceApplication:sourceApplication];
if ([parsedUrl appLinkData]) {
// this is an applink url, handle it here
NSURL *targetUrl = [parsedUrl targetURL];
[[[UIAlertView alloc] initWithTitle:#"Received link:"
message:[targetUrl absoluteString]
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil] show];
}
return YES;
}
But i get nil in [parsedUrl appLinkData]
I am not understand what i do wrong. I also put URLScheme in Plist.
Any help can be appreciable
UPDATE
if i used following method then i get success in delegate method but invite is not send to recipient.
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
// Check if the handler knows what to do with this url
return [[FBSDKApplicationDelegate sharedInstance] application:application
openURL:url
sourceApplication:sourceApplication
annotation:annotation];
}
I referred below url and try to solve the issue but still not able to fix the issue.
Please help me out.
Dropbox SDK 401 Error
My app is working in iPhone 6 but while running the same app in iPhone 5 or 5s its showing the error:
[WARNING] DropboxSDK: error making request to /1/metadata/dropbox/ALLCREW.TXT - (401) No auth method found.
2014-12-11 16:58:14.628 user_schedule_3[2331:112832] Error loading metadata: Error Domain=dropbox.com Code=401 "The operation couldn’t be completed. (dropbox.com error 401.)" UserInfo=0x7fbb50d851c0 {path=/ALLCREW.TXT, error=No auth method found.}.
the code is given below:
AppDelegate.m:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions
{
// Override point for customization after application launch.
DBSession *dbSession = [[DBSession alloc]
initWithAppKey:#"******h4xl9l4o"
appSecret:#"*******1ujh8"
root:kDBRootDropbox]; // either kDBRootAppFolder or kDBRootDropbox
[DBSession setSharedSession:dbSession];
// NSString *listValue = #"NAME";
return YES;
}
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url
sourceApplication:(NSString *)source annotation:(id)annotation {
if ([[DBSession sharedSession] handleOpenURL:url]) {
if ([[DBSession sharedSession] isLinked]) {
NSLog(#"dropbox linked successfully!");
[[NSNotificationCenter defaultCenter] postNotificationName:#"updateRoot" object:nil];
NSLog(#"came out");
// At this point you can start making API calls
}
return YES;
}
// Add whatever other url handling code your app requires here
return NO;
}
View controller:
- (IBAction)didPressLink {
if (![[DBSession sharedSession] isLinked]) {
[[DBSession sharedSession] linkFromController:self];
NSLog(#"did press link is linked");
} else {
NSLog(#"did press link is reached");
}
}
NSString *filename = #"ALLCREW.TXT";
NSString *localDir = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
NSString *localPath = [localDir stringByAppendingPathComponent:filename];
[self.restClient loadMetadata:#"/ALLCREW.TXT"];
//[self.restClient loadFile:#"/ALLCREW.TXT" intoPath:localPath];
NSString *contentOfFile = [NSString stringWithContentsOfFile:localPath encoding:NSUTF8StringEncoding error:nil];
NSArray *stringWithEnter = [contentOfFile componentsSeparatedByString: #"\n"];
- (void)restClient:(DBRestClient *)client
loadMetadataFailedWithError:(NSError *)error {
NSLog(#"Error loading metadata: %#", error);
}
- (void)restClient:(DBRestClient *)client loadedFile:(NSString *)localPath
contentType:(NSString *)contentType metadata:(DBMetadata *)metadata {
NSLog(#"File loaded into path: %#", localPath);
[self getEntry ];
[self.tableView reloadData];
[spinner stopAnimating];
self.navigationItem.rightBarButtonItem.enabled = true;
}
- (void)restClient:(DBRestClient *)client loadFileFailedWithError:(NSError *)error {
NSLog(#"There was an error loading the file: %#", error);
}
I had the same issue. The solution ended up being that you had to add:
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
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;
}
You seem to have this code in:
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url sourceApplication:(NSString *)source annotation:(id)annotation;
Moving the code to handleOpenURL: should fix the issue.
Also make sure to link Security.framework!
Source: http://innofied.com/integration-of-dropbox-in-ios-applications/
Dropbox documentation explains by default the response for authentication gets fired into Appdelegate.m
How do I make the same fire my own class's delegate?
- (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;
}
In info plist url type --> in url schemes just add db-YourAppKey this method will get called.
This method is getting called automatically. I hope you already created app from dropbox developer site and get the appKey and appSecret. Use this code in app delegate NSString* appKey = #"";
NSString* appSecret = #"";
NSString *root = kDBRootDropbox;
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];
[DBRequest setNetworkRequestDelegate:self];
// [[DBSession sharedSession]unlinkAll];
if ([[DBSession sharedSession] isLinked])
{
isAccountForDropBox = YES;
}
else{
isAccountForDropBox = NO;
}
//After using this that open url will get call automatically.
These method only respond in AppDelegate.m,you can't use outside it.
To use in your ViewController or any class, you should use post notification
- (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!");
// Post Notify here
[[NSNotificationCenter defaultCenter] postNotificationName:#"applicationDidLinkWithDropbox" object:self];
}
return YES;
}
// Add whatever other url handling code your app requires here
return NO;
}
Then receive this notification in your class, in a ViewController for example:
- (void)viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(dropBoxDidLink:)
name:#"applicationDidLinkWithDropbox"
object:nil];
}
- (void) dropBoxDidLink:(NSNotification *)notification {
if ([[notification name] isEqualToString:#"applicationDidLinkWithDropbox"]) {
//Handle your task here
}
}
I am using the Facebook SDK for the first time. I am working with Xcode 5.1 and iOS 7.
I programmatically display FBLoginView:
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(#"viewDidLoad");
// Do any additional setup after loading the view.
if ( !loginView ) {
// loginView =[[FBLoginView alloc] initWithReadPermissions:#[#"basic_info"]];
loginView =[[FBLoginView alloc] initWithReadPermissions:[NSArray arrayWithObjects:#"basic_info", #"user_location", nil]];
}
loginView.delegate = self;
loginView.frame = CGRectOffset(loginView.frame,
(self.view.center.x -(loginView.frame.size.width /2)), 5);
CGPoint vCenter = CGPointMake( CGRectGetMidX(self.view.frame),
CGRectGetMidY(self.view.frame) );
CGPoint lvCenter = CGPointMake( vCenter.x, vCenter.y+100.0 );
loginView.center = lvCenter;
[self.view addSubview:loginView];
[self updateView];
}
I have implemented the required override functions:
#pragma mark - FBLoginViewDelegate
- (void) loginViewFetchedUserInfo:(FBLoginView *)loginView user:(id<FBGraphUser>)user {
NSLog(#"loginViewFetchedUserInfo");
[self updateView];
}
- (void) loginViewShowingLoggedInUser:(FBLoginView *)loginView {
NSLog(#"loginViewShowingLoggedInUser");
[self updateView];
}
- (void) loginViewShowingLoggedOutUser:(FBLoginView *)loginView {
NSLog(#"loginViewShowingLoggedOutUser");
[self updateView];
}
- (void)updateView {
NSLog(#"FB updateView");
[[FBRequest requestForMe] startWithCompletionHandler:
^(FBRequestConnection *connection, NSDictionary<FBGraphUser>*FBUser, NSError *error) {
if (error) {
NSLog(#"updateView - error");
} else {
NSLog(#"updateView - good");
NSNumber *owner_id = [NSNumber numberWithLong:[[FBUser id] longLongValue]];
if ( FB_user_id == nil ) {
FB_user_id = owner_id;
NSLog(#"FBUser ID = %#", FB_user_id);
loggedInSession = [FBSession activeSession];
[[NSUserDefaults standardUserDefaults] setObject:[FBUser id] forKey:#"eventOwnerID"];
[self performSegueWithIdentifier:#"continue_to_app" sender:self];
}
}
}];
if ([self checkFacebookSession]) {
}
dispatch_async(dispatch_get_main_queue(), ^{
[self.view setNeedsDisplay];
});
}
The FBLoginView button appears with "Log in with Facebook". I can log in and accept permissions, but the loginViewShowingLoggedInUser override function never gets called.
Someone suggested adding the following:
- (BOOL) application:(UIApplication *) application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation
{
NSLog ( #"application openURL");
NSLog ( #"URL = %#", url);
NSLog ( #"Application = %#", sourceApplication);
// Call FBAppCall's ha
BOOL wasHandled = [FBAppCall handleOpenURL:url sourceApplication:sourceApplication];
//[LoginUIViewController updateView];
return wasHandled;
}
This code had no effect and was never executed.
What am I doing wrong?
You are using #"basic_info", for this Facebook shows following error when I tried testing your code!
Invalid Scope: basic_info. Use public_profile, user_friends instead
I was interested in knowing where did you add the method:
- (BOOL) application:(UIApplication *) application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation
{
NSLog ( #"application openURL");
NSLog ( #"URL = %#", url);
NSLog ( #"Application = %#", sourceApplication);
// Call FBAppCall's ha
BOOL wasHandled = [FBAppCall handleOpenURL:url sourceApplication:sourceApplication];
//[LoginUIViewController updateView];
return wasHandled;
}
It should be in your AppDelegate, which works for me.
The read permissions have changed.
Refer this :
[https://developers.facebook.com/docs/apps/changelog#v2_0_permissions
][1]
The Error "invalide scope : basic info use public_profile, user friends instead" clearly states that "basic_info" is invalid and it suggests to make use of "public_profile" or "user_friends" as the new scope.
Change it in the following code:
self.loginView.readPermissions = #[#"basic_info"];
TO
self.loginView.readPermissions = #[#"public_profile"];
I am using Flickr in my app. When I click on Flickr button it is redirecting to safari to login with Flickr and Authorization.
Then after successful authorization it is redirecting to my app. But after redirecting I want to call ViewWillAppear. I also set <UIApplicationDelegate> at my view. But it is not calling any of the below methods.
-(void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:YES];
NSLog(#"#####################Flickr Authorized is completed");
}
- (void)UIApplicationWillEnterForeground:(UIApplication *)application
{
NSLog(#"#####################Flickr Authorized is completed at foreground");
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
/*
Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
*/
NSLog(#"#####################Flickr Authorized is completed at become active");
}
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
NSLog(#"######################Flickr Authorized is completed at openURL");
}
-(void)viewWillAppear:(BOOL)animated
{
NSLog(#"#####################Flickr Authorized is completed at viewWillAppear");
[super viewWillAppear:YES];
}
But Below method is calling after redirecting from safari at AppDelegate. I have used Code from SnapAndRun flickr sample.
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
NSLog(#"######################Call Back Here###########");
if ([self flickrRequest].sessionInfo)
{
// already running some other request
NSLog(#"Already running some other request");
}
else {
NSString *token = nil;
NSString *verifier = nil;
BOOL result = OFExtractOAuthCallback(url, [NSURL URLWithString:SRCallbackURLBaseString], &token, &verifier);
if (!result) {
NSLog(#"Cannot obtain token/secret from URL: %#", [url absoluteString]);
return NO;
}
[self flickrRequest].sessionInfo = kGetAccessTokenStep;
[flickrRequest fetchOAuthAccessTokenWithRequestToken:token verifier:verifier];
[activityIndicator startAnimating];
//[viewController.view addSubview:progressView];
}
return YES;
}
I know that we can call my view controllers method here. But Is there any alternative for default delegate method to be called after redirecting at my view itself.
Any Suggestions will be appreciated.
Thanks in Advance.
You can use notificationCenter.
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(someMethod:) name:#"UIApplicationDidBecomeActiveNotification" object:nil];