I have created a Facebook app for my iOS application in Facebook developer console, but when I use that app id, even though I get the response as success it won't get posted. Please find below my code.(even I get the id for that particular post)
But the point is when I execute same code with my existing Facebook app id(Which is currently using for my live app), this get posted and works fine, so my assumption is, there is something I have to do in Facebook app configuration in the developer console, but I couldn't find. can anyone give me a clue?
Thanks in advance.
Note : I use iOS 6 social framwork
Get User method
- (void)getUserAndShare {
NSLog(#"Getting User");
if(!_accountStore)
_accountStore = [[ACAccountStore alloc] init];
ACAccountType *facebookTypeAccount = [_accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
[_accountStore requestAccessToAccountsWithType:facebookTypeAccount
options:#{ACFacebookAppIdKey: #"xxxxxxxxxxxxxx", ACFacebookPermissionsKey: #[#"email"]}
completion:^(BOOL granted, NSError *error) {
if(granted){
NSArray *accounts = [_accountStore accountsWithAccountType:facebookTypeAccount];
_facebookAccount = [accounts lastObject];
NSLog(#"Success account");
[_accountStore renewCredentialsForAccount:_facebookAccount completion:^(ACAccountCredentialRenewResult renewResult, NSError *error) {
if (error){
}
[self postPhoto:nil];
}];
}
}];
}
Share method
-(IBAction)postPhoto{
if(!_accountStore)
_accountStore = [[ACAccountStore alloc] init];
NSDictionary *parameters = #{#"message": #"this is a resource picture 2", ACFacebookAppIdKey: #"xxxxxxxxxxxxxx"};
SLRequest *facebookRequest = [SLRequest requestForServiceType:SLServiceTypeFacebook
requestMethod:SLRequestMethodPOST
URL:[NSURL URLWithString:#"https://graph.facebook.com/me/photos"]
parameters:parameters];
NSData *data = UIImagePNGRepresentation([UIImage imageNamed:#"sec.jpg"]);
[facebookRequest addMultipartData: data
withName:#"source"
type:#"multipart/form-data"
filename:#"msg.jpg"];
facebookRequest.account = _facebookAccount;
[facebookRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error)
{
if (error) {
}
else
{
NSLog(#"Post successful");
NSString *dataString = [[NSString alloc] initWithData:responseData encoding:NSStringEncodingConversionAllowLossy];
NSLog(#"Response Data: %#", dataString);
}
}];
}
Edit : Is it required to request special permission to use graph API when calling requestAccessToAccountsWithType ?
Finally i got it working, and my assumption was correct :) I have to add new permission when i requesting the access. So as i said it worked in my previous Facebook app ID, thats because i have already granted the permission for that app. Anyway, for those who interest to see what is the solution, find it below,
//Specify App ID and permissions
NSDictionary *options = #{
ACFacebookAppIdKey: #"xxxxxxxxxxxxxxx",
ACFacebookPermissionsKey: #[#"publish_stream", #"publish_actions"],
ACFacebookAudienceKey: ACFacebookAudienceFriends
};
Requested two new permissions publish_stream and publish_actions
I think the issue is with your MIME type, issue in this line:
[facebookRequest addMultipartData: data
withName:#"source"
type:#"multipart/form-data"
filename:#"msg.jpg"];
Change that to:
[facebookRequest addMultipartData:data
withName:#"media"
type:#"image/jpeg"
filename:#"msg.jpg"];
Related
I am trying to post new profile picture according to Twitter's documentation at https://dev.twitter.com/rest/reference/post/account/update_profile_image and here is my code:
NSData *jpeg = UIImageJPEGRepresentation(img, 0.9);
NSString *base64 = [jpeg base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
NSURL *url = [NSURL URLWithString:#"https://api.twitter.com/1.1/account/update_profile_image.json"];
NSDictionary *params = #{#"image" : base64
};
SLRequest *request =
[SLRequest requestForServiceType:SLServiceTypeTwitter
requestMethod:SLRequestMethodPOST
URL:url
parameters:params];
[request setAccount:self.twitterAccount];
[request performRequestWithHandler:^(NSData *responseData,
NSHTTPURLResponse *urlResponse,
NSError *error) {
...
}
But URL response is:
errors = (
{
code = 215;
message = "Bad Authentication data.";
}
);
What am I doing wrong? My ACAccount is valid (I've just tried signing out from and into Twitter in Settings.app).
You code seems fine, but you must be missing something.
Make sure that:
That your Twitter account is connected and is listed in the Settings app Twitter settings. I know you already checked, but it is essential that you verify it. Maybe even restart your phone and make sure your Twitter handle is there afterwards.
That your app has requested and granted permission to
access the account (using the requestAccessToAccountsWithType method). Once permission is granted, you should see your app listed in the Twitter settings (in the Settings app) under "ALLOW THESE APPS TO USE YOUR ACCOUNT".
The Twitter account that you're setting to the SLRequest is valid and is not nil.
Given the conditions above I was abled to modify my profile image successfully just now. Here's a sample code based on the code you've provided:
ACAccountStore *accountStore = [[ACAccountStore alloc] init];
ACAccountType *accountType = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
[accountStore requestAccessToAccountsWithType:accountType options:nil completion:^(BOOL granted, NSError *error)
{
if (granted)
{
NSArray *accounts = [accountStore accountsWithAccountType:accountType];
ACAccount *twitterAccount = [accounts lastObject];
NSData *jpeg = UIImageJPEGRepresentation([UIImage imageNamed:#"photo.jpg"], 0.9);
NSString *base64 = [jpeg base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeTwitter
requestMethod:SLRequestMethodPOST
URL:[NSURL URLWithString:#"https://api.twitter.com/1.1/account/update_profile_image.json"]
parameters:#{#"image" : base64}];
[request setAccount:twitterAccount];
[request performRequestWithHandler:^(NSData *responseData,
NSHTTPURLResponse *urlResponse,
NSError *error)
{
NSLog(#"%#", [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:nil]);
}];
}
}];
I am developing an iOS app in which I have to invite to user Facebook Friends to join the app.
I am using Social Framework to do so. I have successfully posted on FB wall of logged in user but there is a problem in the message which I posted. the message says that "User has shared a link via sample app. Pleas join this awesome app.". I want the message:
"User -> Friend
Please join this awesome app.".
I want it like when it appears when we write on Friend FB Wall.
I have added the "to" parameter in which I am passing the friend's unique FB id. But it's not working.
Below is the code which I am using for this:
[accountStore requestAccessToAccountsWithType:facebookAccountType options:dict completion:^(BOOL granted, NSError *error)
{
if (granted)
{
__block ACAccount * facebookAccount;
NSDictionary *options = #{ ACFacebookAppIdKey: **FBAPPID**, ACFacebookPermissionsKey: permissions, #"ACFacebookAudienceKey": ACFacebookAudienceFriends };
[accountStore requestAccessToAccountsWithType:facebookAccountType options:options completion:^(BOOL granted, NSError *error)
{
if (granted)
{
NSArray *accounts = [accountStore accountsWithAccountType:facebookAccountType];
facebookAccount = [accounts lastObject];
NSURL *postURL = [NSURL URLWithString:#"https://graph.facebook.com/me/feed"];
NSMutableDictionary *postDict = [NSMutableDictionary dictionaryWithObjectsAndKeys:
**FRIENDID**, #"to",**FRIENDNAME**, #"name",#"Testing of app.", #"caption", #"please join this awesome app.", #"message", nil];
SLRequest *postToMyWall = [SLRequest requestForServiceType:SLServiceTypeFacebook requestMethod:SLRequestMethodPOST URL:postURL parameters:postDict];
[postToMyWall setAccount:facebookAccount];
[postToMyWall performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error)
{
if (error) {
}
else
{
NSLog(#"Post successful");
NSString *dataString = [[NSString alloc] initWithData:responseData encoding:NSStringEncodingConversionAllowLossy];
NSLog(#"Response Data: %#", dataString);
[self performSelectorOnMainThread:#selector(postSuccess) withObject:nil waitUntilDone:NO];
}
}];
}
else
{
NSLog(#"rfc");
}
}];
}
else
{
[self performSelectorOnMainThread:#selector(showerrorAlert:) withObject:error waitUntilDone:NO];
}
}];
Please if anyone can give a solution for this. I can use Facebook Framework also but I need to authorize the user and fetch his/her friend list using the credentials stored in iPhone Device Settings. So if you have an alternate solution then please let me know.
I'm using the social framework in iOS 6 to integrate facebook video uploading into my app. However, nothing happens when I run the program, and I instead receive these errors:
The operation couldn’t be completed. (com.apple.accounts error 6.)
"An active access token must be used to query information about the current user.","type":"OAuthException","code":2500}}"
Below is my code, the first half of which I implemented from this tutorial. granted is set to false, causing the first error.
- (void)uploadToFb {
ACAccountStore *accountStore = [[ACAccountStore alloc] init];
ACAccountType *facebookAccountType = [accountStore
accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
// Specify App ID and permissions
NSDictionary *options = #{
ACFacebookAppIdKey: #"2************",
ACFacebookPermissionsKey: #[#"publish_stream", #"publish_actions"],
ACFacebookAudienceKey: ACFacebookAudienceFriends
};
[accountStore requestAccessToAccountsWithType:facebookAccountType
options:options completion:^(BOOL granted, NSError *e) {
if (granted)
{
NSArray *accounts = [accountStore accountsWithAccountType:facebookAccountType];
facebookAccount = [accounts lastObject];
}
else
{
NSLog(#"Error %#", e.localizedDescription); }
}
}];
NSURL *videourl = [NSURL URLWithString:#"https://graph.facebook.com/me/videos"];
NSString *filePath = [outputURL path];
NSURL *pathURL = outputURL;
NSData *videoData = [NSData dataWithContentsOfFile:filePath];
NSDictionary *params = #{
#"title": #"Face Puppets Video",
#"description": #"A funny video I made with the #FacePuppets iOS app."
};
SLRequest *uploadRequest = [SLRequest requestForServiceType:SLServiceTypeFacebook
requestMethod:SLRequestMethodPOST
URL:videourl
parameters:params];
[uploadRequest addMultipartData:videoData
withName:#"source"
type:#"video/quicktime"
filename:[pathURL absoluteString]];
uploadRequest.account = facebookAccount;
[uploadRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
if(error){
NSLog(#"Error %#", error.localizedDescription);
}else
NSLog(#"%#", responseString);
}];
}
Hi Here it is a very nice Sharing example iOS (Wiki) (Sample Project for iOS, ~3 MB) Using this you can share Video in to Facebook, YouTube, Flicker, Vimeo Take a look above link and test this Example.
You need to set You AppId in to ESSViewController.m class In this Method:
- (IBAction)facebook:(id)sender
{
self.fb = [[[ESSFacebook alloc] initWithDelegate:self
appID:#"youAppID"
appSecret:#"secret"] autorelease];
NSURL *url = [[NSBundle mainBundle] URLForResource:#"IMG_1203" withExtension:#"MOV"];
[self.fb uploadVideoAtURL:url];
}
Might Be this is an Old virsion of Facebook but for getting Idea about how to process for share Video from ourApp.
All of your code after NSURL *videourl should be moved to another method. Currently it is being executed while the requestAccessToAccountsWithType: request is in progress so the facebookAccount reference isn't available yet. So, the new method that you create and move that code to should be called from the completion block if granted is true.
Note hat you can't just immediately request publish permissions. You must request read permissions first and then, once it's been granted, request publish permissions.
The problem seems to be with your NSDictionary creation.
NSDictionary *options = #{
ACFacebookAppIdKey: #"2************",
ACFacebookPermissionsKey: #[#"publish_stream", #"publish_actions"],
ACFacebookAudienceKey: ACFacebookAudienceFriends
};
you see you are passing keys first and objects later, where NSDictionary calls +dictionaryWithObjectsAndKeys in this case...
try using the correct format like:
NSDictionary *options = [[NSDictionary alloc] initWithObjectsAndKeys:
#"###############", ACFacebookAppIdKey,
[NSArray arrayWithObject:#"publish_stream"], ACFacebookPermissionsKey,
nil];
this should work.
see the same question here:
Getting "Error Code 8" When Calling [ACAccountStore requestAccessToAccountsWithType] - iOS Facebook
I am trying to upload a video on an iPhone to the user's facebook timeline using Social Framework. I used the snippet given in this answer. Here is my code:
- (void)performActivity {
NSLog(#"sharing on facebook.");
ACAccountStore *accountStore = [[ACAccountStore alloc] init];
ACAccountType *facebookAccountType = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
NSDictionary *options = #{ACFacebookAppIdKey : #"***", ACFacebookPermissionsKey : #[#"email"], ACFacebookAudienceKey:ACFacebookAudienceFriends};
[accountStore requestAccessToAccountsWithType:facebookAccountType options:options completion:^(BOOL granted, NSError *error) {
if (granted) {
NSDictionary *options = #{ACFacebookAppIdKey : #"***", ACFacebookPermissionsKey : #[#"publish_stream"], ACFacebookAudienceKey:ACFacebookAudienceFriends};
[accountStore requestAccessToAccountsWithType:facebookAccountType options:options completion:^(BOOL granted, NSError *error) {
if (granted) {
NSLog(#"Publishing");
ACAccount *fbAccount = [accountStore accountsWithAccountType:facebookAccountType][0];
NSURL *videourl = [NSURL URLWithString:#"https://graph.facebook.com/me/videos"];
NSURL *pathURL = [NSURL fileURLWithPath:[NSString stringWithFormat:#"%#session.mov", NSTemporaryDirectory()]];
NSData *videoData = [NSData dataWithContentsOfFile:[NSString stringWithFormat:#"%#session.mov", NSTemporaryDirectory()]];
NSDictionary *params = #{
#"title": #"Nebuu",
#"description": #"mebuu"
};
SLRequest *uploadRequest = [SLRequest requestForServiceType:SLServiceTypeFacebook
requestMethod:SLRequestMethodPOST
URL:videourl
parameters:params];
[uploadRequest addMultipartData:videoData
withName:#"source"
type:#"video/quicktime"
filename:#"Nebuu Video"];
uploadRequest.account = fbAccount;
[uploadRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
if(error){
NSLog(#"Error %#", error.localizedDescription);
}else
NSLog(#"%#", responseString);
}];
}}];
}}];
}
As you can see, I first requested read permission(email) then, requested publish permission if the first request is granted. The code works fine, all the permissions are granted and the app begins uploading video(I can see this in my network monitoring tool). However, after video is uploaded I get this error:
{
"error": {
"message": "An unexpected error has occurred. Please retry your request later.",
"type": "OAuthException"
}
}
What might be the problem here? I read some other SO posts and seems it is possible thet the error is originated from Facebook's side. Any suggestions?
I'm trying to get the feed of a public Facebook page using the Graph API and I can't figure out how to do so without prompting the user for permissions.
The following code works, but prompts the user for permissions:
- (void)doFacebookAuthCompletion:(void (^)(ACAccount* account))completion
{
ACAccountStore* accountStore = [[ACAccountStore alloc] init];
ACAccountType* accountType = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
NSDictionary* fbOptions = #{
ACFacebookAppIdKey: #"<app-id-key>",
ACFacebookPermissionsKey: #[ #"email" ]
};
[accountStore requestAccessToAccountsWithType:accountType
options:fbOptions
completion:^(BOOL granted, NSError *error) {
if (granted) {
completion([[accountStore accountsWithAccountType:accountType] lastObject]);
} else {
NSLog(#"%#", [error localizedDescription]);
}
}];
}
- (void)updateFeed
{
[self doFacebookAuthCompletion:^(ACAccount* account) {
// What we want to get
NSURL* url = [NSURL URLWithString:#"https://graph.facebook.com/microsoft/feed"];
NSDictionary* parameters = #{ };
// The request
SLRequest* request = [SLRequest requestForServiceType:SLServiceTypeFacebook
requestMethod:SLRequestMethodGET
URL:url
parameters:parameters];
[request setAccount:account];
// Send it
[request performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
if (error) {
NSLog(#"%#", [error localizedDescription]);
} else {
NSString *dataString = [[NSString alloc] initWithData:responseData encoding:NSStringEncodingConversionAllowLossy];
NSLog(#"Response Data: %#", dataString);
}
}];
}];
}
I have even tried using the app token referenced at https://developers.facebook.com/docs/reference/api/page/ that is only safe to use server-side, but still didn't get anywhere. This code:
- (void)doFacebookAuthCompletion:(void (^)(ACAccount* account))completion
{
ACAccountStore* accountStore = [[ACAccountStore alloc] init];
ACAccountType* accountType = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
ACAccount* account = [[ACAccount alloc] initWithAccountType:accountType];
account.credential = [[ACAccountCredential alloc] initWithOAuthToken:#"<app-token>" tokenSecret:#"<app-secret>"];
completion(account);
}
Gives the following output:
Response Data: {"error":{"message":"An access token is required to request this resource.","type":"OAuthException","code":104}}
While the Graph API Explorer works just fine when given the same <app-token> (it doesn't ask for the secret like - initWithOAuthToken:tokenSecret: does).
Even if this approach worked, it would not be safe to release.
I'm stuck now. Help, please?
I can't give a complete answer because I've never used iOS, but on the Facebook side of things, the Graph API won't let you obtain anything without some kind of token. Secure or not, the only way to do that is to use your app id and secret to generate a token which can then be used. You can get one using, for example:
https://graph.facebook.com/oauth/access_token?
client_id=YOUR_APP_ID&client_secret=YOUR_APP_SECRET&
grant_type=client_credentials