How to Retrieve the Results of "FBSDKGraphRequest" to Use Outside? - ios

I am using Facebook SDK for iOS. I can output the results with "NSLog" but I do not know how to retrieve the values of the results from FBSDKGraphRequest outside since they are located in a completion block. I need these values for the later manipulations. I tried to put them in NSArray or NSMutableArray but could not make it.
The code for the illustration is given below:
__block NSMutableArray *results;
__block NSArray *obj;
if ([[FBSDKAccessToken currentAccessToken] hasGranted:#"user_groups"]) {
NSLog(#"user_groups permission is granted!");
FBSDKGraphRequest *fgr = [[[FBSDKGraphRequest alloc]
initWithGraphPath:#"me/groups?fields=id"
parameters: nil
HTTPMethod:#"GET"]
startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
if (!error) {
//here I can output the results
NSLog(#"User's groups:%#", [result[#"data"] valueForKey:#"id"]);
//trying to pass the values to NSMutableArray
obj = [result[#"data"] valueForKey:#"id"];
results = [NSMutableArray arrayWithArray:obj];
}
}];
}
...
NSLog(#"The size of the array of the results : %lu", [results count]);
Here it seems that NSMutableArray of the results is empty, so, I could not put the data of the results there. How can I retrieve the results from inside of "FBSDKGraphRequest" in order to use them later (externally)? What kind of container would help me?

You need to use [FBSDKTypeUtility arrayValue] to fetch the data.
Something like this:
NSMutableArray *_results;
FBSDKGraphRequest *request =
[[FBSDKGraphRequest alloc]
initWithGraphPath:#"me/groups?fields=id""
parameters:nil];
[request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
if (!error) {
NSArray *items = [FBSDKTypeUtility arrayValue:result[#"data"]];
_results = [[NSSet alloc] initWithArray:items];
}
}];
Does this solve the issue for you?
Here is an example of how this is used on the SDK Samples:
https://github.com/facebook/facebook-ios-sdk/blob/652fb84a949ef358ff05afedfb2a7c408bd5c839/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKGameRequestFrictionlessRecipientCache.m#L87

Related

How to use facebook pagination in ios

Hi I have recently started coding for iOS.I am trying to get videos from facebook using the following code.
-(void)facebookGetVideos:(UIViewController*)vc completionHandler:(void (^)(NSMutableArray*))completionBlock{
__block NSMutableArray * itemArray;
FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc]
initWithGraphPath:#"me/videos/uploaded"
parameters:#{#"fields":#"source,description,thumbnail,title"}
HTTPMethod:#"GET"];
[request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection,
id result,
NSError *error) {
if(error!=nil){
NSLog(#"Error after fb dwnld %#",error);
[MBProgressHUD hideHUDForView:vc.view animated:true];
[self showAlert:#"Error" message:error.localizedDescription viewController:vc];
}else{
NSLog(#"Results %#",result);
itemArray = [[NSMutableArray alloc]init];
// [itemArray addObject:[result valueForKey:#"data"]];
itemArray =[result valueForKey:#"data"];
completionBlock(itemArray);
}
}];
}
The response I am getting from there is as below:-
{
data = (
{
id = 1845903302379295;
source = "https://video.xx.fbcdn.net/v/t43.1792-2/27475816_220074475216744_8742438766032977920_n.mp4?efg=eyJybHIiOjE1MDAsInJsYSI6MTAyNCwidmVuY29kZV90YWciOiJzdmVfaGQifQ%3D%3D&rl=1500&vabr=382&oh=d4c3f6028a979c5919fdd8e444e24179&oe=5A89882A";
},
{
id = 1814936632142629;
source = "https://video.xx.fbcdn.net/v/t42.14539-2/23925286_2650490725061654_2502749796398268416_n.mp4?efg=eyJybHIiOjU3NiwicmxhIjo1MTIsInZlbmNvZGVfdGFnIjoic2QifQ%3D%3D&rl=576&vabr=320&oh=2fde1aea6eff33d8139ccb8fe7a33fd4&oe=5A8980C0";
}
);
paging = {
cursors = {
after = MTgxNDkzNjYzMjE0MjYyOQZDZD;
before = MTg0NTkwMzMwMjM3OTI5NQZDZD;
};
};
}
I am trying to use this after before as parameters as below:-
-(void)afterValues:(NSString*)afterVal{
NSDictionary * parameters =#{#"fields":#"source",#"after": afterVal};
FBSDKGraphRequest *request1 = [[FBSDKGraphRequest alloc]
initWithGraphPath:#"me/videos/uploaded"
parameters:parameters
HTTPMethod:#"GET"];
[request1 startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection,
id result,
NSError *error) {
NSLog(#"after videos%#",result);
}];
}
And getting the following as response:-
after videos{
data = (
);
}
Can anyone please point out at my mistake.Any kind of help/suggestion or guidance in this directions would be highly appreciated.Thanks in advance!
Have you requested the manage_pages permission from the respective user through the login dialog? I think you see an empty result because of the missing permission.

How to access a variable inside the block of id type in Objective-C? [duplicate]

This question already has answers here:
Return Result of Completion Block
(2 answers)
Closed 6 years ago.
After searching for this type of error:
Variable is not assignable (missing __block type specifier)
I found the following solution Assign a variable inside a Block to a variable outside a Block and after I read about the __block I could not benefit from the accepted answer and my code is different scenario.
Here is the code that I am using:
NSDictionary *strongUser = [[NSDictionary alloc]init];
__block NSDictionary *user = strongUser;
NSMutableDictionary* parameters = [NSMutableDictionary dictionary];
[parameters setValue:#"id, name, email" forKey:#"fields"];
[[[FBSDKGraphRequest alloc] initWithGraphPath:#"me" parameters:parameters]
startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
user = result;
}];
NSLog(#"%#",user);
NSLog print nothing
What I want is to given the result value to extern variable outside the block.
I would suggest using __block NSDictionary *strongUser. I'm concerned that the pointer user still exists inside the block, but the underlying variable to which it is pointing may no longer be accessible. For example:
__block NSDictionary *strongUser = [[NSDictionary alloc]init];
NSMutableDictionary* parameters = [NSMutableDictionary dictionary];
[parameters setValue:#"id, name, email" forKey:#"fields"];
[[[FBSDKGraphRequest alloc] initWithGraphPath:#"me" parameters:parameters]
startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error)
{
strongUser = result;
}];
Add the following inside your block:
NSLog(#"Doing assignment inside the block");
Then run your code.
The answer to your question will be obvious.
HTH
You run your code async, and your log evaluates before completion handler.
Add your log directly inside completion handler's scope.
NSDictionary *strongUser = [[NSDictionary alloc]init];
__block NSDictionary *user = strongUser;
NSMutableDictionary* parameters = [NSMutableDictionary dictionary];
[parameters setValue:#"id, name, email" forKey:#"fields"];
[[[FBSDKGraphRequest alloc] initWithGraphPath:#"me" parameters:parameters]
startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error)
{
user = result;
NSLog(#"%#",user);
}];
You have a local variable strongUser, it means that when this scope(function) will be finished, your local variable strongUser will be deallocated - so when your block works __block variavle user is alive but it points to unexist object.
The easy wasy to implement it right is to create a property with lazy setter:
#property (nonatomic, strong) NSDictionary *strongUser;
- (NSDictionary *)strongUser {
if (!_strongUser) {
_strongUser = [[NSDictionary alloc] init];
}
return _strongUser;
}
And call it with selfinside block:
NSMutableDictionary* parameters = [NSMutableDictionary dictionary];
[parameters setValue:#"id, name, email" forKey:#"fields"];
[[[FBSDKGraphRequest alloc] initWithGraphPath:#"me"parameters:parameters]
startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
self.strongUser = result;
NSLog(#"%#",self.strongUser);
}];
Hope it helps!

How to use the result of FBSDKGraphRequest Outside the Block

I am designing an application which uses Facebook to display the feeds in a table view ..so in order to get the result of the feeds i have called a method FBSDKGraphRequest but I do not know how to retrieve the values of the results from FBSDKGraphRequest outside since they are located in a completion block.I want to display the name and message in the table view....
The code illustration is below:-
FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc]initWithGraphPath:Path parameters:#{ #"fields": #"feed{from,message,created_time}",} tokenString:accessToken version:FBSDK_TARGET_PLATFORM_VERSION HTTPMethod:#"GET"];
[request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
if(error)
NSLog(#"No Data");
else {
FeedCount = [NSDictionary dictionaryWithDictionary:result];
NSDictionary*feed = [FeedCount objectForKey:#"feed"];
NSArray*array1 = [feed objectForKey:#"data"];
NSArray*array3 = [array1 valueForKey:#"from"];
NSLog(#"Data:%#",array3); ---------------> **Displaying Data**
}
}];
NSLog(#"FeedCount:%#",FeedCount);----------------->**Showing Null**
Any help will be Appreciated
To get the result of dictionary from fbsdk please declare variable as __block NSDictionary *json;
Then assign this inside block like,
json =[FeedCount objectForKey:#"feed"];
Did you try this like,
__block NSDictionary *json;
FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc]initWithGraphPath:Path parameters:#{ #"fields": #"feed{from,message,created_time}",} tokenString:accessToken version:FBSDK_TARGET_PLATFORM_VERSION HTTPMethod:#"GET"];
[request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
if(error)
NSLog(#"No Data");
else {
FeedCount = [NSDictionary dictionaryWithDictionary:result];
json = [FeedCount objectForKey:#"feed"];
NSArray*array1 = [feed objectForKey:#"data"];
NSArray*array3 = [array1 valueForKey:#"from"];
NSLog(#"Data:%#",array3); ---------------> **Displaying Data**
}
}];
NSLog(#"json:%#",json);

Sorting Through Graph API of Facebook Page on iOS

I am using:
if ([FBSDKAccessToken currentAccessToken]) {
[[[FBSDKGraphRequest alloc] initWithGraphPath:#"/v2.3/ID/feed" parameters:nil]
startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
if (!error) {
NSLog(#"fetched user:%#", result);
}
}];
}
This gives me a JSON string of ALL data (AND I MEAN ALL) from a Facebook Page. It gives me the posts, IDs of those who liked the posts, every comment, every person who shared. I really just need the post itself, which is listed as 'message' in the JSON result. Is there a way I can do this in the API call, or does it have to be done after?
Also,
Is there any way to get it to pull the pictures that are associated with each post? I know how to get photos posted to page, but I just want to view the posts made to the page, and have it also pull up the picture.
You can filter out feed response as below
if ([FBSDKAccessToken currentAccessToken]) {
[[[FBSDKGraphRequest alloc] initWithGraphPath:#"/v2.3/ID/feed" parameters:[NSMutableDictionary dictionaryWithObject:#"id, message, link.picture" forKey:#"fields"]]
startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
if (!error) {
NSLog(#"fetched user:%#", result);
}
}];
}
As you can check, I've mentioned the parameters which I information I requires to get filter out.
NOTE: You can filter out things according to your requirement.
Please check below link for available filter possibilities on facebook SDK.
https://developers.facebook.com/docs/graph-api/reference/v2.3/user/feed
I hope it will help you, Not sure about the picture you want to pull up but may be 'link.picture' in 'fields' will help you the picture you want to get.
Use
/{page_id}/feed?fields=id,message
With Graph API v2.4 this will be the standard usage that you have to specify each field.
this, it's the variable of NSString "link" that you want:
if ([FBSDKAccessToken currentAccessToken]) {
FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:#"me" parameters:nil];
[request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
if (!error) {
NSDictionary *userData = (NSDictionary *)result;
NSString *facebookID = userData[#"id"];
NSString *link = userData[#"link"];
NSString *locale = userData[#"locale"];
NSString *timezone = userData[#"timezone"];
NSString *last_name = userData[#"last_name"];
NSString *email = userData[#"email"];
NSString *gender = userData[#"gender"];
NSString *first_name = userData[#"first_name"];
} else if (error) {
//tbd
}
}];
} else if (![FBSDKAccessToken currentAccessToken]) {
//tbd
}

How to extract Facebook posts information

I'm using this code to read the last post with location of all my facebook friends:
(FacebookFriend is an object I've created mySelf and contains also the friend's id and _facebookFriends contains all my facebook friends)
_postsWithLocationList = [[NSMutableArray alloc] init];
for (FacebookFriend *currentFriend in _facebookFriends) {
FBRequestConnection *connection = [[FBRequestConnection alloc] init];
NSString *path = [NSString stringWithFormat:#"%#/posts?limit=1&with=location",currentFriend.id];
FBRequest *postsWithLocationRequest = [FBRequest requestWithGraphPath:path parameters:nil HTTPMethod:#"GET"];
[connection addRequest:postsWithLocationRequest completionHandler:^(FBRequestConnection *connection, NSDictionary *result, NSError *error) {
NSDictionary *postData = [result objectForKey:#"data"];
if (postData.count != 0) //some people don't have any post with position
{
// how to extract "place" object?
}
}];
[connection start];
}
and then I would like to store every location in my NSMutable array _postsWithLocationList.
Once I've extracted *postData I printed it's content and it looked like a dictionary (where "place" is a key) exactly as in the Facebook Graph API Explorer.
But when I printed
NSLog(#"%i", postData.count);
I saw that the length of "postData" was always 1, so I think that it's a single object that contains all the instances of the post. I looked at https://developers.facebook.com but I don't understand the type of this object and how to extract it's content.

Resources