iOS SDK
The Kevel Audience iOS SDK is open-source and can be found at https://github.com/adzerk/audience-ios-objc-sdk.
Installation
Installation with CocoaPods
To integrate the Kevel Audience SDK into your Xcode project using CocoaPods, specify it in your Podfile
:
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '12.1'
project 'MyProject.xcodeproj'
target "MyProject" do
pod 'VelocidiSDK', '~> 0.4.0'
end
Then, run:
$ pod install
Installation with Carthage
To integrate VelocidiSDK into your Xcode project using Carthage, specify it in your Cartfile
:
github "velocidi/velocidi-ios-objc-sdk" ~> 0.4.0
Then, run carthage
to build the framework and drag the built VelocidiSDK.framework into your Xcode project.
Requirements
VelocidiSDK should work with any version of iOS equal or bigger than 10.0.
Usage
Initialize the SDK
Initialize the VelocidiSDK with the necessary trackingBaseUrl
and the matchBaseUrl
URLs. Without this, VelocidiSDK will not work. We suggest doing this when the application launches.
- Swift
- Objective-C
import VelocidiSDK
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
let config = VSDKConfig(trackingBaseUrl: "https://tr.yourdomain.com", matchBaseUrl:"https://match.yourdomain.com")!
VSDKVelocidi.start(config)
return true
}
@import VelocidiSDK;
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
VSDKConfig * config = [[VSDKConfig alloc] initWithTrackingBaseUrl:@"https://tr.yourdomain.com" matchBaseUrl: @"https://match.yourdomain.com"];
[VSDKVelocidi start: config];
return YES;
}
Collecting IDs
iOS 14 and Collecting IDs
In iOS 14, Apple changed their privacy guidelines and APIs. We recommend reading Apple's instructions on User Privacy and Data Use.
Due to those changes, the SDK no longer uses the IDFA by default and instead requires the developer to explicitly define an ID to identify the user. It is up to the developer to choose which user IDs to use, taking in consideration that the ID type should be supported by the CDP system. Refer to our list of supported IDs.
Using Your Own First-Party ID
You can use any ID in our list of supported IDs with VSDKUserId, as exemplified in Make a Match and Send a tracking event. If you would like to use an ID not present in our list of supported IDs, please contact our support so that we can add it.
Using the IDFV
The Identifier for Vendor (IDFV) is an ID that is shared amongst apps from the same vendor in the same device. It allows a vendor to uniquely identify a user's device, without relying on the device-wide IDFA, and its respective limitations. Per Apple's guidelines "The IDFV may not be combined with other data to track a user across apps and websites owned by other companies unless you have been granted permission to track by the user".
- Swift
- Objective-C
let idfv = UIDevice.current.identifierForVendor!.uuidString
let userId = VSDKUserId(id: idfv, type: "idfv")
Objective-C
NSString *idfv = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
VSDKUserId *userId = [[VSDKUserId alloc] initWithId:idfv type:@"idfv"];
Using the IDFA
If you are using the Identifier for Advertisers (IDFA) to identify the user, please make sure to read Apple's instructions on User Privacy and Data Use and be sure that your use case is compliant with Apple's guidelines.
The following examples should provide a general approach on retrieving the IDFA, but we recommend reading Apple's documentation on how to use the App Tracking Transparency framework.
Using the IDFA requires explicit authorization from the user for each application. To do so, start by establishing the message that will be presented to the user in the permission dialog. This can be done by adding the NSUserTrackingUsageDescription key to the Info.plist file of the application. The value of this key will be the message presented.
Before starting to send events, we have to request access to the IDFA, and only if that permission is granted, can we send events with the IDFA. If the user has not given permission yet, this might show the permission dialog box with the message previously set.
- Swift
- Objective-C
import AppTrackingTransparency
import AdSupport
func useIDFA(completionHandler: (Bool, String) -> Void) {
if #available(iOS 14, *) { // After iOS 14, we request the IDFA to the AppTrackingTransparency framework
ATTrackingManager.requestTrackingAuthorization { status in
let isTrackingEnabled = status == .authorized
var idfa: String? = nil
if isTrackingEnabled {
idfa = ASIdentifierManager.shared().advertisingIdentifier.uuidString
}
completionHandler(idfa)
}
} else { // On older devices, we can access the IDFA directly
let isTrackingEnabled = ASIdentifierManager.shared().isAdvertisingTrackingEnabled
var idfa: String? = nil
if isTrackingEnabled {
idfa = ASIdentifierManager.shared().advertisingIdentifier.uuidString
}
completionHandler(idfa)
}
}
#import <AdSupport/ASIdentifierManager.h>
@import AppTrackingTransparency;
- (void)useIDFA:(void (^)(NSString *))completionHandler {
if (@available(iOS 14, *)) { // After iOS 14, we request the IDFA to the AppTrackingTransparency framework
[ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(
ATTrackingManagerAuthorizationStatus status) {
bool isTrackingEnabled = status == ATTrackingManagerAuthorizationStatusAuthorized;
NSString *idfa = nil;
if (isTrackingEnabled) {
idfa = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
}
completionHandler(idfa);
}];
} else { // On older devices, we can access the IDFA directly
bool isTrackingEnabled = [[ASIdentifierManager sharedManager] isAdvertisingTrackingEnabled];
NSString *idfa = nil;
if (isTrackingEnabled) {
idfa = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
}
completionHandler(idfa);
}
}
Once we established a method of requesting permission for using the IDFA, we just have to call it and provide a completion handler where we are creating the event.
- Swift
- Objective-C
useIDFA(completionHandler: { (idfaOpt) in
if let idfa = idfaOpt {
let userId = VSDKUserId(id: idfa, type: "idfa")
// ...
}
})
[self useIDFA:^(NSString *idfa) {
if (idfa != nil) {
VSDKUserId *userId = [[VSDKUserId alloc] initWithId:idfa type:@"idfa"];
// ...
}
}];
User ID Matches
Match requests are used to link multiple identifiers in Kevel Audience. This way, any action made with any of the identifiers, across multiple channels (Browser, Mobile App, ...), can be associated to the same user.
In VelocidiSDK, a match request will link together all the provided user IDs:
- Swift
- Objective-C
@IBAction func sendMatchEvent(_ sender: Any) {
let userId1 = VSDKUserId(userId: "<email_hash>", "email_sha256")
let userId2 = VSDKUserId(userId: "<other ID>", "<other ID Type>")
let idsArray = NSMutableArray(array: [userId1, userId2])
VSDKVelocidi.sharedInstance().match("<match provider>", userIds: idsArray,
onSuccess:{ (response: URLResponse, responseObject: Any) in
print("Success! Response: \(response)")
}, onFailure:{(error: Error) in
print("Failed! Error: \(error.localizedDescription)")
})
}
- (IBAction)sendMatch:(id)sender {
VSDKUserId * userId1 = [[VSDKUserId alloc] initUserId:@"<email_hash>":@"email_sha256"];
VSDKUserId * userId2 = [[VSDKUserId alloc] initUserId:@"<other ID>":@"other ID type"];
NSMutableArray * idsArray = [[NSMutableArray alloc] initWithObjects: userId1, userId2, nil];
[VSDKVelocidi.sharedInstance match: @"<match provider>"
userIds: idsArray
onSuccess: ^(NSURLResponse * response, id responseObject){
NSLog(@"Success! Response: %@", trackingNumber);
} onFailure: ^(NSError * error){
NSLog(@"Failed! Error: %@", [error localizedDescription]);
}];
Collecting Events
A tracking event will log a user action in Kevel Audience.
In order to send a tracking event, create a JSON string representation of the event type you wish to send (or a equivalent NSDictionary
representation) and call the track
method.
- Swift
- Objective-C
import VelocidiSDK
...
let trackingEvent =
"""
{
"clientId": "bar",
"siteId": "foo",
"type": "appView",
"customFields": {
"debug": "true",
"role": "superuser"
},
"title": "Welcome Screen"
}
"""
// OR
let trackingEvent = [
"type": "appView",
"siteId": "foo",
"clientId": "bar",
"title": "Welcome Screen",
"customFields": [
"debug": "true",
"role": "superuser"
]
] as [String: Any]
let userId = VSDKUserId(id: "<user-idfa>", type: "idfa")
VSDKVelocidi.sharedInstance().track(trackingEvent, userId: userId)
@import VelocidiSDK;
...
NSString * trackingEvent = @"\
{\
\"clientId\": \"bar\",\
\"siteId\": \"foo\",\
\"type\": \"appView\",\
\"customFields\": {\
\"debug\": \"true\",\
\"role\": \"superuser\"\
},\
\"title\": \"Welcome Screen\"\
}\
";
// OR
NSDictionary *trackingEvent = @{
@"clientId" : @"foo",
@"siteId" : @"bar",
@"type" : @"appView",
@"customFields" : @{
@"debug" : @"true",
@"role" : @"superuser"
},
@"title" : @"Welcome Screen"
};
VSDKUserId * userId = [[VSDKUserId alloc] initWithId:@"user-idfa" type: @"idfa"];
[VSDKVelocidi.sharedInstance track: trackingEvent userId: userId]
Please refer to Event Collection to discover which event types and schemas are supported.
You can also pass callback blocks that will be called when the request either succeeds or fails.
- Swift
- Objective-C
VSDKVelocidi.sharedInstance().track(trackingEvent, userId: userId, onSuccess:{ (response: URLResponse, responseObject: Any) in
print("Success! Response: \(response)")
}, onFailure:{(error: Error) in
print("Failed! Error: \(error.localizedDescription)")
})
[VSDKVelocidi.sharedInstance track: trackingEvent userId: userId onSuccess: ^(NSURLResponse * response, id responseObject){
NSLog(@"Success! Response: %@", trackingNumber);
} onFailure: ^(NSError * error){
NSLog(@"Failed! Error: %@", [error localizedDescription]);
}];