Can I Retrieve 'installed'=0 as fieldsForRequest using FBFriendPickerViewController? - ios

I am currently using FBFriendPickerViewController to create a friend picker containing all friends that have field #"installed" = 1. This works fine.
My question is, can you instead create a friend picker for inviting friends to join like:
self.friendPickerController = [[FBFriendPickerViewController alloc]
initWithNibName:nil bundle:nil];
self.friendPickerController.fieldsForRequest = [NSSet setWithObjects:#"installed", nil];
[self.friendPickerController loadData];
[self.friendPickerController presentModallyFromViewController:self.navigationController
animated:YES
handler:^(FBViewController *sender, BOOL donePressed) {
if (donePressed) {
[self inviteFriend];
}
}];
- (BOOL)friendPickerViewController:(FBFriendPickerViewController *)friendPicker shouldIncludeUser:(id <FBGraphUser>)user
{
NSNumberFormatter * f = [[NSNumberFormatter alloc] init];
[f setNumberStyle:NSNumberFormatterDecimalStyle];
BOOL isInstalled = (BOOL)[f numberFromString:[NSString stringWithFormat:#"%#",[user objectForKey:#"installed"]]].intValue;
return !isInstalled;
}
Currently when I request #"installed" as a fieldsForRequest, it only retrieves friends who have installed=1, but does not return all friends (which is what I want).
EDIT: I want this in order to create a friend invite dialog of friends who do not have the app installed.

It looks like Facebook removed this from V2 so you can only retrieve friends with installed app. You can use this instead (For my purposes, I wanted a friend invite from iOS - this fits the bill):
FBDialogs presentShareDialogWithLink:params.link name:name caption:caption description:description picture:[NSURL URLWithString:picture] clientState:nil handler:^(FBAppCall *call, NSDictionary *results, NSError *error) {
}];
Docs here: https://developers.facebook.com/docs/ios/share

Related

iOS 8.3 and later, Facebook share text not inserted

After updating to iOS 8.3 the text is not inserted into the share dialog
i use a standard
UIActivityViewController *vc = [[UIActivityViewController alloc] initWithActivityItems:items applicationActivities:applicationActivities];
NSArray *excludeActivities = #[UIActivityTypeAssignToContact];
vc.excludedActivityTypes = excludeActivities;
if (IsUserInterfaceIdiomPad) {
vc.popoverPresentationController.sourceView = self.navigationController.view;
}
[self.navigationController presentViewController:vc animated:YES completion:^{
}];
where the items are a NSString and an NSURL
Looks like Facebook doesn't want the app to pre-propagate the share dialog with text anymore :(
It doesn't have to do anything with the iOS version, but with the build in Facebook App (as the share processes is somehow interlinked with the FB app)
It's stupid and on Android you couldn't do it either (it was disabled longer ago) i hope Facebook reconsiders this as it will lead to fewer shares and some might be willing to drop the share option
Note: if the user doesn't have the FB app installed (he removed it), than the text is added to the status, but i guess that only a small amount of users, but maybe a good reason to still supply text to the share items
NSString *strName= #"Mohit Thatai";
FBSDKLoginManager *login = [[FBSDKLoginManager alloc] init];
[login
logInWithReadPermissions: #[#"public_profile", #"email"]
handler:^(FBSDKLoginManagerLoginResult *result, NSError *error) {
if (error)
{
NSLog(#"Process error");
}
else if (result.isCancelled)
{
NSLog(#"Cancelled");
}
else
{
FBSDKShareLinkContent *content = [[FBSDKShareLinkContent alloc] init];
[content setContentTitle:#"GPS Tracker"];
[content setContentDescription:[NSString stringWithFormat:#"%# shared an interesting link\n This might be interesting to you: GPS Tracker for Kids",strName]];
content.contentURL = [NSURL URLWithString:[NSString stringWithFormat:#"http://gpsphonetrackerkids.com"]];
[FBSDKShareDialog showFromViewController:self
withContent:content
delegate:nil];
}
}];

Explicit Sharing on Facebook iOS SDK 4.0

I want to explicitly share an open graph action on Facebook using the new iOS 4.0 SDK. The following does not work. It shows up on my Activity Log, but not on my Timeline.
// Construct an FBSDKSharePhoto
FBSDKSharePhoto *photo = [[FBSDKSharePhoto alloc] init];
photo.image = img;
photo.userGenerated = YES;
// Create an object
NSDictionary *properties = #{
#"og:type": #"theprose:post",
#"og:title": post.title,
#"og:description": post.text,
#"og:caption": #"A fresh picked Prose for you.",
#"og:url": post.url,
#"fb:explicitly_shared": #"true"
};
FBSDKShareOpenGraphObject *object = [FBSDKShareOpenGraphObject objectWithProperties:properties];
// Create an action
FBSDKShareOpenGraphAction *act = [[FBSDKShareOpenGraphAction alloc] init];
act.actionType = #"theprose:share";
[act setObject:object forKey:#"theprose:post"];
[act setPhoto:photo forKey:#"image"];
// Create the content
FBSDKShareOpenGraphContent *content = [[FBSDKShareOpenGraphContent alloc] init];
content.action = act;
content.previewPropertyName = #"theprose:post";
[[FBSDKShareAPI shareWithContent:content delegate:nil] share];
Piecing together the answers from this page, this is what worked for me:
1. Check the Explicitly Shared box
Go to your open graph settings, action types and then choose your custom action. Scroll down to capabilities section and make sure that "explicitly share" box is checked.
2. Set fb:explicitely_shared On Action
[action setString:#"true" forKey:#"fb:explicitly_shared"];
3. Set the Relationship Between Action & Object
Make sure that you know the correct to connect your action to your object. In this case the key is "article":
[FBSDKShareOpenGraphAction actionWithType:#"mynamespace:share" object:object key:#"article"]
You can find that key by looking at the Action Type you created in your FB app's Open Graph settings. When you connected the Action with the Object via a Story, a new key for that relationship appears on the Action's page under the Property Name column.
The original poster is using the namespace:property_name format when what you really need is just the property_name for that key. This could be the fix for the OP.
4. Set the Delegate, Look For Errors
The OP is not taking advantage of the FBSDKSharingDelegate features. It reports errors and will help you fix the problem:
[[FBSDKShareAPI shareWithContent:content delegate:self] share];
And implement the delegate methods in self:
#pragma mark - FBSDKSharingDelegate
- (void) sharer:(id<FBSDKSharing>)sharer didCompleteWithResults:(NSDictionary *)results {
NSLog(#"Facebook sharing completed: %#", results);
}
- (void) sharer:(id<FBSDKSharing>)sharer didFailWithError:(NSError *)error {
NSLog(#"Facebook sharing failed: %#", error);
}
- (void) sharerDidCancel:(id<FBSDKSharing>)sharer {
NSLog(#"Facebook sharing cancelled.");
}
For Reference, Here's My Working Code
// Create the object
NSMutableDictionary *properties = [NSMutableDictionary dictionaryWithDictionary: #{
#"og:type": #"mynamespace:article",
#"og:title": myModel.title,
#"og:description": #"myModel.description",
#"og:url": #"http://mywebsite.com"
}];
NSURL *imageURL = [myModel getImageURL];
if (imageURL) {
FBSDKSharePhoto *photo = [FBSDKSharePhoto photoWithImageURL:imageURL userGenerated:NO];
[properties setObject:#[photo] forKey:#"og:image"];
}
FBSDKShareOpenGraphObject *object = [FBSDKShareOpenGraphObject objectWithProperties:properties];
// Create the action
FBSDKShareOpenGraphAction *action = [FBSDKShareOpenGraphAction actionWithType:#"mynamespace:share" object:object key:#"article"];
[action setString:#"true" forKey:#"fb:explicitly_shared"];
// Create the content
FBSDKShareOpenGraphContent *content = [[FBSDKShareOpenGraphContent alloc] init];
content.action = action;
content.previewPropertyName = #"article";
// Share the content
FBSDKShareAPI *shareAPI = [[FBSDKShareAPI alloc] init];
shareAPI.shareContent = content;
shareAPI.delegate = self;
[shareAPI share];
The same problem but works fine with FBSDKShareDialog under the same account. So the problem is in something else.
I got the same problem. I mean the reason in your code is, that you set the fb:explicitly_shared property in the object not in the concerning action.
The following code should solve the issue.
[action setString:#"true" forKey:#"fb:explicitly_shared"];
If your Facebook app is not public, make sure you have the test account added as a Test account, in the Roles section.
Make sure you have requested the publish_actions permission:
https://developers.facebook.com/docs/facebook-login/ios/permissions
You have no delegate assigned to your call, there is a high chance you are not getting the error returned by Facebook
Go to your open graph settings, action types and then choose your custom action. Scroll down to capabilities section and make sure that "explicitly share" box is checked.
It shouldn't work because there is a bug in FB with SDK versions before 4.1:
https://developers.facebook.com/bugs/943100005734949/
https://developers.facebook.com/bugs/1563738347248670
but with SDK version 4.1 this bug is fixed but the content for custom story/action/object was shown in very different way in compare with FSDKShareDialog (((
One more check to the checklist: FBSDKShareApi only works on the main thread. So make sure you are sharing from there.

Show App Store app page in app

There are some apps (like the free version of Cut the Rope) that present the App Store page of other apps directly in the app (probably using a modal view controller).
How do I implement this in my own app?
Example from Cut the Rope:
You can use SKStoreProductViewController for this, check out documentation for more detail
if ([SKStoreProductViewController class]) {
NSString *yourAppID = #"";//Give your app id here
NSDictionary *appParameters = #{SKStoreProductParameterITunesItemIdentifier :yourAppID};
SKStoreProductViewController *productViewController = [[SKStoreProductViewController alloc] init];
[productViewController setDelegate:self];
[productViewController loadProductWithParameters:appParameters completionBlock:nil];
[self presentViewController:productViewController animated:YES completion:nil];
}
One can implement a App Store page of any application within their own app by using the SKStoreProductViewController class.
NSString *strURL = #"" //Keep the App store URL here.
if ([[[UIDevice currentDevice]systemVersion]floatValue] >= 6.0)
{
SKStoreProductViewController *storeProductViewController = [[SKStoreProductViewController alloc] init];
NSRange range = [strURL rangeOfString:#"/id"];
NSRange rangeID = {range.location + 3, 9};
NSString *strAppID = [strURL substringWithRange:rangeID];
NSLog(#"appid = %#", strAppID);
// Configure View Controller
[storeProductViewController setDelegate:self];
[storeProductViewController loadProductWithParameters:#{SKStoreProductParameterITunesItemIdentifier : strAppID}
completionBlock:^(BOOL result, NSError *error) {
if (error) {
NSLog(#"Error %# with User Info %#.", error, [error userInfo]);
} else {
}
}];
// Present Store Product View Controller
[self presentViewController:storeProductViewController animated:YES completion:nil];
}
The above code also extracts the app ID from the URL.
You can read about it in the class reference.

Can I preselect friends in the new FBDialogs?

I am using the FBDialogs to open Facebook Messenger (if user has it installed on the device) to send a personal message. However I cannot already preselect friends in my app (messenger always gives me a list and prompts me to select there).
I am using presentMessageDialogWithParams:clientState:handler: which receives FBLinkShareParams object.
FBLinkShareParams friends array
An array of NSStrings or FBGraphUsers to tag in the post. If using NSStrings, the values must represent the IDs of the users to tag.
But when I send FBGraphUsers they are not preselected in messenger app. Should they? Or is this just a "tag a friend" feature?
My code:
NSMutableArray *inviteFriends = [[NSMutableArray alloc] init];
FBRequest* friendsRequest = [FBRequest requestForMyFriends];
[friendsRequest startWithCompletionHandler: ^(FBRequestConnection *connection,
NSDictionary* result,
NSError *error) {
NSArray* friends = [result objectForKey:#"data"];
NSLog(#"Found: %i friends", friends.count);
for (NSDictionary<FBGraphUser>* friend in friends) {
if ([friend.name isEqualToString:#"XXX"]) {
NSLog(#"I have a friend named %# with id %#", friend.name, friend.id);
[inviteFriends addObject:friend];
}
}
FBLinkShareParams *params = [[FBLinkShareParams alloc] init];
params.link = [NSURL URLWithString:#"https://developers.facebook.com/docs/ios/share/"];
params.name = #"Message Dialog Tutorial";
params.caption = #"Build great social apps that engage your friends.";
params.picture = [NSURL URLWithString:#"http://i.imgur.com/g3Qc1HN.png"];
params.description = #"Send links from your app using the iOS SDK.";
params.friends = inviteFriends;
// If the Facebook app is installed and we can present the share dialog
if ([FBDialogs canPresentMessageDialogWithParams:params]) {
[FBDialogs presentMessageDialogWithParams:params clientState:nil handler:^(FBAppCall *call, NSDictionary *results, NSError *error) {
//
}];
}
}];
The "friends" and "place" parameters are ignored by Messenger since those are specific for tagging, and Messenger doesn't support tagging.
You cannot specify users to preselect using the message dialog.
We will update the docs to reflect this in the future.

Facebook Request Dialog for mobile - filtering users

I'm using request dialog in mobile app. Reading
https://developers.facebook.com/docs/reference/dialogs/requests/
I've found that
Note: the filters option is disabled on mobile dialogs and will not affect the set of users that appear in the dialog.
Unfortunately I need to show only friends with app installed in one dialog, and rest in the other. Is there any reasonable way to filter users like this while still using FB request dialog?
You could take a look at the Hackbook sample app, packaged with the SDK to show you how to do this, but in essence you have to create an API call to get, say users with the app installed and pass this to a parameter called "suggestions".
- (void)sendRequest:(NSArray *) targeted {
NSMutableDictionary* params = [NSMutableDictionary dictionaryWithObjectsAndKeys:
#"It's your turn, quit slacking.", #"message",
nil];
// Filter and only show targeted friends
if (targeted != nil && [targeted count] > 0) {
NSString *selectIDsStr = [targeted componentsJoinedByString:#","];
[params setObject:selectIDsStr forKey:#"suggestions"];
}
[self.facebook dialog:#"apprequests"
andParams:params
andDelegate:self];
}
- (void) sendToAppUsers {
FBRequest *appUsersRequest = [[FBRequest alloc]
initWithSession:FBSession.activeSession
restMethod:#"friends.getAppUsers"
parameters:nil
HTTPMethod:#"GET"];
FBRequestConnection *appUsersConnection = [[FBRequestConnection alloc] init];
[appUsersConnection
addRequest:appUsersRequest
completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
// Process the results
NSMutableArray *friendsWithApp = [[NSMutableArray alloc] init];
// Many results
if ([result isKindOfClass:[NSArray class]]) {
[friendsWithApp addObjectsFromArray:result];
} else if ([result isKindOfClass:[NSDecimalNumber class]]) {
[friendsWithApp addObject: [result stringValue]];
}
// User has friends that pass this filter
if ([friendsWithApp count] > 0) {
[self sendRequest:friendsWithApp];
}
}];
[appUsersConnection start];
}

Resources