The RavelinCore SDK enables:
- The generation of a unique and persistent device ID
- The collection of additional device details
- Session tracking
You can choose what functionality of the SDK you would like to use. However, at a mimimum we advise that you use the SDK to generate a reliable device ID and to send the additional device details for your app traffic. Device IDs are critical throughout our fraud prevention tool, especially for use in our graph database.
This repo provides some simple projects, showing the integration and usage of RavelinCore:
- Swift using SPM
- Swift using Cocoapods
- Objective-C using Cocoapods
Before you can integrate with the Ravelin mobile SDKs for iOS, you will need to obtain valid API keys which are available in the Ravelin dashboard in the account menu under the Developer option
If you have any questions on getting started, please ask us in your Ravelin support channel on Slack.
- Minimum Requirements
- User Privacy
- Install
- Update
- Usage
- Privacy Manifest
- Release Notes
- Core Class Reference
The RavelinCore
framework, version 2.x.x and above, supports a minimum of iOS 12. Versions 1.x.x suport a minimum of iOS 9.
Although the Ravelin Core SDK collects device data, because the purpose is fraud prevention, it falls under an exemption from having to ask your client for permission to track data through the AppTrackingTransparency framework. Please refer to:
"The following use cases are not considered tracking, and do not require user permission through the AppTrackingTransparency framework... When the data broker with whom you share data uses the data solely for fraud detection, fraud prevention, or security purposes. For example, using a data broker solely to prevent credit card fraud."
Privacy manifest files describe privacy practices in relation to:
- Data that their app or SDK collects and its purpose.
- Required Reason APIs that their app or SDK uses and the reason for using them.
Starting with version 1.1.2, RavelinCore includes a privacy manifest file and are also digitally signed.
In this respect, the SDK gathers the following data types to help prevent fraud:
- Precise location
- User ID
- Device ID
- Product Interaction
- Other Data Types
A detailed breakdown of the privacy manifest as provided by the Ravelin Core SDK.
The SDK is available via Cocoapods or Swift Package Manager(SPM).
Add RavelinCore to your PodFile:
pod 'RavelinCore', '~> 2.0.0', :source => 'https://github.com/unravelin/Specs.git'
Then, from the command line: pod install
Add RavelinCore via Xcode, Add Package Dependency: a package manifest is available at: [email protected]:unravelin/ravelin-core-ios-xcframework-distribution.git
In your PodFile change the version to the latest SDK version number.
Use the Cocoapod command line and run pod update RavelinCore
.
To verify the latest Ravelin SDK version check our Release Notes section.
You can update to the latest version of any packages you depend on by selecting File â–¸ Swift Packages â–¸ Update to Latest Package Versions.
Before v1.1.0 the SDK was only available as a "fat" framework, since v1.1.0 and above we have updated to use the XCFrameworks.
To update to the XCFrameworks in your project's Podfile, change from using:
'pod 'RavelinCore', '1.0.2' or: pod 'RavelinCore'
to:
pod 'RavelinCore', '~> 2.0.0', :source => 'https://github.com/unravelin/Specs.git'
To verify the latest Ravelin SDK version check our Release Notes section.
NOTE: For location tracking to be included in the data collected by the Ravelin Core SDK, your application should establish user permissions for location sharing before initialising the SDK. Please refer to the Apple documentation here for more information on the subject.
To use the framework within your project, import RavelinCore where required:
Swift
import RavelinCore
Objective-C
@import RavelinCore;
The singleton Ravelin class should be accessed via the sharedInstance
method. For RavelinCore version 2 and above, a shared
property is also available. You will first need to initialise the SDK with the createInstance
method passing your Ravelin Publishable API Key. See the Authentication for where to find this key. For RavelinCore version 2 and above, there is an alternative, configure
method.
Please ensure you use your Publishable API Key. Your Secret API Key should never be embedded in your app -- it should only be used to send requests from your backend to api.ravelin.com.
Swift
// Instantiation for tracking only
let ravelin = Ravelin.createInstance("publishable_key_live_----")
For RavelinCore version 2 and above, there is a preferred/alternative way to create and configure the shared instance:
/// Configure the singleton instance of the Ravelin sdk with your public key
/// - Parameters:
/// - apiKey: The public API key from your Ravelin dashboard
/// - Optional Parameters:
/// - customerId: Set a customerId
/// - tempCustomerId: Set a tempCustomerId
/// - orderId: Set an orderId
/// - customDeviceId: Set a customDeviceId
/// - appVersion: Set an appVersion
/// - logLevel: Set the logLevel (for debug/development)
/// - sendFingerprint: Defaults to true to send a fingerprint
/// - reset: reset the persisted ID
/// - completion: Completion handler for the response
/// - Remark: Use this method when using RavelinSDK in your app for the first time
public func configure(apiKey: String, customerId: String?, tempCustomerId: String? = nil, orderId: String? = nil, customDeviceId: String? = nil, appVersion: String? = nil, logLevel: RavelinCore.LogLevel = .error, sendFingerprint: Bool = true, reset: Bool = false, completion: @escaping RavelinCore.TrackResultResponse)
For example:
Ravelin.shared.configure(apiKey: "publishable_key_live_----", customerId: "customer012345", appVersion: "1.2.3") { result in
switch result {
case .success:
if let deviceId = Ravelin.shared.deviceId {
print("deviceId: \(deviceId)")
}
case .failure(let error):
print("\(error)")
return false
}
}
NOTE: by default, calling configure
will also send device fingerprint data, avoiding the need to make a subsequent trackFingerprint
call. However, if required, this behaviour can be disabled:
Ravelin.shared.configure(apiKey: "publishable_key_live_----", customerId: "customer012345", sendFingerprint: false)
Objective-C
// Instantiation for tracking only
self.ravelin = [Ravelin createInstance:@"publishable_key_live_----"];
Once initialised, you can use the sharedInstance
directly to access methods and properties.
For RavelinCore version 2 and above, a shared
property is also available and the tyepealias 'RavelinSDK' can be used in place of 'Ravelin'.
Swift
// Directly
Ravelin.sharedInstance().methodName()
// For RavelinCore version 2
RavelinSDK.shared.methodName()
Objective-C
// Directly
[[Ravelin sharedInstance] methodName];
Alternatively, keep a reference to the shared instance:
Swift
// Variable
let ravelin = Ravelin.sharedInstance()
// For RavelinCore version 2
let ravelinSDK = RavelinSDK.shared
Objective-C
// Variable
Ravelin *ravelin = [Ravelin sharedInstance];
Using the Ravelin Mobile SDK, you can capture various built in events along with your own custom ones that can later be viewed in the Ravelin dashboard. This can be very useful for analysts to gain additional context during an investigation. For example, if you can see that a user is going through unexpected parts of your customer journey at a set speed on a new device that could indicate suspicious activity. It can also be powerfull information to use for our Machine Learning Models to identify new parterns and behaviours.
These are the available predefined events:
- trackFingerprint
- trackPage
- trackSearch
- trackSelectOption
- trackAddToCart
- trackRemoveFromCart
- trackAddToWishlist
- trackRemoveFromWishlist
- trackViewContent
- trackLogin
- trackLogout
Available from version 2:
Special cases:
Sends the device Fingerprint to Ravelin. Call this function before any important moment in the customer journey that matches a [checkpoint]({{% ref "/merchant/guides/other-guides/checkpoints" %}}). The fingerprint is used to profile a user's device. The following is a list of possible checkpoints (subject to the Ravlein products you are using):
- Right after initialisation and before trackLogin.
- Before any call to the checkout API.
- Before sending a refund request.
- Before sending an account registration request.
Ensure that the customerId
is set before trackFingerprint()
is called.
Swift
let ravelinSDK = Ravelin.createInstance("publishable_key_live_----")
ravelinSDK.customerId = "customer012345"
ravelinSDK.trackFingerprint()
// optionally providing customerId as a parameter and/or a completion handler:
ravelinSDK.trackFingerprint("customer012345") { _,_,_ in
if let deviceId = self.ravelinSDK.deviceId {
print("trackFingerprint for deviceId: \(deviceId)")
}
}
// from version 2, there is an equivalent async/await function
try await ravelinSDK.trackFingerprint()
NOTE: For version 2 and above, using configure
, in place of 'createInstance', defaults to sending trackFingerprint
.
ravelinSDK.configure(apiKey: "publishable_key_live_----", customerId: "customer012345")
Objective-C
self.ravelin = [Ravelin createInstance:@"publishable_key_live_----"];
self.ravelin.customerId = @"customer012345";
[self.ravelin trackFingerprint];
To indicate when the user hits a new page. We would like this to be used for every new page or screen the user goes to.
Swift
let ravelinSDK = RavelinSDK.shared
// after ravelinSDK has been configured
ravelinSDK.trackPage("checkout page")
// optionally providing additional parameters and/or a completion handler:
ravelinSDK.trackPage("checkout page", eventProperties: ["p1" : "v1", "p2": "v2"]) {_, response, error in
if let error {
print("\(error)")
}
}
// from v2, there is an equivalent async/await function
try await ravelinSDK.trackPageLoadedEvent("checkout page")
Objective-C
NSDictionary *eventProperties = @{
@"p1" : @"v1",
@"p2" : @"v2",
@"p3" : @"v3"
};
[self.ravelin trackPage: @"checkout page" eventProperties: eventProperties];
To be used when a user performs a search. There is an optional searchValue
property that can be added to let us know about the search term.
Swift
ravelinSDK.trackSearch("search page", searchValue: "searchValue")
Objective-C
[[Ravelin sharedInstance] trackPage:@"search page" searchValue: @"searchValue"];
To be used when a user selects or changes a product option like colour, size or delivery option.
There is an optional option
property that can be added to let us know about the what option was selected, we suggest using one of the following values colour
, size
, date
, time
, seat
, ticketType
, delivery option
, but other values are accepted.
There is also an optional optionValue
porperty that can be sent to let us know what value was selected.
Swift
ravelinSDK.trackSelectOption("selection page", option: "option selected", optionValue: "option value")
Objective-C
[[Ravelin sharedInstance] trackSelectOption:@"selection page" option: @"option selected"];
To be used when an item is added or removed from the cart. There are two optional properteis itemName
and quantity
that can be added to let us know the product name and the quantity.
Swift
ravelinSDK.trackAddToCart("basket", itemName: "item name", quantity: 1)
ravelinSDK.trackRemoveFromCart("basket", itemName: "item name", quantity: 1)
Objective-C
[[Ravelin sharedInstance] trackAddToCart:@"basket" itemName: @"item name"];
[[Ravelin sharedInstance] trackRemoveFromCart:@"basket" itemName: @"item name"];
To be used when an item is added or removed from the wishlist. There is an optional itemName
property that can be added to let us know the product name.
Swift
ravelinSDK.trackAddToWishlist("wish list", itemName: "item name")
ravelinSDK.trackRemoveFromWishlist("wish list", itemName: "item name")
Objective-C
[[Ravelin sharedInstance] trackAddToWishlist:@"wish list" itemName: @"item name"];
[[Ravelin sharedInstance] trackRemoveFromWishlist:@"wish list" itemName: @"item name"];
To be used when the user interacts with product content like plays a video, expands a photo, expands product details.
There is an optional contentType_ property
to let us know what content the user intercated with, we suggest using one of the following values video
, photo
, productDescription
, deliveryOptions
, but other values are accepted.
Swift
ravelinSDK.trackViewContent("content page", contentType: "video")
Objective-C
[[Ravelin sharedInstance] trackViewContent:@"content page" contentType: @"deliveryOptions"];
To indicate that the user has just authenticated themselves. Use eventProperties to add additional key/pair information to the payload
Swift
ravelinSDK.trackLogin("login page")
// optionally providing additional parameters:
ravelinSDK.trackLogin("login page", eventProperties: ["p1" : "v1", "p2": "v2"])
Objective-C
NSDictionary *eventProperties = @{
@"p1" : @"v1",
@"p2" : @"v2",
@"p3" : @"v3"
};
[self.ravelin trackLogin: @"login page" eventProperties: eventProperties];
To indicate when the user has signed out of their session.
Swift
ravelinSDK.trackLogout("logout page")
Objective-C
[self.ravelin trackLogout: @"logout page"];
To indicate when the user has changed the currency. The currency
itself is an optional parameter and it should be compatible with ISO-4217.
Swift
ravelinSDK.trackCurrencyChange("currency update", currency: "EUR")
Objective-C
[self.ravelin trackCurrencyChange: @"currency update"];
To indicate when the user has changed the language.
The language
is an optional parameter and it should be compatible with ISO-639.
Swift
ravelinSDK.trackLanguageChange("currency update", language: "en-us")
Objective-C
[self.ravelin trackLanguageChange: @"currency update"];
To indicate when the user has pasted a value.
The pastedValue
is an optional parameter.
Swift
ravelinSDK.trackPaste("user details form", pastedValue: "pasted value")
Objective-C
[self.ravelin trackPaste: @"user details for"];
We can detect paste events using the UITextFieldDelegate method shouldChangeCharactersInRange
in conjunction with the Ravelin track
to send a custom event.
For version 2 of the SDK, a predefined trackPaste
is available.
Swift
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
// avoid checking the pasteboard when a user is typing and only adding a single character at a time
guard string.count > 1 else {
return true
}
guard string.contains(UIPasteboard.general.string ?? "") else {
return true
}
let pageTitle = "home"
// Send paste event to Ravelin SDK v1
RavelinSDK.shared.track(pageTitle, eventName: "PASTE", eventProperties: ["pastedValue": string])
// Send paste event to Ravelin SDK v2
RavelinSDK.shared.trackPaste(pageTitle, pastedValue: string)
return true
}
Objective-C
- (BOOL)textField:(UITextField *)iTextField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
// avoid checking the pasteboard when a user is typing and only adding a single character at a time
if(string.length <= 1) { return YES; }
// Check if the textfield contains pasted text
if([string containsString:[UIPasteboard generalPasteboard].string]) {
NSString *pageTitle = @"home";
// Send paste event to Ravelin SDK v1
[self.ravelin track:pageTitle eventName:@"PASTE" eventProperties: @{@"pastedValue": string}];
// Send paste event to Ravelin SDK v2
[self.ravelin trackPaste:pageTitle pastedValue:string];
}
return YES;
}
The track method can be used to log notable client-side events:
Swift
let pageTitle = "product page"
let eventName = "SHARE_PRODUCT"
let meta = ["productId" : "213", "sharePlaftorm" : "facebook"]
ravelinSDK.track(pageTitle, eventName: eventName, eventProperties: meta)
Objective-C
NSString *pagetitle = @"product page";
NSString *eventName = @"SHARE_PRODUCT";
NSDictionary *meta = @{@"productId" : @"213", @"sharePlaftorm" : @"facebook"};
[[Ravelin sharedInstance]track:pageTitle eventName:eventName eventProperties:meta];
NOTE: Track events have overload methods with completion handlers and will accept nil values for eventProperties
Here is a simple end-to-end example of using the RavelinCore within a View.
NOTE: All Ravelin network methods are asynchronous. Completion blocks are provided so you can handle each request accordingly. The example code will not necessarily call each method sequentially and is for demonstration purposes only.
Swift - RavelinCore version 2:
import UIKit
import RavelinCore
class ViewController: UIViewController {
let ravelinSDK = RavelinSDK.shared
override func viewDidLoad() {
super.viewDidLoad()
setupRavelinSDK()
}
func setupRavelinSDK() {
// by default, calling `configure` will also send device fingerprint data, avoiding the need to make a subsequent call to `trackFingerprint`
ravelinSDK.configure(apiKey: "publishable_key_live_----", customerId: "customer012345", appVersion: "1.2.3") { result in
switch result {
case .success():
print("setup success")
case .failure(let error):
print("setup error: \(error)")
}
}
}
@IBAction func trackButtonTouched(_ sender: Any) {
trackLogin()
}
func trackLogin() {
guard ravelinSDK.apiKey != nil else {
print("trackLogin - apiKey has not been set")
return
}
ravelinSDK.trackLogin("loginPage", eventProperties: nil) {_,_,error in
if let error {
print("trackLogin - didFailWithError \(error.localizedDescription)")
return
}
}
}
}
Swift - - RavelinCore version 1:
import UIKit
import RavelinCore
class ViewController: UIViewController {
// Declare Ravelin Shared Instance with API keys
private var ravelin = Ravelin.createInstance("publishable_key_live_----")
override func viewDidLoad() {
super.viewDidLoad()
trackFingerprint()
}
func trackFingerprint() {
ravelin.customerId = "customer012345"
ravelin.trackFingerprint() { _, response, error in
if let error = error { // handle error
print("Ravelin error \(error.localizedDescription)")
} else if let httpResponse = response as? HTTPURLResponse {
if httpResponse.statusCode == 200 { // handle success
ravelin.trackLogin("loginPage")
ravelin.orderId = "order-001"
ravelin.trackPage("checkout")
}
}
}
}
}
Objective-C - RavelinCore
@import RavelinCore;
@interface ViewController ()
@property (strong, nonatomic) Ravelin *ravelin;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self useCore];
}
- (void)useCore {
// Make Ravelin instance with API keys
self.ravelin = [Ravelin createInstance:@"publishable_key_live_----"];
self.ravelin.customerId = @"customer012345";
// Send a device fingerprint with a completion block
[self.ravelin trackFingerprint:^(NSData *data, NSURLResponse *response, NSError *error) {
if(!error) {
NSDictionary *responseData;
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
if (httpResponse.statusCode == 200) {
responseData = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers|NSJSONReadingAllowFragments error:nil];
NSLog(@"trackFingerprint - success");
// track login
[self.ravelin trackLogin:@"login"];
self.ravelin.orderId = @"order-001";
// track customer moving to a new page
[self.ravelin trackPage:@"checkout"];
// track logout
[self.ravelin trackLogout:@"logout"];
} else {
// Status was not 200. Handle failure
NSLog(@"trackFingerprint - failure");
}
} else {
NSLog(@"%@",error.localizedDescription);
}
}];
}
@end
For apps that provide part of the user interface with WebViews, embedded within a native app, it is recommended making a deviceId cookie available to those WebViews that utilise [ravelinjs]({{% relref "../../ravelinjs" %}}). The current version of ravelinjs will adhere to any ravelinDeviceId cookie that it finds.
Here is a simple example of sharing the deviceId via a cookie.
Swift
import UIKit
import WebKit
import RavelinCore
extension WKWebView {
func set(cookie: HTTPCookie, completion: SetCookieResponse? = nil) {
configuration.websiteDataStore.httpCookieStore.setCookie(cookie, completionHandler: completion)
}
}
class WebViewController: UIViewController {
// get a reference to the deviceId from the shared instance which has been configured elsewhere
private let deviceId = Ravelin.sharedInstance().deviceId
private var webView: WKWebView!
private func makeWebView() -> WKWebView {
let configuration = WKWebViewConfiguration()
configuration.websiteDataStore = WKWebsiteDataStore.default()
let webView = WKWebView(frame: .zero, configuration: configuration)
webView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(self.webView)
// ... complete WebView configuration and layout
return webView
}
private func makeDeviceIdCookie(deviceId: String) -> HTTPCookie? {
// example cookie
var properties: [HTTPCookiePropertyKey: Any] = [
.domain: "your.webite.com",
.path: "/",
.name: "ravelinDeviceId",
.expires: NSDate(timeIntervalSinceNow: yearInterval),
.value: deviceId]
if #available(iOS 13.0, *) {
properties[.sameSitePolicy] = HTTPCookieStringPolicy.sameSiteLax
}
return HTTPCookie(properties: properties)
}
private func shareDeviceIdWithWebView(deviceId: String, webView: WKWebView) {
let cookie = makeDeviceIdCookie(deviceId)
webView.set(cookie: cookie) {
print("setting cookie: \(cookie)")
}
}
override func viewDidLoad() {
super.viewDidLoad()
webView = makeWebView()
shareDeviceIdWithWebView(deviceId: deviceId, webView: webView)
}
}
Privacy Manifest File for Ravelin Core SDK Starting with v1.1.2, Ravelin Core SDK for iOS includes a privacy manifest file. Apple requires that every privacy manifest file contains the following keys.
NSPrivacyTracking Ravelin Core SDK does not use the collected data for tracking and hence this key is set to false.
<!-- Privacy manifest file for Ravelin Core SDK for iOS -->
<key>NSPrivacyTracking</key>
<false/>
NSPrivacyTrackingDomains Ravelin Core SDK for iOS does not connect with any Internet domains that engage in tracking users. This key is set to an empty array of domains.
<!-- Privacy manifest file for Ravelin Core SDK for iOS -->
<key>NSPrivacyTrackingDomains</key>
<array/>
NSPrivacyCollectedDataTypes Apple has identified a list of data types that when collected may help to identify/track the device. Device ID is the only data from that list that our iOS SDK collects from the device. As part of this dictionary item, Apple also requires the reason this data is collected to be declared in the privacy manifest file. This data is represented in the privacy manifest file:
<!-- Privacy manifest file for Ravelin Core SDK for iOS -->
<key>NSPrivacyCollectedDataTypes</key>
<array>
<dict>
<key>NSPrivacyCollectedDataType</key>
<string>NSPrivacyCollectedDataTypeDeviceID</string>
<key>NSPrivacyCollectedDataTypeLinked</key>
<false/>
<key>NSPrivacyCollectedDataTypeTracking</key>
<false/>
<key>NSPrivacyCollectedDataTypePurposes</key>
<array>
<string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
</array>
</dict>
<dict>
<key>NSPrivacyCollectedDataType</key>
<string>NSPrivacyCollectedDataTypePreciseLocation</string>
<key>NSPrivacyCollectedDataTypeLinked</key>
<false/>
<key>NSPrivacyCollectedDataTypeTracking</key>
<false/>
<key>NSPrivacyCollectedDataTypePurposes</key>
<array>
<string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
</array>
</dict>
<dict>
<key>NSPrivacyCollectedDataType</key>
<string>NSPrivacyCollectedDataTypeProductInteraction</string>
<key>NSPrivacyCollectedDataTypeLinked</key>
<false/>
<key>NSPrivacyCollectedDataTypeTracking</key>
<false/>
<key>NSPrivacyCollectedDataTypePurposes</key>
<array>
<string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
</array>
</dict>
<dict>
<key>NSPrivacyCollectedDataType</key>
<string>NSPrivacyCollectedDataTypeOtherUsageData</string>
<key>NSPrivacyCollectedDataTypeLinked</key>
<false/>
<key>NSPrivacyCollectedDataTypeTracking</key>
<false/>
<key>NSPrivacyCollectedDataTypePurposes</key>
<array>
<string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
</array>
</dict>
</array>
NSPrivacyAccessedAPITypes Ravelin Core SDK does not use any of the APIs
<!-- Privacy manifest file for Ravelin Core SDK for iOS -->
<key>NSPrivacyAccessedAPITypes</key>
<array/>
- supports iOS 12 and above
- adds a convenience
configure
function - adds predefined tracking events
- adds the option to provide a
customDeviceId
and associate anappVersion
- supports async/await
- provides acccess to fingerprint and tracked event data
- Provides a privacy manifest.
- And is digitally signed.
- SDK version captured during framework build (rather than at runtime)
- Support for XCFrameworks, supporting both M1 and Intel architectures when developing via Simulator
- Added Swift Packager Manager (SPM) support.
-
Small improvements
-
Last release providing a legacy "fat" framework on versions 1.0.2 and below. However, were possible, we recommend that you use the XCFramework distribution, since the legacy framework will no longer have new updates.
- RavelinCore.framework - available via RavelinCore
- Fixed crash associated with deviceId failing to persist to the keychain.
Fatal Exception: NSInvalidArgumentException
- Support for iOS 14.
- Security improvements.
- Fixed crash when retrying events.
Fatal Exception:NSInvalidArgumentException
- Queueing and retrying events when there is no internet connection or server errors.
- Collecting new device properties (Emulator and Jailbroken).
- More events to track customer activity ( example: trackSearch, trackAddToWishList, ... ).
- We had to bump the version from 0.3.1 to 0.3.3 due to some issues during the release process.
- Documentation improvements for CocoaPods.
- Added altitude tracking.
- SDK is modularised into "Core" and "Encrypt" components.
- RavelinCore.framework - which is used for deviceId, fingerprinting and tracking activity.
- Updates to encryption.
- Minor refactoring.
/// The singleton instance of the class
public static let shared: RavelinCore.Ravelin
/// for legacy compatibility
public static func sharedInstance() -> RavelinCore.Ravelin
/// get or set the orderId
public var orderId: String?
/// get or set customerId
public var customerId: String?
/// get or set tempCustomerId
public var tempCustomerId: String?
/// get or set customDeviceId
public var customDeviceId: String?
/// get or set appVersion
public var appVersion: String?
/// get or set logLevel
public var logLevel: RavelinCore.LogLevel
/// if set, return customDeviceId or return sdk generated deviceId
public var deviceId: String? { get }
/// return the sdk generated sessionId
public var sessionId: String? { get }
/// return the public API key from your Ravelin dashboard
public var apiKey: String? { get }
public typealias RavelinSDK = RavelinCore.Ravelin
public typealias RVNCore = RavelinCore.Ravelin
/// Configure the singleton instance of the Ravelin sdk with your public key
/// - Parameters:
/// - apiKey: The public API key from your Ravelin dashboard
/// - customerId: Set a customerId
/// - tempCustomerId: Set a tempCustomerId
/// - orderId: Set an orderId
/// - customDeviceId: Set a customDeviceId
/// - appVersion: Set an appVersion
/// - logLevel: Set the logLevel
/// - sendFingerprint: Defaults to true to send a fingerprint
/// - reset: reset the persisted ID
/// - completion: Completion handler for the response
/// - Remark: Use this method when using RavelinSDK in your app for the first time
public func configure(apiKey: String, customerId: String?, tempCustomerId: String? = nil, orderId: String? = nil, customDeviceId: String? = nil, appVersion: String? = nil, logLevel: RavelinCore.LogLevel = .error, sendFingerprint: Bool = true, reset: Bool = false, completion: @escaping RavelinCore.TrackResultResponse)
/// Configure the singleton instance of the Ravelin sdk with your public key
/// - Parameters:
/// - apiKey: The public API key from your Ravelin dashboard
/// - customerId: Set a customerId
/// - tempCustomerId: Set a tempCustomerId
/// - orderId: Set an orderId
/// - customDeviceId: Set a customDeviceId
/// - appVersion: Set an appVersion
/// - logLevel: Set the logLevel
/// - sendFingerprint: Defaults to true to send a fingerprint
/// - reset: reset the persisted ID
/// - Remark: Use this method when using RavelinSDK in your app for the first time
@available(iOS 13.0.0, *)
public func configure(apiKey: String, customerId: String?, tempCustomerId: String? = nil, orderId: String? = nil, customDeviceId: String? = nil, appVersion: String? = nil, logLevel: RavelinCore.LogLevel = .error, sendFingerprint: Bool = true, reset: Bool = false) async throws
/// Return the events that have been sent
/// - Returns: an array of events as json data
public var eventsData: Data? { get }
// example usage
if let eventsData = ravelinSDK.eventsData,
let jsonString = String(data: eventsData, encoding: .utf8) {
print("\(jsonString)")
}
/// Removes any previously cached sent event data
public func deleteEventsData()
NOTE this only relates to what is stored in an events data log and will not impact what is sent to the Ravelin API
/// Configure a singleton instance of the Ravelin sdk with your public key
/// - Parameters:
/// - apiKey: The public API key from your Ravelin dashboard
/// - Returns: The singleton instance of the class
/// - Remark: Use this method when using RavelinSDK in your app for the first time
public class func createInstance(_ apiKey: String) -> RavelinCore.Ravelin
NOTE the use of configure
is preferred over createInstance
- trackFingerprint
- trackPage
- trackSearch
- trackSelectOption
- trackAddToCart
- trackRemoveFromCart
- trackAddToWishlist
- trackRemoveFromWishlist
- trackViewContent
- trackLogin
- trackLogout
- track
available from version 2:
/// Fingerprints the device and sends results to Ravelin
/// - Parameters:
/// - customerId: The customerId to set for this device fingerprint.
/// - completionHandler: Completion handler for the response
public func trackFingerprint(_ customerId: String?, completionHandler: RavelinCore.TrackResponse?)
/// Fingerprints the device and sends results to Ravelin
/// - Parameters:
/// - customerId: The customerId to set for this device fingerprint.
@available(iOS 13.0.0, *)
public func trackFingerprint(customerId: String?) async throws
/// Sends a track page event to Ravelin
/// - Parameters:
/// - pageTitle: The title of the current page
/// - eventProperties: A dictionary of meta data to send with the event
/// - completionHandler: Completion handler for the response
public func trackPage(_ pageTitle: String?, eventProperties: [String : Any]?, completionHandler: RavelinCore.TrackResponse?)
/// Sends a track page loaded event to Ravelin
/// - Parameters:
/// - pageTitle: The title of the current page
/// - eventProperties: A dictionary of meta data to send with the event
@available(iOS 13.0.0, *)
public func trackPageLoadedEvent(_ pageTitle: String?, eventProperties: [String : Any]? = nil) async throws
/// Sends a track search event to Ravelin
/// - Parameters:
/// - pageTitle: The title of the current page
/// - searchValue: The searched term
/// - completionHandler: Completion handler for the response
public func trackSearch(_ pageTitle: String?, searchValue: String?, completionHandler: RavelinCore.TrackResponse?)
/// Sends a track search event to Ravelin
/// - Parameters:
/// - pageTitle: The title of the current page
/// - searchValue: The searched term
@available(iOS 13.0.0, *)
public func trackSearchEvent(_ pageTitle: String?, searchValue: String?) async throws
/// Sends a track select option event to Ravelin
/// - Parameters:
/// - pageTitle: The title of the current page
/// - option: The name of the option
/// - optionValue: The value of the option
/// - completionHandler: Completion handler for the response
public func trackSelectOption(_ pageTitle: String?, option: String?, optionValue: String?, completionHandler: RavelinCore.TrackResponse?)
/// Sends a track select option event to Ravelin
/// - Parameters:
/// - pageTitle: The title of the current page
/// - option: The name of the option
/// - optionValue: The value of the option
@available(iOS 13.0.0, *)
public func trackSelectOptionEvent(_ pageTitle: String?, option: String?, optionValue: String?) async throws
/// Sends a track add to cart event to Ravelin
/// - Parameters:
/// - pageTitle: The title of the current page
/// - itemName: Name of the item
/// - quantity: Quantity of the item
/// - completionHandler: Completion handler for the response
public func trackAddToCart(_ pageTitle: String?, itemName: String?, quantity: NSNumber?, completionHandler: RavelinCore.TrackResponse?)
/// Sends a track add to cart event to Ravelin
/// - Parameters:
/// - pageTitle: The title of the current page
/// - itemName: Name of the item
/// - quantity: Quantity of the item
@available(iOS 13.0.0, *)
public func trackAddToCartEvent(_ pageTitle: String?, itemName: String?, quantity: NSNumber?) async throws
/// Sends a track remove from cart event to Ravelin
/// - Parameters:
/// - pageTitle: The title of the current page
/// - itemName: Name of the item
/// - quantity: Quantity of the item
/// - completionHandler: Completion handler for the response
public func trackRemoveFromCart(_ pageTitle: String?, itemName: String?, quantity: NSNumber?, completionHandler: RavelinCore.TrackResponse?)
/// Sends a track remove from cart event to Ravelin
/// - Parameters:
/// - pageTitle: The title of the current page
/// - itemName: Name of the item
/// - quantity: Quantity of the item
@available(iOS 13.0.0, *)
public func trackRemoveFromCartEvent(_ pageTitle: String?, itemName: String?, quantity: NSNumber?) async throws
/// Sends a track add to wishlist event to Ravelin
/// - Parameters:
/// - pageTitle: The title of the current page
/// - itemName: Name of the item
/// - completionHandler: Completion handler for the response
public func trackAddToWishlist(_ pageTitle: String?, itemName: String?, completionHandler: RavelinCore.TrackResponse?)
/// Sends a track add to wishlist event to Ravelin
/// - Parameters:
/// - pageTitle: The title of the current page
/// - itemName: Name of the item
@available(iOS 13.0.0, *)
public func trackAddToWishlistEvent(_ pageTitle: String?, itemName: String?) async throws
/// Sends a track remove from wishlist event to Ravelin
/// - Parameters:
/// - pageTitle: The title of the current page
/// - itemName: Name of the item
/// - completionHandler: Completion handler for the response
public func trackRemoveFromWishlist(_ pageTitle: String?, itemName: String?, completionHandler: RavelinCore.TrackResponse?)
/// Sends a track remove from wishlist event to Ravelin
/// - Parameters:
/// - pageTitle: The title of the current page
/// - itemName: Name of the item
@available(iOS 13.0.0, *)
public func trackRemoveFromWishlistEvent(_ pageTitle: String?, itemName: String?) async throws
/// Sends a track view content event to Ravelin
/// - Parameters:
/// - pageTitle: The title of the current page
/// - contentType: The type of the content
/// - completionHandler: Completion handler for the response
public func trackViewContent(_ pageTitle: String?, contentType: String?, completionHandler: RavelinCore.TrackResponse?)
/// Sends a track view content event to Ravelin
/// - Parameters:
/// - pageTitle: The title of the current page
/// - contentType: The type of the content
@available(iOS 13.0.0, *)
public func trackViewContentEvent(_ pageTitle: String?, contentType: String?) async throws
/// Sends a track login event to Ravelin and sends customerId automatically if set
/// - Parameters:
/// - pageTitle: The title of the current page
/// - eventProperties: A dictionary of meta data to send with the event
/// - completionHandler: Completion handler for the response
public func trackLogin(_ pageTitle: String?, eventProperties: [String : Any]?, completionHandler: RavelinCore.TrackResponse?)
/// Sends a track login event to Ravelin
/// - Parameters:
/// - pageTitle: The title of the current page
/// - eventProperties: A dictionary of meta data to send with the event
@available(iOS 13.0.0, *)
public func trackLoginEvent(_ pageTitle: String?, eventProperties: [String : Any]? = nil) async throws
/// Ends current Ravelin session and sends logout event to Ravelin
/// - Parameters:
/// - pageTitle: The title of the current page
/// - eventProperties: A dictionary of meta data to send with the event
/// - completionHandler: Completion handler for the response
public func trackLogout(_ pageTitle: String?, eventProperties: [String : Any]?, completionHandler: RavelinCore.TrackResponse?)
/// Sends a track logout event to Ravelin
/// - Parameters:
/// - pageTitle: The title of the current page
/// - eventProperties: A dictionary of meta data to send with the event
@available(iOS 13.0.0, *)
public func trackLogoutEvent(_ pageTitle: String?, eventProperties: [String : Any]? = nil) async throws
/// Sends a track event to Ravelin
/// - Parameters:
/// - pageTitle: The title of the current page
/// - eventName: The name of the event
/// - eventProperties: A dictionary of meta data to send with the event
/// - completionHandler: Completion handler for the response
public func track(_ pageTitle: String?, eventName: String?, eventProperties: [String : Any]?, completionHandler: RavelinCore.TrackResponse?)
/// Sends a track event to Ravelin
/// - Parameters:
/// - pageTitle: The title of the current page
/// - eventName: The name of the event
/// - eventProperties: A dictionary of meta data to send with the event
@available(iOS 13.0.0, *)
public func trackEvent(_ pageTitle: String?, eventName: String?, eventProperties: [String : Any]?) async throws
/// Sends a track currency change event to Ravelin
/// - Parameters:
/// - pageTitle: The title of the current page
/// - currency: Name of the currency
/// - completionHandler: Completion handler for the response
public func trackCurrencyChange(_ pageTitle: String?, currency: String?, completionHandler: RavelinCore.TrackResponse?)
/// Sends a track currency change event to Ravelin
/// - Parameters:
/// - pageTitle: The title of the current page
/// - currency: Name of the currency
@available(iOS 13.0.0, *)
public func trackCurrencyChangeEvent(_ pageTitle: String?, currency: String?) async throws
/// Sends a track language change event to Ravelin
/// - Parameters:
/// - pageTitle: The title of the current page
/// - language: Name of the language
/// - completionHandler: Completion handler for the response
public func trackLanguageChange(_ pageTitle: String?, language: String?, completionHandler: RavelinCore.TrackResponse?)
/// Sends a track language change event to Ravelin
/// - Parameters:
/// - pageTitle: The title of the current page
/// - language: Name of the language
@available(iOS 13.0.0, *)
public func trackLanguageChangeEvent(_ pageTitle: String?, language: String?) async throws
/// Sends a track paste event to Ravelin
/// - Parameters:
/// - pageTitle: The title of the current page
/// - pastedValue: The pasted vale
/// - completionHandler: Completion handler for the response
public func trackPaste(_ pageTitle: String?, pastedValue: String?, completionHandler: RavelinCore.TrackResponse?)
/// Sends a track paste event to Ravelin
/// - Parameters:
/// - pageTitle: The title of the current page
/// - pastedValue: The pasted vale
@available(iOS 13.0.0, *)
public func trackPasteEvent(_ pageTitle: String?, pastedValue: String?) async throws