Skip to content

Commit

Permalink
Putting back, again, the attribute code
Browse files Browse the repository at this point in the history
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
vijaye committed Aug 1, 2012
1 parent 39306b2 commit a2269dc
Show file tree
Hide file tree
Showing 8 changed files with 171 additions and 3 deletions.
3 changes: 3 additions & 0 deletions src/FBSession.m
Expand Up @@ -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"
Expand Down Expand Up @@ -264,6 +265,8 @@ - (id)initWithAppID:(NSString*)appID
[tokenCachingStrategy clearToken];
}
}

[FBSettings autoPublishInstall:self.appID];
}
return self;
}
Expand Down
23 changes: 23 additions & 0 deletions 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
28 changes: 26 additions & 2 deletions src/FBSettings.h
Expand Up @@ -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
104 changes: 104 additions & 0 deletions src/FBSettings.m
Expand Up @@ -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;
Expand All @@ -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
5 changes: 5 additions & 0 deletions src/FBURLConnection.m
Expand Up @@ -21,6 +21,7 @@
#import "FBLogger.h"
#import "FBUtility.h"
#import "FBSettings.h"
#import "FBSettings+Internal.h"

static NSArray* _cdnHosts;

Expand Down Expand Up @@ -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;
}
Expand Down
3 changes: 2 additions & 1 deletion src/FBUtility.h
Expand Up @@ -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;

Expand Down
4 changes: 4 additions & 0 deletions src/FBUtility.m
Expand Up @@ -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]) {
Expand Down
4 changes: 4 additions & 0 deletions src/facebook-ios-sdk.xcodeproj/project.pbxproj
Expand Up @@ -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, ); }; };
Expand Down Expand Up @@ -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>"; };
Expand Down Expand Up @@ -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 */,
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit a2269dc

Please sign in to comment.