Singular iOS SDK | |
---|---|
Download |
Singular iOS SDK version 11.0.7 (see Change Log) |
Compatibility | iOS 8+ |
Sample App |
Our sample app includes a complete integration of the Singular SDK. Review the code to see how the different parts of the integration come together using best practices. |
Integration Guides |
Adding Ad Revenue Attribution Support
Note: Starting in version 11.0.0, Singular added the option to set up ad revenue attribution through the Singular SDK.
Ad revenue attribution can still be set up the old way, using API calls, without updating the Singular SDK in your apps. However, if you want to measure ad revenue for SKAdNetwork campaigns, you have to set up ad revenue attribution through the SDK.
To add ad revenue attribution support in the Singular SDK:
- If you haven't done so yet, contact your Singular Customer Success Manager to enable ad revenue attribution for your account.
- Update to the latest version of the Singular SDK.
- Add the appropriate code snippet to your Singular SDK integration, depending on the mediation platform you use for ad revenue data.
// Note: This is a beta feature. Contact Admob to have it enabled.
GADRewardedAd* rewardedAd;
[GADRewardedAd loadWithAdUnitID:@"AD_UNIT_ID"
request:request
completionHandler:^(GADRewardedAd *ad, NSError *error) {
if (error) {
NSLog(@"Rewarded ad failed to load with error: %@", [error localizedDescription]);
return;
}
self.rewardedAd = ad;
self.rewardedAd.paidEventHandler = ^void(GADAdValue *_Nonnull adValue){
GADAdValue* impressionData = adValue;
SingularAdData* data = [[SingularAdData alloc] initWithAdPlatfrom:@"Admob" withCurrency:[impressionData currencyCode] withRevenue:[impressionData value]];
[data setAdUnitId:[rewardedAd adUnitID]];
[data setNetworkName:rewardedAd.responseInfo.adNetworkClassName];
}
}];
// The object received from AppLovin MAX's event, didReceivedMessage
ALCMessage* message;
SingularAdData* data = [[SingularAdData alloc] initWithAdPlatfrom:@"AppLovin" withCurrency:@"USD" withRevenue:message.data[@"revenue"] doubleValue];
[data setAdUnitId:message.data[@"max_ad_unit_id"]];
[data setNetworkName:message.data[@"network_name"]];
[data setAdType:message.data[@"ad_format"]];
[Singular adRevenue:data];
// The object received from IronSource's event, impressionDataDidSucceed
ISImpressionData* impressionData;
SingularAdData* data = [[SingularAdData alloc] initWithAdPlatfrom:@"IronSource" withCurrency:@"USD" withRevenue:impressionData.revenue];
[data setAdUnitId:[impressionData instanceId]];
[data setAdUnitName:[impressionData instanceName]];
[data setImpressionId:[impressionData auctionId]];
[data setNetworkName:[impressionData adNetwork]];
[data setAdPlacementName:[impressionData placement]];
[data setAdType:[impressionData adUnit]];
[Singular adRevenue:data];
// Ensure that the ARM SDK Postbacks Flag (click here) in IronSource is turned on
// The object received from Mopub's event, OnImpression
MPImpressionData* impressionData;
SingularAdData* data = [[SingularAdData alloc] initWithAdPlatfrom:@"Mopub" withCurrency:[impressionData currency] withRevenue:[impressionData publisherRevenue]];
[data setAdGroupId:[impressionData adGroupID]];
[data setAdGroupName:[impressionData adGroupName]];
[data setAdGroupType:[impressionData adGroupType]];
[data setAdGroupPriority:[impressionData adGroupPriority]];
[data setAdUnitId:[impressionData adUnitID]];
[data setAdUnitName:[impressionData adUnitName]];
[data setImpressionId:[impressionData impressionID]];
[data setNetworkName:[impressionData networkName]];
[data setAdPlacementName:"AD_PLACEMENT_NAME" ];
[data setAdType:"AD_TYPE"];
[Singular adRevenue:data];
// Initialize the SingularAdData object with the relevant data
SingularAdData* data = [[SingularAdData alloc] initWithAdPlatfrom:@"YOUR_AD_PLATFORM" withCurrency:@"CURRENCY_CODE" withRevenue:[NSNumber numberWithDouble:9.90]];
// The more ad data you add, the greater the granularity
[data setAdGroupId:@"AD_GROUP_ID"];
[data setNetworkName:@"AD_NETWORK_NAME"];
// Report the data to Singular
[Singular adRevenue:data];
Tracking Uninstalls
Note: Uninstall tracking is only available to Enterprise customers.
To let Singular track your app's uninstalls:
- Make sure uninstall tracking is enabled for your app in Singular. See Setting Up iOS Install Tracking for instructions.
- In the app, send Singular the device token returned from the Apple Push Notification Service (APNS). To pass the device token to Singular use the registerDeviceTokenForUninstall or registerDeviceToken method. Do this before the Singular StartSession call.
If your app doesn't support push notifications yet, see Apple's guide to implementing APNS.
Note:
- If you are already retrieving a device token from an existing push notification implementation, you can use that value.
- The APNS token is usually binary data in the native form. Pass the token as received from APNS. If the app alters the token data type pass it as a hex-encoded string, like the following example: b0adf7c9730763f88e1a048e28c68a9f806ed032fb522debff5bfba010a9b052
registerDeviceTokenForUninstall Method (Objective-C) | |
---|---|
Description | Pass the device token returned from APNS. |
Signature | + (void)registerDeviceTokenForUninstall:(NSData*)deviceToken; |
Usage Example |
Objective-C:
Swift:
|
Adding Global Properties
The Singular SDK lets you define custom additional properties that you want to send to the Singular servers with every session and event sent from the app. These properties can represent any information you want about the user, the app mode or status, or anything else. Once you set these properties, they are available as dimensions in your reports and you can use them to break down your data.
For example, if you have a gaming app, you can define a property called "Level" and set it initially to "0". Any session and event sent from the app will be sent with "Level": "0". Once the user levels up you reset the property to "1" and so on. You can then get your stats for sessions, events, and revenue data, broken down by the player's game level.
- You can define up to 5 global properties.
- They persist between app runs (with the latest value you gave them) until you unset them or the user uninstalls the app.
- Each property name and value can be up to 200 characters long. If you pass a longer property name or value, it will be truncated to 200 characters.
- Global properties are currently reflected in Singular's user-level event logs (see Exporting Attribution Logs) and in postbacks. Support for global properties in Singular's aggregate reporting (the Reports page or the reporting API) will be added in the future. If you have questions about this feature, or are interested in updates to global properties support, contact your Singular customer success manager.
Setting Global Properties through SingularConfig
To set global properties before initializing the SDK, use the setGlobalProperty method in SingularConfig.
Note that since global properties and their values persist between app runs, the property that you are setting may already be set to a different value. Use the overrideExisting parameter to tell the SDK whether to override an existing property with the new value or not.
setGlobalProperty Method | |
---|---|
Description | Set a global property. |
Signature | setGlobalProperty:(NSString*)key withValue:(NSString*)value overrideExisting:(BOOL)overrideExisting |
Usage Example |
Objective-C:
Swift:
|
Setting Global Properties After Initialization
Use the following methods to set, unset, and retrieve global properties at any time in the app's run.
setGlobalProperty Method | |
---|---|
Description |
Set a global property to a given value. Notes:
|
Signature | (BOOL) setGlobalProperty:(NSString*)key andValue:(NSString*)value overrideExisting:(BOOL)overrideExisting |
Usage Example |
|
getGlobalProperties Method | |
Description | Retrieve all the global properties and their current values as a Map. |
Signature | (NSDictionary*) getGlobalProperties |
Usage Example |
|
unsetGlobalProperty Method | |
Description | Remove a global property. |
Signature | (void) unsetGlobalProperty:(NSString*)key |
Usage Example |
|
clearGlobalProperties Method | |
Description | Remove all global properties. |
Signature | (void) clearGlobalProperties |
Usage Example |
|
Using the Singular SDK JavaScript Interface
Singular provides a JavaScript interface that you can use in order to call Singular from within javaScript code in your app.
For example, if you set up the JavaScript interface, you can send events to Singular from JavaScript code as follows:
Singular.event('event');
Singular.event('test', JSON.stringify({"a1":"bar",
"a2":"boo", "a3":"baz"}));
The interface supports the following SDK methods:
- setCustomUserID
- unsetCustomUserID
- event
- revenue
Enabling the JavaScript Interface
Note: Starting in iOS 8.0+ Apple recommends using WKWebView to add web content to your app. Do not use UIWebView or WebView. See Apple's WKWebView documentation for more information.
To enable the JavaScript interface when using WKWebView , you need to add some code to the webView method of the WKNavigationDelegate protocol (this protocol helps you implement custom behaviors triggered when a web view handles a navigation request).
Swift:
extension ViewController: WKNavigationDelegate {
func webView(_: WKWebView, decidePolicyFor: WKNavigationAction,
decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
// Singular handler
let js = "typeof(Singular)"
webView.evaluateJavaScript(js) { (result, error) -> Void in
if let resultString = result as? String {
if resultString.isEqual("undefined") {
do {
let contents = try String(contentsOfFile:
Bundle.main.path(forResource: "Singular", ofType: "js")!)
self.webView.evaluateJavaScript(contents,
completionHandler: nil)
} catch {
}
}
else {
print(decidePolicyFor.request)
Singular.processJSRequestWK(self.webView,
withURL:decidePolicyFor.request)
}
}
}
// rest of your code goes here
}
If you are using the older UIWebView (deprecated in iOS 8.0), update the method webView:shouldStartLoadWithRequest:navigationType: in your UIWebViewDelegate file as follows:
Objective-C:
- (BOOL)webView:(UIWebView *)webView
shouldStartLoadWithRequest:(NSURLRequest *)request
navigationType:(UIWebViewNavigationType)navigationType{
if([[webView stringByEvaluatingJavaScriptFromString:@"typeof(Singular)"] isEqualToString:@"undefined"]) {
// Inject Singular.js into the HTML
[webView stringByEvaluatingJavaScriptFromString:[NSString
stringWithContentsOfFile:[[NSBundle mainBundle]
pathForResource:@"Singular" ofType:@"js"] usedEncoding:nil error:nil]];
} else {
// process request in Singular.js
[Singular processJSRequest:webView withURL:request];
}
// The rest of your code goes here
return true;
}
Complying with Data Privacy Laws
Singular provides privacy-safeguarding functionality to help you cooperate with any partners who may be complying with consumer privacy laws such as GDPR and CCPA (California Consumer Privacy Act). These partners want to be notified if the end-user has consented to share their private information.
If you have implemented a way to ask users for consent to share their information, use the limitDataSharing method to notify Singular of the user's choice:
- Use limitDataSharing:NO to indicate that the user consented (opted in) to share their information.
- Use limitDataSharing:YES if the user did not consent.
Singular will pass this information on to partners who require it in order to comply with relevant regulations.
Note: The use of the method is optional, but there may be attribution information that the partner will share with Singular only if specifically notified that the user has opted in.
limitDataSharing Method | |
---|---|
Description | Notify Singular of user consent (opt-in) for sharing private data in compliance with the CCPA. |
Signature | limitDataSharing:(BOOL) shouldLimitDataSharing |
Usage Example |
|
Additional Methods for GDPR Compliance
The Singular SDK provides several methods to help you comply with GDPR policies and let Singular know about user consent or non-consent for tracking.
trackingOptIn Method | |
---|---|
Description | Notify Singular of user consent for tracking (opt-in). |
Usage Example | Objective-C:
Swift:
|
stopAllTracking Method | |
Description | Stopping all tracking activities for this user on this app Important: Calling this method effectively disables the SDK, even between app restarts (the state is persistent). The only way to turn it off is by calling the resumeAllTracking method |
Usage Example |
Objective-C:
Swift:
|
resumeAllTracking Method | |
Description | Resuming tracking activities for this user on this app |
Usage Example |
Objective-C:
Swift:
|
isAllTrackingStopped Method | |
Description | Checking the status of tracking for this user on this app |
Usage Example |
Objective-C:
Swift:
|