iPhone Facebook SDK Error - iphone

I'm trying to figure out what this error means...
I'm trying to get user information via Facebook sdk. All I need is their email and name
Error Domain=facebookErrDomain Code=10000 "The operation couldn’t be completed. (facebookErrDomain error 10000.)" UserInfo=0xde94ad0 {error=<CFBasicHash 0xde7d100 [0x3f616650]>{type = mutable dict, count = 3,
entries =>
2 : <CFString 0xde722a0 [0x3f616650]>{contents = "type"} = <CFString 0xdeba1a0 [0x3f616650]>{contents = "OAuthException"}
3 : <CFString 0xde6ba20 [0x3f616650]>{contents = "message"} = <CFString 0xdeb12a0 [0x3f616650]>{contents = "An active access token must be used to query information about the current user."}
6 : <CFString 0xde74c40 [0x3f616650]>{contents = "code"} = 2500
}
}
My basic code... (below in my viewDidLoad)
facebook = [[Facebook alloc] initWithAppId:#"random#123456" andDelegate:self];
[self login];
(below in my login method)
- (void) login {
NSArray *permissionsArray = [NSArray arrayWithObjects:#"email", nil];
[facebook authorize:permissionsArray];
}
(and my Facebook request methods...)
- (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(#"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"]) {}
};
- (void)request:(FBRequest *)request didFailWithError:(NSError *)error{
NSLog(#"%#",error);
}
I'm really confused to why I get an error and what I need to change or add in order to fix it...
Any ideas?
EDIT: My request code:::
- (IBAction)requestFBFriends:(id)sender {
NSLog(#"HERE");
[facebook requestWithGraphPath:#"me/friends" andDelegate:self];
}

Here's how you can get the name and email...
I didn't test it so if it doesn't work just tell and I'll find out the problem.
The method that sends the request needs to authenticate if you don't have a valid access token
-(void)getUserFBInfo
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if ([defaults objectForKey:#"FBAccessTokenKey"] && [defaults objectForKey:#"FBExpirationDateKey"]) {
self.facebook.accessToken = [defaults objectForKey:#"FBAccessTokenKey"];
self.facebook.expirationDate = [defaults objectForKey:#"FBExpirationDateKey"];
}
if (![self.facebook isSessionValid]) {
NSLog(#"auth");
[self.facebook authorize:[NSArray arrayWithObject:#"email"]];
} else {
[self apiFQLIMe];
}
}
#pragma mark -
#pragma mark FBSessionDelegate
/**
* Called when the user successfully logged in.
*/
- (void)fbDidLogin
{
[self reportAction:#"FB allowed"];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:[self.facebook accessToken] forKey:#"FBAccessTokenKey"];
[defaults setObject:[self.facebook expirationDate] forKey:#"FBExpirationDateKey"];
[defaults synchronize];
[self apiFQLIMe];
}
/**
* Called when the user dismissed the dialog without logging in.
*/
- (void)fbDidNotLogin:(BOOL)cancelled
{
NSLog("did not login");
}
/**
* Called after the access token was extended. If your application has any
* references to the previous access token (for example, if your application
* stores the previous access token in persistent storage), your application
* should overwrite the old access token with the new one in this method.
* See extendAccessToken for more details.
*/
- (void)fbDidExtendToken:(NSString*)accessToken
expiresAt:(NSDate*)expiresAt
{
NSLog(#"token extended");
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:accessToken forKey:#"FBAccessTokenKey"];
[defaults setObject:expiresAt forKey:#"FBExpirationDateKey"];
[defaults synchronize];
}
/**
* Called when the user logged out.
*/
- (void)fbDidLogout
{
NSLog("did logout")
}
/**
* Called when the current session has expired. This might happen when:
* - the access token expired
* - the app has been disabled
* - the user revoked the app's permissions
* - the user changed his or her password
*/
- (void)fbSessionInvalidated
{
[self.facebook authorize:[NSArray arrayWithObject:#"email"]];
}
#pragma mark -
#pragma mark FBRequestDelegate
- (void)apiFQLIMe {
NSMutableDictionary *params = [NSMutableDictionary dictionaryWithObjectsAndKeys:
#"SELECT name, first_name, middle_name, last_name, username, contact_email FROM user WHERE uid=me()", #"query",
nil];
[self.facebook requestWithMethodName:#"fql.query"
andParams:params
andHttpMethod:#"POST"
andDelegate:self];
}
/**
* 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
{
DLog(#"received response");
}
/**
* Called when a request returns and its response has been parsed into
* an object.
*
* The resulting object may be a dictionary, an array or a string, 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(#"%#",result);
// check the log to know how you receive the result
}
/**
* Called when an error prevents the Facebook API request from completing
* successfully.
*/
- (void)request:(FBRequest *)request didFailWithError:(NSError *)error
{
NSLog(#"Err message: %#", [[error userInfo] objectForKey:#"error_msg"]);
NSLog(#"Err code: %d", [error code]);
}
If you have questions ask them in the comments

If you are running the application on Simulator/device Try cleaning the build and fresh install the application. The current error might be due to inactive/revoked access token which is no longer valid to access user data.
Hope it helps!!!

Related

how to find username and key in twitter in ios5.0 iphone

Hi I am successfully integrated twitter in my iphone app with ios5.0.
My question is i have login with two accounts in twitter in ios 5.0 then for tweet from my app how i am know about which user tweeted or user id of Active account
use this methods to get the userinfo
- (void) storeCachedTwitterOAuthData: (NSString *) data forUsername: (NSString *) username
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject: data forKey: #"authData"];
[defaults synchronize];
}
- (NSString *) cachedTwitterOAuthDataForUsername: (NSString *) username
{
return [[NSUserDefaults standardUserDefaults] objectForKey: #"authData"];
}
and also
- (void)userInfoReceived:(NSArray *)userInfo forRequest:(NSString *)connectionIdentifier
{
NSLog(#"User Info Received: %#", userInfo);
}
we will get the username here
in the TWTweetComposeViewController you can get a picker shown in image and you can select one of your account from it.
when you are tweeting directly , with the help of ACAccount you can get it by
+ (void)pritnUserName {
// Create an account store object.
ACAccountStore *accountStore = [[ACAccountStore alloc] init];
// Create an account type that ensures Twitter accounts are retrieved.
ACAccountType *accountType = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
// Request access from the user to use their Twitter accounts.
[accountStore requestAccessToAccountsWithType:accountType withCompletionHandler:^(BOOL granted, NSError *error) {
if(granted) {
// Get the list of Twitter accounts.
NSArray *accountsArray = [accountStore accountsWithAccountType:accountType];
// For the sake of brevity, we'll assume there is only one Twitter account present.
// You would ideally ask the user which account they want to tweet from, if there is more than one Twitter account present.
if ([accountsArray count] > 0) {
// Grab the initial Twitter account to tweet from.
for (int i = 0 ; i < [accountsArray count] ;i++){
ACAccount *twitterAccount = [accountsArray objectAtIndex:i];
NSLog(#"username :%d is %#",i+1,twitterAccount.username);
}
}
}
}];
[accountStore release];
}

Facebook always reauthorizing on each app launch?

I have recently added Facebook integration to my app, and everything works fine except when the user relaunches the app. Each time the app is restarted, Facebook has to go back through its authorization process. This involves switching out of the app to Safari/Facebook, then back to my app. How can I make Facebook save the info, or be able to get blanket permissions for my app so that I doesn't constantly reauthorize?
Here is my code from the applicationDidFinishLaunchingWithOptions: method:
facebook = [[Facebook alloc] initWithAppId:#"203604286395694" andDelegate:self];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if ([defaults objectForKey:#"FBAccessTokenKey"]
&& [defaults objectForKey:#"FBExpirationDateKey"]) {
facebook.accessToken = [defaults objectForKey:#"FBAccessTokenKey"];
facebook.expirationDate = [defaults objectForKey:#"FBExpirationDateKey"];
}
if (![facebook isSessionValid]) {
[facebook authorize:nil];
}
Relevant Facebook delegate methods:
- (void)fbDidLogin {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:[facebook accessToken] forKey:#"FBAccessTokenKey"];
[defaults setObject:[facebook expirationDate] forKey:#"FBExpirationDateKey"];
[defaults synchronize];
}
- (void) requestDialogButtonClicked {
NSMutableDictionary* params =
[NSMutableDictionary dictionaryWithObjectsAndKeys:
#"invites you to check out cool stuff", #"message",
#"Check this out", #"notification_text",
nil];
[facebook dialog:#"apprequests"
andParams:params
andDelegate:self];
}
- (void)dialogDidComplete:(FBDialog *)dialog {
NSLog(#"dialog completed successfully");
}
Are you calling Facebook authorize: somewhere? That's how the fbDidLogin will be triggered. Assuming you are, the behavior indicates that either the token or the date (or both) is nil, or that the date is past expiration (unlikely).
Log the values upon writing and reading the user defaults. My guess is that the authorize either wasn't called, or failed (due to app key or some other problem not shown in the code), leaving the fbDidLogin method uncalled or saving nil values.
That's because you are not asking for permissions when you authorize your app .. "offline_access" provide a long term access token so you will not need to get a new access token every time the user wants to use the Facebook .. so what you need to authorize your app like this
if (![facebook isSessionValid]) {
NSArray *permissions = [[NSArray alloc] initWithObjects:
#"user_likes",
#"read_stream",
#"offline_access"
nil];
[facebook authorize:permissions];
[permissions release];
}
Edit :
Please check the following in your implementation :
1.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];
}
2.In your info.plist add to URL types > URL Schemes > your Facebook app ID with fb prefix (finally your value will be like this for ex. fb313714***).

Facebook Dialog Delegate callback value

Trying to implement Facebook iOS SDK on my iphone App. I am using FBDialog Delegate to allow the user to login and get the response/callback using the delegate.
I would like to grab the code in response_type from the user once the login is successful.
Can anyone help me out here or let me know where to take the guide from.
I have the following code which is implemented :
-(void) login{
self.fb = [[Facebook alloc] initWithAppId:AppID andDelegate:self];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if ([defaults objectForKey:#"FBAccessTokenKey"]
&& [defaults objectForKey:#"FBExpirationDateKey"]) {
self.fb.accessToken = [defaults objectForKey:#"FBAccessTokenKey"];
self.fb.expirationDate = [defaults objectForKey:#"FBExpirationDateKey"];
}
fb.sessionDelegate = self;
NSMutableDictionary *params = [NSMutableDictionary dictionary];
[params setObject:AppID forKey:#"client_id"];
[params setObject:#"code" forKey:#"response_type"];
[fb dialog:#"oauth" andParams:params andDelegate:self];
NSLog(#"Callback: %#", params);
}
In didReceiveResponse, the delegate method called when response is beginning (not yet complete and parsed), get the statusCode from the response object.
- (void)request:(FBRequest *)request didReceiveResponse:(NSURLResponse *)response {
if (200 == [response statusCode]) {
NSLog(#"Success");
}
}
Just handle the delegate methods:
/**
* Your application should implement this delegate to receive session callbacks.
*/
#protocol FBSessionDelegate <NSObject>
#optional
/**
* Called when the user successfully logged in.
*/
- (void)fbDidLogin;
/**
* Called when the user dismissed the dialog without logging in.
*/
- (void)fbDidNotLogin:(BOOL)cancelled;
/**
* Called when the user logged out.
*/
- (void)fbDidLogout;
#end

Facebook SDK + iPhone SDK + SSO

I know that this question has been asked, but I have been reading through threads all day and have applied all of the fixes I could find and am still having an issue.
I am trying to implement Facebook SDK's new SSO feature to allow my app to authenticate with Facebook's app instead of a webView. When my app switches to Facebook's app, it says loading for a few seconds and switches back but the token is still null. I have a feeling it has to do with the URL scheme for my app but I have followed many tutorials and am fairly confident that my current plist values are correct:
Here is the code I have implemented in my appDelegate and viewController files:
appDelegate.h
Facebook *facebook;
appDelegate.m
// 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];
}
SecondViewController.m
-(IBAction) fbButton {
//FACEBOOK INTEGRATION
appDelegate.facebook = [[Facebook alloc] initWithAppId:#"222087841143437" andDelegate:appDelegate];
// Check and retrieve authorization information
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if ([defaults objectForKey:#"FBAccessTokenKey"]
&& [defaults objectForKey:#"FBExpirationDateKey"]) {
appDelegate.facebook.accessToken = [defaults objectForKey:#"FBAccessTokenKey"];
appDelegate.facebook.expirationDate = [defaults objectForKey:#"FBExpirationDateKey"];
}
if (![appDelegate.facebook isSessionValid]) {
appDelegate.facebook.sessionDelegate = self;
[appDelegate.facebook authorize:permissions];
NSLog(#"Token: %#", [defaults objectForKey:#"FBAccessTokenKey"]);
} else {
NSLog(#"Already logged in!");
}
[appDelegate.facebook requestWithGraphPath:#"me" andDelegate:self];
}
- (void)request:(FBRequest *)request didLoad:(id)result {
NSString *nameID = [[NSString alloc] initWithFormat:#"%# (%#)", [result objectForKey:#"name"], [result objectForKey:#"id"]];
NSMutableArray *userData = [[NSMutableArray alloc] initWithObjects:
[NSDictionary dictionaryWithObjectsAndKeys:
[result objectForKey:#"id"], #"id",
nameID, #"name",
[result objectForKey:#"picture"], #"details",
nil], nil];
[userData release];
[nameID release];
NSLog(#"DATA RECEIVED: %#", result);
}
- (void)request:(FBRequest *)request didReceiveResponse:(NSURLResponse *)response {
NSLog(#"request:didReceiveResponse:");
}
- (void)request:(FBRequest *)request didFailWithError:(NSError *)error {
NSLog(#"%#", [error localizedDescription]);
NSLog(#"Err details: %#", [error description]);
};
- (void)fbDidLogin {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:[[appDelegate facebook] accessToken] forKey:#"FBAccessTokenKey"];
[defaults setObject:[[appDelegate facebook] expirationDate] forKey:#"FBExpirationDateKey"];
[defaults synchronize];
NSLog(#"Facebook Logged in!");
[appDelegate.facebook requestWithGraphPath:#"me" andDelegate:self];
}
I know that I call [appDelegate.facebook requestWithGraphPath:#"me" andDelegate:self] twice, but I don't think that's the problem.
Here is a snippet from the console when I press the login button:
2011-10-18 15:37:33.287 Track[2235:707] Token: (null)
2011-10-18 15:37:36.578 Track[2235:707] request:didReceiveResponse:
2011-10-18 15:37:36.584 Track[2235:707] The operation couldn’t be completed. (facebookErrDomain error 10000.)
2011-10-18 15:37:36.586 Track[2235:707] Err details: Error Domain=facebookErrDomain Code=10000 "The operation couldn’t be completed. (facebookErrDomain error 10000.)" UserInfo=0x1ce480 {error=<CFBasicHash 0x1c9560 [0x3e368630]>{type = mutable dict, count = 2,
entries =>
2 : <CFString 0x19a830 [0x3e368630]>{contents = "type"} = <CFString 0x11d230 [0x3e368630]>{contents = "OAuthException"}
3 : <CFString 0x1f5b60 [0x3e368630]>{contents = "message"} = <CFString 0x1f8a70 [0x3e368630]>{contents = "An active access token must be used to query information about the current user."}
I appreciate the help and I really hope I didn't miss a discussion on here that solves this problem. Here are a few (of the many) that I have read through and had no success in finding a solution
How to implement Single Sign On (SSO) using facebook ios sdk for iphone
Facebook SSO and request iOS SDK
Facebook API for iPhone Error: An active access token must be used
Make sure that your Facebook application (the actual application that you created on Facebook) is not in sandbox mode and if it is make sure that the user your Facebook application (the iPhone Facebook client) is currently logged in with is a developer for that application.

How to use Facebook Graph API on iOS properly

I am making an application where I need to invoke requests in multiple view controllers. I don't want the Facebook log in screen to show when the app is launched. It should only open when the user taps a button in another view controller if the user is not logged in, so putting the code in app delegate is not working solution to the problem. And the whole asynchronous process of requesting data in the Facebook API is killing me, I am starting to loose hair.
A class with static methods to get the facebook object and treat it as a singleton.
#import "PBSocialMedia.h"
#import "PBFacebookDelegate.h"
static Facebook *facebook;
static PBFacebookDelegate *facebookDelegate;
#implementation PBSocialMedia
+ (Facebook *)sharedFacebook {
if (facebook == nil) {
facebookDelegate = [[PBFacebookDelegate alloc] init];
facebook = [[Facebook alloc] initWithAppId:#"156687441079334" andDelegate:facebookDelegate];
}
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if ([defaults objectForKey:#"FBAccessTokenKey"]
&& [defaults objectForKey:#"FBExpirationDateKey"]) {
facebook.accessToken = [defaults objectForKey:#"FBAccessTokenKey"];
facebook.expirationDate = [defaults objectForKey:#"FBExpirationDateKey"];
}
NSArray *permissions = [NSArray arrayWithObjects:#"user_photo_video_tags", #"friends_photo_video_tags", #"user_photos", #"friends_photos", nil];
if (![facebook isSessionValid]) {
[facebook authorize:permissions];
} else {
[[NSNotificationCenter defaultCenter] postNotificationName:#"connectedToFacebook" object:self];
}
return facebook;
}
+ (Facebook *)sharedFacebookWithoutAuthorizing {
return facebook;
}
#end
A class that implements the Facebook session delegate used in the class above
#import "PBFacebookDelegate.h"
#import "PBSocialMedia.h"
#implementation PBFacebookDelegate
/**
* Called when the user successfully logged in.
*/
- (void)fbDidLogin {
Facebook *facebook = [PBSocialMedia sharedFacebook];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:[facebook accessToken] forKey:#"FBAccessTokenKey"];
[defaults setObject:[facebook expirationDate] forKey:#"FBExpirationDateKey"];
[defaults synchronize];
[[NSNotificationCenter defaultCenter] postNotificationName:#"connectedToFacebook" object:self];
}
/**
* Called when the user dismissed the dialog without logging in.
*/
- (void)fbDidNotLogin:(BOOL)cancelled {
[[NSNotificationCenter defaultCenter] postNotificationName:#"dismissedFacebookDialog" object:self];
}
/**
* Called when the user logged out.
*/
- (void)fbDidLogout {
[[NSNotificationCenter defaultCenter] postNotificationName:#"disconnectedFromFacebook" object:self];
}
#end
As you see from the two classes above I am making use of notifications so that I know when the user logs in/out of Facebook. The code below is an example of how I am trying to use it:
- (void)viewDidLoad {
[super viewDidLoad];
Facebook *facebook = [PBSocialMedia sharedFacebook];
if (self.canUseGraphAPI) {
[facebook requestWithGraphPath:#"106378916135129/photos" andDelegate:self];
NSLog(#"Can use");
} else {
NSLog(#"Can't use");
}
}
- (void)connectedToFacebook {
self.canUseGraphAPI = YES;
}
- (void)disconnectedFromFacebook {
self.canUseGraphAPI = NO;
}
This is ofcourse NOT working as intended because of the stupid asynchronous request. It will work correct only when the user is logged in. So the first time I open the app it invokes the [PBSocialMedia sharedFacebook]; Then it proceed with the request function AND NOT waiting for the sharedFacebook function to finish. I really hope somebody has encountered this problem before. I want to do requests in different places in my code, but only when the user is logged in, and it need to WAIT while the user logs in before requesting. The code below is not working but it shows what I want!
- (void)viewDidLoad {
[super viewDidLoad];
Facebook *facebook = [PBSocialMedia sharedFacebook];
while (self.canUseGraphAPI) {
// WAITING FOR LOGIN IN
}
[facebook requestWithGraphPath:#"106378916135129/photos" andDelegate:self];
}
- (void)connectedToFacebook {
self.canUseGraphAPI = YES;
}
- (void)disconnectedFromFacebook {
self.canUseGraphAPI = NO;
}
I would start restructuring your code to work by passing in blocks that you want executed upon getting your answer back from FB. This is similar to how you do ajax in JQuery.
- (void)viewDidLoad {
[super viewDidLoad];
Facebook *facebook = [PBSocialMedia sharedFacebook];
[self withGraphAPIDo: ^{
[facebook requestWithGraphPath:#"106378916135129/photos" andDelegate:self];
}];
}