What should I write in place of ACFacebookAppIdKey? - iphone

if ([SLComposeViewController isAvailableForServiceType:SLServiceTypeFacebook]) {
ACAccountStore *accountStore = [[ACAccountStore alloc] init];
ACAccountType *facebookAcc = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
NSDictionary *options = #{ (NSString *)ACFacebookAppIdKey: #"##########",
(NSString *)ACFacebookPermissionsKey: [NSArray arrayWithObject:#"email"],
(NSString *)ACFacebookAudienceKey: ACFacebookAudienceEveryone,
};
[accountStore requestAccessToAccountsWithType:facebookAcc options:options completion:^(BOOL granted, NSError *error){
if (granted) {
ACAccount *facebookAccount = [[accountStore accountsWithAccountType:facebookAcc] firstObject];
NSLog(#"facebook usre name: %#, Full name: %#", facebookAccount.username, facebookAccount);
}
else if (error)
NSLog(#"Error occured:%#", [error localizedDescription]);
}];
}
and I am getting
Error occurred:The Facebook server could not fulfill this access request: invalid app id
what should I write ACFacebookAppIdKey

go to https://developers.facebook.com/. Create new a new app for iOS or choose your app. At the Dashboard menu, you can see your App ID. This App ID you should put to the ACFacebookAppIdKey.

Related

Facebook integration iOS 6 Social/Accounts Frameworks

I want to code a singleton for facebook integration with iOS 6.
I use Social and Accounts Frameworks.
This my FacebookData.h :
#class FacebookData;
#protocol FacebookDataDelegate <NSObject>
#optional
- (void)FacebookDataDidLoadRequest:(NSDictionary *)result;
- (void)FacebookDataDidFailToLoadRequest:(NSError *)error;
#end
#interface FacebookData : NSObject{
NSString *facebookAppID;
ACAccountStore *facebookAccountStore;
ACAccountType *facebookAccountType;
ACAccount *facebookAccount;
BOOL readPermissionsGranted;
BOOL RequestPermissionsGranted;
}
#property (nonatomic) id delegate;
+ (FacebookData*)sharedFacebookData;
- (void)setAppID:(NSString *)appID;
- (NSString *)currentAppID;
- (void)requestPermissions:(NSArray*)Permissions andLoadRequest:(NSString*)theRequest;
- (void)loadRequest:(NSString*)theRequest;
#end
The most important methods of my FacebookData.m :
- (void)requestPermissions:(NSArray*)Permissions andLoadRequest:(NSString*)theRequest{
if(!readPermissionsGranted){
__block NSArray *facebookPermissions = #[#"read_stream", #"email"];
__block NSDictionary *facebookOptions = #{ ACFacebookAppIdKey : facebookAppID,
ACFacebookAudienceKey : ACFacebookAudienceFriends,
ACFacebookPermissionsKey : facebookPermissions};
[facebookAccountStore requestAccessToAccountsWithType:facebookAccountType options:facebookOptions completion:^(BOOL granted, NSError *error)
{
if (granted) {
readPermissionsGranted = YES;
[self requestPermissions:Permissions andLoadRequest:theRequest];
}
// If permission are not granted to read.
if (!granted)
{
NSLog(#"Read permission error: %#", [error localizedDescription]);
[self.delegate FacebookDataDidFailToLoadRequest:error];
readPermissionsGranted = NO;
if ([[error localizedDescription] isEqualToString:#"The operation couldn’t be completed. (com.apple.accounts error 6.)"])
{
[self performSelectorOnMainThread:#selector(showError) withObject:error waitUntilDone:NO];
}
}
}];
}else{
__block NSArray *facebookPermissions = [NSArray arrayWithArray:Permissions];
__block NSDictionary *facebookOptions = #{ ACFacebookAppIdKey : facebookAppID,
ACFacebookAudienceKey : ACFacebookAudienceFriends,
ACFacebookPermissionsKey : facebookPermissions};
[facebookAccountStore requestAccessToAccountsWithType:facebookAccountType options:facebookOptions completion:^(BOOL granted2, NSError *error)
{
if (granted2)
{
RequestPermissionsGranted = YES;
// Create the facebook account
facebookAccount = [[ACAccount alloc] initWithAccountType:facebookAccountType];
NSArray *arrayOfAccounts = [facebookAccountStore accountsWithAccountType:facebookAccountType];
facebookAccount = [arrayOfAccounts lastObject];
[self loadRequest:theRequest];
NSLog(#"Permission granted");
}
if (!granted2)
{
NSLog(#"Request permission error: %#", [error localizedDescription]);
[self.delegate FacebookDataDidFailToLoadRequest:error];
RequestPermissionsGranted = NO;
}
}];
}
}
- (void)loadRequest:(NSString*)theRequest{
__block NSDictionary *result= [[NSDictionary alloc]init];
// Create the URL to the end point
NSURL *theURL = [NSURL URLWithString:theRequest];
// Create the SLReqeust
SLRequest *slRequest = [SLRequest requestForServiceType:SLServiceTypeFacebook requestMethod:SLRequestMethodGET URL:theURL parameters:nil];
// Set the account
[slRequest setAccount:facebookAccount];
// Perform the request
[slRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
if (error)
{
// If there is an error we populate the error string with error
__block NSString *errorString = [NSString stringWithFormat:#"%#", [error localizedDescription]];
NSLog(#"Error: %#", errorString);
[self.delegate FacebookDataDidFailToLoadRequest:error];
} else
{
NSLog(#"HTTP Response: %i", [urlResponse statusCode]);
NSDictionary *jsonResponse = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:nil];
result = jsonResponse;
[self.delegate FacebookDataDidLoadRequest:jsonResponse];
}
}];
}
I use this singleton like this :
FacebookData *data = [FacebookData sharedFacebookData];
data.delegate = self;
[data setAppID:APPIDKEY];
[data requestPermissions:#[#"friends_location"] andLoadRequest:#"https://graph.facebook.com/me/friends?fields=id,name,location"];
This request with this permissions fails whereas the same method with permissions :#[#"email"] and request: https://graph.facebook.com/me/friends works perfectly.
This is the error that I can see in the console :
error = {
code = 2500;
message = "An active access token must be used to query information about the current user.";
type = OAuthException;
};
I can't find where the bug is, I don't know how to use tokens with these frameworks.
Thanks for your help !
IMO your LoadRequest URL is not correct
andLoadRequest:#"https://graph.facebook.com/me/friends?fields=id,name,location"];
SLRequest gives an oauth error even though its real problem with the URL. SLRequest doesn't support "?fields=id,name,location" directly in URL. You need to pass them as parameter in SLRequest
See the example below:
NSString* queryString = NULL;
queryString = [NSString stringWithFormat:#"https://graph.facebook.com/me/friends", nil];
NSURL *friendsRequestURL = [NSURL URLWithString:queryString];
SLRequest *friendsRequest = [SLRequest requestForServiceType:SLServiceTypeFacebook
requestMethod:SLRequestMethodGET URL:friendsRequestURL
parameters:#{#"fields":#"id,name,location"}];
PS: I was facing the similar problem last night and cursing the facebook for given wrong error statement. But finally able to solve it at the end. :)

Twitter integration issue with ACAccountStore (iOS 5)

When I run below code with iOS 6.0, Its working
ACAccountStore *account = [[ACAccountStore alloc] init];
ACAccountType *accountType = [account accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
[account requestAccessToAccountsWithType:accountType options:nil
completion:^(BOOL granted, NSError *error)
{
dispatch_async(dispatch_get_main_queue(), ^{
if (granted)
{
//MY CODE
}
});
}];
and When I run this code with iOS 5.0 or 5.1, It crashes with following output,
*** Terminating app due to uncaught exception 'NSInvalidArgumentException',
reason: '-[ACAccountStore requestAccessToAccountsWithType:options:completion:]:
unrecognized selector sent to instance 0x68a57c0'
Don't know about this weird crash log..
Please tell me, How to get rid of this..
Use below method:
[account requestAccessToAccountsWithType:accountType withCompletionHandler:^(BOOL granted, NSError *error)
{
if (granted) {
//Your code
}
}
}];
This is a bit late, but the reason you're getting that error is that requestAccessToAccountsWithType:options:completion: is new in iOS 6.
In iOS 5 and earlier use the requestAccessToAccountsWithType:withCompletionHandler method instead (this method is deprecated in iOS 6)
See the docs: https://developer.apple.com/library/ios/documentation/Accounts/Reference/ACAccountStoreClassRef/Reference/Reference.html#//apple_ref/doc/uid/TP40011021-CH1-SW12
Try update for this:
ACAccountStore *account = [[ACAccountStore alloc] init];
ACAccountType *accountType = [account accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
// iOS 6
if ( [account respondsToSelector:#selector(requestAccessToAccountsWithType: options: completion:)] )
{
[account requestAccessToAccountsWithType:accountType options:nil
completion:^(BOOL granted, NSError *error)
{
dispatch_async(dispatch_get_main_queue(), ^{
if (granted)
{
//MY CODE
}
});
}];
}
// iOS 5
else if ( [account respondsToSelector:#selector(requestAccessToAccountsWithType: withCompletionHandler:)] )
{
[account requestAccessToAccountsWithType:accountType
withCompletionHandler:^(BOOL granted, NSError *error)
{
dispatch_async(dispatch_get_main_queue(), ^{
if (granted)
{
//MY CODE
}
});
}];
}
else
{
// iOS 4 or less
}
Thanks #CReaTuS, I want to clarify this up to some more bit, Note that in case of iOS6 we make SLRequest where in iOS5 we have to perform request using TWRequest. See below-
ACAccountStore *accountStore = [[ACAccountStore alloc] init];
ACAccountType *accountType = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
if ( [accountStore respondsToSelector:#selector(requestAccessToAccountsWithType: options: completion:)] )
{
[accountStore requestAccessToAccountsWithType:accountType options:nil
completion:^(BOOL granted, NSError *error)
{
dispatch_async(dispatch_get_main_queue(), ^{
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.
ACAccount *twitterAccount = [accountsArray objectAtIndex:0];
NSMutableDictionary *tempDict = [[NSMutableDictionary alloc] init];
[tempDict setValue:#"Twitter_Name" forKey:#"screen_name"];
[tempDict setValue:#"true" forKey:#"follow"];
//Code specific to iOS6 or later
SLRequest *followRequest = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodPOST URL:[NSURL URLWithString:#"https://api.twitter.com/1.1/friendships/create.json"] parameters:tempDict];
// To unfollow hit URL-https://api.twitter.com/1.1/friendships/destroy.json
[followRequest setAccount:twitterAccount];
[followRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
NSString *output = [NSString stringWithFormat:#"HTTP response status: %i", [urlResponse statusCode]];
NSLog(#"%#", output);
if (error) {
dispatch_async(dispatch_get_main_queue(), ^{
//Update UI to show follow request failed
});
}
else {
dispatch_async(dispatch_get_main_queue(), ^{
//Update UI to show success
});
}
}];
}
}
});
}];
}
else if ( [accountStore respondsToSelector:#selector(requestAccessToAccountsWithType: withCompletionHandler:)] )
{
[accountStore requestAccessToAccountsWithType:accountType withCompletionHandler:^(BOOL granted, NSError *error)
{
dispatch_async(dispatch_get_main_queue(), ^{
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.
ACAccount *twitterAccount = [accountsArray objectAtIndex:0];
NSMutableDictionary *tempDict = [[NSMutableDictionary alloc] init];
[tempDict setValue:#"Twitter_Name" forKey:#"screen_name"];
[tempDict setValue:#"true" forKey:#"follow"];
//Code specific to iOS5
TWRequest *followRequest = [[TWRequest alloc] initWithURL:[NSURL URLWithString:#"https://api.twitter.com/1/friendships/create.json"]
parameters:tempDict
requestMethod:TWRequestMethodPOST];
[followRequest setAccount:twitterAccount];
[followRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
NSString *output = [NSString stringWithFormat:#"HTTP response status: %i", [urlResponse statusCode]];
NSLog(#"%#", output);
if (error) {
dispatch_async(dispatch_get_main_queue(), ^{
//Update UI to show follow request failed
});
}
else {
dispatch_async(dispatch_get_main_queue(), ^{
//Update UI to show success
});
}
}];
}
}
});
}];
}
else
{
dispatch_async(dispatch_get_main_queue(), ^{
//Update UI to show follow request completely failed
});
}
Happy coding :)

Get Facebook uid from ACAccountStore in iOS?

Hi i want to get the Facebook user's UID from ACAccountStore in iOS 6
self.accountStore = [[ACAccountStore alloc]init];
ACAccountType *FBaccountType= [self.accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
NSString *key = #"01234567890123";
NSDictionary *dictFB = [NSDictionary dictionaryWithObjectsAndKeys:key,ACFacebookAppIdKey,#[#"email"],ACFacebookPermissionsKey, nil];
[self.accountStore requestAccessToAccountsWithType:FBaccountType options:dictFB completion:
^(BOOL granted, NSError *e) {
if (granted) {
NSArray *accounts = [self.accountStore accountsWithAccountType:FBaccountType];
//it will always be the last object with single sign on
self.facebookAccount = [accounts lastObject];
//i Want to get the Facebook UID and log it here
NSLog(#"facebook account =%#",self.facebookAccount);
} else {
//Fail gracefully...
NSLog(#"error getting permission %#",e);
}
}];
self.facebookAccount has UID, but i am unable to get it...
I wanted to get the UID without using the Facebook API. It can done by using the following method
self.accountStore = [[ACAccountStore alloc]init];
ACAccountType *FBaccountType= [self.accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
NSString *key = #"01234567890123";
NSDictionary *dictFB = [NSDictionary dictionaryWithObjectsAndKeys:key,ACFacebookAppIdKey,#[#"email"],ACFacebookPermissionsKey, nil];
[self.accountStore requestAccessToAccountsWithType:FBaccountType options:dictFB completion:
^(BOOL granted, NSError *e) {
if (granted) {
NSArray *accounts = [self.accountStore accountsWithAccountType:FBaccountType];
//it will always be the last object with single sign on
self.facebookAccount = [accounts lastObject];
//i got the Facebook UID and logged it here (ANSWER)
NSLog(#"facebook account =%#",[self.facebookAccount valueForKeyPath:#"properties.uid"]);
} else {
//Fail gracefully...
NSLog(#"error getting permission %#",e);
}
}];
You need to call the Facebook Graph API; use the SLRequest as follows:
NSUrl requestURL = NSUrl.FromString("https://graph.facebook.com/me");
SLRequest sl = SLRequest.Create(SLServiceKind.Facebook, SLRequestMethod.Get, requestURL, null);
sl.Account = // your ACAccount object here
sl.PerformRequest((data, response, error) => {
if (error == null) {
// success! parse response
}
else {
// handle failure
}
});
That should do it!

SLRequest performRequestWithHandler does not work in ios 6

I am trying to build simple prototype where I post some text to my facebook account. I have read the ios 6 facebook integration documentation and came up with following code. Everything seems to work fine until I hit the last block where I create SLRequest object in method postTextToFacebook and try to execute performRequestWithHandler with handler block. Control never does inside the handler block. I am assuming that performRequestWithHandler call is not successful in this case. Any one have done with successfully? Here is code for your reference.
#import <Social/Social.h>
#import "ViewController.h"
#implementation ViewController
#synthesize facebookAccount;
#synthesize accountStore;
#synthesize textToPost;
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
-(IBAction) postToFacebook:(id)sender
{
self.statusLabel.text = #"Logging in ...";
if(self.accountStore == nil)
{
self.accountStore = [[ACAccountStore alloc] init];
}
ACAccountType *facebookAccountType = [self.accountStore enter code hereaccountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
NSMutableDictionary *myOptions = [NSMutableDictionary dictionaryWithObjectsAndKeys:
#"172197712918906", ACFacebookAppIdKey,
[NSArray arrayWithObjects:#"email", #"user_about_me", #"user_likes", nil], ACFacebookPermissionsKey, ACFacebookAudienceFriends, ACFacebookAudienceKey, nil];
[self.accountStore requestAccessToAccountsWithType:facebookAccountType options:myOptions completion:^(BOOL granted, NSError *error){
__block NSString *statusText;
if(granted)
{
NSArray *accounts = [self.accountStore accountsWithAccountType:facebookAccountType];
self.facebookAccount = [accounts lastObject];
[myOptions setObject:[NSArray arrayWithObjects:#"publish_stream", nil] forKey:ACFacebookPermissionsKey];
[self.accountStore requestAccessToAccountsWithType:facebookAccountType options:myOptions completion:^(BOOL granted, NSError *error) {
__block NSString *statusText1;
if(granted && error == nil)
{
NSArray *accounts = [self.accountStore accountsWithAccountType:facebookAccountType];
self.facebookAccount = [accounts lastObject];
[self postTextToFacebook];
statusText1 = #"Text Posted.";
}
else{
statusText1 = #"Publish Failed.";
}
dispatch_async(dispatch_get_main_queue(), ^{
self.statusLabel.text = statusText1;
});
}];
}
else{
statusText = #"Login Failed.";
NSLog(#"Error = %#",error);
}
}];
}
-(void) postTextToFacebook
{
NSDictionary *parameters = #{#"message":self.textToPost.text};
NSURL *feedURL = [NSURL URLWithString:#"https://graphs.facebook.com/me/feed"];
SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeFacebook requestMethod:SLRequestMethodPOST URL:feedURL parameters:parameters];
request.account = self.facebookAccount;
[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);
//handle errors
if(error == nil)
{
dispatch_async(dispatch_get_main_queue(), ^{
self.statusLabel.text = #"text posted to facebook";
});
}
}];
}
#end
Your url should be
https://graph.facebook.com/me/feed
instead of
https://graphs.facebook.com/me/feed
I was having a same issue and got an NSURLErrorDomain -1003 error on it.

Twitter.framework Image and message issue

I'm using Twitter.framework to post images with message to Twitter. But I see images without message in my Twitter account. I use this code
// 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];
if ([accountsArray count] > 0) {
// Grab the initial Twitter account to tweet from.
ACAccount *twitterAccount = [accountsArray objectAtIndex:0];
UIImage *image =[UIImage imageNamed:#"logo"];
TWRequest *postRequest = [[TWRequest alloc] initWithURL:[NSURL URLWithString:#"https://upload.twitter.com/1/statuses/update_with_media.json"]
parameters:[NSDictionary dictionaryWithObjectsAndKeys:#"Hello. This is a tweet.", #"status", #"My message", #"message", nil] requestMethod:TWRequestMethodPOST];
// "http://api.twitter.com/1/statuses/update.json"
[postRequest addMultiPartData:UIImagePNGRepresentation(image) withName:#"media" type:#"multipart/png"];
// Set the account used to post the tweet.
[postRequest setAccount:twitterAccount];
[postRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
NSString *output = [NSString stringWithFormat:#"HTTP response status: %i", [urlResponse statusCode]];
NSLog(#"output = %#\n\n", output);
}];
}
}
}];
What I see in twitter:
And when I unroll:
But I don't see a message
Try FOllowing code i m using it and its working fine. Hope it will help you as well
-(IBAction)goTweet:(id)sender{
if ([TWTweetComposeViewController canSendTweet])
{
TWTweetComposeViewController *tweetSheet = [[TWTweetComposeViewController alloc] init];
[tweetSheet setInitialText:[NSString stringWithFormat:#"YOUR TWEET HERE"]];
[tweetSheet addImage:[UIImage imageNamed:#"site-logo.jpg"]];
[self presentModalViewController:tweetSheet animated:YES];
[shareLoading stopAnimating];
}
else
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Twitter"
message:#"Sorry, you can't send a Tweet yet, please make sure you are connected to the internet and have at least one Twitter account set up on your phone in Settings --> Twitter."
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alertView show];
}
}
I fount out, how to send text with image:
Add this code
[postRequest addMultiPartData:[#"This photo is taken with my iPhone using nPassword!" dataUsingEncoding:NSUTF8StringEncoding] withName:#"status" type:#"multipart/form-data"];