How to Retrieve Facebook Response Using Facebook iOS Sdk

How to retrieve Facebook response using Facebook iOS SDK

I thought may be I should make it a wiki and tell the people how I am doing it. because lot of people are facing similar problem.

The first thing that I did was.

In Facebook.m class I added the following statement in the following method

(void)authorizeWithFBAppAuth:(BOOL)tryFBAppAuth
safariAuth:(BOOL)trySafariAuth
trySafariAuth = NO;

This prevents a safari page to get open for the facebook login, but it pops up a screen in app itself. Then i created a helper class for Facebook, the header file code is here.

#import <UIKit/UIKit.h>
#import "FBConnect.h"

@interface FaceBookHelper : UIViewController
<FBRequestDelegate,
FBDialogDelegate,
FBSessionDelegate>{

Facebook *facebook;
NSArray *permissions;
}

@property(readonly) Facebook *facebook;

- (void)login;

-(void)getUserInfo:(id)sender;

- (void)getUserFriendList:(id)sender;

-(void)postToFriendsWall;

The .m file.

static NSString* kAppId = @"xxx";
#define ACCESS_TOKEN_KEY @"fb_access_token"
#define EXPIRATION_DATE_KEY @"fb_expiration_date"

@implementation FaceBookHelper

@synthesize facebook;

//////////////////////////////////////////////////////////////////////////////////////////////////
// UIViewController

/**
* initialization
*/
- (id)init {
if (self = [super init]) {
facebook = [[Facebook alloc] initWithAppId:kAppId];
facebook.sessionDelegate = self;
permissions = [[NSArray arrayWithObjects:
@"email", @"read_stream", @"user_birthday",
@"user_about_me", @"publish_stream", @"offline_access", nil] retain];
[self login];
}
return self;

}

///////////////////////////////////////////////////////////////////////////////////////////////////
// NSObject

- (void)dealloc {
[facebook release];
[permissions release];
[super dealloc];
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// private

/**
* Login.
*/
- (void)login {
// only authorize if the access token isn't valid
// if it *is* valid, no need to authenticate. just move on
if (![facebook isSessionValid]) {
[facebook authorize:permissions delegate:self];
}
}

/**
* This is the place only where you will get the hold on the accessToken
*
**/
- (void)fbDidLogin {
NSLog(@"Did Log In");
NSLog(@"Access Token is %@", facebook.accessToken );
NSLog(@"Expiration Date is %@", facebook.expirationDate );
// Store the value in the NSUserDefaults
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:facebook.accessToken forKey:ACCESS_TOKEN_KEY];
[defaults setObject:facebook.expirationDate forKey:EXPIRATION_DATE_KEY];
[defaults synchronize];
// This is the best place to login because here we know that user has already logged in
[self getUserInfo:self];
//[self getUserFriendList:self];
//[self postToFriendsWall];
}

- (void)fbDidNotLogin:(BOOL)cancelled {
NSLog(@"Failed to log in");
}

- (void)getUserInfo:(id)sender {
[facebook requestWithGraphPath:@"me" andDelegate:self];
}

- (void)getUserFriendList:(id)sender {
[facebook requestWithGraphPath:@"me/friends" andDelegate:self];
}
////////////////////////////////////////////////////////////////////////////////
// FBRequestDelegate

/**
* Called when the Facebook API request has returned a response. This callback
* gives you access to the raw response. It's called before
* (void)request:(FBRequest *)request didLoad:(id)result,
* which is passed the parsed response object.
*/
- (void)request:(FBRequest *)request didReceiveResponse:(NSURLResponse *)response {
NSLog(@"Inside didReceiveResponse: received response");
//NSLog(@"Status Code @", [response statusCode]);
NSLog(@"URL @", [response URL]);
}

/**
* Called when a request returns and its response has been parsed into
* an object. The resulting object may be a dictionary, an array, a string,
* or a number, depending on the format of the API response. If you need access
* to the raw response, use:
*
* (void)request:(FBRequest *)request
* didReceiveResponse:(NSURLResponse *)response
*/
- (void)request:(FBRequest *)request didLoad:(id)result {
NSLog(@"Inside didLoad");
if ([result isKindOfClass:[NSArray class]]) {
result = [result objectAtIndex:0];
}
// When we ask for user infor this will happen.
if ([result isKindOfClass:[NSDictionary class]]){
//NSDictionary *hash = result;
NSLog(@"Birthday: %@", [result objectForKey:@"birthday"]);
NSLog(@"Name: %@", [result objectForKey:@"name"]);
}
if ([result isKindOfClass:[NSData class]])
{
NSLog(@"Profile Picture");
//[profilePicture release];
//profilePicture = [[UIImage alloc] initWithData: result];
}
NSLog(@"request returns %@",result);
//if ([result objectForKey:@"owner"]) {}

};

/**
* Called when an error prevents the Facebook API request from completing
* successfully.
*/
- (void)request:(FBRequest *)request didFailWithError:(NSError *)error {
//[self.label setText:[error localizedDescription]];
};

////////////////////////////////////////////////////////////////////////////////
// FBDialogDelegate

/**
* Called when a UIServer Dialog successfully return.
*/
- (void)dialogDidComplete:(FBDialog *)dialog {
//[self.label setText:@"publish successfully"];
}

@end

Swift version of Facebook iOS SDK and how to access data in Response

I faced this problem today as well. I got the user id and name inside MyProfileRequest

struct Response: GraphResponseProtocol {
init(rawResponse: Any?) {
// Decode JSON from rawResponse into other properties here.
guard let response = rawResponse as? Dictionary<String, Any> else {
return
}

if let name = response["name"],
let id = response["id"] {

print(name)
print(id)
}
}
}

EDIT: I redesigned my code like this to use the values in .success(let response) case

struct Response: GraphResponseProtocol {

var name: String?
var id: String?
var gender: String?
var email: String?
var profilePictureUrl: String?

init(rawResponse: Any?) {
// Decode JSON from rawResponse into other properties here.
guard let response = rawResponse as? Dictionary<String, Any> else {
return
}

if let name = response["name"] as? String {
self.name = name
}

if let id = response["id"] as? String {
self.id = id
}

if let gender = response["gender"] as? String {
self.gender = gender
}

if let email = response["email"] as? String {
self.email = email
}

if let picture = response["picture"] as? Dictionary<String, Any> {

if let data = picture["data"] as? Dictionary<String, Any> {
if let url = data["url"] as? String {
self.profilePictureUrl = url
}
}
}
}
}

And in the success case you can get the values like this:

let connection = GraphRequestConnection()
connection.add(MyProfileRequest()) { response, result in
switch result {
case .success(let response):
print("My facebook id is \(response.id!)") //Make sure to safely unwrap these :)
print("My name is \(response.name!)")
case .failed(let error):
print("Custom Graph Request Failed: \(error)")
}
}
connection.start()

how to get user data from Facebook SDK on iOS

Your GraphRequest was incorrect. If you want to take user data, graphPathe should be "me" and you should request paramter in order to get relationship state and other information. And also you need to request public profile in LogInWithReadPermissons, So In read permisson :-

    let fbLoginManager : FBSDKLoginManager = FBSDKLoginManager()
fbLoginManager.loginBehavior = FBSDKLoginBehavior.Web
fbLoginManager.logInWithReadPermissions(["public_profile","email"], fromViewController: self) { (result, error) -> Void in
if error != nil {
print(error.localizedDescription)
self.dismissViewControllerAnimated(true, completion: nil)
} else if result.isCancelled {
print("Cancelled")
self.dismissViewControllerAnimated(true, completion: nil)
} else {

}
}

And When retrieving information :-

   FBSDKGraphRequest(graphPath: "me", parameters: ["fields": "id, name, first_name, relationship_status"]).startWithCompletionHandler({ (connection, result, error) -> Void in
if (error == nil){
let fbDetails = result as! NSDictionary
print(fbDetails)
}
})

By the way if you want marital status you should use graphPath as "me" not "/{user-id}/family". You can use that for get The person's family relationships.

IOS Facebook SDK: login doesn't return email despite permissions granted

Facebook Graph API broke it’s backward compatibility (when used in a default fashion) Since Graph-API version 2.4 (Pod Version 4.4.0).

FB Graph-API 2.4 does NOT return all default fields for user

To resolve this you can either use explicitly graph version 2.3:

[[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:nil tokenString:[FBSDKAccessToken currentAccessToken].tokenString version:@"v2.3" HTTPMethod:nil]

in which case FB assures v2.3 will be available at least 2 years from now.
https://developers.facebook.com/docs/graph-api/overview:

The Graph API has multiple versions available to access at any one
time. Each version contains a set ofcore fields and edge operations.
We make a guarantee that those core APIs will be available and
un-modified in that version for at least 2 years from release. The
platform changelog can tell you which versions are currently
available.

OR

you can use new Graph-API (v2.4) in by asking for specific fields you are interested in:

[[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:@{@"fields" : @"email,name"}]

How can we get Facebook Page List in iOS SDK

Have you requested the manage_pages permission from the respective user through the login dialog? The code you posted look ok IMHO, I think you see an empty result because of the missing permission.

[Facebook-iOS-SDK 4.0]How to get user email address from FBSDKProfile

To fetch email you need to utilize the graph API, specifically providing the parameters field populated with the fields you want. Take a look at Facebook's Graph API explore tool, which can help to figure out the queries. https://developers.facebook.com/tools/explorer

The code that worked for me to fetch email is the following, which assumes you are already logged in:

    NSMutableDictionary* parameters = [NSMutableDictionary dictionary];
[parameters setValue:@"id,name,email" forKey:@"fields"];

[[[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:parameters]
startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection,
id result, NSError *error) {
aHandler(result, error);
}];

Get email and name Facebook SDK v4.4.0 Swift

I've used fields in android, so I figured to try it in iOS as well, and it works.

let req = FBSDKGraphRequest(graphPath: "me", parameters: ["fields":"email,name"], tokenString: accessToken.tokenString, version: nil, HTTPMethod: "GET")
req.startWithCompletionHandler({ (connection, result, error : NSError!) -> Void in
if(error == nil) {
print("result \(result)")
} else {
print("error \(error)")
}
}
)

result will print:

result {
email = "email@example.com";
id = 123456789;
name = "Your Name";
}

Found that these fields are equal to the User endpoint, see this link where you can see all the fields that you can get.

Update for Swift 4 and above

let r = FBSDKGraphRequest(graphPath: "me",
parameters: ["fields": "email,name"],
tokenString: FBSDKAccessToken.current()?.tokenString,
version: nil,
httpMethod: "GET")

r?.start(completionHandler: { test, result, error in
if error == nil {
print(result)
}
})

Update for Swift 5 with FBSDKLoginKit 6.5.0

guard let accessToken = FBSDKLoginKit.AccessToken.current else { return }
let graphRequest = FBSDKLoginKit.GraphRequest(graphPath: "me",
parameters: ["fields": "email, name"],
tokenString: accessToken.tokenString,
version: nil,
httpMethod: .get)
graphRequest.start { (connection, result, error) -> Void in
if error == nil {
print("result \(result)")
}
else {
print("error \(error)")
}
}

How to move to the next page in Facebook JSON response using iOS SDK?

all what you need that add a method to the Facebook subclass or itself

- (void)requestWithURLString:(NSString *)fullURL
andHttpMethod:(NSString *)httpMethod
andDelegate:(id <FBRequestDelegate>)delegate {
[self openUrl:fullURL params:nil httpMethod:httpMethod delegate:delegate];
}

ps the second param "httpMethod" may be always @"GET" you can omit it



Related Topics



Leave a reply



Submit