RakutenAdvertisingAttribution iOS SDK
Our attribution SDK enables you to track app activity, including installs and purchase events, within your affiliate program.
Important: We recommend reading through the entire SDK documentation before beginning your SDK integration to make sure everything is clear. Your Implementation Specialist is happy to answer any questions you may have. Engineering support is also available to you as needed.
Requirements
- iOS 11.0+
- Xcode 11+
- Swift 5+
Import the attribution SDK into your iOS workspace
CocoaPods
Use CocoaPods to install attribution SDK as a pod. If you don’t have Cocoapods installed, follow this guide for intallations. If you have Cocopods already installed add the following lines in your Podfile:
source 'https://github.com/CocoaPods/Specs.git'
source 'https://github.com/Rakuten-Advertising-Developers/Specs.git'
target 'YOUR_TARGET_NAME' do
use_frameworks!
pod 'RakutenAdvertisingAttribution'
end
Run the following command from your project’s Podfile location
pod install --repo-update
Swift Package Manager
Also you can use the Swift Package Manager as integration method. If you want to use the Swift Package Manager as integration method, either use Xcode to add the package dependency or add the following dependency to your Package.swift
:
dependencies: [
.package(name: "RakutenAdvertisingAttribution",
url: "https://github.com/Rakuten-Advertising-Developers/RakutenAdvertisingAttribution-iOS-SDK.git",
.upToNextMajor(from: "1.0.0"))
]
Creating public/private key pairs
To integrate the SDK into your application, you must generate public/private key pairs using the following commands.
openssl genrsa -out rad_rsa_private.pem 4096
openssl rsa -in rad_rsa_private.pem -outform PEM -pubout -out rad_rsa_public.pem
The above commands will create the following two files.
- rad_rsa_private.pem: Store this private key securely. This key is required by the SDK to report events to our attribution server in a secured manner. We recommend obfuscating the private key which is required during SDK initialization. To obfuscate the private key, follow the instructions the “Private Key Obfuscation steps” section.
- rad_rsa_public.pem: This file is required by our attribution server to verify the signature.
Note: Email the rad_ras_public.pem public key and your app bundle id details to ra-sdk-support@mail.rakuten.com
Setup attribution SDK initialization
Optionally you can obfuscate your key using the following guide
In your AppDelegate application:didFinishLaunchingWithOptions:
initialize Configuration
struct
let configuration = Configuration(key: PrivateKey.data(value: <Your Private Key>),
launchOptions: launchOptions)
Optionally you can provide another server information, for example for stage environment
let backendInfo = BackendInfo.stageConfiguration
let configuration = Configuration(key: PrivateKey.data(value: <Your Private Key>),
launchOptions: launchOptions,
backendURLProvider: backendInfo)
Then pass it to SDK
RakutenAdvertisingAttribution.setup(with: configuration)
User Consent
According to User Privacy and Data Use SDK will ignore any events until user consent will be provided. To do this you have to provide next parameters
RakutenAdvertisingAttribution.shared.adSupport.isTrackingEnabled = true
RakutenAdvertisingAttribution.shared.adSupport.advertisingIdentifier = <IDFA_VALUE>
You can also retrive this value via ASIdentifierManager
by yourself or using IDFAFetcher
helper class which provided as part of SDK.
fetchIfAuthorized
checks current user’s consent state and fetch values. It’s common practise to call this function along with SDK configuration code and provide needed IDFA values as soon as possible.
IDFAFetcher.fetchIfAuthorized {
RakutenAdvertisingAttribution.shared.adSupport.isTrackingEnabled = $0
RakutenAdvertisingAttribution.shared.adSupport.advertisingIdentifier = $1.uuidString
}
In case you haven’t ask user’s consent previously, call requestTracking
function to do this, at an appropriate time in your app (SDK will ignore all events until receive consent from user)
IDFAFetcher.requestTracking {
RakutenAdvertisingAttribution.shared.adSupport.isTrackingEnabled = $0
RakutenAdvertisingAttribution.shared.adSupport.advertisingIdentifier = $1.uuidString
}
Don’t forget to add to Info.plist tracking usage description information
<key>NSUserTrackingUsageDescription</key> <string>This identifier will be used to deliver personalized ads to you.</string>
Handling INSTALL and OPEN events along with deeplink data
Our attribution SDK provides a function (resolve) to capture app install events automatically.
Simply call the RakutenAdvertisingAttribution.shared.linkResolver.resolve
function in AppDeletgate foreground method.
In your AppDelegate use:
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
RakutenAdvertisingAttribution.shared.linkResolver.resolve(url: url)
return true
}
func application(_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
RakutenAdvertisingAttribution.shared.linkResolver.resolve(userActivity: userActivity)
return true
}
Optionally you can use delegate
property of linkResolver
, to handle data from the response
class LinkResolveHandler {
...
}
extension LinkResolveHandler: LinkResolvableDelegate {
func didResolveLink(response: ResolveLinkResponse) {
DispatchQueue.main.async {
// handle response
}
}
func didFailedResolve(link: String, with error: Error) {
DispatchQueue.main.async {
// error case handling
}
}
}
...
var handler = LinkResolveHandler()
...
RakutenAdvertisingAttribution.shared.linkResolver.delegate = handler
When the app launches for the first time after installation, the resolve() method flags the session as the first session and our attribution server records the event as an INSTALL.
Important: When
resolve()
is called, our attribution server will attempt to attribute the event to an affiliate link referral. Please follow your business requirement on when to callresolve()
. Any excluding logic is the individual developer’s responsibility; however, we have included the following sample code to illustrate how to callresolve()
for specific traffic.
func shouldIgnoreLinkResolver(userActivity: NSUserActivity) -> Bool {
guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
let incomingURL = userActivity.webpageURL,
let host = incomingURL.host else { return false }
let excludedDomains: Set<String> = ["example.com", "excluded.com"]
return excludedDomains.contains(host)
}
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
if !shouldIgnoreLinkResolver(userActivity: userActivity) {
RakutenAdvertisingAttribution.shared.linkResolver.resolve(userActivity: userActivity)
}
return true
}
Handling Purchase Events
Our attribution SDK provides a function RakutenAdvertisingAttribution.shared.eventSender
to capture in-app purchase events. Upon successfully completing the order processing routine, call the RakutenAdvertisingAttribution.shared.eventSender
function passing details about the purchase.
Sample purchase event reporting code:
// Item level details (item1)
let content1: EventContentItem = [.price: 100,
.quantity: 1,
.sku: "788672541568328428",
.productName: "First Product Name"]
// Item level details (item2)
let content2: EventContentItem = [.price: 150,
.quantity: 2,
.sku: "788672541527138674",
.productName: "Second Product Name"]
// if you have more items continue with content3, content4 and so on and include in the Event() as below
// Order details
let eventData = EventData(transactionId: "12345",
currency: "USD",
revenue: 415,
shipping: 15,
tax: 7)
let event = Event(name: "PURCHASE",
eventData: eventData,
contentItems: [content1, content2])
RakutenAdvertisingAttribution.shared.eventSender.send(event: event)
Similarly, you can use delegate
property of eventSender
, to track status of sending events
class EventSenderHandler {
...
}
extension EventSenderHandler: EventSenderableDelegate {
func didSend(eventName: String, resultMessage: String) {
DispatchQueue.main.async {
// handle result
}
}
func didFailedSend(eventName: String, with error: Error) {
DispatchQueue.main.async {
// error case handling
}
}
}
...
var handler = EventSenderHandler()
...
RakutenAdvertisingAttribution.shared.eventSender.delegate = handler
Debugging
For debugging enable the logger as below:
RakutenAdvertisingAttribution.shared.logger.enabled = true
Once the logging flag enabled, you will be able to see resolve() and sendEvent() request and response payloads in the debug console.
Sample debug log:
RakutenAdvertisingAttribution.Logger
----->
POST https://attribution-sdk-endpoint-z7j3tzzl4q-uc.a.run.app/v2/resolve-link-rak
HEADERS: {
"Content-Type" : "application\/json",
"Authorization" : "Bearer eyJ0eX <...> EuY"
}
BODY: {
"device_data" : {
"is_simulator" : true,
"os" : "iOS",
"device_id" : "DA128118-C52B-4EAA-9F65-4C6A6F686F66",
"screen_width" : 414,
"model" : "iPhone",
"os_version" : "14.0",
"screen_height" : 896,
"ios_vendor_id" : "DA128118-C52B-4EAA-9F65-4C6A6F686F66",
"fingerprint" : "{\"userAgent\":\"Mozilla\/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit\/605.1.15 (KHTML, like Gecko) Mobile\/15E148\",\"webdriver\":false,\"language\":\"en-us\",\"colorDepth\":32,\"deviceMemory\":\"not available\",\"pixelRatio\":2,\"hardwareConcurrency\":\"not available\",\"screenResolution\":[896,414],\"availableScreenResolution\":[896,414],\"timezoneOffset\":-180,\"timezone\":\"Europe\/Kiev\",\"sessionStorage\":true,\"localStorage\":true,\"indexedDb\":true,\"addBehavior\":false,\"openDatabase\":false,\"cpuClass\":\"not available\",\"platform\":\"iPhone\",\"doNotTrack\":\"not available\",\"webglVendorAndRenderer\":\"Apple Inc.~Apple GPU\",\"adBlock\":false,\"hasLiedLanguages\":false,\"hasLiedResolution\":false,\"hasLiedOs\":false,\"hasLiedBrowser\":false,\"touchSupport\":[5,true,true],\"fontsFlash\":\"swf object not loaded\",\"audio\":\"35.10892752557993\",\"ip\":\"192.168.1.2\"}",
"hardware_id_type" : "vendor_id"
},
"universal_link_url" : "",
"first_session" : false,
"user_data" : {
"sdk_version" : "1.0.0",
"bundle_identifier" : "com.rakutenadvertising.RADAttribution-Example",
"app_version" : "1.0.0"
}
}
----->
RakutenAdvertisingAttribution.Logger
<-----
POST https://attribution-sdk-endpoint-z7j3tzzl4q-uc.a.run.app/v2/resolve-link-rak
CODE: 200
RESPONSE: {
"session_id" : "5f6c7374421aa900012733c4",
"link" : "",
"click_timestamp" : 0,
"device_fingerprint_id" : "5f6c7374421aa9000127343f"
}
<-----
IMPORTANT: We recommend disabling debugging in the production build.
Demo app
We provide a sample app that demonstrate the use of the Rakuten Advertising attribution SDK. You can find the open source application at this Git Repsitory
Example
To run the example project, clone the repo, and run pod install
from the Example directory first.
Usage
All examples require
import RakutenAdvertisingAttribution
somewhere in the source file.
Documentation
Author
Rakuten Advertising
License
RakutenAdvertisingAttribution iOS SDK is available under the MIT license. See the LICENSE file for more info.