iOS obj-c: POST data super slow? [duplicate] - ios

Im getting Facebook User Data to auto completing signup textfields.
Problem: I did a test and NSLog returns information quickly, but to update the TextFields.text it's delaying.
Code:
- (IBAction)facebookProfile:(id)sender {
if(!_accountStore)
_accountStore = [[ACAccountStore alloc] init];
ACAccountType *facebookTypeAccount = [_accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
[_accountStore requestAccessToAccountsWithType:facebookTypeAccount
options:#{ACFacebookAppIdKey: #"417425124162461", ACFacebookPermissionsKey: #[#"email"]}
completion:^(BOOL granted, NSError *error) {
if(granted){
NSArray *accounts = [_accountStore accountsWithAccountType:facebookTypeAccount];
_facebookAccount = [accounts lastObject];
NSLog(#"Success");
[self me];
}else{
// ouch
NSLog(#"Fail");
NSLog(#"Error: %#", error);
}
}];
}
- (void)me {
NSURL *meUrl = [NSURL URLWithString:#"https://graph.facebook.com/me"];
SLRequest *meRequest = [SLRequest requestForServiceType:SLServiceTypeFacebook requestMethod:SLRequestMethodGET URL:meUrl parameters:nil];
meRequest.account = _facebookAccount;
[meRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
if (!error) {
NSDictionary *resultsDictionary = [responseData objectFromJSONData];
NSLog(#"%#", [resultsDictionary objectForKey:#"name"]);
// The problem is here. While NSLog runs in seconds showing Facebook User Name, the textfiend.text updates take about 10 seconds longer.
_tfName.text = [resultsDictionary objectForKey:#"name"];
_tfEmail.text = [resultsDictionary objectForKey:#"email"];
_tfGender.text = [resultsDictionary objectForKey:#"gender"];
_tfBirthday.text = [resultsDictionary objectForKey:#"birthday"];
}
}];
}

You need to perform UI updates on the main thread. Your completion handler is being called on a background thread.
[meRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
if (!error) {
NSDictionary *resultsDictionary = [responseData objectFromJSONData];
NSLog(#"%#", [resultsDictionary objectForKey:#"name"]);
// The problem is here. While NSLog runs in seconds showing Facebook User Name, the textfiend.text updates take about 10 seconds longer.
// Ensure UI updated on main queue
dispatch_async(dispatch_get_main_queue(), ^{
_tfName.text = [resultsDictionary objectForKey:#"name"];
_tfEmail.text = [resultsDictionary objectForKey:#"email"];
_tfGender.text = [resultsDictionary objectForKey:#"gender"];
_tfBirthday.text = [resultsDictionary objectForKey:#"birthday"];
});
}
}];

Related

How to get Email param of facebook using SLRequest in iOS Social Framework

I tried the below code for getting email of the person who logged in iOS Settings Facebook.
Please help me how to get email from SLRequest.
- (void) getMyDetails {
if (! _accountStore) {
_accountStore = [[ACAccountStore alloc] init];
}
if (! _facebookAccountType) {
_facebookAccountType = [_accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
}
NSDictionary *options = #{ ACFacebookAppIdKey: FB_APP_ID };
[_accountStore requestAccessToAccountsWithType: _facebookAccountType
options: options
completion: ^(BOOL granted, NSError *error) {
if (granted) {
NSArray *accounts = [_accountStore accountsWithAccountType:_facebookAccountType];
_facebookAccount = [accounts lastObject];
NSURL *url = [NSURL URLWithString:#"https://graph.facebook.com/me"];
SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeFacebook
requestMethod:SLRequestMethodGET
URL:url
parameters:nil];
request.account = _facebookAccount;
[request performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
NSDictionary *responseDictionary = [NSJSONSerialization JSONObjectWithData:responseData
options:NSJSONReadingMutableContainers
error:nil];
NSLog(#"id: %#", responseDictionary[#"id"]);
}];
}
}];
}
Here is the code tested on iOS 8 that returns email. The solution doesn't require Facebook SDK, although the system grants access to Facebook account only if a user logged in with Facebook in Settings app.
// Required includes
#import Accounts;
#import Social;
// Getting email
ACAccountStore *theStore = [ACAccountStore new];
ACAccountType *theFBAccountType = [theStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
NSDictionary *theOptions = #{
ACFacebookAppIdKey : #"YOUR_APP_ID",
ACFacebookPermissionsKey : #[#"email"]
};
[theStore requestAccessToAccountsWithType:theFBAccountType options:theOptions completion:^(BOOL granted, NSError *error) {
if (granted) {
ACAccount *theFBAccount = [theStore accountsWithAccountType:theFBAccountType].lastObject;
SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeFacebook
requestMethod:SLRequestMethodGET
URL:[NSURL URLWithString:#"https://graph.facebook.com/me"]
parameters:#{#"fields" : #[#"email"]}];
request.account = theFBAccount;
[request performRequestWithHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error == nil && ((NSHTTPURLResponse *)response).statusCode == 200) {
NSError *deserializationError;
NSDictionary *userData = [NSJSONSerialization JSONObjectWithData:data options:0 error:&deserializationError];
if (userData != nil && deserializationError == nil) {
NSString *email = userData[#"email"];
NSLog(#"%#", email);
}
}
}];
}
}];
You can get email id by below mentioned way.
Call Facebook graph API by the help of access token that you got from Account store
And yes, to get email id from Facebook, you need to provide "email" permission while requesting access token, without the permission you won't be able to get email parameter
Here is my code
NSString *FB_EncodedToken = [APP_CONSTANT.facebookToken stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
AFHTTPRequestOperationManager *opearation = [AFHTTPRequestOperationManager manager];
opearation.requestSerializer = [AFHTTPRequestSerializer serializer];
opearation.responseSerializer = [AFJSONResponseSerializer serializer];
NSString *strUrl = [NSString stringWithFormat:#"https://graph.facebook.com/me?"];
NSDictionary *param = [NSDictionary dictionaryWithObjectsAndKeys:FB_EncodedToken,#"access_token", nil];
[opearation GET:strUrl parameters:param success:^(AFHTTPRequestOperation *operation, id responseObject) {
DLogs(#"Description %#",responseObject);
//Lets pasre the JSON data fetched from facebook
[self parseUserDetail:responseObject];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
DLogs(#"Error description %#",error.description);
self.completionHandler(error);
}];
Then parse the data
-(void)parseUserDetail:(NSDictionary *)dict
{
FBProfileBO *profile = [[FBProfileBO alloc] init];
profile.userFirstName = [dict objectForKey:#"first_name"];
profile.userLastName = [dict objectForKey:#"last_name"];
profile.userEmail = [dict objectForKey:#"email"];
profile.userName = [dict objectForKey:#"name"];
profile.userDOB = [dict objectForKey:#""];
profile.facebookId = [dict objectForKey:#"id"];
//Call back methods
self.completionHandler(profile);
profile = nil;
}

User friends are showing empty list in Facebook Sdk Graph Api v2

I have updated the version for the graph Api to v2. Now the issue I am facing is,when I executed the following code It shows me empty array :
FBRequest *friendsRequest = [FBRequest requestForMyFriends];
[friendsRequest startWithCompletionHandler:^(FBRequestConnection *connection, NSDictionary<FBGraphUser> *result, NSError *error) {
NSArray *friendshipid;
NSString *username;
if (!error) {
NSLog(#"friends = %#", [result description]);
}
if (completion) {
completion(friendshipid, username, error);
}
}];
}
}
I got to know that facebook sdk had some changes for the user friends and now It has to take the permission for the user_friends, but I have no idea where to make changes to ask for Permission for user_friends
You can use the given code snippet. Here, i have used the Classes of Social Framework to get the Facebook friends. Hope it will work for you.
- (void) connectWithFacebookFriends
{
ACAccountStore *accountStore = [[ACAccountStore alloc] init];
ACAccountType *accountTypeFacebook = [accountStore accountTypeWithAccountTypeIdentifier:
ACAccountTypeIdentifierFacebook];
NSDictionary *options = #{ACFacebookAppIdKey: kFaceBookId,
ACFacebookPermissionsKey: #[#"user_friends"],
ACFacebookAudienceKey: ACFacebookAudienceFriends
};
[accountStore requestAccessToAccountsWithType:accountTypeFacebook
options:options
completion:^(BOOL granted, NSError *error)
{
if(granted) {
NSArray *accounts = [accountStore
accountsWithAccountType:accountTypeFacebook];
ACAccount* facebookAccount = [accounts lastObject];
NSString *acessToken = [NSString stringWithFormat:#"%#",facebookAccount.credential.oauthToken];
NSDictionary *parameters = #{#"access_token": acessToken};
NSURL *feedURL = [NSURL URLWithString:#"https://graph.facebook.com/me/friends"];
SLRequest *feedRequest =
[SLRequest requestForServiceType:SLServiceTypeFacebook
requestMethod:SLRequestMethodGET
URL:feedURL
parameters:parameters];
[feedRequest performRequestWithHandler:^(NSData *responseData,
NSHTTPURLResponse *urlResponse, NSError *error)
{
NSString * str = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
DLog(#"%#",str);
NSLog(#"Request failed, %#", [urlResponse description]);
}];
} else {
NSLog(#"Access Denied");
NSLog(#"[%#]",[error localizedDescription]);
}
}];
}

Login and list Facebook friends using Social Framework

Could someone give me some pointers on how to integrate this? my goal is to get list of friends who installed my app (fb app). initially I need to login user to my app first and list friends who have / haven't installed the app.
PS : I don't want to use Facebook SDK. I had nightmares in the past due to facebook did countless time changing the sdk.
===========
UPDATE
I've successfully login and list my facebook friends. But now problem to list my friend who have the app and list picture as well. I tried this :
URL : https://graph.facebook.com/me/friends?friends?fields=id,name,installed,picture
which give me OAuthException : An active access token must be used to query information about the current user. problem.
I tried also in API Graph, it works without mentioned error.
if I try only me/friends works perfectly, it will list down all my friends.
First import Social, Account, SystemConfiguration framework in your project.
Then use this code on your.m file
-(void)facebook
{
self.accountStore = [[ACAccountStore alloc]init];
ACAccountType *FBaccountType= [self.accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
NSString *key = #"XXXXXXXXXXXXX";//get your key form creating new app in facebook app section
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];
ACAccountCredential *facebookCredential = [self.facebookAccount credential];
NSString *accessToken = [facebookCredential oauthToken];
NSLog(#"Facebook Access Token: %#", accessToken);
NSLog(#"facebook account =%#",self.facebookAccount);
[self get];
[self getFBFriends];
isFacebookAvailable = 1;
} else
{
//Fail gracefully...
NSLog(#"error getting permission yupeeeeeee %#",e);
sleep(10);
NSLog(#"awake from sleep");
isFacebookAvailable = 0;
}
}];
}
-(void)get
{
NSURL *requestURL = [NSURL URLWithString:#"https://graph.facebook.com/me"];
SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeFacebook requestMethod:SLRequestMethodGET URL:requestURL parameters:nil];
request.account = self.facebookAccount;
[request performRequestWithHandler:^(NSData *data, NSHTTPURLResponse *response, NSError *error) {
if(!error)
{
NSDictionary *list =[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
NSLog(#"Dictionary contains: %#", list );
fbID = [NSString stringWithFormat:#"%#", [list objectForKey:#"id"]];
globalFBID = fbID;
gender = [NSString stringWithFormat:#"%#", [list objectForKey:#"gender"]];
playerGender = [NSString stringWithFormat:#"%#", gender];
NSLog(#"Gender : %#", playerGender);
self.globalmailID = [NSString stringWithFormat:#"%#",[list objectForKey:#"email"]];
NSLog(#"global mail ID : %#",globalmailID);
fbname = [NSString stringWithFormat:#"%#",[list objectForKey:#"name"]];
NSLog(#"faceboooookkkk name %#",fbname);
if([list objectForKey:#"error"]!=nil)
{
[self attemptRenewCredentials];
}
dispatch_async(dispatch_get_main_queue(),^{
});
}
else
{
//handle error gracefully
NSLog(#"error from get%#",error);
//attempt to revalidate credentials
}
}];
self.accountStore = [[ACAccountStore alloc]init];
ACAccountType *FBaccountType= [self.accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
NSString *key = #"451805654875339";
NSDictionary *dictFB = [NSDictionary dictionaryWithObjectsAndKeys:key,ACFacebookAppIdKey,#[#"friends_videos"],ACFacebookPermissionsKey, nil];
[self.accountStore requestAccessToAccountsWithType:FBaccountType options:dictFB completion:
^(BOOL granted, NSError *e) {}];
}
-(void)getFBFriends
{
NSURL *requestURL = [NSURL URLWithString:#"https://graph.facebook.com/me/friends"];
SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeFacebook requestMethod:SLRequestMethodGET URL:requestURL parameters:nil];
request.account = self.facebookAccount;
[request performRequestWithHandler:^(NSData *data, NSHTTPURLResponse *response, NSError *error) {
if(!error)
{
NSDictionary *friendslist =[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
for (id facebookFriendList in [friendslist objectForKey:#"data"])
{
NSDictionary *friendList = (NSDictionary *)facebookFriendList;
[facebookFriendIDArray addObject:[friendList objectForKey:#"id"]];
}
if([friendslist objectForKey:#"error"]!=nil)
{
[self attemptRenewCredentials];
}
dispatch_async(dispatch_get_main_queue(),^{
});
}
else
{
//handle error gracefully
NSLog(#"error from get%#",error);
//attempt to revalidate credentials
}
}];
self.accountStore = [[ACAccountStore alloc]init];
ACAccountType *FBaccountType= [self.accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
NSString *key = #"451805654875339";
NSDictionary *dictFB = [NSDictionary dictionaryWithObjectsAndKeys:key,ACFacebookAppIdKey,#[#"friends_videos"],ACFacebookPermissionsKey, nil];
[self.accountStore requestAccessToAccountsWithType:FBaccountType options:dictFB completion:
^(BOOL granted, NSError *e) {}];
}
-(void)accountChanged:(NSNotification *)notification
{
[self attemptRenewCredentials];
}
-(void)attemptRenewCredentials
{
[self.accountStore renewCredentialsForAccount:(ACAccount *)self.facebookAccount completion:^(ACAccountCredentialRenewResult renewResult, NSError *error){
if(!error)
{
switch (renewResult) {
case ACAccountCredentialRenewResultRenewed:
NSLog(#"Good to go");
[self get];
break;
case ACAccountCredentialRenewResultRejected:
NSLog(#"User declined permission");
break;
case ACAccountCredentialRenewResultFailed:
NSLog(#"non-user-initiated cancel, you may attempt to retry");
break;
default:
break;
}
}
else{
//handle error gracefully
NSLog(#"error from renew credentials%#",error);
}
}];
}
I finally got it, apparently you cannot append inside the URL. you need to pass the fields in parameter inside SLRequest
NSURL *requestURL = [NSURL URLWithString:#"https://graph.facebook.com/me/friends"];
NSDictionary *param=[NSDictionary dictionaryWithObjectsAndKeys:#"picture,id,name,installed",#"fields", nil];
SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeFacebook
requestMethod:SLRequestMethodGET
URL:requestURL
parameters:param];

Reading information from Facebook

I am a beginner in iOS. I am trying to create an app and referred a lot of posts in the stackoverflow and some other sites and i used the following code to access the Facebook account.
AppDelegate *appDelegate = [[UIApplication sharedApplication]delegate];
if (appDelegate.session.isOpen) {
[appDelegate.session closeAndClearTokenInformation];
} else {
if (appDelegate.session.state != FBSessionStateCreated) {
appDelegate.session = [[FBSession alloc] init];
}
[appDelegate.session openWithCompletionHandler:^(FBSession *session,
FBSessionState status,
NSError *error) {
}];
}
After that in a function i used the following code to access the Facebook details of the user.
if (FBSession.activeSession.isOpen) {
[[FBRequest requestForMe] startWithCompletionHandler:
^(FBRequestConnection *connection,
NSDictionary<FBGraphUser> *user,
NSError *error) {
if (!error) {
_FirstName.text = user.first_name;
regisrationdetails.fbid = user.id;
_LastName.text=user.last_name;
_EmailAddress.text=user.email;
NSArray *locationarray=[[NSArray alloc]initWithObjects:user.location,nil];
_City.text=[locationarray objectAtIndex:1];
NSLog(#"%#",user.first_name);
}
}];
No error is being shown but i can't get the information from Facebook the the text fields.If anyone good at this knows how to access the information then please help me out.
- (IBAction)getMeButtonTapped:(id)sender {
if(!_accountStore)
_accountStore = [[ACAccountStore alloc] init];
ACAccountType *facebookTypeAccount = [_accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
[_accountStore requestAccessToAccountsWithType:facebookTypeAccount
options:#{ACFacebookAppIdKey: #"571438296262222", ACFacebookPermissionsKey: #[#"email"]}
completion:^(BOOL granted, NSError *error) {
if(granted){
NSArray *accounts = [_accountStore accountsWithAccountType:facebookTypeAccount];
_facebookAccount = [accounts lastObject];
NSLog(#"Success");
[self me];
}else{
// ouch
NSLog(#"Fail");
NSLog(#"Error: %#", [error localizedDescription]);
}
}];
}
- (void)me
{
NSURL *meurl = [NSURL URLWithString:#"https://graph.facebook.com/me"];
SLRequest *merequest = [SLRequest requestForServiceType:SLServiceTypeFacebook
requestMethod:SLRequestMethodGET
URL:meurl
parameters:nil];
merequest.account = _facebookAccount;
[merequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
NSString *meDataString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
NSLog(#"%#", meDataString);
}];}
Use this hope this helps you, also add social framework as well as Accounts Framework
try this..
- (void)fetchFacebookUserInfo {
if ( FBSession.activeSession.isOpen) {
[FBRequestConnection startForMeWithCompletionHandler:^(FBRequestConnection *connection,
id<FBGraphUser> user,
NSError *error) {
if (!error) {
NSString *name = user.name;
NSString *userName = user.username;
NSString *firstName = user.first_name;
NSString *lastName = user.last_name;
NSString *email1 = [user objectForKey:#"email"];
NSString *birthday1 = user.birthday;
NSString *locale = [user objectForKey:#"locale"];
NSString *location = [user.location objectForKey:#"name"];
}
}];
}

Getting error code 32 from Twitter while fetching users details using Social Framework & SLRequest

- (IBAction)loginToTwitter:(id)sender {
self.accountStore = [[ACAccountStore alloc] init];
ACAccountType *accountType = [self.accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
[self.accountStore requestAccessToAccountsWithType:accountType options:nil completion:^(BOOL granted, NSError *error) {
if(granted) {
NSArray *accounts = [self.accountStore accountsWithAccountType:accountType];
if ([accounts count] > 0) {
ACAccount *twitterAccount = [accounts objectAtIndex:0];
NSLog(#"User Name: %#",twitterAccount.username);
NSLog(#"Account Type: %#",twitterAccount.accountType);
NSArray *userID = [[accounts valueForKey:#"properties"] valueForKey:#"user_id"];
NSString *url_users_show = [NSString stringWithFormat:#"https://api.twitter.com/1.1/users/show.json?user_id=%#",[userID objectAtIndex:0]];
SLRequest *getRequest = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodGET URL:[NSURL URLWithString:url_users_show] parameters:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:#"%#",[userID objectAtIndex:0]] forKey:#"user_id"]];
getRequest.account = twitterAccount;
[getRequest performRequestWithHandler:^(NSData *responseData,
NSHTTPURLResponse *urlResponse, NSError *error)
{
if(responseData) {
NSLog(#"Twitter HTTP response: %i", [urlResponse statusCode]);
NSDictionary *responseDictionary = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableContainers error:&error];
if(responseDictionary) {
NSLog(#"Response: %#", responseDictionary);
if ([responseDictionary objectForKey:#"errors"]) {
dispatch_async(dispatch_get_main_queue(), ^{
[self showAlert: #"Twitter": [[[responseDictionary objectForKey:#"errors"] objectAtIndex:0] objectForKey:#"message"]];
});
}
}
} else {
// responseDictionary is nil
dispatch_async(dispatch_get_main_queue(), ^{
[self showAlert: #"Twitter": #"Unable to authenticate you"];
});
}
}];
}
} else {
//Failed
NSLog(#"error getting permission %#",error);
dispatch_async(dispatch_get_main_queue(), ^{
[self showAlert: #"No Twitter Account Detected": #"Please go into your device's settings menu to add your Twitter account."];
});
}
}];
}
Above is my code and below is the output on my console.
Output:
Twitter HTTP response: 401
Response: {
errors = (
{
code = 32;
message = "Could not authenticate you";
}
);
}
I want to fetch users data like First Name, Last Name, Profile Picture, Login ID from Twitter.
Thanks in advance...

Resources