I read facebook docs and find some ways to login facebook. How to login with Embedded WebView Login Dialog with FB sdk 3.5.x
Link facebook docs here
It may be usefull to you and few delegate methods of facebook are also shown below
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
return [facebook handleOpenURL:url];
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
// Although the SDK attempts to refresh its access tokens when it makes API calls,
// it's a good practice to refresh the access token also when the app becomes active.
// This gives apps that seldom make api calls a higher chance of having a non expired
// access token.
[[self facebook] extendAccessTokenIfNeeded];
}
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
NSLog(#"url->%#",url);
return [self.facebook handleOpenURL:url];
}
- (BOOL)isFBLoggedIn
{
return [facebook isSessionValid];
}
- (void)login
{
if (![facebook isSessionValid])
{
[facebook authorize:[[NSArray alloc] initWithObjects:#"offline_access", nil]];
} else
{
[facebook logout];
[facebook authorize:[[NSArray alloc] initWithObjects:#"offline_access", nil]];
}
}
- (void)fetchFBFriends
{
[facebook requestWithGraphPath:#"me/friends" andDelegate:self];
}
-(void)fetchFbDetails
{
[facebook requestWithGraphPath:#"me" andDelegate:self];
}
- (void)storeAuthData:(NSString *)accessToken expiresAt:(NSDate *)expiresAt
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:accessToken forKey:#"FBAccessTokenKey"];
[defaults setObject:expiresAt forKey:#"FBExpirationDateKey"];
[defaults synchronize];
}
NSString *strRes = [NSString stringWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:#"https://graph.facebook.com/me?fields=name,username,email,gender,birthday,hometown,picture&access_token=%#",facebook.accessToken]] usedEncoding:&encoding error:&error];
NSMutableDictionary *dirFbDetails = [[NSMutableDictionary alloc] initWithDictionary:[strRes JSONValue]];
-(void)fbDidExtendToken:(NSString *)accessToken expiresAt:(NSDate *)expiresAt
{
NSLog(#"token extended");
[self storeAuthData:accessToken expiresAt:expiresAt];
}
-(void)doFaceBookLogin
{
[self.facebook authorize:[NSArray arrayWithObjects:#"friends_birthday",#"user_birthday",#"email",#"publish_stream",nil]];
}
#pragma mark - FBRequestDelegate Methods
- (void)request:(FBRequest *)request didReceiveResponse:(NSURLResponse *)response
{
}
- (void)request:(FBRequest *)request didLoad:(id)result
{
}
- (void)request:(FBRequest *)request didFailWithError:(NSError *)error
{
NSLog(#"Err message: %#", [[error userInfo] objectForKey:#"error_msg"]);
NSLog(#"Err code: %d", [error code]);
}
Related
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/
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'm using STTwitterto interface with Twitter in an iOS app I'm changing for someone. When I call the twitter authorization page for the first time with the following code:
- (void)newUser
{
[[NetworkManager sharedInstance] resetTwitterAPI];
[[[NetworkManager sharedInstance] twitterAPI] postTokenRequest:^(NSURL *url, NSString *oauthToken) {
[[UIApplication sharedApplication] openURL:url];
} oauthCallback:#"tweepr://twitter_access_token" errorBlock:^(NSError *error) {
NSLog(#"Error %s", __PRETTY_FUNCTION__);
}];
}
* Which, in turn, calls this:
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
if (![[url scheme] isEqualToString:#"tweepr"]) {
return NO;
}
NSDictionary *d = [self parametersDictionaryFromQueryString:[url query]];
NSString *token = d[#"oauth_token"];
NSString *verifier = d[#"oauth_verifier"];
[[UserLoadingRoutine sharedRoutine] setOAuthToken:token verifier:verifier];
return YES;
}
* Which finally calls this:
- (void)setOAuthToken:(NSString *)token verifier:(NSString *)verifier
{
[[[NetworkManager sharedInstance] twitterAPI] postAccessTokenRequestWithPIN:verifier successBlock:^(NSString *oauthToken, NSString *oauthTokenSecret, NSString *userID, NSString *screenName) {
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
dict[#"nickname"] = screenName;
dict[#"token"] = oauthToken;
dict[#"secret"] = oauthTokenSecret;
dict[#"user_id"] = userID;
self.userDict = dict;
NSMutableArray *users = [self.availableUsers mutableCopy];
if (![users containsObject:dict]) {
[users addObject:dict];
}
self.availableUsers = [users copy];
[[NSUserDefaults standardUserDefaults] setObject:self.availableUsers forKey:#"availableUsers"];
[[NSUserDefaults standardUserDefaults] synchronize];
[self selectUserWithIdentifier:dict[#"nickname"]];
} errorBlock:^(NSError *error) {
NSLog(#"Error");
}];
}
The twitter authorization page, the first time it comes up, has login and password fields to fill in as shown below at This Screenshot. If I bring the authorization page up again via the above code to authorize under a different user, This Screenshot appears and I need to sign out on the top. Is there a way to do this progmatically?
Append &force_login=1 to the URL string in -[STTwitterOAuth postTokenRequest:oauthCallback:errorBlock:].
Let me know if it works.
I am a newbie for StackOverflow and iOS. I am trying get user informations like groups, books etc. and I need use the Facebook graph API for that. To use graph API you must use an access token. I read article on the Facebook developer page about this topic and I wrote some code, but it didn't work. Can you help me? Is my code right or shall I use another way?
my .h file:
#import <UIKit/UIKit.h>
#import "FBConnect.h"
#interface FirstViewController : UIViewController <FBSessionDelegate,FBLoginDialogDelegate,FBRequestDelegate>{
Facebook *face;
}
#property(nonatomic,retain)Facebook *face;
-(IBAction)facePushed:(id)sender;
-(IBAction)logoutPushed:(id)sender;
my .m file:
-(IBAction)facePushed:(id)sender{
NSLog(#"FacePushed Began");
face=[[Facebook alloc]initWithAppId:#"313714785358239" andDelegate:self];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if ([defaults objectForKey:#"FBAccessTokenKey"]
&& [defaults objectForKey:#"FBExpirationDateKey"]) {
face.accessToken = [defaults objectForKey:#"FBAccessTokenKey"];
face.expirationDate = [defaults objectForKey:#"FBExpirationDateKey"];
}
if (![face isSessionValid]) {
[face authorize:nil ];
}
else {
NSLog(#"Session is valid");
}
NSLog(#"FacePushed End");
}
}
- (void)fbDidLogin {
NSLog(#"aslan");
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:[face accessToken] forKey:#"FBAccessTokenKey"];
[defaults setObject:[face expirationDate] forKey:#"FBExpirationDateKey"];
NSLog(#"%#", [face accessToken]);
[defaults synchronize];
}
- (void)fbDialogLogin:(NSString *)token expirationDate:(NSDate *)expirationDate {
NSLog(#"%#",token);
}
you have to check the following in your implementation :
you need to get a permissions before you authorize your app
if (![face isSessionValid])
{
NSArray *permissions = [[NSArray alloc] initWithObjects:
#"user_likes",
#"read_stream",
#"publish_stream",
nil];
[face authorize:permissions];
[permissions release];
}
you need to add the following functions in your application delegate(the facebook object here is your instance value of FaceBook Class).
// Pre 4.2 support
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
return [facebook handleOpenURL:url];
}
// For 4.2+ support
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
return [facebook handleOpenURL:url];
}
in your info.plist add to URL types > URL Schemes > your facebok app ID with fb prefix (finally your value will be like this fb313714785358239).
Good Luck.
I am using the Facebook iOS SDK for iPhone. I initialize the Facebook instance
facebook = [[Facebook alloc] initWithAppId:kAppId];
And then I do login:
[facebook authorize:permissions delegate:self];
After I logged in to Facebook I am doing the following to get the user profile information:
[facebook requestWithGraphPath:#"me" andDelegate:self];
NSMutableData *response = [fbRequest responseText];
unsigned char *firstBuffer = [response mutableBytes];
NSLog(#"Got Facebook Profile: : \"%s\"\n", (char *)firstBuffer);
But I get the following on my console:
Got Facebook Profile: "(null)"
What am I doing wrong, also I believe that Facebook response is a json string and I am looking to get a hold of that json string.
I thought may be I should make it a wiki and tell the people how I am doing it. because lot of people are facing similar problem.
The first thing that I did was.
In Facebook.m class I added the following statement in the following method
(void)authorizeWithFBAppAuth:(BOOL)tryFBAppAuth
safariAuth:(BOOL)trySafariAuth
trySafariAuth = NO;
This prevents a safari page to get open for the facebook login, but it pops up a screen in app itself. Then i created a helper class for Facebook, the header file code is here.
#import <UIKit/UIKit.h>
#import "FBConnect.h"
#interface FaceBookHelper : UIViewController
<FBRequestDelegate,
FBDialogDelegate,
FBSessionDelegate>{
Facebook *facebook;
NSArray *permissions;
}
#property(readonly) Facebook *facebook;
- (void)login;
-(void)getUserInfo:(id)sender;
- (void)getUserFriendList:(id)sender;
-(void)postToFriendsWall;
The .m file.
static NSString* kAppId = #"xxx";
#define ACCESS_TOKEN_KEY #"fb_access_token"
#define EXPIRATION_DATE_KEY #"fb_expiration_date"
#implementation FaceBookHelper
#synthesize facebook;
//////////////////////////////////////////////////////////////////////////////////////////////////
// UIViewController
/**
* initialization
*/
- (id)init {
if (self = [super init]) {
facebook = [[Facebook alloc] initWithAppId:kAppId];
facebook.sessionDelegate = self;
permissions = [[NSArray arrayWithObjects:
#"email", #"read_stream", #"user_birthday",
#"user_about_me", #"publish_stream", #"offline_access", nil] retain];
[self login];
}
return self;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// NSObject
- (void)dealloc {
[facebook release];
[permissions release];
[super dealloc];
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// private
/**
* Login.
*/
- (void)login {
// only authorize if the access token isn't valid
// if it *is* valid, no need to authenticate. just move on
if (![facebook isSessionValid]) {
[facebook authorize:permissions delegate:self];
}
}
/**
* This is the place only where you will get the hold on the accessToken
*
**/
- (void)fbDidLogin {
NSLog(#"Did Log In");
NSLog(#"Access Token is %#", facebook.accessToken );
NSLog(#"Expiration Date is %#", facebook.expirationDate );
// Store the value in the NSUserDefaults
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:facebook.accessToken forKey:ACCESS_TOKEN_KEY];
[defaults setObject:facebook.expirationDate forKey:EXPIRATION_DATE_KEY];
[defaults synchronize];
// This is the best place to login because here we know that user has already logged in
[self getUserInfo:self];
//[self getUserFriendList:self];
//[self postToFriendsWall];
}
- (void)fbDidNotLogin:(BOOL)cancelled {
NSLog(#"Failed to log in");
}
- (void)getUserInfo:(id)sender {
[facebook requestWithGraphPath:#"me" andDelegate:self];
}
- (void)getUserFriendList:(id)sender {
[facebook requestWithGraphPath:#"me/friends" andDelegate:self];
}
////////////////////////////////////////////////////////////////////////////////
// FBRequestDelegate
/**
* Called when the Facebook API request has returned a response. This callback
* gives you access to the raw response. It's called before
* (void)request:(FBRequest *)request didLoad:(id)result,
* which is passed the parsed response object.
*/
- (void)request:(FBRequest *)request didReceiveResponse:(NSURLResponse *)response {
NSLog(#"Inside didReceiveResponse: received response");
//NSLog(#"Status Code #", [response statusCode]);
NSLog(#"URL #", [response URL]);
}
/**
* Called when a request returns and its response has been parsed into
* an object. The resulting object may be a dictionary, an array, a string,
* or a number, depending on the format of the API response. If you need access
* to the raw response, use:
*
* (void)request:(FBRequest *)request
* didReceiveResponse:(NSURLResponse *)response
*/
- (void)request:(FBRequest *)request didLoad:(id)result {
NSLog(#"Inside didLoad");
if ([result isKindOfClass:[NSArray class]]) {
result = [result objectAtIndex:0];
}
// When we ask for user infor this will happen.
if ([result isKindOfClass:[NSDictionary class]]){
//NSDictionary *hash = result;
NSLog(#"Birthday: %#", [result objectForKey:#"birthday"]);
NSLog(#"Name: %#", [result objectForKey:#"name"]);
}
if ([result isKindOfClass:[NSData class]])
{
NSLog(#"Profile Picture");
//[profilePicture release];
//profilePicture = [[UIImage alloc] initWithData: result];
}
NSLog(#"request returns %#",result);
//if ([result objectForKey:#"owner"]) {}
};
/**
* Called when an error prevents the Facebook API request from completing
* successfully.
*/
- (void)request:(FBRequest *)request didFailWithError:(NSError *)error {
//[self.label setText:[error localizedDescription]];
};
////////////////////////////////////////////////////////////////////////////////
// FBDialogDelegate
/**
* Called when a UIServer Dialog successfully return.
*/
- (void)dialogDidComplete:(FBDialog *)dialog {
//[self.label setText:#"publish successfully"];
}
#end
Thanks for this hint Yogesh!
In facebook.m you can also set the safariAuth param in the authorize method.
- (void)authorize:(NSArray *)permissions
delegate:(id<FBSessionDelegate>)delegate {
...
[self authorizeWithFBAppAuth:YES safariAuth:NO];
}