Complete installation and tagging guide for the Eulerian Analytics iOS SDK.
- Installation
- Initialization
- Tag types
- Generic page —
EAProperties - Product page —
EAProducts(1 product) - Category page —
EAProducts(N products) - Search engine page —
EASearch - 404 error page —
EAProperties - Estimate page —
EAEstimate - Cart page —
EACart - Order page —
EAOrder - Merchandise tracking —
EATpView/EATpClick - Actions —
EAOAction - Context Flag (CFLAG) —
EAOSiteCentricCFlag
- Generic page —
- WebView tracking
- App metrics
- Consent (GDPR)
- Privacy (iOS 14+)
If you don't have CocoaPods yet, install it:
sudo gem install cocoapodsIf your project doesn't have a Podfile yet, initialise one at the project root:
pod initAdd the dependency to your Podfile:
pod 'EAnalytics'Then run:
pod installOpen your project using the
.xcworkspacefile generated by CocoaPods (not the.xcodeproj).
In Xcode, go to File → Add Package Dependencies and enter the Eulerian iOS GitHub repository URL. Or add it directly to Package.swift:
dependencies: [
.package(url: "https://github.com/EulerianTechnologies/eulerian-sdk-ios", from: "1.5.0")
]Supported platforms: iOS 9.0+ (CocoaPods) / iOS 11.0+ (SPM) · tvOS 9.0+
Initialise the SDK once in application(_:didFinishLaunchingWithOptions:). The SDK is a singleton — a second call to initWithHost is silently ignored.
Swift
import EAnalytics
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Replace with your tracking subdomain
EAnalytics.initWithHost("example.demo.com", andWithDebugLogs: false)
return true
}
}Objective-C
#import <EAnalytics/EAnalytics.h>
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[EAnalytics initWithHost:@"example.demo.com" andWithDebugLogs:NO];
return YES;
}The second parameter enables (
true) or disables (false) debug logs in the Xcode console.
Tracking subdomain: the value to pass is provided by your Eulerian team. It looks like
example.demo.com— do not includehttps://or/. The SDK rejects hosts containing.eulerian.com.
Traffic attribution in Eulerian: a native app has no URL. The SDK automatically uses the app name (
ea-appname) as an internal identifier, and the subdomain passed toinitWithHostto attribute traffic to the correct site in the Eulerian interface.
If several apps share the same tracking subdomain, use the
fromparameter viasetEulerianWithValue(_:forKey:)to distinguish them.
EUIDL: the SDK automatically generates and persists a unique identifier per installation (
euidl). It is stored inNSUserDefaultsand survives app updates. Accessible viaEAnalytics.euidl().
Offline & retry: if the device has no connection when
trackis called, the tag is serialised locally and automatically resent on the nexttrackcall or the next app launch. The actual timestamp of the interaction is preserved (ereplay-time).
path(page name) is mandatory on every tag. It is never retrieved automatically — unlike the web where the URL identifies the page. Use a hierarchical convention with|as a separator, for example"home|main","catalogue|shoes|men","funnel|payment|confirmation". The value is free but must be stable and meaningful for reporting.
Generic method
setEulerianWithValue(_:forKey:): available on all tags, it lets you add any custom parameter not covered by the dedicated methods. Example:setEulerianWithValue("monthly", forKey: "subscription").
Use on all pages that are not product pages, cart, order or estimate pages (including the homepage and intermediate steps in the conversion funnel). Reports site-centric traffic, page views, visits and organic sources.
Methods:
initWithPath(_ path: String)— page name (mandatory)setEulerianWithUid(_ value: String)— internal ID of the logged-in user; consolidates multi-device historysetEulerianWithEmail(_ value: String)— user's email addresssetEulerianWithProfile(_ value: String)— user profile (e.g.visitor,buyer,looker)setEulerianWithPageGroup(_ value: String)— page group for reportingsetEulerianWithValue(_ value: Any, forKey key: String)— free custom parametersetEulerianWithCFlag(_ value: EAOSiteCentricCFlag)— attaches one or more context flags (see Context Flag)
Swift
let props = EAProperties(path: "home|main")
props.setEulerianWithUid("123asd")
props.setEulerianWithEmail("test@test.com")
props.setEulerianWithProfile("visitor")
props.setEulerianWithPageGroup("MY-PAGEGROUP")
props.setEulerianWithValue("value", forKey: "KEY-CUSTOM-PARAM")
EAnalytics.track(props)Objective-C
EAProperties *props = [[EAProperties alloc] initWithPath:@"home|main"];
[props setEulerianWithUid:@"123asd"];
[props setEulerianWithEmail:@"test@test.com"];
[props setEulerianWithProfile:@"visitor"];
[props setEulerianWithPageGroup:@"MY-PAGEGROUP"];
[props setEulerianWithValue:@"value" forKey:@"KEY-CUSTOM-PARAM"];
[EAnalytics track:props];Tracks product page views and feeds the "Product Acquisition & Performance" report. A tag is considered a product page when it contains exactly one product and none of the parameters scart, estimate, ref, amount.
Methods:
initWithPath(_ path: String)— page name (mandatory)setEulerianWithProducts(_ products: [EAOProduct])— array containing the product (mandatory)setEulerianWithUid(_ value: String)— internal user IDsetEulerianWithEmail(_ value: String)— user's email addresssetEulerianWithProfile(_ value: String)— user profilesetEulerianWithPageGroup(_ value: String)— page groupsetEulerianWithValue(_ value: Any, forKey key: String)— free custom parameter
Building an EAOProduct:
initWithRef(_ ref: String)— product reference (mandatory)setEulerianWithName(_ value: String)— human-readable product name for reportingsetEulerianWithGroup(_ value: String)— margin group (AorB)setEulerianWithParams(_ value: EAOParams)— product categories (e.g.prdparam-category,prdparam-brand)
Building an EAOParams:
setEulerianWithStringValue(_ value: String, forKey key: String)— product category; the key is the suffix afterprdparam-setEulerianWithIntValue(_ value: Int32, forKey key: String)— integer value
Swift
let params = EAOParams()
params.setEulerianWithStringValue("clothes", forKey: "category") // prdparam-category
params.setEulerianWithStringValue("nike", forKey: "brand") // prdparam-brand
let product = EAOProduct(ref: "ref-product")
product.setEulerianWithName("name-product")
product.setEulerianWithGroup("A")
product.setEulerianWithParams(params)
let page = EAProducts(path: "product|detail")
page.setEulerianWithUid("123asd")
page.setEulerianWithEmail("test@test.com")
page.setEulerianWithProfile("looker")
page.setEulerianWithProducts([product])
EAnalytics.track(page)Objective-C
EAOParams *params = [[EAOParams alloc] init];
[params setEulerianWithStringValue:@"clothes" forKey:@"category"];
[params setEulerianWithStringValue:@"nike" forKey:@"brand"];
EAOProduct *product = [[EAOProduct alloc] initWithRef:@"ref-product"];
[product setEulerianWithName:@"name-product"];
[product setEulerianWithGroup:@"A"];
[product setEulerianWithParams:params];
EAProducts *page = [[EAProducts alloc] initWithPath:@"product|detail"];
[page setEulerianWithUid:@"123asd"];
[page setEulerianWithEmail:@"test@test.com"];
[page setEulerianWithProfile:@"looker"];
[page setEulerianWithProducts:@[product]];
[EAnalytics track:page];Sends the first N product references shown on a results or category page. A tag is considered a category page when it contains more than one product and none of the parameters scart, estimate, ref, amount.
Use the same EAProducts class, passing an array with multiple products.
Swift
let product1 = EAOProduct(ref: "ref-product1")
let product2 = EAOProduct(ref: "ref-product2")
let product3 = EAOProduct(ref: "ref-product3")
let page = EAProducts(path: "category|shoes")
page.setEulerianWithUid("123asd")
page.setEulerianWithEmail("test@test.com")
page.setEulerianWithPageGroup("my-pagegroup")
page.setEulerianWithProducts([product1, product2, product3])
EAnalytics.track(page)Objective-C
EAOProduct *product1 = [[EAOProduct alloc] initWithRef:@"ref-product1"];
EAOProduct *product2 = [[EAOProduct alloc] initWithRef:@"ref-product2"];
EAOProduct *product3 = [[EAOProduct alloc] initWithRef:@"ref-product3"];
EAProducts *page = [[EAProducts alloc] initWithPath:@"category|shoes"];
[page setEulerianWithUid:@"123asd"];
[page setEulerianWithEmail:@"test@test.com"];
[page setEulerianWithPageGroup:@"my-pagegroup"];
[page setEulerianWithProducts:@[product1, product2, product3]];
[EAnalytics track:page];Tracks internal search engine queries, result counts and search parameters. A tag is considered a search engine page when it contains isearchengine. Non-exclusive: can be combined with a product on the same tag.
Methods:
initWithPath(_ path: String, withName name: String)— page name + engine name (mandatory)setEulerianWithResults(_ value: Int32)— number of results returnedsetEulerianWithParams(_ value: EAOParams)— search parameters (key/value pairs mapping toisearchkey/isearchdata)setEulerianWithUid(_ value: String)— internal user IDsetEulerianWithValue(_ value: Any, forKey key: String)— free custom parameter
Swift
let searchParams = EAOParams()
searchParams.setEulerianWithStringValue("jacket", forKey: "keyword")
searchParams.setEulerianWithStringValue("100.00", forKey: "price_min")
searchParams.setEulerianWithStringValue("400.00", forKey: "price_max")
let page = EASearch(path: "internal_search|jacket", withName: "internal_search")
page.setEulerianWithUid("34678")
page.setEulerianWithResults(150)
page.setEulerianWithParams(searchParams)
EAnalytics.track(page)Objective-C
EAOParams *searchParams = [[EAOParams alloc] init];
[searchParams setEulerianWithStringValue:@"jacket" forKey:@"keyword"];
[searchParams setEulerianWithStringValue:@"100.00" forKey:@"price_min"];
[searchParams setEulerianWithStringValue:@"400.00" forKey:@"price_max"];
EASearch *page = [[EASearch alloc] initWithPath:@"internal_search|jacket" withName:@"internal_search"];
[page setEulerianWithUid:@"34678"];
[page setEulerianWithResults:150];
[page setEulerianWithParams:searchParams];
[EAnalytics track:page];Flag a 404 error page by adding setEulerianWithValue("1", forKey: "error") to an EAProperties tag. Feeds the "Error pages" report.
Swift
let props = EAProperties(path: "error|404")
props.setEulerianWithValue("1", forKey: "error")
EAnalytics.track(props)Objective-C
EAProperties *props = [[EAProperties alloc] initWithPath:@"error|404"];
[props setEulerianWithValue:@"1" forKey:@"error"];
[EAnalytics track:props];Tracks estimates and their associated products. Estimates are deduplicated by reference: a second call with the same reference is ignored.
Methods:
initWithPath(_ path: String, withRef ref: String)— page name + unique estimate reference (mandatory)setEulerianWithAmount(_ value: Double)— total VAT-inclusive amount (decimal separator: period)setEulerianWithType(_ value: String)— estimate type according to your own taxonomysetEulerianWithCurrency(_ value: String)— currency if different from the one configured in the interfaceaddEulerian(_ product: EAOProduct, amount: Double, quantity: Int32)— adds a product with its unit amount and quantitysetEulerianWithUid(_ value: String)— internal user IDsetEulerianWithEmail(_ value: String)— user's email addresssetEulerianWithValue(_ value: Any, forKey key: String)— free custom parameter
Swift
let product = EAOProduct(ref: "505")
let page = EAEstimate(path: "credit|estimate", withRef: "C4536567")
page.setEulerianWithUid("123asd")
page.setEulerianWithEmail("test@test.com")
page.setEulerianWithAmount(5000.00)
page.setEulerianWithType("credit_48months")
page.setEulerianWithCurrency("EUR")
page.setEulerianWithValue("custom-value", forKey: "custom-param-key")
page.addEulerian(product, amount: 5000.00, quantity: 1)
EAnalytics.track(page)Objective-C
EAOProduct *product = [[EAOProduct alloc] initWithRef:@"505"];
EAEstimate *page = [[EAEstimate alloc] initWithPath:@"credit|estimate" withRef:@"C4536567"];
[page setEulerianWithUid:@"123asd"];
[page setEulerianWithEmail:@"test@test.com"];
[page setEulerianWithAmount:5000.00];
[page setEulerianWithType:@"credit_48months"];
[page setEulerianWithCurrency:@"EUR"];
[page setEulerianWithValue:@"custom-value" forKey:@"custom-param-key"];
[page addEulerian:product amount:5000.00 quantity:1];
[EAnalytics track:page];Tracks initiated carts and enables conversion and abandonment rate calculations. A tag is considered a cart page when it contains the scart parameter, set automatically by the EACart class. Cart lifetime: 30 rolling minutes.
Methods:
initWithPath(_ path: String)— page name (mandatory)setEulerianWithCumul(_ value: Bool)—false: the products in the tag represent the entire cart (snapshot);true: products accumulate across successive callsaddEulerian(_ product: EAOProduct, amount: Double, quantity: Int32)— adds a product with its unit amount and quantitysetEulerianWithUid(_ value: String)— internal user IDsetEulerianWithEmail(_ value: String)— user's email addresssetEulerianWithProfile(_ value: String)— user profilesetEulerianWithPageGroup(_ value: String)— page groupsetEulerianWithValue(_ value: Any, forKey key: String)— free custom parameter
Swift
let params = EAOParams()
params.setEulerianWithStringValue("T-Shirt", forKey: "category")
params.setEulerianWithStringValue("Nike", forKey: "brand")
let product = EAOProduct(ref: "product-123")
product.setEulerianWithName("product-name")
product.setEulerianWithParams(params)
let page = EACart(path: "cart")
page.setEulerianWithUid("123asd")
page.setEulerianWithEmail("test@test.com")
page.setEulerianWithProfile("shopper")
page.setEulerianWithPageGroup("my-page-group")
page.setEulerianWithCumul(false)
page.addEulerian(product, amount: 50.30, quantity: 2)
EAnalytics.track(page)Objective-C
EAOParams *params = [[EAOParams alloc] init];
[params setEulerianWithStringValue:@"T-Shirt" forKey:@"category"];
[params setEulerianWithStringValue:@"Nike" forKey:@"brand"];
EAOProduct *product = [[EAOProduct alloc] initWithRef:@"product-123"];
[product setEulerianWithName:@"product-name"];
[product setEulerianWithParams:params];
EACart *page = [[EACart alloc] initWithPath:@"cart"];
[page setEulerianWithUid:@"123asd"];
[page setEulerianWithEmail:@"test@test.com"];
[page setEulerianWithProfile:@"shopper"];
[page setEulerianWithPageGroup:@"my-page-group"];
[page setEulerianWithCumul:NO];
[page addEulerian:product amount:50.30 quantity:2];
[EAnalytics track:page];Tracks conversions and ROI. Orders are deduplicated by reference. Implement this tag as early as possible in the payment funnel so it is not missed if the user does not return to the app after the payment platform.
Methods:
initWithPath(_ path: String, withRef ref: String)— page name + unique order reference (mandatory)setEulerianWithAmount(_ value: Double)— total VAT-inclusive amount excluding shipping (mandatory)setEulerianWithPayment(_ value: String)— payment method used (e.g.credit card,paypal)setEulerianWithType(_ value: String)— sale type according to your own taxonomysetEulerianWithCurrency(_ value: String)— currency if different from the one configured in the interfacesetEulerianWithNewCustomer(_ value: Bool)—true: new buyer;false: returning customersetEulerianWithEstimateRef(_ value: String)— reference of the estimate linked to this order (optional)addEulerian(_ product: EAOProduct, amount: Double, quantity: Int32)— adds a product with its unit amount and quantitysetEulerianWithUid(_ value: String)— internal user IDsetEulerianWithEmail(_ value: String)— user's email addresssetEulerianWithProfile(_ value: String)— user profilesetEulerianWithValue(_ value: Any, forKey key: String)— free custom parameter
Swift
let params = EAOParams()
params.setEulerianWithStringValue("T-Shirt", forKey: "category")
params.setEulerianWithStringValue("Nike", forKey: "brand")
let product = EAOProduct(ref: "product-123")
product.setEulerianWithName("product-name")
product.setEulerianWithParams(params)
let page = EAOrder(path: "funnel|confirmation", withRef: "F654335671")
page.setEulerianWithUid("123asd")
page.setEulerianWithEmail("test@test.com")
page.setEulerianWithProfile("buyer")
page.setEulerianWithNewCustomer(true)
page.setEulerianWithAmount(50.30)
page.setEulerianWithType("online")
page.setEulerianWithPayment("credit card")
page.setEulerianWithCurrency("EUR")
page.setEulerianWithEstimateRef("asd123qwe")
page.setEulerianWithValue("custom-value", forKey: "custom-param-key")
page.addEulerian(product, amount: 25.15, quantity: 2)
EAnalytics.track(page)Objective-C
EAOParams *params = [[EAOParams alloc] init];
[params setEulerianWithStringValue:@"T-Shirt" forKey:@"category"];
[params setEulerianWithStringValue:@"Nike" forKey:@"brand"];
EAOProduct *product = [[EAOProduct alloc] initWithRef:@"product-123"];
[product setEulerianWithName:@"product-name"];
[product setEulerianWithParams:params];
EAOrder *page = [[EAOrder alloc] initWithPath:@"funnel|confirmation" withRef:@"F654335671"];
[page setEulerianWithUid:@"123asd"];
[page setEulerianWithEmail:@"test@test.com"];
[page setEulerianWithProfile:@"buyer"];
[page setEulerianWithNewCustomer:YES];
[page setEulerianWithAmount:50.30];
[page setEulerianWithType:@"online"];
[page setEulerianWithPayment:@"credit card"];
[page setEulerianWithCurrency:@"EUR"];
[page setEulerianWithEstimateRef:@"asd123qwe"];
[page setEulerianWithValue:@"custom-value" forKey:@"custom-param-key"];
[page addEulerian:product amount:25.15 quantity:2];
[EAnalytics track:page];Tracks impressions and clicks on merchandise blocks (recommendation lists, banners, etc.). Sent as GET requests to /tpview/ and /tpclick/ — unlike other tags which are sent via POST. Supports the same offline retry mechanism as the rest of the SDK.
EATpView methods (impression):
initWithPath(_ path: String)— reference page (mandatory)setSiteName(_ value: String)— merchant site namesetCampaign(_ value: String)— campaign namesetPlacement(_ value: String)— block position within the pageaddProductWithRef(_ ref: String, position: NSNumber)— product reference and its position in the block; repeat for each displayed productsetUrl(_ value: String)— context URLsetPublisher(_ value: String)— publisher (optional)setMedia(_ value: String)— media type (optional)setCategory(_ value: String)— block category (optional)
EATpClick methods (click):
initWithPath(_ path: String)— reference page (mandatory)setSiteName(_ value: String)— merchant site namesetCampaign(_ value: String)— campaign namesetPlacement(_ value: String)— block position within the pagesetProductWithRef(_ ref: String, position: Int)— reference and position of the clicked product (mandatory)setProductWithRef(_ ref: String, position: Int, totalProducts: NSNumber)— variant with the total number of products in the blocksetUrl(_ value: String)— context URLsetPublisher(_ value: String)— publisher (optional)setMedia(_ value: String)— media type (optional)setCategory(_ value: String)— block category (optional)
Swift
// Impression on a merchandise block
let view = EATpView(path: "homepage")
view.setSiteName("my-site")
view.setCampaign("summer_sale")
view.setPlacement("banner_top")
view.addProductWithRef("PROD_001", position: NSNumber(value: 0))
view.addProductWithRef("PROD_002", position: NSNumber(value: 1))
view.setUrl("https://www.example.com")
EAnalytics.track(view)
// Click on a product within the block
let click = EATpClick(path: "homepage")
click.setSiteName("my-site")
click.setCampaign("summer_sale")
click.setPlacement("banner_top")
click.setProductWithRef("PROD_001", position: 0)
click.setUrl("https://www.example.com")
EAnalytics.track(click)Objective-C
// Impression
EATpView *view = [[EATpView alloc] initWithPath:@"homepage"];
[view setSiteName:@"my-site"];
[view setCampaign:@"summer_sale"];
[view setPlacement:@"banner_top"];
[view addProductWithRef:@"PROD_001" position:@(0)];
[view addProductWithRef:@"PROD_002" position:@(1)];
[view setUrl:@"https://www.example.com"];
[EAnalytics track:view];
// Click
EATpClick *click = [[EATpClick alloc] initWithPath:@"homepage"];
[click setSiteName:@"my-site"];
[click setCampaign:@"summer_sale"];
[click setPlacement:@"banner_top"];
[click setProductWithRef:@"PROD_001" position:2];
[click setUrl:@"https://www.example.com"];
[EAnalytics track:click];Actions let you track user interactions (subscription funnel, questionnaire, cross-section navigation, etc.) outside of classic page views. An action can be attached to any tag via setEulerianWithAction: (replaces any previous action) or addEulerianWithAction: (accumulates multiple actions on the same tag).
To send an action without an associated page view, call setEulerianStandalone() on the tag — the hit will not count as a page view in Eulerian.
EAOAction methods:
setEulerianWithName(_ value: String)— action name (mandatory)setEulerianWithMode(_ value: String)— action direction:"in"(entry) or"out"(exit)setEulerianWithLabel(_ value: String)— action label(s), comma-separatedsetEulerianWithRef(_ value: String)— reference identifying the action in your systems (optional)setEulerianWithParams(_ value: EAOParams)— additional key/value parameters
Swift — action on a page view
let action1 = EAOAction()
action1.setEulerianWithName("subscription-step1")
action1.setEulerianWithMode("in")
action1.setEulerianWithLabel("premium-offer")
let action2 = EAOAction()
action2.setEulerianWithName("subscription-step1")
action2.setEulerianWithMode("out")
action2.setEulerianWithLabel("abandoned")
let props = EAProperties(path: "subscription|step1")
props.setEulerianWithUid("123asd")
props.addEulerianWithAction(action1)
props.addEulerianWithAction(action2)
EAnalytics.track(props)Swift — standalone action (no page view)
let action = EAOAction()
action.setEulerianWithName("cta-click")
action.setEulerianWithMode("in")
action.setEulerianWithLabel("hero-banner")
let params = EAOParams()
params.setEulerianWithStringValue("martinique", forKey: "origin")
action.setEulerianWithParams(params)
let props = EAProperties(path: "homepage")
props.setEulerianStandalone() // does not count as a page view
props.setEulerianWithUid("123asd")
props.addEulerianWithAction(action)
EAnalytics.track(props)Objective-C
EAOAction *action = [[EAOAction alloc] init];
[action setEulerianWithName:@"cta-click"];
[action setEulerianWithMode:@"in"];
[action setEulerianWithLabel:@"hero-banner"];
EAOParams *params = [[EAOParams alloc] init];
[params setEulerianWithStringValue:@"martinique" forKey:@"origin"];
[action setEulerianWithParams:params];
EAProperties *props = [[EAProperties alloc] initWithPath:@"homepage"];
[props setEulerianStandalone];
[props setEulerianWithUid:@"123asd"];
[props addEulerianWithAction:action];
[EAnalytics track:props];Attach one or more context flags to any tag to enrich your reports with contextual dimensions. Each flag accepts multiple values.
EAOSiteCentricCFlag methods:
setEulerianWithValues(_ values: [String], forKey key: String)— defines a contextual dimension with one or more values
Attach to a tag via:
setEulerianWithCFlag(_ value: EAOSiteCentricCFlag)— available on all tag types
Swift
let cflag = EAOSiteCentricCFlag()
cflag.setEulerianWithValues(["rolandgarros", "wimbledon"], forKey: "category_1")
cflag.setEulerianWithValues(["tennis"], forKey: "category_2")
cflag.setEulerianWithValues(["usopen"], forKey: "category_3")
let props = EAProperties(path: "home|main")
props.setEulerianWithUid("123asd")
props.setEulerianWithEmail("email@test.com")
props.setEulerianWithCFlag(cflag)
EAnalytics.track(props)Objective-C
EAOSiteCentricCFlag *cflag = [[EAOSiteCentricCFlag alloc] init];
[cflag setEulerianWithValues:@[@"rolandgarros", @"wimbledon"] forKey:@"category_1"];
[cflag setEulerianWithValues:@[@"tennis"] forKey:@"category_2"];
[cflag setEulerianWithValues:@[@"usopen"] forKey:@"category_3"];
EAProperties *props = [[EAProperties alloc] initWithPath:@"home|main"];
[props setEulerianWithUid:@"123asd"];
[props setEulerianWithEmail:@"email@test.com"];
[props setEulerianWithCFlag:cflag];
[EAnalytics track:props];For hybrid apps that open a WebView, pass the SDK's internal identifier in the opening URL to ensure tracking continuity between the native app and the web session. Also add the edev parameter to qualify traffic as native.
Swift
let euidl = EAnalytics.euidl()
// Build the URL with the required parameters
var components = URLComponents(string: "https://www.example.com/landing")!
components.queryItems = [
URLQueryItem(name: "ea-euidl-bypass", value: euidl),
URLQueryItem(name: "edev", value: "AppNativeIOSphone")
]
let webViewURL = components.url!
// Load in the WebView
webView.load(URLRequest(url: webViewURL))Objective-C
NSString *euidl = [EAnalytics euidl];
NSURLComponents *components = [NSURLComponents componentsWithString:@"https://www.example.com/landing"];
components.queryItems = @[
[NSURLQueryItem queryItemWithName:@"ea-euidl-bypass" value:euidl],
[NSURLQueryItem queryItemWithName:@"edev" value:@"AppNativeIOSphone"]
];
[webView loadRequest:[NSURLRequest requestWithURL:components.URL]];Accepted values for edev:
| Value | Device |
|---|---|
AppNativeIOSphone |
iPhone |
AppNativeIOStablet |
iPad |
AppNativeAndroidphone |
Android phone |
AppNativeAndroidtablet |
Android tablet |
ea-euidl-bypassmust be present on every URL change within the WebView, otherwise the link between app and web navigation is lost.
Track downloads and updates by including these parameters in the first tag sent at app launch.
| Parameter | Value | Description |
|---|---|---|
ea-appname |
App name | App identifier — must never change — collected automatically by the SDK |
ea-appversion |
Version string | Current version — collected automatically by the SDK |
ea-appinstalled |
1 |
Must be passed manually if the app existed before Eulerian was integrated |
These parameters are collected automatically by the SDK on every hit. You only need to pass ea-appinstalled during a migration.
System logic:
- The Download metric is incremented when
ea-appnameis seen for the first time for this user (withoutea-appinstalled). - The Update metric is incremented when
ea-appnameis unchanged butea-appversionhas a new value compared to the last launch.
Migration (app that existed before Eulerian):
let props = EAProperties(path: "home|main")
props.setEulerianWithValue("1", forKey: "ea-appinstalled")
EAnalytics.track(props)The two modes below are mutually exclusive. Choose one and never use both in the same application.
Send the TCString generated by your CMP once per visitor, at the moment the user expresses their opt-in or opt-out.
Swift
let props = EAProperties(path: "universe|section|page")
props.setEulerianWithUid("5434742")
props.setEulerianWithValue("monthly", forKey: "subscription")
props.setEulerianWithValue("EADURF214345", forKey: "gdpr_consent") // your TCString
EAnalytics.track(props)Pass the Eulerian IDs of refused categories, separated by -. Send - alone if the user accepts all categories.
Swift
let props = EAProperties(path: "universe|section|page")
props.setEulerianWithUid("5434742")
props.setEulerianWithValue("monthly", forKey: "subscription")
props.setEulerianWithValue("1-10", forKey: "pmcat") // IDs of refused categories
EAnalytics.track(props)Example category mapping:
| Category | Eulerian ID |
|---|---|
| analytics | 1 |
| advertising | 10 |
| functional | 19 |
Example: user refuses analytics + advertising → pmcat = 1-10
Provide this URL on your "Privacy / GDPR" page or in your CMP for an unconditional full opt-out:
https://<your-collection-domain>/optout.html?url=<your-domain>
| TCF v2 mode | Categories mode | |
|---|---|---|
| Parameter | gdpr_consent |
pmcat |
| When | On opt-in/out | On opt-in/out |
| Content | TCString | Refused IDs or - |
| CMP compatibility | TCF v2 CMP | In-house / non-TCF CMP |
The SDK includes a PrivacyInfo.xcprivacy file declaring the collected data and the system APIs used. This file has been required by the App Store since spring 2024 for third-party SDKs.
Data declared in the manifest:
| Data type | Usage |
|---|---|
| Email address | Linking |
| User ID | Linking + Tracking |
| Device ID / IDFV | Linking |
| Purchase history | Linking |
| Product interaction | Linking |
| Other usage data | Linking |
Declared system API: NSUserDefaults (reason: CA92.1 — offline queue storage).
If your application enables advertising tracking (IDFA), add your collection domain to Info.plist:
<key>NSPrivacyTrackingDomains</key>
<array>
<string>example.demo.com</string>
</array>The SDK automatically collects the IDFA if the AdSupport framework is linked and the user has granted permission via ATTrackingManager. No additional configuration is required on the SDK side.