Permutive Developer Hub

Welcome to the Permutive developer hub. You'll find comprehensive guides and documentation to help you start working with Permutive as quickly as possible, as well as support if you get stuck. Let's jump right in!

API Reference

Permutive iOS SDK

The Permutive iOS SDK (beta) has full support for Permutive's core functionality: event tracking, segment retrieval and identity management.

The SDK is accessible as a framework, downloadable from our website. If you prefer the traditional CocoaPods and static libraries delivery mechanism, this is fully supported as well.

In future, we plan to release kit libraries in addition to our core SDK, for enabling feature-rich integrations with third-party SDKs. This will enable you to more easily plug-in to other products, with minimal effort for developers.

Installing from CocoaPods

To install the SDK using CocoaPods, just add this line to your Podfile:
pod 'PermutiveSDK', '~> 0.12'

Initialise The SDK

The SDK requires that you provide the PermutiveOptions object. The options object is created with the Project ID and API Key - which are available from the Permutive dashboard. No other functionality of the SDK is available until these are passed in.

This call should only be made once in the entire code. We suggest putting this alongside other initialisations - in the application:didFinishLaunchingWithOptions:.

Here is an example of the configuration call:

import Permutive

if let projectId = UUID(uuidString: "becfaab8-d61e-4b64-99fd-d519baf368b3"),
    let apiKey = UUID(uuidString: "fff4fade-30ec-ad70-1686-6f7a27fa9cd9"),
    let options = PermutiveOptions.init(projectId: projectId, apiKey: apiKey) {
    // optional user identity
    options.userIdentity = ""
    Permutive.configure(with: options)
} else {
    print("configuration is incorrect")
// If modules are turned on:
@import Permutive;

// OR:
#import <Permutive/Permutive.h>

NSUUID *projectId = [[NSUUID alloc] initWithUUIDString:@"8e4deed5-bead-4a78-9063-73148668cde6"];
NSUUID *apiKey = [[NSUUID alloc] initWithUUIDString:@"45a03370-b962-4bab-cdef-067446d524ba"];
PermutiveOptions *options = [PermutiveOptions optionsWithProjectId:projectId apiKey:apiKey];

// optional: set identity at this point
options.userIdentity = @"";

if (options != nil) {
    [Permutive configureWithOptions:options];
} else {
    NSLog(@"configuration went wrong");

Identity Management

You can set a custom identity for the user, whenever it's available. This may be appropriate when users log in to your app, and a custom identity such as an internal identifier or email address may be available. Identifying a user with a custom identity is useful if you want to identify and synchronise users across platforms, for example across iOS and web.

You do not need to set a custom identity in order to track the user across iOS applications. By default, the IDFA will be used to identify the user if the IDFA is enabled and available on the device.

You can obtain the user identifier and is guaranteed to never be nil. However you need to remember that the userIdentifier changes every time that the user is setting a new identity.

// User ID
let userId = Permutive.userId()
// "1tcf4ab8-d51d-ab64-a9fd-cc19baf365c3"

// change Identity

// User ID
// "fgt4fa11-d516-5b64-30ec-0f7a27fa9cft0"
// User ID
NSString *userId = [Permutive userId];
NSLog(@"%@", )
// "1tcf4ab8-d51d-ab64-a9fd-cc19baf365c3"

// change Identity
[Permutive setIdentity:@""];

// User ID
NSString *userId = [Permutive userId];
NSLog(@"%@", )
// "fgt4fa11-d516-5b64-30ec-0f7a27fa9cft0"

Coding Patterns

The Permutive SDK API uses flexible and lightweight objects to allow for flexible event tracking, querying and update subscription. Once the SDK has been initialised with the Project and API Keys, the Permutive.permutive() services provider interface will provide a number of different objects. Feel free to request as many of these instances as necessary. These are not singletons and so they are thread safe.

Objects whose methods take a block will retain the blocks for their lifespan. Our SDK does not use Delegation or Singleton patterns - aside from the initial configuration. We leave the choice of calling our API from any object or thread in your app or just embedding it in one abstraction layer to the developer.

The [Permutive permutive], or Permutive.permutive() call will return NULL/nil if no API Key or Project ID has been provided.

Event Tracking

Events represent any activity in your application worth tracking. Examples include entering and leaving a view, engagement changes (e.g. scrolling inside an article) and any other user or environment driven inputs.

To track an event, grab an instance of the eventTracker object and call the track method. Event tracking can include properties, passed in as a dictionary. Please note, that event names and properties should only contain characters in [a-zA-Z0-9_]. Any character outside of the allowed character set will be removed before the event is tracked.

As with other Permutive SDK APIs, the event tracker object is lightweight and multiple instances of it can be created, as needed. Event tracking is thread-safe, so feel free to track event from any thread. It is also asynchronous, and will not block.

    properties: ["firstTime": true]

// Or one with no Properties
[[[Permutive permutive] eventTracker] track:@"AppLaunched" properties:@{
  @"firstTime": @(YES)

// Or one with no Properties
[[[Permutive permutive] eventTracker] track:@"AppStarted"];

You are able to use event enrichment in iOS in the same way as Web. Enrichment implementations are in place for picking up information about the user's geographical location and ISP information. Currently supported property values for enrichment are PermutiveEventPropertyValueConsts.geo_info and PermutiveEventPropertyValueConsts.isp_info. For example:

if let p = Permitive.permutive() {
       properties: ["geo_info": PermutiveEventPropertyValueConsts.geo_info, 
                    "isp_info": PermutiveEventPropertyValueConsts.isp_info]
id<PermutiveEventActionInterface> eventTracker = [[Permutive permutive] eventTracker];
if (eventTracker != nil) {
    [[[Permutive permutive] eventTracker] track:@"ScreenView" properties:@{
      @"geo_info": PermutiveEventPropertyValueConsts.geo_info, 
      @"isp_info": PermutiveEventPropertyValueConsts.isp_info

If Permutive is able to detect geographical and ISP information for the user, the geo_info and isp_info properties will be replaced with a JSON object, resulting in an event with the following structure:

  "geo_info": {
    "city": "Thundersley",
    "country": "United Kingdom",
    "continent": "Europe",
    "province": "Essex",
    "postal_code": "SS7"
  "isp_info": {
    "isp": "Sky Broadband",
    "organization": "Sky Broadband",
    "autonomous_system_number": 5607,
    "autonomous_system_organization": "Sky UK Limited"

If enrichment wasn't possible for any property, the corresponding properties will be excluded from the event.

Events Context

Events can contain contextual information, similarly to web events. Event context can be passed at the time event tracker is provided. The context object passed in is immutable and as such any subsequent changes to the context won't take effect. You can set values for the URL, title and referrer. The domain is automatically inferred from the URL if it has been set. Subsequent calls to track will contain the extra context as part of the event.

Here's an example:

let eventAContext = PermutiveEventActionContext()

eventAContext.url = URL(string: "")
eventAContext.title = "Main"

let p = Permutive.permutive()
let eventTracker = p?.eventTracker(with: eventAContext)

eventTracker?.track("sdk link")
PermutiveEventActionContext *eventAContext = [[PermutiveEventActionContext alloc] init];
eventAContext.url = [NSURL URLWithString: @""];
eventAContext.title = @"Main";

id<PermutiveEventActionInterface> eventAction = [[Permutive permutive] eventTrackerWithContext:eventAContext];

[eventAction track:@"event"];

Segment Query

The developer can query the list of all segments current user belongs to, using the API calls below. The segment list is returned as NSNumber array. These correspond to the segment IDs shown in the Permutive dashboard.

let segments: [Number]? = Permutive.permutive()?.triggersProvider.querySegments
// or to avoid optional

let segments: [Number] = Permutive.permutive()?.triggersProvider.querySegments ?? []
NSArray<NSNumber *> *segments = [[[Permutive permutive] triggersProvider] querySegments];

Tracking Segment Changes

To track changes in segment states, you can use triggers. Trigger actions are lightweight objects set up to track individual changes in segments. Each action object is responsible for a callback block, which will be executed whenever a change in one of the desired segments has occurred. To stop tracking the segment, just​ release the trigger action object.

Please be aware that the block will be called from a different thread than the one setting it up.
To track all segments, use the triggerActionForAllSegments method.

let triggersProvider = Permutive.permutive()?.triggersProvider
let triggerAction = triggersProvider?.triggerAction(forSegments: [1], triggerType: .onChange)
triggerAction?.setTriggerBlock({ (segment, value, oldValue) in
    let valueBool = value?.boolValue ?? false
    let oldValueBool = oldValue?.boolValue ?? false
    print("segment \(segment) changed from \(oldValueBool), \(valueBool)")

// retain triggerAction for as long as it is needed
// ...
triggerAction = nil

// Track all segments
let allSegmentsAction = triggersProvider?.triggerActionForAllSegments(with: .onChange)
allSegmentsAction?.setTriggerBlock({ (segment, old, new) in
  print("segment: \(segment), old: \(old), new: \(new)") 

id<PermutiveTriggersProvider> triggersProvider = [[Permutive permutive] triggersProvider];

id<PermutiveTriggerAction> triggerAction = [triggersProvider triggerActionForSegments:@[@(1)] triggerType:PermutiveTriggerOnChange];

[triggerAction setTriggerBlock:^(NSUInteger segment, NSNumber * _Nullable value, NSNumber * _Nullable oldValue) {
    NSLog(@"segment %d changed: old value->(%@), new value->(%@)", segment, oldValue, value);
// retain triggerAction for as long as it is needed
// ...
triggerAction = nil
// Track all segments
id<PermutiveTriggerAction> triggerAction = [[[Permutive permutive] triggersProvider] triggerActionForAllSegmentsWithTriggerType:PermutiveTriggerOnChange];

[triggerAction setTriggerBlock:^(NSUInteger segmentID, NSNumber * _Nullable value, NSNumber * _Nullable oldValue) {
  NSLog(@"segment: %d, new value: %@, old value: %@", segmentID, value, oldValue);

Google AdWords DFP Custom Targets

Our iOS SDK will return a dictionary of targeting data, which can be fed directly into your DFPRequest object instances. Using the triggers provider, simply get the required dictionary from the dfpRequestCustomTargeting property. This dictionary contains Permutive targeting data for the user. If you are already setting customTargeting property on your DFPRequests, you will need to merge the two dictionaries.

let request = DFPRequest()

if let segments = Permutive.permutive()?.triggersProvider.dfpRequestCustomTargeting {
    request.customTargeting = segments

NSDictionary<NSString *, NSArray<NSNumber *> *> *segments = [[[Permutive permutive] triggersProvider] dfpRequestCustomTargeting];

DFPRequest *request = [DFPRequest request];
request.customTargeting = segments

[self.bannerView loadRequest:request];