Track Facebook app installs through ads - ios

We are looking for a way to track if the current user comes from a Facebook ad. Is there a way to achieve that?
We need to set this info in our database in order to make queries on these people (cohorts).
I found some similar questions :
Here
And here.
We are not looking for external services, we need to have this info in our database to create cohorts.
P.S: We are already tracking installs with [FBSettings publishInstall:FACEBOOK_APP_ID];

While reverse engineering some Tracking frameworks I found that most of them are getting the Facebook Attribute ID (Advertiser ID) from the pasteboard. It seems that Facebook is setting that after the ad is touched.
I couldn't find any documentation but the Facebook SDK has a class FBUtility with an attributionID class method.
+ (NSString *)attributionID
{
return [[UIPasteboard pasteboardWithName:#"fb_app_attribution" create:NO] string];
}

Related

iOS: Detect whether my SDK is installed on another apps on the device

I am developing a location based Q&A SDK for mobile devices.
When a question is asked about a specific location, the server side targets the most relevant user and sends the question to that user. If the user fails to answer, the question is sent to the second best user, and so on.
The problem is that my SDK might be installed on more than one application on the device, meaning that the user can get a question more than once.
Is there a way to detect whether my SDK is installed on more than one app? I thought that sending the UDID to the server might work, but iOS UDIDs differ between applications.
You can use UIPasteboard to share data between applications on the device.
The UIPasteboard class enables an app to share data within the app and with another app. To share data with any other app, you can use system-wide pasteboards; to share data with another app that has the same team ID as your app, you can use app-specific pasteboards.
In your SDK, do something like this:
#interface SDKDetector : NSObject
#end
#implementation SDKDetector
+ (void)load
{
int numberOfApps = (int)[self numberOfAppsInDeviceUsingSDK];
NSLog(#"Number of apps using sdk:%d", numberOfApps);
}
+ (NSInteger)numberOfAppsInDeviceUsingSDK
{
static NSString *pasteboardType = #"mySDKPasteboardUniqueKey";
NSData *value = [[UIPasteboard generalPasteboard] valueForPasteboardType:pasteboardType];
NSMutableArray *storedData = [[NSKeyedUnarchiver unarchiveObjectWithData:value] mutableCopy];
if (!storedData) {
storedData = [NSMutableArray new];
}
NSString *bundleId = [[NSBundle mainBundle] bundleIdentifier];
if (![storedData containsObject:bundleId]) {
[storedData addObject:[[NSBundle mainBundle] bundleIdentifier]];
}
value = [NSKeyedArchiver archivedDataWithRootObject:storedData];
[[UIPasteboard generalPasteboard] setData:value forPasteboardType:pasteboardType];
return [storedData count];
}
#end
If you only want to provide an SDK, it is not possible. Apple has added security steps to prevent that for user privacy. Keychain sharing will not work, because apps must share the same bundle seed ID (see here for more info).
If you want to provide an app along with your SDK, then you could do something like Facebook does, where app sends a "helo" message, Facebook asks user and finally Facebook sends "ehlo" message.
Your App -> "I would like to use the SDK; please give me token" -> SDK Controller App -> (Remember which apps have requested use) -> "OK, you can use the SDK; here is a token: #123" -> Your App
The SDK controller app can now send the server the list of apps.
I think you can group the apps on the same device by IP address as they will use the same address to connect to your server.
So the IP address will represent the device and the API key will represent the app that uses the SDK.
Can you try using
advertisingIdentifier
Not sure whether it serves your purpose. It is explained in here ASIdentifierManager class reference : Apple doc
I think its possible using keychain, you can have an unique keychain key in which you can save anything you want, and can be accessed by other apps if available. So for your SDK, lets say if there is one app, it will register some value in keychain with a unique key which is private to your SDK only if the key doesn't exist, and if it exist you get to know, since you can save any value in keychain, you can try multiple options and combinations which suits you.
You can use KeychainItemWrapper for the implementations.
Elaboration
Lets say we have an method.
[MySDK register];
Which can be used anywhere, say in AppDelegate. The register method will generate a token for the app, for the device, which we will save in the keychain using an unique key we have defined in the SDK, say in com.mysdk.key. And while saving in keychain the SDK can actually do a registration.
We consider the above method is implemented in multiple apps.
Now we have scenario.
User installs an App-A which uses the SDK, the register method will call and create a token and will save in keychain for the first time.
Now user installs another App-B which also uses the SDK, the same register method will call, but now it will check for the key com.mysdk.key in keychain, if exist it will just update the count for the token, which meant for the device.
Note
Keychain not meant to save only unique identifier, you can save other informations too.
Update
Check demo projects https://db.tt/7xpKrgMp
The wrapper I have used in the projects is same as SDK in your case which is same in both the projects.
Cheers.

How to integrate Facebook User's Newsfeed (or) Wall post in iOS App

I'm trying to integrate a custom view which shows a few post of the users Facebook news feed.
I'm looking for a good starting point. I don't want to use a UIWebView or something like this to grab the mobile site of Facebook instead I want to get data in JSON format or similar and display it in a custom fashion.
Can you give me any advice or links to tutorials how i can get the Facebook news feed data?
Edit: I want to update my requirements. I looked a bit into the Facebook Documentation and the SDK. There are some Sample Codes which are useful but I'm missing a straight forward tutorial or sample which does fetch the users newsfeed and displays it. This is why I made the bounty.
I will give the +100 Rep for somebody that creates a sample or tutorial which does get posts of the users newsfeed. Required would be: Get the name of the poster, message, timestamp and attached image. It would be nice if you also show them in a uiview but it is not required. If there is an existing framework feel free to link it.
I'm working myself on something similar and will publish it too. I think this could be tribute to the community.
I have created a sample starter project that gets the user's facebook newsfeed and displays it. It shows who did the post, the poster's profile picture, and when it was posted along with the message.
It is fairly rudimentary and could use some enhancement from other developers, i.e. endless scrolling, displaying any links, likes or recognizing URLs, etc.
https://github.com/AaronBratcher/UserFeed
I would integrate the Facebook API on my project, and then you can have access of many informations available on Facebook.
A good start point is read the documentation that you can find here:
https://developers.facebook.com
It's not hard to understand, but it has a lot of information!
Good luck.
At first, you need "read_stream" permission for your app.
Then read Facebook Query Language (FQL) Reference https://developers.facebook.com/docs/reference/fql/
To get the Newsfeed you can use the following code:
NSString *fqlString = #"SELECT * FROM stream WHERE filter_key IN (SELECT filter_key FROM stream_filter WHERE uid=me() AND type='newsfeed') AND is_hidden=0 LIMIT <YOUR_LIMIT>";
[FBRequestConnection startWithGraphPath:#"/fql"
parameters: #{#"q": fqlString}
HTTPMethod:#"GET"
completionHandler:^(FBRequestConnection *connection, id result, NSError *error)
{
<ANALYZE RESPONSE>
}];
Facebook API / SDK Request Wrapper
News feed post class
Simple UI to test the code
Getting Started:
facebook-sdk-posting-to-user-news-feed
Sample App
To my knowledge you cannot obtain News Feed data in your application. stream table shows only the posts that have appeared on your wall. To create a News Feed for a user Facebook uses his own private algorithm (it was Facebook Edgerank, but read that recently they had changed this algorithm to a new one).
To my point of view, to achieve your goal you can crawl data of all your friends and try to create an algorithm that will range these posts similar to the way it is done by Facebook.

How to get Facebook attribution ID on iOS?

Facebook attribution ID is available if user installed Facebook app on his phone.
On Android, it can be extracted with this piece of code -
Report Android app install back to facebook without using their api
By looking at Facebook's SDK for iOS, they access it with -
+ (NSString *)attributionID {
return [[UIPasteboard pasteboardWithName:#"fb_app_attribution" create:NO] string];
}
(https://github.com/facebook/facebook-ios-sdk/blob/master/src/FBUtility.m)
But when I call this method on a phone with FB app installed, it returns nil.
How do I extract it on iOS?
Unfortunately I think the answer is that you can't do this. At least for as long as Facebook is using the UIPasteboard.
That code in your post would access an app-specific pasteboard. If it was created by the Facebook application then it would only be accessible to Facebook's other applications.
The UIPasteboard class enables an app to share data within the app and
with another app. To share data with any other app, you can use
system-wide pasteboards; to share data with another app that has the
same team ID as your app, you can use app-specific pasteboards.
The quote above is from the docs

Where exactly should I put the call to [FBSettings publishInstall:appId]

I'm looking at integrating support for tracking Facebook's new mobile app ads.
I've read the tutorial here:
https://developers.facebook.com/docs/tutorials/mobile-app-ads/
It says:
Include the following code to be executed when your app opens for the first time by user
[FBSettings publishInstall:appId];
So the first question is - where do I put this so that it only invokes the call if the install was driven from Facebook? I don't want FB to get credit for someone who found my app themselves on the app store.
Do I need to manually track whether or not I've called the publishInstall before for this specific user? (The preamble sentence implies this - but the SDK documentation for publishInstall implies otherwise).
And even more confusing is that the SDK FBSettings reference includes shouldAutoPublishInstall which defaults to YES. This would suggest that I don't need to do anything other than have the SDK integrated. So why does the tutorial not mention this as an option?
I assume that the appId is the associated Facebook appId (as opposed to the App Store App ID). This is also not clear from the documentation.
I browsed the sources of facebook iOS SDK, and it seems that guide is wrong.
You are right, that autoPublishInstall is set to YES by default, which means we don't need to invoke [FBSettings publishInstall:appId]; manually. AppId is indeed the facebook app id.
When you invoke openActiveSessionWith.... method, it initializes FBSession with
initWithAppID:permissions:defaultAudience:urlSchemeSuffix:tokenCacheStrategy: which contains in the end [FBSettings autoPublishInstall:self.appID];
+ (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];
});
}
}
So technically it should report the install out of the box (if I'm not missing something). I'm going to play with it a little more today to see if it works as expected and update answer with results.
Just put it at -[application:didFinishLaunchingWithOptions].
Not all of the apps want to integrate the Facebook login. They only want the feature "mobile app install ads". For these kind of app, they should invoke +[FBSettings publishInstall:appId] manually. On the other hand, if your app has already integrated facebook login, you can assume that the FB sdk has published the installation.
If we just have to put
[FBSettings publishInstall:appId];
manually in
-[application:didFinishLaunchingWithOptions]
how will I identify which install happened from facebook? I don't want FB to get credit for someone who found my app themselves on the app store.
put the code in Appdelegate DidbecomeActive method
- (void)applicationDidBecomeActive:(UIApplication *)application
hope this help :)

Facebook facebook-ios-sdk and graph api is not working

I am using the official facebook ios sdk in my app (https://github.com/facebook/facebook-ios-sdk)
It was all working fine. I was able to log in, pull all my info from Facebook, post things on my wall. Do all those regular stuff that you do...
But since last night, it appears to be broken. When the login window appears and the user logs in, instead of getting the authkey and getting a callback. The login window directs users to facebook.com.
Did anyone else notice the problem? Is there any fix to it or we just assume that the graph API is broken right now and wait?
I assume Facebook were just having a problem. If you had it working & did not change the code then the issue is elsewhere?
In general it's a pain to get working so the following is a brief hint to anyone who is stuck.
Having spent 2 days getting this working I recommend (assuming you have registered an app with Facebook) :
First get the demo app working.
This ensures you have your app ID and worked out how to add the URL stuff into the plist. This is explained in the docs so should not give you much trouble.
Once all the options in the demo app work (login, post, upload a sample photo) you can think about your own app.
Many things are different but you still need to have the AppDelegate method for the URL stuff. Also this method does not work as is assuming your app is using more than one view controller.
I went for the approach of setting up facebook in the app delegate eg:
Facebook *facebook
and in the actual facebook routine referencing that appDelegate's facebook object eg:
appDelegate.facebook
This approach is the subject of quite a few posts on the interweb so you should be able to google it.
I can log on, get info, post & upload photos.
I'm having the same issue, i downloaded the "official example" from gitHub, and wehn compiled it does she#. After i login, it open safari and redirects to http://www.facebook.com/connect/uiserver.php, and the app stalls. Well that's not the way to do it, Facebook. They are obsoleting the old rest api, meanwhile the "new" graph things not working. Im currently using graph API with my own calls to graph.
Check if you have done the following
1.URL scheme corresponding to your Facebook application ID is set. Your URL Schemes must contain item looking like "fb1234567890"
2.AppDelegate's method must be implemented:
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
it is described in https://github.com/facebook/facebook-ios-sdk "Authentication and Authorization".
Read also "Single Sign-On".

Resources