I have 3 chained requests: 1.fbRequest and 2.meRequest are identical. 3. thirdPartyIdRequest
meRequest and thirdPartyIdRequest are dependent on fbRequest.
When this runs, every time fbRequest returns a null response dictionary while meRequest(which is an identical call called a second time) and thirdPartyIdRequest return valid responses. I'm not sure why this is happening.
NSDictionary *dictionary = #{#"fields": #"id, first_name, middle_name, last_name, email, picture.type(large)"};
NSDictionary *dictionaryThirdPartyIdRequest = #{};
FBSDKGraphRequest *fbRequest = [[FBSDKGraphRequest alloc] initWithGraphPath:#"me" parameters:dictionary HTTPMethod:#"GET"];
FBSDKGraphRequest *meRequest = [[FBSDKGraphRequest alloc] initWithGraphPath:#"me" parameters:dictionary HTTPMethod:#"GET"];
FBSDKGraphRequest *thirdPartyIdRequest = [[FBSDKGraphRequest alloc]
initWithGraphPath:#"custom_audience_third_party_id"
parameters:dictionaryThirdPartyIdRequest
HTTPMethod:#"GET"];
FBSDKGraphRequestConnection *connection = [[FBSDKGraphRequestConnection alloc] init];
//request me
[connection addRequest:fbRequest
completionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
//TODO: process me information
NSLog(#"result fbRequest %#",(NSDictionary *)result);
} batchEntryName:#"fbRequest"];
//request addRequest:thirdPartyIdRequest ok
[connection addRequest:thirdPartyIdRequest
completionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
//TODO: process like information
NSLog(#"result thirdPartyIdRequest %#",(NSDictionary *)result);
} batchParameters:#{#"depends_on" : #"fbRequest"}];
//request me ok
[connection addRequest:meRequest
completionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
//TODO: process like information
NSLog(#"result meRequest %#",(NSDictionary *)result);
} batchParameters:#{#"depends_on" : #"fbRequest"}];
[connection start];
Related
I don't want to use graph story. But all other methods are rejected by Facebook team with message: Please make sure you are not pre-filling message field.
for example:
NSMutableDictionary *params = [NSMutableDictionary dictionary];
[params setObject:text forKey:#"message"];
[params setObject:#"link" forKey:#"type"];
//[params setObject:#"http://google.com/" forKey:#"link"];
if(photoID) {
[params setObject:photoID forKey:#"object_attachment"];
}
FBRequestConnection *connection = [[FBRequestConnection alloc] init];
NSMutableDictionary* photosParams = [NSMutableDictionary dictionaryWithObjectsAndKeys:
image,#"source",
text,#"message",
nil];
FBRequest *request = [[FBRequest alloc] initWithSession:[FBSession activeSession]
graphPath:#"me/photos"
parameters:photosParams
HTTPMethod:#"POST"];
[connection addRequest:request completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
completionBlock(error);
}];
FBRequest *req = [FBRequest requestForGraphPath:#"me/feed"];
req.graphObject = (id<FBGraphObject>)[NSDictionary dictionaryWithDictionary:params];
[connection addRequest:req
completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
if (!error && result) {
NSLog(#"%#",result);
}
}
];
Please explain what method I should use in this case?
In case if correct behavior is use stories then why other methods are not marked as deprecated?
Thanks.
I have problem publishing a photo from ios app to facebook page as the page's admin. The only thing I can publish as admin is a status message.
Here what I did.
// get access token first
[FBRequestConnection startWithGraphPath:#"/__facebook_page_id__?fields=access_token" completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
// make sure its not nil
if ([result valueForKey:#"access_token"] != nil) {
NSString *accessToken = [result objectForKey:#"access_token"];
NSLog(#"Access token: %#", accessToken);
NSMutableDictionary* params = [[NSMutableDictionary alloc] init];
[params setObject:#"This is some status message" forKey:#"message"];
[params setObject:accessToken forKey:#"access_token"];
[FBRequestConnection startWithGraphPath:#"/__facebook_page_id__/feed" parameters:params HTTPMethod:#"POST" completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
NSLog(#"Result: %#", result);
NSLog(#"Error: %#", error);
}];
}
}];
The above code successfully publish to facebook page as the admin. Since I need to publish a photo, I need to change the grap path to /facebook_page_id/photos.
NSMutableDictionary* params = [[NSMutableDictionary alloc] init];
[params setObject:UIImagePNGRepresentation(self.imagePreview.image) forKey:#"picture"];
[params setObject:#"This is some description" forKey:#"message"];
[params setObject:accessToken forKey:#"access_token"];
[FBRequestConnection startWithGraphPath:[NSString stringWithFormat:#"/__facebook_page_id__/photos"] parameters:params HTTPMethod:#"POST" completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
NSLog(#"Result: %#", result);
NSLog(#"Error: %#", error);
}];
The above code is successfully published, but not as admin. Eventhough I am using the page's access token.
I thought the path fb_page_id/photos was broken, so I tried to use the fb_page_id/feed and send other fields such as link, picture, etc. But still, it posted as the user, not the page's admin.
Please let me know if I am doing wrong.
Some Information:
- Deployment target: 5.1 and above
- Facebook SDK Version: 3.7
Thank you in advance.
I finally found the answer. Just in case somebody having the same problem, here is what I am doing.
You will need a Page's access_token by accessing /page_id?fields=access_token
[FBRequestConnection startWithGraphPath:[NSString stringWithFormat:#"/%#?fields=access_token", FB_PAGE_ID] completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
// if the access_token is not there, the user might not able to post. check the permission
if ([result valueForKey:#"access_token"] != nil) {
NSString *accessToken = [result objectForKey:#"access_token"];
}
}];
After getting the Page's access_token, you need to post the image using REST API. Here I am using AFNetworking, and manually upload the image.
if ([result valueForKey:#"access_token"] != nil) {
NSString *accessToken = [result objectForKey:#"access_token"];
NSURL *url = [NSURL URLWithString:#"https://graph.facebook.com"];
AFHTTPClient *client = [AFHTTPClient clientWithBaseURL:url];
// parameter
NSDictionary *params = #{#"access_token": accessToken, #"message": message};
// image data
NSData *imageData = UIImageJPEGRepresentation(self.imagePreview.image, 1);
// create Request and upload the image
NSMutableURLRequest *request = [client multipartFormRequestWithMethod:#"POST" path:[NSString stringWithFormat:#"/%#/photos/", [defaults stringForKey:#"fb_page_id"]] parameters:params constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithFileData:imageData name:#"source" fileName:accessToken mimeType:#"image/jpeg"];
}];
// publish!
AFJSONRequestOperation *json = [AFJSONRequestOperation JSONRequestOperationWithRequest:request1 success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
// IMAGE PUBLISHED!!!
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
// SOMETHING WRONG HAPPEN
}];
[json start];
}
Don't ask me why I'm using REST API, I tried everything using their SDK, but its always failed.
I hope somebody will find it usefull for this piece of codes.
I am trying to query information about a user using iOS 6's new Facebook integration API. This is the code I'm using, which is basically identical to what they demoed at WWDC:
{
NSDictionary *parameters = #{};
NSURL *url = [NSURL URLWithString:#"https://graph.facebook.com/me"];
SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeFacebook
requestMethod:SLRequestMethodGET
URL:url
parameters:parameters];
request.account = self.account;
[request performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
NSLog(#"Facebook request received, status code %d", urlResponse.statusCode);
NSString *response = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
NSLog(#"Response data: %#", response);
dispatch_async(dispatch_get_main_queue(), ^{
});
}];
}
Problem is I am getting error code 2500 from Facebook: "An active access token must be used to query information about the current user." If I change the query to https://graph.facebook.com/[facebook id] then it works fine. I am assuming the problem is that iOS is passing the access token of the app instead of the user's access token when sending the request via requestForServiceType. I just don't know how to fix it. Obviously anticipating and hardcoding the Facebook IDs of my users is not an option. Any suggestions?
add your active access token in paramete like
NSDictionary *parameters = [NSDictionary dictionaryWithObject:#"PUT_ACCESS_TOKEN_HERE" forKey:#"access_token"];
I faced with the same issue and found the workaround:
NSString *uid = [NSString stringWithFormat:#"%#", [[self.account valueForKey:#"properties"] valueForKey:#"uid"]] ;
NSURL *url = [NSURL URLWithString:[#"https://graph.facebook.com" stringByAppendingPathComponent:uid]];
OK here is how I do this integration with iOS 6 and get what I want from Facebook:
In AppDelegate I do this:
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
return [FBSession.activeSession handleOpenURL:url];
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
[FBSession.activeSession handleDidBecomeActive];
}
- (void)applicationWillTerminate:(UIApplication *)application
{
[FBSession.activeSession close];
}
and in my ViewController where I want to retrieve information about myself or my friends I do this (NOTE: this is a test, so it is a lot of permissions!):
NSArray *permissions =
[NSArray arrayWithObjects:#"email", #"user_location",
#"user_birthday",
#"user_likes", #"user_interests",#"friends_interests",#"friends_birthday",#"friends_location",#"friends_hometown",#"friends_photos",#"friends_status",
#"friends_about_me", #"friends_birthday", #"friends_hometown", #"friends_interests", #"friends_likes", #"friends_location", nil];
[FBSession openActiveSessionWithReadPermissions:permissions
allowLoginUI:YES
completionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
/* handle success + failure in block */
if (status) {
NSLog(#"Facebook Read Permission is successful!");
[self presentPostOptions];
// [self presentPostOptions];
}
}];
Then in "presentPostOptions" I do this (in this example I try to retrieve something from my friend):
- (void)presentPostOptions
{
[[FBRequest requestForMyFriends] startWithCompletionHandler:^(FBRequestConnection *connection, NSDictionary<FBGraphUser> *user, NSError *error)
{
if (!error) {
NSArray *data = [user objectForKey:#"data"];
NSLog(#"%d", [data count]);
for (FBGraphObject<FBGraphUser> *friend in data) {
NSLog(#"%#", [friend first_name]);
NSLog(#"%#", [friend last_name]);
NSLog(#"%#", [friend id]);
//make sure you have FBProfilePictureView outlet in your view
//otherwise skip the profile picture!
self.fbProfilePic.profileID = #"you'r friend's profile.id";
}
}
else
{
NSLog(#"error");
// [self didFailWithError:error];
}
}];
I don't know what else you want to do because in your question you just tried to make a connection but this way you can do what ever you want while you are integrated in iOS 6.
One more thing, make sure about your App Settings over Facebook and the configs over there like enable your app for iOS and the ID for iPhone/iPad. Also the FacebookAppID in your plist.
Let me know if it works out for you,
EDIT: btw my Facebook SDK is 3.1.1.
I had the same error message, I fixed it by saving my account after renewing the credential.
Make sure your (ACAccount *)facebookAccount (or in your case self.account)
object is strong and you set it correctly while getting permissions.
The answer is simple
in viewDidLoad() use:
accountStore= [[ACAccountStore alloc]init];
facebookAccountType= [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
NSDictionary *options= #{
ACFacebookAudienceKey: ACFacebookAudienceEveryone,
ACFacebookAppIdKey: #"<YOUR FACEBOOK APP ID>",
ACFacebookPermissionsKey: #[#"public_profile"]
};
[accountStore requestAccessToAccountsWithType:facebookAccountType options:options completion:^(BOOL granted, NSError *error) {
if (granted) {
NSLog(#"Permission has been granted to the app");
NSArray *accounts= [accountStore accountsWithAccountType:facebookAccountType];
facebookAccount= [accounts firstObject];
[self performSelectorOnMainThread:#selector(facebookProfile) withObject:nil waitUntilDone:NO];
} else {
NSLog(#"Permission denied to the app");
}
}];
And the function-(void)facebookProfile
NSURL *url = [NSURL URLWithString:#"https://graph.facebook.com/me"];
Notice the params you need are added as dictionary
Refer below for complete list
https://developers.facebook.com/docs/graph-api/reference/user
NSDictionary *param=[NSDictionary dictionaryWithObjectsAndKeys:#"picture,id,name",#"fields", nil];
SLRequest *profileInfoRequest= [SLRequest requestForServiceType:SLServiceTypeFacebook requestMethod:SLRequestMethodGET URL:url parameters:param];
profileInfoRequest.account= facebookAccount;
[profileInfoRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
NSLog(#"Facebook status code is : %ld", (long)[urlResponse statusCode]);
if ([urlResponse statusCode]==200) {
NSDictionary *dictionaryData= [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableLeaves error:&error];
} else {
}
}];
}
I'm trying to use this code, and these instructions to do direct messages. Posting a normal tweet works perfectly fine, but when I try to send a direct message I get a 406.
This is the full code:
ACAccountStore *account = [[ACAccountStore alloc] init];
ACAccountType *accountType = [account accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
// Request access from the user to access their Twitter account
[account requestAccessToAccountsWithType:accountType withCompletionHandler:^(BOOL granted, NSError *error) {
// Did user allow us access?
if (granted == YES)
{
// Populate array with all available Twitter accounts
NSArray *arrayOfAccounts = [account accountsWithAccountType:accountType];
// Sanity check
if ([arrayOfAccounts count] > 0)
{
// Keep it simple, use the first account available
ACAccount *acct = [arrayOfAccounts objectAtIndex:0];
// Build a twitter request
NSURL *url = [NSURL URLWithString:#"https://api.twitter.com/1/direct_messages/new.format"];
NSDictionary *p = [NSDictionary dictionaryWithObjectsAndKeys:
#"UserName", #"screen_name",
#"Super awsome direct message", #"text",
nil
];
TWRequest *postRequest = [[TWRequest alloc]
initWithURL: url
parameters: p
requestMethod: TWRequestMethodPOST
];
// Post the request
[postRequest setAccount:acct];
// Block handler to manage the response
[postRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
NSLog(#"Twitter response, HTTP response: %i", [urlResponse statusCode]);
CCLOG(#"Response Data\n%#", responseData);
if (!error)
CCLOG(#"%#", [error description]);
}];
}
}
}];
Try using
https://api.twitter.com/1/direct_messages/new.json
instead of
https://api.twitter.com/1/direct_messages/new.format
I am trying to post a tweet and then getting the latest tweets from the timeline and get the url of the image i just posted.
But somehow its not showing me the recent one. This is the code i am using:
-(void)shareButtonClicked:(id)sender
{
if ([TWTweetComposeViewController canSendTweet])
{
// Create account store, followed by a twitter account identifier
// At this point, twitter is the only account type available
ACAccountStore *account = [[ACAccountStore alloc] init];
ACAccountType *accountType = [account accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
// Request access from the user to access their Twitter account
[account requestAccessToAccountsWithType:accountType withCompletionHandler:^(BOOL granted, NSError *error)
{
// Did user allow us access?
if (granted == YES)
{
// Populate array with all available Twitter accounts
NSArray *arrayOfAccounts = [account accountsWithAccountType:accountType];
// Sanity check
if ([arrayOfAccounts count] > 0)
{
// Keep it simple, use the first account available
ACAccount *acct = [arrayOfAccounts objectAtIndex:0];
// Build a twitter request
UIImage * image = [UIImage imageNamed:#"welcomescreen-header.png"];
NSString * status = #"This is welcome screen.";
NSString * completeHandle = [NSString stringWithFormat:#"%##%#",status,twitterHandle.text];
NSData * data=[completeHandle dataUsingEncoding:NSUTF8StringEncoding];
NSLog(#"Text:%#",completeHandle);
NSData * imageData = (UIImageJPEGRepresentation(photo.image, 90));
TWRequest *postRequest = [[TWRequest alloc] initWithURL:
[NSURL URLWithString:#"https://upload.twitter.com/1/statuses/update_with_media.json"]
parameters:nil requestMethod:TWRequestMethodPOST];
[postRequest addMultiPartData:imageData withName:#"media" type:#"image/jpeg"];
[postRequest addMultiPartData:data withName:#"status" type:#"text"];
// Post the request
[postRequest setAccount:acct];
// Block handler to manage the response
[postRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error)
{
NSLog(#"Twitter Response, HTTP response: %i", [urlResponse statusCode]);
if ([urlResponse statusCode] == 200) {
[self getTheUserTimeLine];
}
}];
}
}
}];
}
}
-(void)getTheUserTimeLine
{
TWRequest *postRequest = [[TWRequest alloc] initWithURL:
[NSURL URLWithString:#"https://api.twitter.com/1/statuses/user_timeline.json?include_entities=true&include_rts=true&screen_name=ashu1702&count=1"]
parameters:nil requestMethod:TWRequestMethodGET];
// Block handler to manage the response
[postRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error)
{
if ([urlResponse statusCode] == 200)
{
// The response from Twitter is in JSON format
// Move the response into a dictionary and print
NSError *error;
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:&error];
NSLog(#"Twitter response: %#", [dict description]);
}
else
NSLog(#"Twitter error, HTTP response: %i", [urlResponse statusCode]);
}];
}
Try using http://twitter.com/statuses/user_timeline/ashu1702.json?count=1 in your browser and see what happens. I misread your code earlier but trying this now it seems okay to me.