Permalink
Browse files

Adds frictionless apprequest support

Summary:
Here are the mods to the sdk:
1. adds four methods to the Facebook class, for use by applications
  * enableFrictionlessRequests
  * reloadFrictionlessRecipientCache
  * isFrictionlessEnabledForRecipient
  * isFrictionlessEnabledForRecipients
2. extends dialog method and support class to support frictionless behavior for “apprequest” dialogs
3. extends Hacbook sample to add frictionless app-request support

Notes:
* enableFrictionlessRequests method of FBFrictionless turns on frictionless apprequest behavior in the SDK
* frictionless apprequest behavior means
  a.) a cache of allowed frictionless recipients is maintained
  b.) cache checked by dialog, and dialog is invisible for frictionless recipients
  c.) send responses are checked and recipient list is updated
  d.) logout and login cause clear and refetch of cache respectively
1 parent 9acf743 commit 4e3567c40e3b7f8156a82f18e5a2f5cd18e077eb @onebit onebit committed Feb 10, 2012
View
@@ -0,0 +1,5 @@
+{
+ "project_id" : "facebook-ios-sdk",
+ "conduit_uri" : "https://phabricator.fb.com/api/",
+ "copyright_holder" : "Facebook"
+}
View
@@ -21,7 +21,6 @@ test/UnitTest/UnitTest.xcodeproj/*.mode*
test/UnitTest/build/
*~
*#
-.arcconfig
.DS_Store
project.xcworkspace
xcuserdata
@@ -38,6 +38,7 @@
30EA73FC13F5D590003DC0D2 /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 30EA73FB13F5D590003DC0D2 /* CoreLocation.framework */; };
30ED588C14358F8A00A226C3 /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 30ED588B14358F8A00A226C3 /* Default@2x.png */; };
30ED588F14358F9400A226C3 /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 30ED588E14358F9400A226C3 /* Icon@2x.png */; };
+ 84E7D99614D9CC13006A6299 /* FBFrictionlessRequestSettings.m in Sources */ = {isa = PBXBuildFile; fileRef = 84E7D99514D9CC13006A6299 /* FBFrictionlessRequestSettings.m */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
@@ -92,6 +93,8 @@
30EA73FB13F5D590003DC0D2 /* CoreLocation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreLocation.framework; path = System/Library/Frameworks/CoreLocation.framework; sourceTree = SDKROOT; };
30ED588B14358F8A00A226C3 /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default@2x.png"; sourceTree = "<group>"; };
30ED588E14358F9400A226C3 /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon@2x.png"; sourceTree = "<group>"; };
+ 84E7D99414D9CC13006A6299 /* FBFrictionlessRequestSettings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FBFrictionlessRequestSettings.h; path = ../../src/FBFrictionlessRequestSettings.h; sourceTree = "<group>"; };
+ 84E7D99514D9CC13006A6299 /* FBFrictionlessRequestSettings.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FBFrictionlessRequestSettings.m; path = ../../src/FBFrictionlessRequestSettings.m; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -197,6 +200,8 @@
30EA73D613F5D523003DC0D2 /* FBLoginDialog.m */,
30EA73D713F5D523003DC0D2 /* FBRequest.h */,
30EA73D813F5D523003DC0D2 /* FBRequest.m */,
+ 84E7D99414D9CC13006A6299 /* FBFrictionlessRequestSettings.h */,
+ 84E7D99514D9CC13006A6299 /* FBFrictionlessRequestSettings.m */,
30EA73D913F5D523003DC0D2 /* JSON */,
);
name = FBConnect;
@@ -310,6 +315,7 @@
30EA73F013F5D523003DC0D2 /* SBJsonBase.m in Sources */,
30EA73F113F5D523003DC0D2 /* SBJsonParser.m in Sources */,
30EA73F213F5D523003DC0D2 /* SBJsonWriter.m in Sources */,
+ 84E7D99614D9CC13006A6299 /* FBFrictionlessRequestSettings.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -540,6 +540,28 @@ - (void)getUserFriendTargetDialogRequest {
}
/*
+ * API: Enable frictionless in the SDK, retrieve friends enabled for frictionless send
+ */
+- (void)enableFrictionlessAppRequests {
+ HackbookAppDelegate *delegate =
+ (HackbookAppDelegate *)[[UIApplication sharedApplication] delegate];
+
+ // Enable frictionless app requests
+ [[delegate facebook] enableFrictionlessRequests];
+
+ UIAlertView *alertView = [[UIAlertView alloc]
+ initWithTitle:@"Enabled Frictionless Requests"
+ message:@"Request actions such as\n"
+ @"Send Request and Send Invite\n"
+ @"now support frictionless behavior."
+ delegate:self
+ cancelButtonTitle:@"OK"
+ otherButtonTitles:nil,
+ nil];
+ [alertView show];
+}
+
+/*
* --------------------------------------------------------------------------
* Graph API
* --------------------------------------------------------------------------
@@ -939,12 +961,13 @@ - (void)request:(FBRequest *)request didLoad:(id)result {
}
case kAPIFriendsForDialogFeed:
{
- NSArray *resultData = [result objectForKey:@"data"];
+ NSArray *resultData = [result objectForKey: @"data"];
// Check that the user has friends
if ([resultData count] > 0) {
// Pick a random friend to post the feed to
int randomNumber = arc4random() % [resultData count];
- [self apiDialogFeedFriend:[[resultData objectAtIndex:randomNumber] objectForKey:@"id"]];
+ [self apiDialogFeedFriend:
+ [[resultData objectAtIndex: randomNumber] objectForKey: @"id"]];
} else {
[self showMessage:@"You do not have any friends to post to."];
}
@@ -1015,17 +1038,24 @@ - (void)request:(FBRequest *)request didLoad:(id)result {
}
case kAPIFriendsForTargetDialogRequests:
{
- NSArray *resultData = [result objectForKey:@"data"];
- if ([resultData count] > 0) {
- [self apiDialogRequestsSendTarget:[[resultData objectAtIndex:0] objectForKey:@"id"]];
+ NSArray *resultData = [result objectForKey: @"data"];
+ // got friends?
+ if ([resultData count] > 0) {
+ // pick a random one to send a request to
+ int randomIndex = arc4random() % [resultData count];
+ NSString* randomFriend =
+ [[resultData objectAtIndex: randomIndex] objectForKey: @"id"];
+ [self apiDialogRequestsSendTarget:randomFriend];
} else {
- [self showMessage:@"You have no friends to select."];
+ [self showMessage: @"You have no friends to select."];
}
break;
}
case kAPIGraphMe:
{
- NSString *nameID = [[NSString alloc] initWithFormat:@"%@ (%@)", [result objectForKey:@"name"], [result objectForKey:@"id"]];
+ NSString *nameID = [[NSString alloc] initWithFormat: @"%@ (%@)",
+ [result objectForKey:@"name"],
+ [result objectForKey:@"id"]];
NSMutableArray *userData = [[NSMutableArray alloc] initWithObjects:
[NSDictionary dictionaryWithObjectsAndKeys:
[result objectForKey:@"id"], @"id",
@@ -1162,7 +1192,7 @@ - (void)dialogCompleteWithUrl:(NSURL *)url {
// Successful requests return one or more request_ids.
// Get any request IDs, will be in the URL in the form
// request_ids[0]=1001316103543&request_ids[1]=10100303657380180
- NSMutableArray *requestIDs = [[NSMutableArray alloc] init];
+ NSMutableArray *requestIDs = [[[NSMutableArray alloc] init] autorelease];
for (NSString *paramKey in params) {
if ([paramKey hasPrefix:@"request_ids"]) {
[requestIDs addObject:[params objectForKey:paramKey]];
@@ -101,13 +101,20 @@ - (id)init {
@"Send request", @"button",
@"getUserFriendTargetDialogRequest", @"method",
nil];
+ NSDictionary *requestMenu5 = [[NSDictionary alloc] initWithObjectsAndKeys:
+ @"Enable frictionless requests", @"title",
+ @"To enable a no-prompt request and invite experience, enable frictionless requests.", @"description",
+ @"Enable frictionless", @"button",
+ @"enableFrictionlessAppRequests", @"method",
+ nil];
NSArray *requestMenuItems = [[NSArray alloc] initWithObjects:
requestMenu1,
requestMenu2,
requestMenu3,
requestMenu4,
- nil];
+ requestMenu5,
+ nil];
NSDictionary *requestConfigData = [[NSDictionary alloc] initWithObjectsAndKeys:
@"Requests", @"title",
@@ -122,6 +129,7 @@ - (id)init {
[requestMenu2 release];
[requestMenu3 release];
[requestMenu4 release];
+ [requestMenu5 release];
[requestMenuItems release];
[requestConfigData release];
@@ -49,28 +49,28 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(
self.navigationController = navController;
[rootViewController release];
[navController release];
-
+
// Initialize Facebook
facebook = [[Facebook alloc] initWithAppId:kAppId andDelegate:rootViewController];
-
+
// Check and retrieve authorization information
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if ([defaults objectForKey:@"FBAccessTokenKey"] && [defaults objectForKey:@"FBExpirationDateKey"]) {
facebook.accessToken = [defaults objectForKey:@"FBAccessTokenKey"];
facebook.expirationDate = [defaults objectForKey:@"FBExpirationDateKey"];
}
-
+
// Initialize API data (for views, etc.)
apiData = [[DataSet alloc] init];
-
+
// Initialize user permissions
userPermissions = [[NSMutableDictionary alloc] initWithCapacity:1];
-
+
// Override point for customization after application launch.
// Add the navigation controller's view to the window and display.
self.window.rootViewController = self.navigationController;
[self.window makeKeyAndVisible];
-
+
// Check App ID:
// This is really a warning for the developer, this should not
// happen in a completed app
@@ -119,7 +119,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(
[alertView release];
}
}
-
+
return YES;
}
Oops, something went wrong.

0 comments on commit 4e3567c

Please sign in to comment.