Skip to content
Browse files

Putting back, again, the attribute code

Summary:
This reverts commit c89fea4.

Based on new information, we're putting back the app attribution code into the SDK.

Test Plan: Build + run unit tests

Reviewers: jacl, mmarucheck, clang, jketchpaw

Reviewed By: jketchpaw

CC: msdkexp@

Differential Revision: https://phabricator.fb.com/D536848
  • Loading branch information...
1 parent 39306b2 commit a2269dccf34e239fbda4ccf87c7dbca84d0ae162 @vijaye vijaye committed Aug 1, 2012
View
3 src/FBSession.m
@@ -21,6 +21,7 @@
#import "FBSession+Protected.h"
#import "FBSessionTokenCachingStrategy.h"
#import "FBSettings.h"
+#import "FBSettings+Internal.h"
#import "FBError.h"
#import "FBLogger.h"
#import "FBUtility.h"
@@ -264,6 +265,8 @@ - (id)initWithAppID:(NSString*)appID
[tokenCachingStrategy clearToken];
}
}
+
+ [FBSettings autoPublishInstall:self.appID];
}
return self;
}
View
23 src/FBSettings+Internal.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2012 Facebook
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "FBSettings.h"
+
+@interface FBSettings (Internal)
+
++ (void)autoPublishInstall:(NSString *)appID;
+
+@end
View
28 src/FBSettings.h
@@ -47,12 +47,36 @@ extern NSString *const FBLoggingBehaviorPerformanceCharacteristics;
/*!
@method
-
+
@abstract Set the current Facebook SDK logging behavior. This should consist of strings defined as
constants with FBLogBehavior*, and can be constructed with [NSSet initWithObjects:].
-
+
@param loggingBehavior A set of strings indicating what information should be logged.
*/
+ (void)setLoggingBehavior:(NSSet *)loggingBehavior;
+/*! @abstract Retreive the current auto publish behavior. Defaults to YES. */
++ (BOOL)shouldAutoPublishInstall;
+
+/*!
+ @method
+
+ @abstract Sets whether the SDK will automatically publish an install to Facebook during first FBSession init
+ or on first network request to Facebook.
+ */
++ (void)setShouldAutoPublishInstall:(BOOL)autoPublishInstall;
+
+// For best results, call this function during app activation.
+/*!
+ @method
+
+ @abstract Manually publish an attributed install to the facebook graph. Use this method if you have disabled
+ auto publish and wish to manually send an install from your code. This method acquires the current attribution
+ id from the facebook application, queries the graph API to determine if the application has install
+ attribution enabled, publishes the id, and records success to avoid reporting more than once.
+
+ @param appID A specific appID to publish an install for. If nil, uses [FBSession defaultAppID].
+ */
++ (void) publishInstall:(NSString *)appID;
+
@end
View
104 src/FBSettings.m
@@ -14,17 +14,41 @@
* limitations under the License.
*/
+#import "FBRequest.h"
+#import "FBSession.h"
#import "FBSettings.h"
+#import "FBSettings+Internal.h"
+
+#import <UIKit/UIKit.h>
NSString *const FBLoggingBehaviorFBRequests = @"fb_requests";
NSString *const FBLoggingBehaviorFBURLConnections = @"fburl_connections";
NSString *const FBLoggingBehaviorAccessTokens = @"include_access_tokens";
NSString *const FBLoggingBehaviorSessionStateTransitions = @"state_transitions";
NSString *const FBLoggingBehaviorPerformanceCharacteristics = @"perf_characteristics";
+NSString *const FBLastAttributionPing = @"com.facebook.sdk:lastAttributionPing%@";
+NSString *const FBSupportsAttributionPath = @"%@?fields=supports_attribution";
+NSString *const FBPublishActivityPath = @"%@/activities";
+NSString *const FBMobileInstallEvent = @"MOBILE_APP_INSTALL";
+NSString *const FBAttributionPasteboard = @"fb_app_attribution";
+NSString *const FBSupportsAttribution = @"supports_attribution";
+
+NSTimeInterval const FBPublishDelay = 0.1;
+
+@protocol FBActivity<FBGraphObject>
+
+@property (retain, nonatomic) NSString *event;
+@property (retain, nonatomic) NSString *attribution;
+
+@end
+
+
@implementation FBSettings
static NSSet *g_loggingBehavior;
+static BOOL g_autoPublishInstall = YES;
+static dispatch_once_t g_publishInstallOnceToken;
+ (NSSet *)loggingBehavior {
return g_loggingBehavior;
@@ -36,4 +60,84 @@ + (void)setLoggingBehavior:(NSSet *)newValue {
g_loggingBehavior = newValue;
}
++ (BOOL)shouldAutoPublishInstall {
+ return g_autoPublishInstall;
+}
+
++ (void)setShouldAutoPublishInstall:(BOOL)newValue {
+ g_autoPublishInstall = newValue;
+}
+
++ (void)autoPublishInstall:(NSString *)appID {
+ if ([FBSettings shouldAutoPublishInstall]) {
+ dispatch_once(&g_publishInstallOnceToken, ^{
+ // dispatch_once is great, but not re-entrant. Inside publishInstall we use FBRequest, which will
+ // cause this function to get invoked a second time. By scheduling the work, we can sidestep the problem.
+ [[FBSettings class] performSelector:@selector(publishInstall:) withObject:appID afterDelay:FBPublishDelay];
+ });
+ }
+}
+
+
+#pragma mark -
+#pragma mark proto-activity publishing code
+
++ (void)publishInstall:(NSString *)appID {
+ if (!appID) {
+ appID = [FBSession defaultAppID];
+ }
+
+ if (!appID) {
+ // if the appID is still nil, exit early.
+ return;
+ }
+
+ // look for a previous ping & grab the facebook app's current attribution id.
+ NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
+ NSString *pingKey = [NSString stringWithFormat:FBLastAttributionPing, appID, nil];
+ NSDate *lastPing = [defaults objectForKey:pingKey];
+ NSString *attributionID = [[UIPasteboard pasteboardWithName:FBAttributionPasteboard create:NO] string];
+
+ if (attributionID && !lastPing) {
+ FBRequestHandler publishCompletionBlock = ^(FBRequestConnection *connection,
+ id result,
+ NSError *error) {
+ if (!error) {
+ // if server communication was successful, take note of the current time.
+ [defaults setObject:[NSDate date] forKey:pingKey];
+ [defaults synchronize];
+ } else {
+ // there was a problem. allow a repeat execution.
+ g_publishInstallOnceToken = 0;
+ }
+ };
+
+ FBRequestHandler pingCompletionBlock = ^(FBRequestConnection *connection,
+ id result,
+ NSError *error) {
+ if (!error) {
+ if ([result respondsToSelector:@selector(objectForKey:)] &&
+ [[result objectForKey:FBSupportsAttribution] boolValue]) {
+ // set up the HTTP POST to publish the attribution ID.
+ NSString *publishPath = [NSString stringWithFormat:FBPublishActivityPath, appID, nil];
+ id<FBActivity> installActivity = (id<FBActivity>)[FBGraphObject graphObject];
+ installActivity.event = FBMobileInstallEvent;
+ installActivity.attribution = attributionID;
+
+ FBRequest *publishRequest = [[[FBRequest alloc] initForPostWithSession:nil graphPath:publishPath graphObject:installActivity] autorelease];
+ [publishRequest startWithCompletionHandler:publishCompletionBlock];
+ } else {
+ // the app has turned off install insights. prevent future attempts.
+ [defaults setObject:[NSDate date] forKey:pingKey];
+ [defaults synchronize];
+ }
+ }
+ };
+
+ NSString *pingPath = [NSString stringWithFormat:FBSupportsAttributionPath, appID, nil];
+ FBRequest *pingRequest = [[[FBRequest alloc] initWithSession:nil graphPath:pingPath] autorelease];
+ [pingRequest startWithCompletionHandler:pingCompletionBlock];
+ }
+}
+
@end
View
5 src/FBURLConnection.m
@@ -21,6 +21,7 @@
#import "FBLogger.h"
#import "FBUtility.h"
#import "FBSettings.h"
+#import "FBSettings+Internal.h"
static NSArray* _cdnHosts;
@@ -111,6 +112,10 @@ - (FBURLConnection *)initWithRequest:(NSURLRequest *)request
self.handler = handler;
}
+
+ // always attempt to autoPublish. this function internally
+ // handles only executing once.
+ [FBSettings autoPublishInstall:nil];
}
return self;
}
View
3 src/FBUtility.h
@@ -26,7 +26,8 @@
+ (NSString*)stringByURLEncodingString:(NSString*)unescapedString;
+ (id<FBGraphObject>)graphObjectInArray:(NSArray*)array withSameIDAs:(id<FBGraphObject>)item;
-+ (unsigned long)currentTimeInMilliseconds;
++ (unsigned long)currentTimeInMilliseconds;
++ (NSTimeInterval)randomTimeInterval:(NSTimeInterval)minValue withMaxValue:(NSTimeInterval)maxValue;
+ (void)centerView:(UIView*)view tableView:(UITableView*)tableView;
+ (NSString *)stringFBIDFromObject:(id)object;
View
4 src/FBUtility.m
@@ -75,6 +75,10 @@ + (unsigned long)currentTimeInMilliseconds {
return (time.tv_sec * 1000) + (time.tv_usec / 1000);
}
++ (NSTimeInterval)randomTimeInterval:(NSTimeInterval)minValue withMaxValue:(NSTimeInterval)maxValue {
+ return minValue + (maxValue - minValue) * (double)arc4random() / UINT32_MAX;
+}
+
+ (id<FBGraphObject>)graphObjectInArray:(NSArray*)array withSameIDAs:(id<FBGraphObject>)item {
for (id<FBGraphObject> obj in array) {
if ([FBGraphObject isGraphObjectID:obj sameAs:item]) {
View
4 src/facebook-ios-sdk.xcodeproj/project.pbxproj
@@ -7,6 +7,7 @@
objects = {
/* Begin PBXBuildFile section */
+ 2A68590615C1E37E001D4EDD /* FBSettings+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A68590515C1E37E001D4EDD /* FBSettings+Internal.h */; };
5F7CB4201553ACC600C183CF /* FBLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = 5F7CB41E1553ACC600C183CF /* FBLogger.h */; };
5F7CB4211553ACC600C183CF /* FBLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F7CB41F1553ACC600C183CF /* FBLogger.m */; };
8409694C1541F41100479AD9 /* FBOpenGraphAction.h in Headers */ = {isa = PBXBuildFile; fileRef = 8409694B1541F41100479AD9 /* FBOpenGraphAction.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -172,6 +173,7 @@
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
+ 2A68590515C1E37E001D4EDD /* FBSettings+Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "FBSettings+Internal.h"; sourceTree = "<group>"; };
5F7CB41E1553ACC600C183CF /* FBLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBLogger.h; sourceTree = "<group>"; };
5F7CB41F1553ACC600C183CF /* FBLogger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBLogger.m; sourceTree = "<group>"; };
8409694B1541F41100479AD9 /* FBOpenGraphAction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBOpenGraphAction.h; sourceTree = "<group>"; };
@@ -438,6 +440,7 @@
84137156152B94B000B2C0E1 /* FBSessionManualTokenCachingStrategy.h */,
84137157152B94B000B2C0E1 /* FBSessionManualTokenCachingStrategy.m */,
DDB7C34A15A6181100C8DCE6 /* FBSettings.h */,
+ 2A68590515C1E37E001D4EDD /* FBSettings+Internal.h */,
DDB7C34B15A6181100C8DCE6 /* FBSettings.m */,
8525A5B8156F2049009F6F3F /* FBTestSession.h */,
85F29E9315785D72001F0531 /* FBTestSession+Internal.h */,
@@ -582,6 +585,7 @@
DDB7C34C15A6181100C8DCE6 /* FBSettings.h in Headers */,
85E4AC7715B63CB600F17346 /* FBUserSettingsViewController.h in Headers */,
85E4AC7D15B63CC500F17346 /* FBViewController.h in Headers */,
+ 2A68590615C1E37E001D4EDD /* FBSettings+Internal.h in Headers */,
85F99E3F15C3751100D807A5 /* FBViewController+Internal.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;

0 comments on commit a2269dc

Please sign in to comment.
Something went wrong with that request. Please try again.