Custom login with facebook button. Not getting info other than name and UserID - objective-c

I'm trying to get email from my logged in user using Facebook SDK. Here are 2 of my login methods
-(void)loginButtonClicked {
FBSDKLoginManager *login = [[FBSDKLoginManager alloc] init];
[login logInWithReadPermissions: #[#"public_profile", #"email", #"user_friends"]
fromViewController:self
handler:^(FBSDKLoginManagerLoginResult *result, NSError *error) {
if (error) {
NSLog(#"Process error");
} else if (result.isCancelled) {
NSLog(#"Cancelled");
} else {
[self getFBUSerData];
NSLog(#"Logged in");
}
}];
}
- (void) getFBUSerData {
if (FBSDKAccessToken.currentAccessToken != nil) {
[[[FBSDKGraphRequest alloc] initWithGraphPath:#"me" parameters:nil]
startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
if (!error) {
NSLog(#"fetched user:%# and Email : %#", result,result[#"email"]);
}
}];
}
}
The result in the log:
(lldb) po result
{
id = 42357***4506554;
name = "Fname Lname";
}
But no email or friends list. Any help how to get those?

You have to assign the parameters you need to get in getFBUserData().
Something like this:
- (void) getFBUSerData {
if (FBSDKAccessToken.currentAccessToken != nil) {
NSDictionary *dict = [[NSDictionary alloc] initWithObjects:#[#"id, name, first_name, last_name, picture.type(large), email"] forKeys:#[#"fields"]];
[[[FBSDKGraphRequest alloc] initWithGraphPath:#"me" parameters:dict]
startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
if (!error) {
NSLog(#"fetched user:%# and Email : %#", result,result[#"email"]);
}
}]; }
}

Related

The operation couldn’t be completed. (com.facebook.sdk.core error 8.)

Hi i am using ios8 for facebook sharing an image from iphone application to facebook and when i tapped photo button i am getting this error"The operation couldn’t be completed. (com.facebook.sdk error 8.)
this is the code i used to share an image from iphone application to facebook .
- (IBAction)photo:(id)sender
{
FBSDKLoginManager *login = [[FBSDKLoginManager alloc] init];
[login logInWithReadPermissions:#[#"email"] handler:^(FBSDKLoginManagerLoginResult *result, NSError *error)
{
if (error)
{
// Process error
}
else if (result.isCancelled)
{
// Handle cancellations
}
else
{
if ([result.grantedPermissions containsObject:#"email"])
{
//NSLog(#"result is:%#",result);
[self photo];
}
}
}];
}
- (void)photo
{
FBSDKAccessToken *token = [FBSDKAccessToken currentAccessToken];
FBSDKGraphRequestConnection *connection = [[FBSDKGraphRequestConnection alloc] init];
UIImage *image = [UIImage imageNamed:#"TEST.png"];
NSDictionary *parameters = #{
#"message" : #"welcome",
#"picture" : UIImagePNGRepresentation(image),
};
FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:#"me/photos" parameters:parameters tokenString:token.tokenString version:#"nil" HTTPMethod:#"POST"];
[connection addRequest:request completionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
if(error)
NSLog(#"%#", error);
else
NSLog(#"Success");
}];
[connection start];
}
This is the error i am getting
fb sharing[1065:90399] Error Domain=com.facebook.sdk.core Code=8 "The operation couldn’t be completed. (com.facebook.sdk.core error 8.)" UserInfo=0x155c7720 {com.facebook.sdk:FBSDKGraphRequestErrorGraphErrorCode=2500, com.facebook.sdk:FBSDKGraphRequestErrorParsedJSONResponseKey={
body = {
error = {
code = 2500;
"fbtrace_id" = ErePY87sZ34;
message = "Unknown path components: /me/photos";
type = OAuthException;
};
};
code = 400;
}, com.facebook.sdk:FBSDKGraphRequestErrorHTTPStatusCodeKey=400, com.facebook.sdk:FBSDKErrorDeveloperMessageKey=Unknown path components: /me/photos, com.facebook.sdk:FBSDKGraphRequestErrorCategoryKey=0}
Any help is appreciated.

CKDiscoverAllContactsOperation not fetching contacts

I am using CKDiscoverAllContactsOperation but its not working fine for me.
-(void)queryForAllUsers: (void (^)(NSArray *records))completionHandler {
CKDiscoverAllContactsOperation *op = [[CKDiscoverAllContactsOperation alloc] init];
[op setUsesBackgroundSession:YES];
op.queuePriority = NSOperationQueuePriorityNormal;
[op setDiscoverAllContactsCompletionBlock:^(NSArray *userInfos, NSError *error) {
if (error) {
NSLog(#"An error occured in %#: %#", NSStringFromSelector(_cmd), error);
//abort();
} else {
NSLog(#"Number of records in userInfos is: %ld", (unsigned long)[userInfos count]);
dispatch_async(dispatch_get_main_queue(), ^(void){
completionHandler(userInfos);
});
}
}];
[self.container addOperation:op];
}
The container which I'm using is publicCloudDatabase.
The search only works if different users activate the app, approved to be Discoverable and have the other person's iCloud email address in their Contacts.
You should use the discoverAllContactUserInfosWithCompletionHandler on the container like this:
[self.container discoverAllContactUserInfosWithCompletionHandler:^(NSArray *userInfos, NSError *error) {
..
}
this function will only return the contacts that can be linked to an iCloud account and the person has also started up your app.

STTwitter - How can i take just 5 record on Stream API

I used STTwitter in my project and I want 5 tweet on some coordinates. There is question like this but i dont understand.
How can I stop a stream when using STTWitter
I tried like this, but its not stop at 5 records and always return tweet.
-(void)getTwitterActivityWithLocation:(CLLocation *)location withSuccessBlock:(void(^)(NSMutableArray *activities))successBlock
{
STTwitterAPI *twitter = [STTwitterAPI twitterAPIOSWithFirstAccount];
[twitter verifyCredentialsWithSuccessBlock:^(NSString *username) {
NSString *latRectLeft = [[NSString alloc] initWithFormat:#"%f",location.coordinate.latitude];
NSMutableArray *data = [[NSMutableArray alloc] init];
id twitterRequest = [twitter postStatusesFilterUserIDs:nil keywordsToTrack:nil locationBoundingBoxes:#[#"28.9986108",#"41.0377369",#"28.9996108",#"41.0387369"] delimited:#20 stallWarnings:nil progressBlock:^(NSDictionary *tweet) {
if ([data count] > 4) {
[twitterRequest cancel];
successBlock(data);
}
else if (([[tweet valueForKey:#"geo"] valueForKey:#"coordinates"] != nil)) {
if (![tweet isEqual:nil] && [tweet count] > 0)
{
NSLog(#"%#",[tweet valueForKey:#"text"]);
[data addObject:tweet];
}
}
} stallWarningBlock:nil
errorBlock:^(NSError *error) {
NSLog(#"Error");
}];
} errorBlock:^(NSError *error) {
NSLog(#"%#",[error description]);
}];
}
If take [twitterRequest cancel]; line to outside of block, its work. But this time i don't have any tweet record.
How can i solve this ?
Use __block id twitterRequest instead of id twitterRequest.
Example:
STTwitterAPI *twitter = [STTwitterAPI twitterAPIOSWithFirstAccount];
[twitter verifyCredentialsWithSuccessBlock:^(NSString *username) {
NSMutableArray *data = [NSMutableArray array];
__block id twitterRequest = [twitter postStatusesFilterUserIDs:nil
keywordsToTrack:nil
locationBoundingBoxes:#[#"28.9986108",#"41.0377369",#"28.9996108",#"41.0387369"]
delimited:#20
stallWarnings:nil
progressBlock:^(NSDictionary *tweet) {
NSLog(#"-- data count: %lu", (unsigned long)[data count]);
if ([data count] > 4) {
NSLog(#"-- cancel");
[twitterRequest cancel];
} else if (([[tweet valueForKey:#"geo"] valueForKey:#"coordinates"] != nil)) {
if ([tweet count] > 0) {
NSLog(#"%#",[tweet valueForKey:#"text"]);
[data addObject:tweet];
}
}
} stallWarningBlock:nil
errorBlock:^(NSError *error) {
NSLog(#"-- error 2: %#", error);
}];
} errorBlock:^(NSError *error) {
NSLog(#"-- error 1: %#", error);
}];
Logs:
-- data count: 0
Rabbim sana cok sukur (...)
-- data count: 1
+Sevgilin varmı evladım (...)
-- data count: 2
#RussoftMe gt or unf *-*
-- data count: 3
Essege altin semer vursan essek yine essektir...
-- data count: 4
:-) (# Pizza Hut) http://t.co/SZim78OnsU
-- data count: 5
-- cancel

What does the filed "installed" in Facebook graph "me/friends" specify

I am using the code bellow to get the list of all of users friends and check how many of them have installed the app so i can show their scores, and unlock some content for the user.
I can't find solid info about the field installed which seams to be perfect for this case.(If it specifies the user has installed the app which made the request :) )
[FBRequestConnection startWithGraphPath:#"me/friends"
parameters: #{ #"fields" : #"id,installed"}
HTTPMethod:nil
completionHandler:^(FBRequestConnection *connection,
id result,
NSError *error) {
if (!error) {
// Get the result
NSArray *resultData = result[#"data"];
// Check we have data
if ([resultData count] > 0) {
// Loop through the friends returned
for (NSDictionary *friendObject in resultData) {
// Check if devices info available
if (friendObject[#"installed"]) {
//Do some work if user has installed my game
}
}
}
}
}];
-(void)FBFriendList
{
if (!FBSession.activeSession.isOpen)
{
// if the session is closed, then we open it here, and establish a handler for state changes
[FBSession openActiveSessionWithReadPermissions:nil allowLoginUI:YES completionHandler:^(FBSession *session,FBSessionState state, NSError *error)
{
if (error)
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Error" message:error.localizedDescription delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alertView show];
}
else if(session.isOpen)
{
[self FB_Common_Friend];
}
}];
return;
}
}
-(void)FB_Common_Friend
{
FBRequest *request = [FBRequest requestWithGraphPath:#"me/friends" parameters:#{#"fields":#"name,installed,first_name,picture"} HTTPMethod:#"GET"];
[request startWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error)
{
NSLog(#"%#",result);
int count = 0;
NSMutableArray *frnd_arr = [result objectForKey:#"data"];
for (int i = 0; i < [frnd_arr count]; i++)
{
if([[[frnd_arr objectAtIndex:i] objectForKey:#"installed"] boolValue])
{
count++;
}
}
app.fb_frnd_count = count;
}];
}

Method to return block result

- (ACAccount *)accountFacebook{
if (_accountFacebook) {
return _accountFacebook;
}
if (!_accountStoreFacebook) {
_accountStoreFacebook = ACAccountStore.new;
}
ACAccountType *accountTypeFacebook = [self.accountStoreFacebook accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
NSDictionary *options = #{ACFacebookAppIdKey : #"xxxxxxxxx",
ACFacebookAudienceKey : ACFacebookAudienceEveryone,
ACFacebookPermissionsKey : #[#"user_about_me", #"publish_actions"]
};
__block ACAccount *accountFb;
[_accountStoreFacebook requestAccessToAccountsWithType:accountTypeFacebook options:options completion:^(BOOL granted, NSError *error) {
if (granted) {
NSLog(#"Facebook access granted");
accountFb = _accountStoreFacebook.accounts.lastObject;
}else {
NSLog(#"Facebook access denied");
accountFb = nil;}
if (error) {
NSLog(error.localizedDescription);
}
}];
return accountFb;
}
When I run
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
if (appDelegate.accountFacebook) {
NSLog(#"accountFacebook OK");
}else NSLog(#"accountFacebook Not Exists");
appDelegate.accountFacebook return nil always, doesn't wait for block to complete.
What should be changed?
This is an asynchronous call, so the block completes after your method ends. You need to redesign your app to do what it has to do in the completion block. You call appDelegate.accountFacebook and expect to do something if it is not nil. Why not pass this method a completion block that would perform what you want it to perform like so:
typedef void(^HandlerType)(ACAccount* account);
- (void)performForFacebookAccount: (HandlerType) handler{
if (_accountFacebook) {
handler(_accountFacebook);
return;
}
if (!_accountStoreFacebook) {
_accountStoreFacebook = ACAccountStore.new;
}
ACAccountType *accountTypeFacebook = [self.accountStoreFacebook accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
NSDictionary *options = #{ACFacebookAppIdKey : #"xxxxxxxxx",
ACFacebookAudienceKey : ACFacebookAudienceEveryone,
ACFacebookPermissionsKey : #[#"user_about_me", #"publish_actions"]
};
[_accountStoreFacebook requestAccessToAccountsWithType:accountTypeFacebook options:options completion:^(BOOL granted, NSError *error) {
if (granted) {
NSLog(#"Facebook access granted");
_accountFacebook = _accountStoreFacebook.accounts.lastObject;
handler(_accountFacebook);
}else {
NSLog(#"Facebook access denied");
_accountFacebook = nil;}
if (error) {
NSLog(error.localizedDescription);
}
}];
}