I've integrated with Facebook so that I can, among other things, post statuses to my feed. I based some of my code off of the publish to feed developer tutorial. When running the following Graph API request from my iOS application the completion block of the request is never called and no error appears in the XCode debug log.
[FBRequestConnection
startWithGraphPath:#"me/feed"
parameters:params
HTTPMethod:#"POST"
completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
if (error) {
DLog(#"error: domain = %#, code = %d", error.domain, error.code);
} else {
DLog(#"Posted action, id: %#", result[#"id"]);
}
}];
I have two convenience functions that perform checks against the current activeSession before executing this request. They look like this:
+ (BOOL)facebookSessionIsOpen {
return (FBSession.activeSession.isOpen);
}
+ (BOOL)facebookSessionHasPublishPermissions {
if ([FBSession.activeSession.permissions indexOfObject:#"publish_actions"] == NSNotFound ||
[FBSession.activeSession.permissions indexOfObject:#"publish_stream"] == NSNotFound ||
[FBSession.activeSession.permissions indexOfObject:#"manage_friendlists"] == NSNotFound) {
return NO;
} else {
return YES;
}
}
Both of these functions return YES indicating an active session with the necessary publishing permission. What's more confusing is that I can pull the user's profile without issue after performing the same checks successfully (granted publishing permissions are not required to pull the profile) using the following code:
[FBRequestConnection
startWithGraphPath:#"me"
parameters:[NSDictionary dictionaryWithObject:#"picture,id,birthday,email,location,hometown" forKey:#"fields"]
HTTPMethod:#"GET"
completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
NSDictionary* resultDict = (NSDictionary*)result;
NSString* emailAddress = resultDict[#"email"];
NSString* location = resultDict[#"location"][#"name"];
NSString* birthday = resultDict[#"birthday"];
NSString* homeTown = resultDict[#"hometown"][#"name"];
...
}];
Any suggestions on how to debug this issue?
Turns out the issue was a threading one. The Facebook iOS SDK doesn't seem to like to execute a FBRequest on a different thread from the one that you called openActiveSessionWithReadPermissions on and promptly deadlocks. It turns out I was running the postStatus request in a separate thread like so:
dispatch_queue_t some_queue = dispatch_queue_create("some.queue.name", NULL);
dispatch_async(some_queue, ^{
[FacebookHelper postStatusToFacebookUserWall:newStatus withImage:imageData];
}];
Make sure your openActiveSessionWithReadPermissions and any FBRequest permutations all happen on the same thread, or you'll likely run into these silent failures.
Related
Has anyone implemented facebook Notification API in iOS??
I have used it in android its working but for iOS its giving OAuthException.
Its in Beta could be a bug in Notification API??
I am using facebook SDK for iOS v 3.18.
Code
NSString *notification_Id = [NSString stringWithFormat:#"/%#/notifications", friend];
NSString *app_token = #"APP_ID|APP_SECRET";
NSDictionary *dict_notification = #{#"href": url,
#"template": #"You have been invited to Choozr Poll by",
#"access_token" : app_token};
/* make the API call */
[FBRequestConnection startWithGraphPath:notification_Id
parameters:dict_notification
HTTPMethod:#"POST"
completionHandler:^(
FBRequestConnection *connection,
id result,
NSError *error
) {
/* handle the result */
if (error) {
NSLog(#"error: %#", error);
}
NSLog(#"%#",result);
}];
Response from facebook
{ > error = { > code = 15; > message = "(#15) This method must be called with an app access_token."; > type = OAuthException; > }
You need to implement the Facebook notification API on your server side code, not the client.
We are trying to create Facebook test users using the Facebook iOS SDK 3.14.1 according to their website: https://developers.facebook.com/docs/graph-api/reference/v2.0/app/accounts/test-users
Here is our code:
NSString *fbAccessToken = [NSString stringWithFormat:#"%#",FBSession.activeSession.accessTokenData];
NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:
#"true", #"installed",
fbAccessToken, #"owner_access_token",
nil
];
NSString *path = [NSString stringWithFormat:#"/%#/accounts/test-users", kFacebookID];
/* make the API call */
[FBRequestConnection startWithGraphPath:path ///{app-id}/accounts/test-users"
parameters:nil
HTTPMethod:#"POST"
completionHandler:^(
FBRequestConnection *connection,
id result,
NSError *error
)
{
if (result && !error)
{
NSLog(#"Test-User created successfully: %#", result);
}
else
{
NSLog(#"Error creating test-user: %#", error);
NSLog(#"Result Error: %#", result);
}
}];
When we run it we receive the following error:
error = {
code = 15;
message = "(#15) This method must be called with an app access_token.";
type = OAuthException;
};
We have also tried without the parameter owner_access_token but the same error occurs.
How can we create Facebook Test users programmatically using the Facebook iOS SDK?
Solution:
Instead of using the active session access token in you should use the App Token.
Just replace FBSession.activeSession.accessTokenData with your App Token.
The App Token can be found here:
https://developers.facebook.com/tools/accesstoken/
As per WizKid comment above, this is for testing purposes only.
I m using Facebook SDK v3.11.1.
In my app, after i open a session, i look for some information view FQL query:
[FBRequestConnection startWithGraphPath:#"/fql"
parameters:#"SELECT uid, name, can_post FROM user WHERE uid = me()"
HTTPMethod:#"GET"
completionHandler:^(FBRequestConnection *connection,
id result,
NSError *error) {
if (error) {
NSLog(#"Error: %#", [error localizedDescription]);
} else {
NSString* resultString = [NSString stringWithFormat:#"NativeBridge.resultForCallback(mycallback, '%#');", result];
[self.myWebView stringByEvaluatingJavaScriptFromString:resultString];
}
}];
}
I try to invoke javaScript method in my UIWebView.
The object NativeBridge and the method resultForCallback are fine (checked in chrome devTool).
My problem is the parameter result which is actually FBGraphObject.
I try to send to javaScript parameter like:
{
data = (
{
"can_post" = 1;
name = "firstName lastName";
uid = 000000000000000;
}
);
}
But the javascript refuse to get this parameter.
Any help will be great!
Thanks in advance.
In ios 6 using facebook ios sdk 3.5 how can I send a graph request so it's synchornious? Or atleast how can I synchronize the response method?
I'm using the following method:
+(void)hasUserGrantedPermissions:(NSArray*)permissions
andBlock:(void (^)(bool))repeatBlock{
[[FBRequest requestForGraphPath:#"/me/permissions"]
startWithCompletionHandler:^(FBRequestConnection *connection, FBGraphObject* result, NSError *error) {
if([[result valueForKey:#"data"] count] <1){
repeatBlock(false);
}
FBGraphObject* grantedPerms = [[result valueForKey:#"data"] objectAtIndex:0];
for(NSString* requestedPerm in permissions){
if (! [grantedPerms valueForKey:requestedPerm]){
repeatBlock(true);
}
}
}];
}
How can I alter the method or request in such a way that it becomes synchronous?
Thank you
I'm new to facebook SDK.
Last time I used facebook IOS SDK 3.0 and posting image through graph API. It is working but now it's not. I upgraded to 3.1 but still, it always return HTTP ERROR 200. Is there anyone can help me?
this is the code
- (void) facebookPostPhoto:(UIImage *)photo withMessage:(NSString *)msg withOkAction:(SEL)okAction andNGAction:(SEL)ngAction withTarget:(id)target {
ok = okAction;
ng = ngAction;
curView = target;
NSMutableDictionary *params;
params = [NSMutableDictionary dictionaryWithObjectsAndKeys:
UIImageJPEGRepresentation(photo, 90), #"source",
msg, #"message",
nil];
if ([FBSession.activeSession.permissions indexOfObject:FacebookPermission_3] == NSNotFound) {
NSLog(#"permission not found");
// No permissions found in session, ask for it
[FBSession.activeSession reauthorizeWithPublishPermissions:[NSArray arrayWithObjects:FacebookPermission_1, FacebookPermission_3, nil] defaultAudience:FBSessionDefaultAudienceFriends completionHandler:^(FBSession *session, NSError *error)
{
// If permissions granted, publish the story
if (!error) [self initPostFacebookWithParams:params];
}];
} else {
[self initPostFacebookWithParams:params];
} }
- (void)initPostFacebookWithParams:(NSMutableDictionary *)params {
[FBRequestConnection startWithGraphPath:#"me/photos" parameters:params HTTPMethod:#"POST" completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
NSLog(#"ERROR : %#", error.localizedDescription);
if (!error) {
NSLog(#"Facebook Post Success..");
if (ok && curView) {
[curView performSelector:ok];
}
} else {
NSLog(#"Facebook Post Failed..");
if (ng && curView) {
[curView performSelector:ng withObject:error];
}
}
}]; }
I appreciate your fast response and help! Thank You!!
I think it's either facebook upload's server is down or there is a new policy about image size. When I down sized the image to 320x320 it returns no error, sometimes error too by the way.
So for those who see this question, try to resize your image to smaller size.