Skip to content

Latest commit

 

History

History
404 lines (390 loc) · 21.4 KB

README.md

File metadata and controls

404 lines (390 loc) · 21.4 KB

alt tag

alt tag

SDK's Implementation Guide

iOS

Last update : 15/07/2022
Release version : 4.6.4

Introduction

Commanders Act enables marketers to easily add, edit, update, and deactivate tags on web pages, videos and mobile applications with little-to-no support from IT departments.

Instead of implementing several SDK's in the application, Commanders Act for mobile provides clients with a single SDK which sends data to our server which then create and send hits to your partners.

Owing to remote configuration tools, it is also possible to modify the configuration without having to resubmit your application.

The purpose of this document is to explain how to add the SDK module into your application.

Main Technical Specifications

  • Weight from 110 ko to 120 ko in your application depending on the iPhone model.
  • Fully threaded and asynchronous.
  • Offline mode (the hits are stored in the phone to be replayed at the next launch.)
  • Very low CPU and memory usage.
  • Dynamic variable storage. If a value never changes, it's possible to set it only once.
  • The state of the phone is easily accessed through the module (network connection type, name of the phone, geographical location.)
  • Background mode, in the case you really need to send data while the application is in background.

Dynamic Variables

A dynamic variable is a combination of a name and a value. It is used to give the module data such as the name of the current screen or the product ID in a cart.

Dynamic Variables are implemented inside the application. They are replaced on the server at the time of the execution by the value transmitted.

A dynamic variable is formatted like this: #SCREEN#.

The dynamic variables are case sensitive. They should always be in upper case. The dynamic variable both begins and ends with a #. Don't forget them when setting your dynamic variables.

Dynamic Variables has two purposes:

  1. Define information for analytics purposes. For instance, you would put restaurants_list in the #SCREEN# dynamic variable.
  2. Test if conditions are met to fire a tag. For instance, if you set the #EVENT# to click, the tag with the condition #EVENT# EQUAL 'click' will be executed.

Execution

When you call the sendData method, a hit will be packaged and sent to Commanders Act's server.

alt tag

SDK integration

Steps

You can divide the integration of TagCommander's SDK into four steps:

  1. Add the required frameworks
  2. Add the TagCommander framework
  3. Implement TagCommander in your application according to the tagging plan.
  4. Verify that all tags are being sent

Integration of the SDK Module

Please check the Developers Implementation Guide to chose the best way to implement this module in your project.

Dependencies

TagCommander requires the following frameworks:

  • SystemConfiguration.framework
  • libz.dylib

Compiler Flags

Please add the following option to your projects setting or xcconfig file

OTHER_LDFLAGS = $(inherited) -ObjC

Compatibility

  • Architecture: armv7, arm64, i386 and x86_64, bitcode sections
  • iOS version: 9.0 minimum
  • Compiled with the ENABLE_BITCODE = YES option
  • Compiled with ARC enabled

Using the SDK

Initialisation

It is recommended to initialise TagCommander in your AppDelegate's applicationdidFinishLaunchingWithOptions so it will be operational as soon as possible.

A single line of code is required to properly initialize an instance of TagCommander:

TagCommander *TagCommanderInstance = [[TagCommander alloc] initWithSiteID: siteID andContainerID: containerID];

This class is not a Singleton. If you have the need for only one pair of siteID's and containerID's, you might want to use it as a Singleton anyway for reasons of simplification.

Since Apple now forces NSLocationAlwaysUsageDescription if they find any code related on location, we are removing TCLocation. If you want to still use the same variables to match pre-existing tags, please use #TC_LONGITUDE# and #TC_LATITUDE#.

Executing tags

For every element that needs tagging in your application, you need to call addData on your TagCommander instance and when you want to send all those information to the server, you will simply need to call sendData.

[TCInstance addData: @"#EVENT#" withValue: @"click"];
[TCInstance addData: @"#PAGE#" withValue: @"order"];
[TCInstance addData: @"#AMOUNT#" withValue: @"584.46"];

[TCInstance sendData];

For compatibility reasons or for synchronisation reasons, you can still use TCAppVars to pass those information to TagCommander.

TCAppVars *appVar = [[TCAppVars alloc] init];
[appVar set: @"#EVENT#" withValue: @"click"];
[appVar set: @"#PAGE#" withValue: @"order"];
[appVar set: @"#AMOUNT#" withValue: @"584.46"];

[self.TCInstance execute: appVar];

Always handle values as NSStrings!

Example

Let's say that the URL you are using in your server-side container uses the following url:

:::url
http://engage.commander1.com/dms?tc_s=3109&tc_type=dms&data_sysname=#TC_SYSNAME#
&data_sysversion=#TC_SYSVERSION#&page=#SCREEN_NAME#&event=#EVENT#

In order to be executed, the tag needs two values:

  • #EVENT#
  • #SCREEN_NAME#

With the code from the previous section, this tag could be fired from Commanders Act's server. The application sends two dynamic variables (#EVENT# and #SCREEN_NAME#) and the SDK adds all information available to it (like #TC_SYSVERSION# and #TC_SYSNAME# in this hit).

Privacy

To manage the privacy of the user's data you can use our Trust product, another product or nothing at all.

By default, the SDK will try to see if you have added our Privacy module. If so, it will put itself into a waiting for consent mode. In this mode, it will record all hits but wait to consent information to either send everything or delete all waiting hits.

If you don't use our Privacy module, the SDK will be enabled by default.

If you want to change those dehaviours, we added a way to initialise the TagCommander module with an additional information about the behaviour. For now we have 3 behaviours:

- PB_DEFAULT_BEHAVIOUR which is the one described just before
- PB_ALWAYS_ENABLED which forces the SDK to always send information. This is used when you have tags that don't require consent.
- PB_DISABLED_BY_DEFAULT which forces the SDK to disabled. It won't record hits before consent is given and you won't have any up by default time when using tagging the app loading screens. (This might only happen when you're not using our Privacy module)

To initialise the SDK with another behaviour, please call the following function:

TagCommander *tc = [[TagCommander alloc] initWithSiteID: siteID containerID: containerID andDefaultBehaviour: PB_ALWAYS_ENABLED];

Product tags

There are some tags that need to be passed a list of dictionaries, usually representing products. By passing complex information, we are able to create and send complex hits or many hits at the same time.

Tags that needs to be passed a list of dictionaries are easy to spot in the configuration. They have appended to the name of the dynamic variable the name of the key that is retrieved from the dictionary.

Most of the time the data are provided ready to use, but we provide a TCProduct class representing a product and its possible values.

[TCInstance addData: @"#EVENT#" withValue: @"viewCart"];
[TCInstance addData: @"#PARTNER_ID#" withValue: @"868"];
[TCInstance addData: @"#REGIONAL_CODE#" withValue: @"eu"];

TCProduct *product1 = [[TCProduct alloc] init]; product1.ID = @"22561563"; product1.priceATI = @"1.2"; product1.quantity = @"1"; [TCInstance addData: @"#ORDER_PRODUCTS#" withProduct: product1];

TCProduct *product2 = [[TCProduct alloc] init]; product2.ID = @"21669790"; product2.priceATI = @"3.4"; product2.quantity = @"2"; [TCInstance addData: @"#ORDER_PRODUCTS#" withProduct: product2];

TCProduct *product3 = [[TCProduct alloc] init]; product3.ID = @"3886822"; product3.priceATI = @"5.4"; product3.quantity = @"3"; [TCInstance addData: @"#ORDER_PRODUCTS#" withProduct: product3]; [TCInstance sendData];

The following properties can be used with the TCProduct class:

  • ID
  • name
  • quantity
  • category
  • priceATI
  • discountATI
  • priceTF
  • discountTF
  • trademark
  • URLPage
  • URLPicture
  • rating
  • inStock

If you want to add more properties, please use the method on your TCProduct instance:

[product.customProperties setValue: @"12" forKey: @"Menu"];
[product.customProperties setValue: @"0" forKey: @"TakeOut"];

If you are updating from an old version of TagCommander you can still use old functions with TCAppVars and a list of products.

Background Mode

While the application is goind to background, the SDK sends all data that was already queued then stops. This is in order to preserve battery life and not use carrier data when not required.

But some applications need to be able to continue sending data because they have real background activities. For example listening to music.

For those cases, we added a way to bypass the way to SDK usually react to background. Please call:

[tc enableRunningInBackground];

One drawback is that we're not able to ascertain when the application will really be killed. In normal mode, we're saving all hits not sent when going in the background, which is not possible here anymore. To be sure to not loose any hits in background mode, we will save much more often the offline hits.

Please assure that your application has background modes enabled to use this feature.

Deactivating the SDK

If you want to show a privacy message to your users allowing them to stop the tracking, you might want to use the following function to stop it if they refuse to be tracked.

[TCInstance deactivateSDK];

What this function does is stopping all systems in the SDK that update automatically or listen to notifications like background or internet reachability. This will also ignore all calls to the SDK by your application so that nothing is treated anymore and you don't have to protect those calls manually.

[TCInstance activateSDK];

In the case you need to re-enable it after disabling it the first time, you can use this function.

Wait for User-agent

As Apple removed the old class which allowed us to get the user-agent synchroneously, we sometimes have a bit of delay before the user-agent is available. And for unknown reasons, this delay is sometimes more than a minute on real devices.

If it is important for your solution to have acces to the user-agent, please call the following method:

[tc waitForUserAgent: YES];

When the user-agent is ready, it will be added to all the hit waiting to be sent.

Getting IDFA

If you are using iOS 14 or later, the SDK can't get the IDFA automatically. This would force the popup asking for the user permission at any moment which is not the wanted behavior.

Instead, you'll have to control when you want this popup to be displayed with the code here: https://medium.com/@nish.bhasin/how-to-get-idfa-in-ios14-54f7ea02aa42

and in the "case .authorized:", call:

[[TCCoreVariables sharedInstance] setIDFA];

Troubleshooting

The TagCommander SDK also offers methods to help you with the Quality Assessment of the SDK implementation.

Debugging

We recommend using TCLogLevel_Verbose while developing your application:

// Put it before the TagCommander initialization
#ifdef DEBUG
    [TCDebug setDebugLevel: TCLogLevel_Verbose];
    [TCDebug setNotificationLog: YES];
#end
  • The first line allows you to select the verbosity of TagCommander's logs.

    • Verbosity
    Constant Name Verbosity
    TCLogLevel_Verbose Print everything.
    TCLogLevel_Debug Most useful information for debugging.
    TCLogLevel_Info Basic information about TagCommander's state.
    TCLogLevel_Warn Warnings only.
    TCLogLevel_Error Errors only.
    TCLogLevel_Assert Asserts only.
    TCLogLevel_None No print at all.
  • The internal architecture is working with internal notifications. You can ask the Logger to display all the internal notifications with setNotificationLog: YES.

Testing

There are three ways to verify that the module executes the tags in your application:

  • By reading the debug messages in the console.
  • By going to your vendor's platform and check that the hits are displayed and that the data is correct. Please be aware that hits may not display immediately in the vendor account. This delay differs widely between vendors and may also vary for the type of hit under the same vendor.
  • You can also use a network monitor like Wireshark or Charles to check directly what is being sent on the wire to your vendors.

Common errors

  • Enable the debug logs if you have any doubt.
  • Check if TagCommander is called when you think it is. You should see it in the console logs.
  • Make sure you have the latest version.

Using a custom process pool

You might have issue with cookies stored in webviews and want to use a custom-process pool. If you encounter this issue, you need to pass your custom process pool like to TCDebug class:

+ (void) useCustomWKProcessPool: (BOOL);

This tells the SDK to wait before getting the user-agent to prevent cookie issues. If you do need to user-agent, you will need to manually call the following method in TCCoreVariables:

- (void) initUserAgentWithProcessPool: (WKProcessPool *) pool;

Common errors with the tagging plan

  • Don't forget the # at the beginning and the end of each dynamic variable.
  • Always use the String type for the value of each dynamic variable.
  • Always use upper case dynamic variables.
  • The dynamic variables are case sensitive.
  • If you don't set the correct value for one dynamic variable, an empty string will replace it.

Helpers

Persisting variables

TagCommander permits storing of variables that remain the same in the whole application, such as vendors ID, in a TagCommander instance, instead of sending them each time you want to send data.

These variables will have a lower priority to the one given by the addData method but will persist for the whole run of the application.

[self.TagCommanderInstance addPermanentData: @"#VENDOR_ID#" withValue: @"UE-556XXXXX-01"];

They can also be removed if necessary.

[self.TagCommanderInstance removePermanentData: @"#VENDOR_ID#"];

TCPredefinedVariables

TagCommander collects a great deal of information to function with accuracy. You can ask for any variables computed by TagCommander through a simple getData on TCPredefinedVariables.

The two following line are doing exactly the same thing, one using the constants declared in the SDK, the second using the name of the variable as defined in PredefinedVariables.xlsx. You can use either one.

TCPredefinedVariables *predefVariables = [TCPredefinedVariables sharedInstance];
NSString *currentVisit = [predefVariables getData: kTCPredefinedVariable_CurrentVisitMs];
NSString *currentVisit = [predefVariables getData: @"#TC_CURRENT_VISIT_MS#"];

You can find a full list of variables computed by the SDK, explanations and examples here:

TCPredefinedVariables

Swift

If you want to use Swift as your main language, please check the demo TagCommander-In-Swift.

This library is the TCIAB module, you will find the usual podspecs in the repository. Please beware that depending on your XCode version the universal versions might not be working.

Example: TCDemo

To check an example of how to use this module, please check:

Tag Demo

Migration from v2 and v3 to v4

The way we are doing thing in v4 is quite different as we can only send data in post and to TagCommander's servers. But the code didn't change much and we can still use the old basic integration for the v4.

Remove all function not existing anymore like forceReload and the rest should still work. To use new methods you can check in this document how to.

You don't have to update your tagging plan in the application ! You should be able to keep your previous execute as is. What needs to be changed is the container in your TagCommander interface, please check with your consultant.

Support and contacts

alt tag


Support [email protected]

http://www.commandersact.com

Commanders Act | 3/5 rue Saint Georges - 75009 PARIS - France


This documentation was generated on 15/07/2022 14:25:57