iOS V2.1.X

Introduction

SDK overview

Welcome to the Flagship iOS SDK documentation!

The following documentation helps you to run Flagship on your native iOS app using our client library with preconfigured methods to implement the Decision API.

Feel free to contact us if you have any questions regarding this documentation.

SDK features

This SDK version will help you:

Prequisites

  • Your app must be a native app written in Swift or Objective C.
  • Flagship SDK supports at least iOS 8.0+
  • Swift Client application must use Swift 5 or higher

Good to know

Getting Started

Our Flagship iOS SDK is available for distribution through CocoaPods, Swift Package Manager, Carthage or manual installation.

Cocoapods

  1. Install CocoaPods

  2. Open Terminal and browse to the directory that contains your project then, enter the following command: pod init

  3. Open your Podfile and add the following line to the Podfile

target 'Your App' do
    use_frameworks!

    pod 'FlagShip'

    end
  1. Run pod install from your Xcode project's base directory

  2. Make sure you always open the Xcode workspace and not the project file when building your project

Swift Package Manager (SPM)

You can search for Flagship package on GitHub. Add your GitHub or GitHub Enterprise account in Xcode’s preferences, and a package repository appear as you type.

Swift Package Manager video tutorial

For more information about Swift Package Manager, refer to Apple documentation.

Carthage

  1. Install Carthage

  2. Create a Cartfile in the same directory where your .xcodeproj or .xcworkspace is.

  3. Add this line to the Cartfile

github "flagship-io/flagship-ios" ~> 2.1
  1. Run carthage update --use-xcframeworks

  2. A Cartfile.resolved file and a Carthage directory will appear in the same directory where your .xcodeproj or .xcworkspace is.

  3. Drag the built Flagship.xcframework bundles from Carthage/Build into the "Frameworks, Libraries, and Embedded Content" section of your application’s Xcode project.

For More information refer to Carthage

Manual Installation

  1. Download the Flagship xcframework

  2. In Finder, browse to the Flagship.xcframework file and move it under your "Frameworks, Libraries, and Embedded Content" section in Xcode project.

Initialization

To run experiments with Flagship, you will need to start the SDK. Flagship uses a sharedInstance that can activate experiments and track events.

func start( envId:String, apiKey:String, visitorId:String?, config:FSConfig = FSConfig(), onStartDone:@escaping(FlagshipResult)

ParameterTypeRequiredDescription
envIdStringYesIdentifies your Flagship account and environment (preprod or prod). Find this ID
apiKeyStringYesIdentifies your Flagship api key (preprod or prod). Find this api key
visitorIdStringYesUnique identifier for the current user. This can be an ID from your database or a session ID. If no value is passed, the SDK will automatically generate a unique ID. Learn more
configFSConfigNoObject that represent configuration client. Default values are (DECISION_API for the mode and 2 seconds for the api timeout)
onStartDoneblockYesIndicates the codeblock to be invoked when the SDK is ready

📘

Notice Information

Unique identifier for the current user. This can be an ID from your database or a session ID. If no value is passed, the SDK will automatically generate a unique ID. Learn more

🚧

The SDK gives you the ability to change the envId for QA purposes. Don't forget to delete your app cache when changing environments.

FlagshipResult indicates the state of the SDK, Ready or NotReady

  • Ready: This status means the SDK is ready to use and you can get all modifications and send events
  • NotReady: This status means that an error occured at the initialization (see the logs for reason) and only a default value is returned when you call getModification

As the SDK is asynchronous and runs in parallel, this method enables you to set a block which will be executed when the SDK is ready.

📘

Remember to replace "your EnvId" and "your apiKey" with your own.

  1. Navigate to ParametersEnvironment & Security
  2. Copy the environment ID
import Flagship
///Start SDK Flagship with default mode which is Decision api
Flagship.sharedInstance.start(envId:"your envId", apiKey: "your apiKey", visitorId: "visitorId"){ (result) in
                                                                                                 
  if result == .Ready {
    DispatchQueue.main.async {
      // Update UI
    }
	}else{
  			// An error occurs or the SDK is disabled
    }
  }
/////////////////////////////////////////////////////////////////////////////
//////////////// Start SDK Flagship with custom configuration ///////////////
/////////////////////////////////////////////////////////////////////////////

/// init config object
let fsConfig = FSConfig(.BUCKETING)  /// config with bucketing mode

/// Or init config with Decision api mode and 0.2 second for timeout
let fsConfig = FSConfig(.DECISION_API, timeout: 0.2)

/// Or init config with consent to false
let fsConfig = FSConfig(.DECISION_API, timeout: 0.2, hasConsented: false)
  
///Start the SDK
Flagship.sharedInstance.start(envId:"your envId", apiKey: "your apiKey", visitorId: "visitorId", config:fsConfig){ (result) in

  if result == .Ready {
    DispatchQueue.main.async {

      /// Update UI
    }

    }else{

      /// An error occurs or the SDK is disabled
    }
  }

////////////////////////////////////////////////////////////////////////////////////////////
//// //////////////////To let Flagship generate a visitorId for you/////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////

/// Start Flagship with generated visitorId
Flagship.sharedInstance.start(envId:"your envId", apiKey: "your apiKey", visitorId:nil){ (result) in
  if result == .Ready {
    DispatchQueue.main.async {

      /// Update UI
    }

    }else{

      /// An error occurs or the SDK is disabled
    }
  }

// To get your generated visitorId, use:
Flagship.sharedInstance.visitorId
// init config object and set the running mode, timeout, authenticated and consent

FSConfig * config = [[FSConfig alloc] init:FlagshipModeDECISION_API timeout:0.2  authenticated:YES hasConsented:YES];

// Start the sdk
[[Flagship sharedInstance] startWithEnvId:@"you envId" apiKey:@"your apiKey" visitorId:@"visitorId" config:config onStartDone:^(enum FlagshipResult result) {

  if (result == FlagshipResultReady){

    dispatch_async(dispatch_get_main_queue(), ^{

              /// update UI
    });
  }else{

            /// An error occurs or the SDK is disabled
  }

}];

SDK Start Example

This example will walk you through the steps needed to configure a welcome message for VIP users:

This message will only be delivered to users with a VIP attribute present in the user context.

994

To get this message, update the user context with this attribute via the SDK:

/// Set the attribute isVip to true
Flagship.sharedInstance.updateContext("isVip", true)

Then you call the start function:

/// Start the SDK
Flagship.sharedInstance.start(envId:"your envId", apiKey: "your apiKey", visitorId: "visitorId"){ (result) in

  if result == .Ready {
    DispatchQueue.main.async {

      /// Update UI
    }

    }else{

      /// An error occurs or the SDK is disabled
    }
  }

📘

Once the state is Ready, you can access your modifications value from anywhere in your project.

Flagship configuration options

The sdk provide FSConfig object in start function as optional parameter where we can set the desired configuration

init(_ mode:FlagshipMode = .DECISION_API , timeout:TimeInterval = FSTimeoutRequestApi, authenticated:Bool = false, hasConsented:Bool = true)

ParameterTypeRequiredDescription
modeFlagshipModeNoApi or Bucketing. The default value is DECISION_API
timeoutTimeIntervalNoTimeout to fetch campaigns . The default value is FSTimeoutRequestApi which represent 2 seconds
authenticatedBooleanNoSpecify if the visitorId is authenticated true or anonymous false The value is false by default
hasConsentedBooleanNoSpecify if the visitor has consented for personal data usage. The value is true by default

Flagship Mode :

  • When the SDK is running in DECISION_API mode, the campaign assignments and targeting validation take place server-side. In this mode, each call to the synchronizeModifications method to refresh the modifications will create an HTTP request.

  • When the SDK is running in BUCKETING mode, the SDK downloads all the campaigns configurations at once in a single bucketing file so that variation assignment can be computed client-side by the SDK. This bucketing file is stored in cache and will only be downloaded again when campaign configurations are modified in the Flagship interface. Learn more

📘

The default value is DECISION API

Timeout :

This delay only concerns the request on fetching campaigns under the api mode. If the API didn't answer during this interval of time, the SDK will not wait longer for it and will use the modifications values already present on device's cache.
If there is no cache yet, the default values will be returned from the getModification function.

📘

The Timeout default value is 2 Seconds

Authenticated :

The visitorId will be considered as authenticated if true otherwise is anonymous.

📘

The default value is False

Consent :

Specify if the visitor has consented for personal data usage. When false some features will be deactivated, cache will be deactivated and cleared. Default value is True.

📘

The default value is True

Updating the user context

The user context is a property dataset which defines the current user of your app. This dataset is sent and used by the Flagship Decision API as targeting criteria for campaign assignment.

994

For example, if you wanted to enable or disable a specific feature based on VIP status, you would pass that attribute as a key-value pair in the user context so that the Decision API can enable or disable the corresponding feature flag for the user.

Flagship.sharedInstance.updateContext("isVip", true)

📘

User context values are used for targeting configuration.

The SDK provides a set of methods to push new user context values to Flagship.

These functions update the user context value matching the given key. If there isn't an existing value matching that key, a new context value associated with this key will be created.

  • Add Boolean Value to the user context:

    func updateContext(_ key:String, _ boolean:Bool)

  • Add a Double Value to the user context:

    func updateContext(_ key:String, _ double:Double)

  • Add a String Value to the user context:

    func updateContext(_ key:String, _ text:String)

  • Add a Float Value to the user context:

    func updateContext(_ key:String, _ float:Float)

  • Add a Integer Value to the user context:

    public func updateContext(_ key:String, _ integer:Int)

ParameterTypeRequiredDescription
keyStringYesAttribute key associated with the following value
valueString, Double, Boolean, FLoatYesAttribute value to add in the context
  • Add Dictionary to the user context:

func updateContext(_ contextValues:Dictionary<String,Any>)

ParameterTypeRequiredDescription
contextValuesdictionaryYesDictionary of key-value pairs (string, int, double, float, boolean)
// Add basketNumber with value 10 in the user context
Flagship.sharedInstance.updateContext("basketNumber", 10)

// Add isVip with true value to the user context
Flagship.sharedInstance.updateContext("isVip", true)

// Add name with value "alice" to the user context
Flagship.sharedInstance.updateContext("name", "alice")

// Add valueKey with value 1.2 to the user context
Flagship.sharedInstance.updateContext("valueKey", 1.2)

///////////////////////////////////////////////////
//////// Update context through dictionary ////////
///////////////////////////////////////////////////

// Create dictionary
let dictionaryCtx:[String:Any] = ["basketNumber": 10,"isVip":true,"name":"alice","valueKey": 1.2]
// Update context
Flagship.sharedInstance.updateContext(dictionaryCtx)
Add multiple value in the user context

// - isVip with true value
// - basketNumber with value 10 in the user context
// - name  with value "alice" in the user context
// - valueKey with value 1.2 in the user context

[[Flagship sharedInstance] updateContext:@{@"basketNumber":@10, @"isVip":@YES, @"name":@"alice", @"valueKey":@1.2}];

Predefined user context keys

The Flagship SDK contains predefined user context keys that do not count against your plan quota. Some of the predefined keys will automatically set their values, but you can always override them if needed. These key-value pairs are sent to Flagship and be available in the "Persona" section of the Flagship interface.

func updateContext(configuredKey:PresetContext, value:Any)

ParameterTypeRequiredDescription
configuredKeyPresetContextYesThe values defined in an enumeration PresetContext
valueString, Double, Boolean, FLoatYesthe value to add in the context

For a full list of the predefined keys, see the appendix.

////////////////////////////////////////////////////////
//////// update context with pre configured key ////////
////////////////////////////////////////////////////////

/// Set Region
Flagship.sharedInstance.updateContext(configuredKey: PresetContext.LOCATION_REGION, value: "ile de france")

/// Set Country
Flagship.sharedInstance.updateContext(configuredKey: PresetContext.LOCATION_COUNTRY, value: "FRANCE")

//////////////////////////////////////////////////////////////////////
///////// Add several pre configured key using the dictionary ////////
//////////////////////////////////////////////////////////////////////

Flagship.sharedInstance.updateContext([PresetContext.LOCATION_CITY.rawValue:"paris",
PresetContext.LOCATION_COUNTRY.rawValue:"France",
PresetContext.LOCATION_REGION.rawValue:"ile de france"])
/// Update context
[[Flagship sharedInstance] updateContext:@{@"basketNumber":@10, @"name":@"alice",@"valueKey": @1.2  }];

    /// Synchronize modfication
[[Flagship sharedInstance] synchronizeModificationsWithCompletion:^(enum FlagshipResult result) {
  if (result == FlagshipResultUpdated){

            /// Update UI ....
    NSString * title = [[Flagship sharedInstance] getModification:@"bannerTitle" defaultString:@"More Infos" activate:YES];
  }
}];

Campaign synchronization

Synchronizing campaigns

Synchronizing campaign modifications allows you to automatically call the Flagship decision API (or bucketing file), which makes the allocation according to the user context and gets all their modifications.

All the modifications returned by the API (or by the bucketing file) are stored in the SDK and are updated asynchronously when synchronizeModifications() is called.

func synchronizeModifications(completion:@escaping((FlagshipResult)->Void))

ParameterTypeDescription
completioncodeBlock to execute once the sync is completed

FlagshipResult indicates the state of the SDK as Updated or NotReady

  • Updated: The SDK is Updated. You can get all new modifications according to contextValues.
  • NotReady: An error occured at the update for some reason (See the logs). Only previous modifications before the update are still available.

📘

Notice Information

Once the new values given by the Decision API are updated, the block below is executed.

/////////////////////////////////////////////////////////////
//////// Update the context when basket value change ////////
/////////////////////////////////////////////////////////////

Flagship.sharedInstance.synchronizeModifications { (result) in

  if result == .Updated{

    /// Update the UI for users that have basket over or equal 100
    if (Flagship.sharedInstance.getModification("freeDelivery", defaultBool: false, activate: true)){

      DispatchQueue.main.async {

        /// Show your message for free delivery

      }
    }
  }
}
//////////////////////////////////////////////////////////////////////////
//////// Here, for example, update VIP user info and adapt the UI ////////
//////////////////////////////////////////////////////////////////////////

/// Update isVipUser with false value in the user context
[[Flagship sharedInstance] updateContext:@{@"isVipUser":@NO}];

/// Synchronize modfication
[[Flagship sharedInstance] synchronizeModificationsWithCompletion:^(enum FlagshipResult result) {

  if (result == FlagshipResultUpdated){

    dispatch_async(dispatch_get_main_queue(), ^{

      // Update the UI
      // Get title for banner
      NSString * title = [[Flagship sharedInstance] getModification:@"bannerTitle" defaultString:@"More Infos" activate:YES];
      // Set the title ...

   });
  }

}];

Synchronizing Context Example

Here's a quick guide on how to manage a free delivery threshold for e-commerce. In this example, free delivery is triggered when basketValue is greater than $100.

1005

In your code, call the following function

/// Update context with "basketValue" = 120
Flagship.sharedlnstance.updateContext("basketValue", 120)

///  Synchronize campaigns
Flagship.sharedInstance.synchronizeModifications { (result) in

    if result == .Updated{

        /// Update the UI for users having basket's values greater than or equal to 100
        if (Flagship.sharedlnstance.getModification("freeDelivery", defaultBool: false, activate: true)){

            DispatchQueue.main.async {

                /// Show message indicating free delivery threshold has been met
            }
        }
    }
}

This function will ask the decision API and get the new modifications according to context passed as parameters.

Once the update is done, you can display the free delivery message, as described in the example above.

Getting modifications

Once the campaign has been assigned and synchronized, all the modifications are stored in the SDK. You can retrieve these modifications using the following functions:

  • Get Modification for Boolean value:

    func getModification(_ key:String, defaultBool:Bool, activate:Bool) -> Bool

  • Get Modification for String value:

    func getModification(_ key:String, defaultString:String, activate:Bool) -> String

  • Get Modification for Double value:

    func getModification(_ key:String, defaultDouble:Double, activate:Bool) -> Double

  • Get Modification for Float value:

    func getModification(_ key:String, defaulfloat:Float, activate:Bool) -> Float

  • Get Modification for Int value :

    func getModification(_ key:String, defaultInt:Int, activate:Bool) -> Int

  • Get Modification for Json value:

    func getModification(_ key:String, defaultJson:Dictionary<String,Any>, activate:Bool = false)->Dictionary<String,Any>

  • Get Modification for Array:

    func getModification(_ key:String, defaultArray:[Any], activate:Bool = false)->[Any]

🚧

  • If the Decision API doesn't return any value for a key, the SDK will display the default value.
  • When the key value is a json object, the returned value will be a dictionary representing this json.
  • When the key value is an array, the returned value will be an array.
ParameterTypeRequiredDescription
keyStringYeskey associated with the modification.
defaultString, Boolean, Int, Float, Double, Dictionary, ArrayYesdefault value returned when the key doesn't match any modification value.
activateBooleanNofalse by default Set this parameter to true to automatically report on our server that the current visitor has seen this modification. If false, call the activateModification() later.

An example of keys values defined in the variation 1

1001

How to gets values:

/// Get "cta_text"
let title = Flagship.sharedInstance.getModification("cta_text", defaultString: "default", activate: true)

/// Get "cta_vallue"
let value = Flagship.sharedInstance.getModification("cta_value", defaultInt: 0, activate: true)

/// Get "isHidden"
let isTrue = Flagship.sharedInstance.getModification("isHidden", defaultBool: false, activate: true)

// Retrieve modification and activate
let title = FlagShip.sharedInstance.getModification("bannerTitle", defaultString: "More Infos", activate: true)
/// Retrieve modification and activate
 NSString * title = [[Flagship sharedInstance] getModification:@"bannerTitle" defaultString:@"More Infos" activate:YES];

Getting campaign information

You may need to send campaign's informations to a third-party for reporting and/or analytics purposes. The getModificationInfo method returns a dictionary with values you can use.

These values are:

keyTypeDescription
campaignIdStringid for the campaign
variationGroupIdStringId for the variation group
variationIdStringid for variation selected
isReferenceBoolif true that means the selected variation is a reference, otherwise not a reference.

func getModificationInfo(_ key:String) -> [String:Any]?

ParameterTypeRequiredDescription
keyStringYeskey associated with the modification.

📘

  • Return dictionary [String:Any]? with keys : campaignId, variationGroupId , variationId and isReference (e.g. { “campaignId”: “xxxx”, “variationGroupId”: “xxxx“, “variationId”: “xxxx”, "isReference":true})
  • Return nil if key modification doesn't exist
////////////////////////////////////////
////////  get modificationInfo /////////
////////////////////////////////////////

/// Get the informations
let infos = Flagship.sharedInstance.getModificationInfo(key:"btn-color")

if let infoCampaign = infos {

  /// Retreive the campaignId
  let campaignId = infoCampaign["campaignId"] as? String ?? "None"

  /// Retreive the variationGroupId
  let variationGroupId = infoCampaign["variationGroupId"] as? String ?? "None"

  /// Retreive the variationId
  let variationId = infoCampaign["variationId"] as? String ?? "None"

  /// Retreive reference indicator
  let isReference = infoCampaign["isReference"] as? Bool ?? false

  print(campaignId   + variationId   + variationGroupId  )

  }else {

    print("The key modification doesn't exist.")
  }
/// Get modification info
NSDictionary * dico = [[Flagship sharedInstance] getModificationInfoWithKey:@"btn-color"];

if (dico){
      /// Get campaignid
      NSString * campaignId = [dico valueForKey:@"campaignId"];
      /// Get variation group id
      NSString * variationGroupId = [dico valueForKey:@"variationGroupId"]
      /// Get variation id
      NSString * variationId = [dico valueForKey:@"variationId"];
      /// Get the boolean for reference
      BOOL  isRef = [dico valueForKey:@"isReference"];
        NSLog(@" %@ , %@, %@", campaignId, variationGroupId, variationId);
    }else{
        NSLog(@"The key modification doesn't exist.");
    }

Activating modifications

Once a modification is displayed on the screen for a user (and if your activate parameter was false in the getModification method), you must send an activate event to tell Flagship that the user has seen this specific variation.

func activateModification(key:String)

ParameterTypeRequiredDescription
keyStringYesModification identifier

🚧

If the given modification key doesn't exist, the activate event will not be sent

////////////////////////////////////////
//////// Activate modification /////////
////////////////////////////////////////

FlagShip.sharedInstance.activateModification(key: "cta_text")
/////////////////////////////////////
/////// Activate modification ///////
/////////////////////////////////////

[[Flagship sharedInstance] activateModificationWithKey:@"cta_text"];

Get Modification and activate it manually:

/// Get "cta_value"
let value = Flagship.sharedInstance.getModification("cta_value" defaultlnt: 0)

/// Activate Manually
Flagship.sharedlnstance.activateModification(key: "cta_value")

Managing visitor consent

The Sdk allows you to manage the consent on run time

////////////////////////////////////////
/////// Set the consent to false ///////
////////////////////////////////////////

Flagship.sharedInstance.consent = false
// Set the consent to false
[[Flagship sharedInstance]setConsent:FALSE];

📘

When the consent is false, activation and analytics hits will be disabled. Also, the cache will be cleared.

Experience continuity

Dealing with anonymous and logged-in users, experience continuity allows you to maintain the consistency.

  • From anonymous to logged-in, use the authenticateVisitor function

func authenticateVisitor(visitorId:String, visitorContext:[String:Any]? = nil, sync:((FlagshipResult)->Void)? = nil)

ParameterTypeRequiredDescription
visitorIdStringYesNew authenticated visitorId
visitorContext[String:Any]?NoReplace the current visitor context. Passing nil won't replace the current context. The default value is nil
syncblockNoIf a block is passed as parameter the sdk will automatically update the campaigns modifications and invoke this block when the update is done, otherwise you can manually update the modifications through synchronizeModifications function. The default value is nil
  • From logged-in to anonymous, use the unAuthenticateVisitor function

func unAuthenticateVisitor( visitorContext:[String:Any]? = nil, sync:((FlagshipResult)->Void)? = nil)

ParameterTypeRequiredDescription
visitorContext[String:Any]?NoReplace the current visitor context. Passing nil won't replace the current context. The default value is nil
syncblockNoIf a block is passed as parameter the sdk will automatically update the campaigns modifications and invoke this block when the update is done, otherwise you can manually update the modifications through synchronizeModifications function. The default value is nil
/////////////////////////////
/////// Authenticate ///////
////////////////////////////

/// Authenticate with visitorId "Alex" from anonymous to logged-in session
Flagship.sharedInstance.authenticateVisitor(visitorId:"Alex") { (result) in

    if result == .Updated{

      /// Modifications are updated with success
    }
  }

/// unAuthenticate from logged-in to previous anonymous session
Flagship.sharedInstance.unAuthenticateVisitor{ (result) in

     if result == .Updated{
      /// Modifications are updated with success
     }
 }
/// Authenticate with visitorId "Alex" from anonymous to logged-in session
[[Flagship sharedInstance] authenticateVisitorWithVisitorId:@"Alex" visitorContext:nil  sync:^(enum FlagshipResult result) {

    if( result == FlagshipResultUpdated){

        /// Modifications are updated with success
      }

  }];


/// unAuthenticate from logged-in to previous anonymous session
[[Flagship sharedInstance] unAuthenticateVisitorWithVisitorContext:nil sync:^(enum FlagshipResult result) {

     if( result == FlagshipResultUpdated){
       /// Modifications are updated with success
      }
  }];

Hit Tracking

This section helps you track your users in your application and learn how to build hits in order to feed campaign goals. For more information about our measurement protocol, read our Universal Collect documentation.

There are four different types of Hits available:

  • Screen
  • Transaction
  • Item
  • Event

They must all be sent with the following function:

func sendHit<T: FSTrackingProtocol>(_ event:T)

Common Parameters

These parameters can be sent with any type of hit.

ParameterTypeRequiredDescription
userIpStringNoCurrent user IP address
screenResolutionStringNoScreen Resolution
userLanguageStringNoUser Language
currentSessionTimeStampInt64NoCurrent Session Timestamp
sessionNumberIntNoSession Number
///////////////////////////////////////////////////
/////// Create event with common parameters ///////
///////////////////////////////////////////////////

let eventScreen = FSScreen("loginScreen")
/// Fill data for event screen
eventScreen.userIp 				     = "168.192.1.0"
eventScreen.sessionNumber 	   = 12
eventScreen.screenResolution   = "750 x 1334"
eventScreen.screenColorDepth   = "#fd0027"
eventScreen.sessionNumber      = 1
eventScreen.userLanguage    	 = "fr"
eventScreen.sessionEventNumber = 2
/// Send Event
Flagship.sharedInstance.sendHit(eventScreen)
////////////////////////////////////////////////////
/////// Create event with common parameters ///////
///////////////////////////////////////////////////

FSScreen* eventScreen =  [[FSScreen alloc] init:@"loginScreen"];
/// Fill data for event screen
eventScreen.userIp             = @"168.192.1.0";
eventScreen.sessionNumber      = @12;
eventScreen.screenResolution   = @"750 x 1334";
eventScreen.screenColorDepth   = @"#fd0027";
eventScreen.sessionNumber      = @1;
eventScreen.userLanguage       = @"fr";
eventScreen.sessionEventNumber = @2;
[[Flagship sharedInstance] sendScreenEvent:eventScreen];

Screen

This hit should be sent each time a visitor arrives on a new interface.

The FSScreen class represents this hit and it requires location as a string parameter.

init(_ location:String)

ParameterTypeRequiredDescription
locationStringYeslocation name
///////////////////////////////////
/////// Create Screen Hit ///////
///////////////////////////////////

/// Usage: this hit is usually sent when changing screens in the app
let eventScreen = FSScreen("loginScreen")
Flagship.sharedInstance.sendHit(eventScreen)
///////////////////////////////////
/////// Create Screen Event ///////
///////////////////////////////////

// Usage: this hit is usually sent when changing screens in the app
// Create screen event
 FSScreen * eventScreen =  [[FSScreen alloc] init:@"loginScreen"];

// Send Event
[[Flagship sharedInstance] sendScreenEvent:eventScreen];

Transaction

Hit to send when a user completes a Transaction.

FSTransaction represents it and requires a unique transactionId and affiliation name.

📘

The affiliation is the name of Transaction that should appear in the report

init(transactionId:String, affiliation:String)

ParameterTypeRequiredDescription
transactionIdStringYesTransaction unique identifier.
affiliationStringYesTransaction name. Name of the goal in the reporting.
revenueFloatNoTotal revenue associated with the transaction. This value should include any shipping or tax costs.
shippingFloatNoSpecifies the total shipping cost of the transaction.
taxFloatNoSpecifies the total taxes of the transaction.
currencyStringNoSpecifies the currency used for all transaction currency values. Value should be a valid ISO 4217 currency code.
paymentMethodStringNoSpecifies the payment method for the transaction.
shippingMethodStringNoSpecifies the shipping method of the transaction.
itemCountIntNoSpecifies the number of items for the transaction.
couponCodeStringNoSpecifies the coupon code used by the customer for the transaction.
//////////////////////////////////////
/////// Create Transaction Hit ///////
//////////////////////////////////////

/// The affiliation is the name of transaction that should appear in the report
let transacEvent:FSTransaction = FSTransaction(transactionId:"transacId", affiliation:"BasketTransac")
transacEvent.currency 			 = "EUR"
transacEvent.itemCount       = 0
transacEvent.paymentMethod   = "PayPal"
transacEvent.shippingMethod  = "Fedex"
transacEvent.tax             = 2.6
transacEvent.revenue         = 15
transacEvent.shipping        = 3.5
FlagShip.sharedInstance.sendHit(transacEvent)
//////////////////////////////////////
/////// Create Transaction Hit ///////
//////////////////////////////////////

/// The affiliation is the name of transaction that should appear in the report
FSTransaction * transacEvent =  [[FSTransaction alloc] initWithTransactionId:@"transacId" affiliation:@"BasketTransac"];
transacEvent.currency        = @"EUR";
transacEvent.itemCount       = 0;
transacEvent.paymentMethod   = @"PayPal";
transacEvent.shippingMethod  = @"Fedex";
transacEvent.tax             = @2.6;
transacEvent.revenue         = @15;
transacEvent.shipping        = @3.5;
// Send the transaction event
[[Flagship sharedInstance] sendTransactionEvent:transacEvent];

Item

Hit to send an item with a transaction. It must be sent after the corresponding transaction.

FSItem represents this hit and requires transactionId and product name.

init(transactionId:String, name:String, code:String)

ParameterTypeRequiredDescription
transactionIdStringYesTransaction unique identifier
nameStringYesProduct name
priceFloatNoSpecifies the item price
codeStringYesSpecifies the item code or SKU
categoryStringNoSpecifies the item category
quantityIntNoSpecifies the item quantity
//////////////////////////////////////
/////// Create Item Hit //////////////
//////////////////////////////////////

/// Item usually represents a product. An item must be associated with a transaction event.

/// Create item hit
let itemHit = FSItem(transactionId: "idTransaction", name: "itemName", code: "codeSku")
/// Set price
itemHit.price 		= 20
/// set category
itemHit.category 	= "shoes"
/// set quantity
itemHit.quantity 	= 2

/// Send Item
Flagship.sharedInstance.sendHit(itemHit)
//////////////////////////////////////
/////// Create Item Hit //////////////
//////////////////////////////////////

/// Item usually represents a product. An item must be associated with a transaction event.

FSItem * itemhit 	= [[FSItem alloc] initWithTransactionId:@"transacId" name:@"MicroTransac" code:@"codeSku"];
/// Set Price
itemhit.price 		= @20;
/// Set category
itemhit.category 	= @"category";
/// Set quantity
itemhit.quantity 	= @1;

/// Send item event
[[Flagship sharedInstance] sendItemEvent:itemhit];

📘

FSItem hit isn't available yet in the Flagship reporting view.

Event

Hit which represents an event. It can be anything you want: for example a click on an Add to Cart button or a newsletter subscription.

FSEvent represents this hit and requires a category event and action name string.

FSCategoryEvent can be Action_Tracking or User_Engagement.

init(eventCategory:FSCategoryEvent, eventAction:String)

ParameterTypeRequiredDescription
categoryFSCategoryEventYesCategory of the event (Action_Tracking or User_Engagement).
actionStringyesName of the event.
labelStringNoDescription of the event.
eventValueNumberNoValue of the event, must be a non-negative number.

📘

The event action is the name of Event that should appear in the report

//////////////////////////////////////
/////// Create Event Hit /////////////
//////////////////////////////////////

/// Create action tracking category event 
let actionEvent:FSEvent = FSEvent(eventCategory: FSCategoryEvent.Action_Tracking, eventAction: "cta_Shop")
actionEvent.label 			= "cta_Shop_label"
actionEvent.eventValue  = 1

// Send Event Tracking
FlagShip.sharedInstance.sendHit(actionEvent)
//////////////////////////////////////
/////// Create Event Hit /////////////
//////////////////////////////////////

/// Create action tracking category event 
FSEvent * actionEvent  = [[FSEvent alloc] initWithEventCategory:FSCategoryEventAction_Tracking eventAction:@"cta_Shop"];
actionEvent.label 		 = @"cta_Shop_label";
actionEvent.eventValue = @1;
[[Flagship sharedInstance] sendEventTrack:actionEvent];

Logs

Logs are enabled by default. If you want to stop logs, set enableLogs to false.

/// Stop logs from displaying
Flagship.sharedInstance.enableLogs = false
/// Stop logs from displaying
[[Flagship sharedInstance] setEnableLogs:NO];

Appendix

Predefined user context keys

The Flagship SDK contains predefined user context keys.

The keys marked as Yes in the Auto-set by SDK column will be automatically set, while the ones marked as No need to be set by the client.

They are nevertheless overridable at anytime. Then these predefined context keys-value pairs will be sent to the server and be editable in the Persona section of the Flagship platform.

SDK Variable name DescriptionContext Variable nameTypeAuto-set by SDKExample
FIRST_TIME_INITFirst init of the appsdk_firstTimeInitBooleanYestrue (false if the init isn’t the first one)
LOCALE Language of the devicesdk_deviceLanguageStringYesfr_FR
DEVICE_TYPEType fo the device (Tablet/Mobile) sdk_deviceTypeStringYes mobile
LOCATION_CITYCity geolocationsdk_cityStringNotoulouse
 LOCATION_REGIONRegion geolocationsdk_regionStringNooccitanie
LOCATION_COUNTRYCountry geolocationsdk_countryString NoFrance
LOCATION_LATCurrent Latitudesdk_latDoubleNo43.623647
LOCATION_LONGCurrent Longitudesdk_longDoubleNo1.445397
IPIP of the devicesdk_ipStringNo127.0.0.1
OS_NAMEName of the OSsdk_osNameStringYesiOS
IOS_VERSIONVersion of iOSsdk_iOSVersionStringYes9
MVNO / carrierName(Mobile virtual network operator)"Name of the operatorsdk_carrierNameStringYes
DEV_MODEIs the app in debug mode?sdk_devModeBooleanNotrue
INTERNET_CONNECTIONWhat is the internet connectionsdk_internetConnectionStringNo3g
APP_VERSION_NAMEVersion name of the appsdk_versionNameStringNo1.1.2-beta
APP_VERSION_CODEVersion code of the appsdk_versionCodeNumber (int)No40
FLAGSHIP_VERSIONVersion of the Flagship SDKsdk_fsVersionString Yes1.1.2
INTERFACE_NAMEName of the interfacesdk_interfaceNameStringNoProductPage

Here you can see how a predefined key is used to filter a report in the Flagship interface:

2426

📘

To overwrite the keys, use the updateContext method