{"id":19167349,"url":"https://github.com/affise/sdk-ios","last_synced_at":"2025-05-07T13:41:26.364Z","repository":{"id":62174885,"uuid":"550735530","full_name":"affise/sdk-ios","owner":"affise","description":"Affise Attribution iOS SDK","archived":false,"fork":false,"pushed_at":"2025-05-05T12:51:30.000Z","size":747,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-05-05T13:52:57.500Z","etag":null,"topics":["affise","ios","metrics","mobile","sdk"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/affise.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2022-10-13T08:40:49.000Z","updated_at":"2025-05-05T12:51:33.000Z","dependencies_parsed_at":"2023-02-10T09:31:41.344Z","dependency_job_id":"edf76227-8109-4089-8107-09c0100ee0ee","html_url":"https://github.com/affise/sdk-ios","commit_stats":{"total_commits":14,"total_committers":4,"mean_commits":3.5,"dds":0.3571428571428571,"last_synced_commit":"21fde2f364f67a58eeee35fb25a5d8f74d79491e"},"previous_names":[],"tags_count":68,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/affise%2Fsdk-ios","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/affise%2Fsdk-ios/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/affise%2Fsdk-ios/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/affise%2Fsdk-ios/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/affise","download_url":"https://codeload.github.com/affise/sdk-ios/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252889092,"owners_count":21820114,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["affise","ios","metrics","mobile","sdk"],"created_at":"2024-11-09T09:36:55.590Z","updated_at":"2025-05-07T13:41:26.354Z","avatar_url":"https://github.com/affise.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Affise Attribution iOS Library\n\n[Change Log](CHANGELOG.md)\n\n| Pod                         | Version                   |\n| --------------------------- |:-------------------------:|\n| `AffiseAttributionLib`      | [`1.6.49`](https://github.com/CocoaPods/Specs/tree/master/Specs/a/9/3/AffiseAttributionLib) |\n| `AffiseSKAdNetwork`         | [`1.6.49`](https://github.com/CocoaPods/Specs/tree/master/Specs/3/6/f/AffiseSKAdNetwork)    |\n| `AffiseModule/Advertising`  | [`1.6.49`](https://github.com/CocoaPods/Specs/tree/master/Specs/0/3/d/AffiseModule/)        |\n| `AffiseModule/Link`         | [`1.6.49`](https://github.com/CocoaPods/Specs/tree/master/Specs/0/3/d/AffiseModule/)        |\n| `AffiseModule/Persistent`   | [`1.6.49`](https://github.com/CocoaPods/Specs/tree/master/Specs/0/3/d/AffiseModule/)        |\n| `AffiseModule/Status`       | [`1.6.49`](https://github.com/CocoaPods/Specs/tree/master/Specs/0/3/d/AffiseModule/)        |\n| `AffiseModule/Subscription` | [`1.6.49`](https://github.com/CocoaPods/Specs/tree/master/Specs/0/3/d/AffiseModule/)        |\n\n- [Affise Attribution iOS Library](#affise-attribution-ios-library)\n- [Description](#description)\n  - [Quick start](#quick-start)\n    - [SDK compatibility](#sdk-compatibility)\n  - [Integration](#integration)\n    - [Integrate as Cocoapods](#integrate-as-cocoapods)\n    - [Integrate as Swift Package Manager](#integrate-as-swift-package-manager)\n    - [Initialize](#initialize)\n      - [Domain](#domain)\n    - [Modules](#modules)\n      - [Module Advertising](#module-advertising)\n      - [Module Link](#module-link)\n      - [Module Status](#module-status)\n      - [Module Subscription](#module-subscription)\n    - [Requirements](#requirements)\n  - [StoreKit Ad Network](#storekit-ad-network)\n- [Features](#features)\n  - [ProviderType identifiers collection](#providertype-identifiers-collection)\n    - [Attribution](#attribution)\n    - [Advertising](#advertising)\n  - [Event send control](#event-send-control)\n  - [Events tracking](#events-tracking)\n  - [Custom events tracking](#custom-events-tracking)\n  - [Predefined event parameters](#predefined-event-parameters)\n    - [PredefinedString](#predefinedstring)\n    - [PredefinedLong](#predefinedlong)\n    - [PredefinedFloat](#predefinedfloat)\n    - [PredefinedObject](#predefinedobject)\n    - [PredefinedListObject](#predefinedlistobject)\n    - [PredefinedListString](#predefinedliststring)\n  - [Events buffering](#events-buffering)\n  - [Push token tracking](#push-token-tracking)\n  - [Reinstall Uninstall tracking](#reinstall-uninstall-tracking)\n  - [Links](#links)\n    - [Deeplinks](#deeplinks)\n    - [AppLinks](#applinks)\n    - [Get deferred deeplink](#get-deferred-deeplink)\n    - [Get deferred deeplink value](#get-deferred-deeplink-value)\n  - [Get random user Id](#get-random-user-id)\n  - [Get random device Id](#get-random-device-id)\n  - [Get providers](#get-providers)\n  - [Is first run](#is-first-run)\n  - [Get referrer](#get-referrer)\n  - [Get referrer parameter](#get-referrer-parameter)\n  - [Referrer keys](#referrer-keys)\n  - [Get module state](#get-module-state)\n  - [WebView tracking](#webview-tracking)\n    - [Initialize WebView](#initialize-webview)\n    - [Events tracking JS](#events-tracking-js)\n    - [Predefined event parameters JS](#predefined-event-parameters-js)\n    - [Custom events JS](#custom-events-js)\n  - [SDK to SDK integrations](#sdk-to-sdk-integrations)\n    - [AdMob](#admob)\n    - [AppLovin MAX](#applovin-max)\n    - [Helium by Chartboost](#helium-by-chartboost)\n    - [ironSource](#ironsource)\n  - [Custom](#custom)\n    - [ConversionId](#conversionid)\n- [Debug](#debug)\n  - [Validate credentials](#validate-credentials)\n  - [Version](#version)\n- [Troubleshoots](#troubleshoots)\n  \n# Description\n\nAffise SDK is a software you can use to collect app usage statistics, device identifiers, deeplink usage, track install\nreferrer.\n\n## Quick start\n\n### SDK compatibility\n\n- `Xcode` `14.2+`  \n- `iOS`   `12+`\n\n## Integration\n\n### Integrate as Cocoapods\n\nTo add the SDK using Cocoapods, specify the version you want to use in your Podfile:\n\n```ruby\naffise_version = '1.6.49'\n# Affise SDK library\npod 'AffiseAttributionLib', affise_version\n# Affise modules\npod 'AffiseModule/Advertising', affise_version\npod 'AffiseModule/Link', affise_version\npod 'AffiseModule/Status', affise_version\npod 'AffiseModule/Subscription', affise_version\n```\n\nGet source directly from GitHub\n\n```ruby\naffise_version = '1.6.49'\n# Affise SDK library\npod 'AffiseAttributionLib', :git =\u003e 'https://github.com/affise/sdk-ios.git', :tag =\u003e affise_version\n# Affise modules\npod 'AffiseModule/Advertising', :git =\u003e 'https://github.com/affise/sdk-ios.git', :tag =\u003e affise_version\npod 'AffiseModule/Link', :git =\u003e 'https://github.com/affise/sdk-ios.git', :tag =\u003e affise_version\npod 'AffiseModule/Status', :git =\u003e 'https://github.com/affise/sdk-ios.git', :tag =\u003e affise_version\npod 'AffiseModule/Subscription', :git =\u003e 'https://github.com/affise/sdk-ios.git', :tag =\u003e affise_version\n```\n\n### Integrate as Swift Package Manager\n\nTo add the SDK using SPM:\n\n1. Open XCode project, navigate to `File / Add Packages`.\n\n2. In the `Add New Package` window enter `https://github.com/affise/sdk-ios` in `search` field.\n\n3. Click on the `Add Package` button.\n\n4. In `Choose Package Products` window select required packages and click `Add Package`, and it will be added to your iOS project and linked automatically.\n\n### Initialize\n\nAfter library is added as dependency sync project with gradle files and initialize.\n\nFor `swift` use:\n\n\u003e Demo app [AppDelegate.swift](example/app/app/AppDelegate.swift)\n\n```swift\nimport AffiseAttributionLib\n\n@main\nclass AppDelegate: UIResponder, UIApplicationDelegate {\n\n    var window: UIWindow?\n\n    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -\u003e Bool {\n        // Override point for customization after application launch.\n        Affise\n            .settings(\n                affiseAppId: \"Your appId\", //Change to your app id\n                secretKey: \"Your secretKey\" //Change to your appToken\n            )\n            .start(app: application, launchOptions: launchOptions) // Start Affise SDK\n\n        return true\n    }\n}\n```\n\nFor `objective-c` use:\n\n\u003e Demo app [AppDelegate.m](example/app-obj-c/app-obj-c/AppDelegate.m)\n\n```objective-c\n#import \"AppDelegate.h\"\n#import \u003cAffiseAttributionLib/AffiseAttributionLib-Swift.h\u003e\n\n\n@implementation AppDelegate\n\n- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {\n    // Override point for customization after application launch.\n\n    AffiseSettings *affise = [Affise settingsWithAffiseAppId:@\"Your appId\" //Change to your app id\n                                                   secretKey:@\"Your secretKey\" //Change to your appToken\n    ];\n    [affise setProduction:false]; //To enable debug methods set Production to false\n    [affise startWithApp:application launchOptions:launchOptions]; // Start Affise SDK\n\n    return YES;\n}\n@end\n```\n\nCheck if library is initialized\n\n```swift\nAffise\n    .settings(\n        affiseAppId: \"Your appId\",\n        secretKey: \"Your secretKey\" \n    )\n    .setOnInitSuccess {\n        // Called then library is initialized\n    }\n    .start(app: application, launchOptions: launchOptions)\n```\n\n#### Domain\n\nSet SDK server doamin:\n\n```swift\nAffise\n    .settings(\n        affiseAppId: \"Your appId\",\n        secretKey: \"Your secretKey\"\n    )\n    .setDomain(\"https://YourCustomDomain\") // Set custom domain\n    .start(app: application, launchOptions: launchOptions)\n```\n\n### Modules\n\n\u003e **Warning**\n\u003e\n\u003e 🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥\n\u003e\n\u003e How to install modules read in [Integration section](#integration)\n\u003e\n\u003e 🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥\n\n| Module         | Version                                                                              | Start    |\n| -------------- |:------------------------------------------------------------------------------------:|----------|\n| `Advertising`  | [`1.6.49`](https://github.com/CocoaPods/Specs/tree/master/Specs/0/3/d/AffiseModule/) | `Manual` |\n| `Link`         | [`1.6.49`](https://github.com/CocoaPods/Specs/tree/master/Specs/0/3/d/AffiseModule/) | `Auto`   |\n| `Persistent`   | [`1.6.49`](https://github.com/CocoaPods/Specs/tree/master/Specs/0/3/d/AffiseModule/) | `Auto`   |\n| `Status`       | [`1.6.49`](https://github.com/CocoaPods/Specs/tree/master/Specs/0/3/d/AffiseModule/) | `Auto`   |\n| `Subscription` | [`1.6.49`](https://github.com/CocoaPods/Specs/tree/master/Specs/0/3/d/AffiseModule/) | `Auto`   |\n\nIf module start type is `manual`, then call:\n\n```swift\nAffise.Module.moduleStart(.Advertising)\n```\n\nGet list of installed modules:\n\n```swift\nAffise.Module.getModulesInstalled()\n```\n\n#### Module Advertising\n\n\u003e **Warning**\n\u003e\n\u003e 🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥\n\u003e\n\u003e [Start module **Manually**](#modules)\n\u003e\n\u003e 🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥\n\n```swift\nAffise.Module.moduleStart(.Advertising)\n```\n\nThis module required to Use [`IDFA`](https://developer.apple.com/documentation/adsupport/asidentifiermanager/advertisingidentifier) (Identifier for advertisers)\n\n\u003e **Warning**\n\u003e\n\u003e 🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥\n\u003e\n\u003e Module Advertising requires `NSUserTrackingUsageDescription` key in `info.plist`\n\u003e\n\u003e Application **will crash** if key not present\n\u003e\n\u003e 🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥\n\nOpen `info.plist` and add key `NSUserTrackingUsageDescription` with string value. For more information [read requirements](#requirements)\n\n#### Module Link\n\nReturn last url in chan of redirection\n\n🟥Support MAX 10 redirections🟥\n\n```swift\nAffise.Module.linkResolve(\"SITE_WITH_REDIRECTION\") { redirectUrl in\n    // handle redirect url\n}\n```\n\n#### Module Status\n\n```swift\nAffise.Module.getStatus(AffiseModules.STATUS) { response in \n    // handle status response\n};\n```\n\n#### Module Subscription\n\nGet products by ids:\n\n```swift\nlet ids = [\"exampple.product.id_1\", \"exampple.product.id_2\"]\n\nAffise.Module.fetchProducts(ids) { result in\n    switch result {\n    case .failure(let error):\n        print(\"\\(error)\")\n    case .success(let result):\n        let products: [AffiseProduct]  = result.products\n        let invalidIds: [String] = result.invalidIds\n    }\n}\n```\n\nPurchase product:\n\n```swift\n// Specify product type for correct affise event\nAffise.Module.purchase(product, .CONSUMABLE) { result in\n    switch result {\n    case .failure(let error):\n        print(\"\\(error)\")\n    case .success(let purchasedInfo):\n        let info: AffisePurchasedInfo = purchasedInfo\n    }\n}\n```\n\n### Requirements\n\nAffise Advertising module uses `AppTrackingTransparency` framework to get `advertisingIdentifier`\nFor working functionality your app needs to declare [`NSUserTrackingUsageDescription` permission](https://developer.apple.com/documentation/bundleresources/information_property_list/nsusertrackingusagedescription):\n\nOpen XCode project `info.plist` and add key `NSUserTrackingUsageDescription` with string value\n\n```xml\n\u003cplist version=\"1.0\"\u003e\n\u003cdict\u003e\n    ...\n\t\u003ckey\u003eNSUserTrackingUsageDescription\u003c/key\u003e\n\t\u003cstring\u003eYoure permission text\u003c/string\u003e\n\u003c/dict\u003e\n```\n\n## StoreKit Ad Network\n\nTo add the SDK using Cocoapods, specify the version you want to use in your Podfile:\n\n```ruby\n# Wrapper for StoreKit Ad Network \npod 'AffiseSKAdNetwork', '1.6.49'\n```\n\nGet source directly from GitHub\n\n```ruby\n# Wrapper for StoreKit Ad Network \npod 'AffiseSKAdNetwork', :git =\u003e 'https://github.com/affise/sdk-ios.git', :tag =\u003e '1.6.49'\n```\n\nFor `swift` use:\n\n\u003e Demo app [AppDelegate.swift](example/app/app/AppDelegate.swift)\n\n\u003e **Note**\n\u003e\n\u003e 🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦\n\u003e \n\u003e For ios prior `16.1` first call\n\u003e \n\u003e 🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦\n\n```swift\nimport AffiseSKAdNetwork\n\nAffiseSKAd.register { error in\n    // Handle error\n}\n```\n\nFor `objective-c` use:\n\n\u003e Demo app [AppDelegate.m](example/app-obj-c/app-obj-c/AppDelegate.m)\n\n```objective-c\n#import \u003cAffiseSKAdNetwork/AffiseSKAdNetwork-Swift.h\u003e\n\n[AffiseSKAd registerWithCompletionHandler:^(NSString * error) {\n    // Handle error\n}];\n```\n\nUpdates the fine and coarse conversion values, and calls a completion handler if the update fails.\n\n\u003e **Note**\n\u003e\n\u003e 🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦\n\u003e \n\u003e Second argument `coarseValue` is available in iOS `16.1+`\n\u003e\n\u003e 🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦\n\n```swift\nAffiseSKAd.updatePostbackConversionValue(fineValue: 1, coarseValue: CoarseConversionValue.medium) { error in\n    // Handle error\n}\n```\n\nFor `objective-c` use:\n\n```objective-c\n#import \u003cAffiseSKAdNetwork/AffiseSKAdNetwork-Swift.h\u003e\n\n[AffiseSKAd updatePostbackWithFineValue:1\n                            coarseValue:[CoarseConversionValue medium]\n                        completionHandler:^(NSString * error) {\n    // Handle error\n}];\n```\n\nConfigure your app to send postback copies to Affise:\n\nAdd key `NSAdvertisingAttributionReportEndpoint` to `Info.plist`\nSet key value to `https://affise-skadnetwork.com/`\n\nExample: [`example/ios/Runner/Info.plist`](example/ios/Runner/Info.plist)\n\n```xml\n\u003ckey\u003eCFBundleURLTypes\u003c/key\u003e\n\u003carray\u003e\n    \u003cdict\u003e\n      \u003ckey\u003eNSAdvertisingAttributionReportEndpoint\u003c/key\u003e\n      \u003cstring\u003ehttps://affise-skadnetwork.com/\u003c/string\u003e\n    \u003c/dict\u003e\n\u003c/array\u003e\n```\n\n# Features\n\n## ProviderType identifiers collection\n\nTo match users with events and data library is sending, these `ProviderType` identifiers are collected:\n\n### Attribution\n\n- `AFFISE_APP_ID`\n- `AFFISE_PKG_APP_NAME`\n- `AFF_APP_NAME_DASHBOARD`\n- `APP_VERSION`\n- `APP_VERSION_RAW`\n- `STORE`\n- `TRACKER_TOKEN`\n- `TRACKER_NAME`\n- `FIRST_TRACKER_TOKEN`\n- `FIRST_TRACKER_NAME`\n- `LAST_TRACKER_TOKEN`\n- `LAST_TRACKER_NAME`\n- `OUTDATED_TRACKER_TOKEN`\n- `INSTALLED_TIME`\n- `FIRST_OPEN_TIME`\n- `INSTALLED_HOUR`\n- `FIRST_OPEN_HOUR`\n- `INSTALL_FIRST_EVENT`\n- `INSTALL_BEGIN_TIME`\n- `INSTALL_FINISH_TIME`\n- `REFERRAL_TIME`\n- `CREATED_TIME`\n- `CREATED_TIME_MILLI`\n- `CREATED_TIME_HOUR`\n- `UNINSTALL_TIME`\n- `REINSTALL_TIME`\n- `LAST_SESSION_TIME`\n- `CONNECTION_TYPE`\n- `CPU_TYPE`\n- `HARDWARE_NAME`\n- `NETWORK_TYPE`\n- `DEVICE_MANUFACTURER`\n- `PROXY_IP_ADDRESS`\n- `DEEPLINK_CLICK`\n- `DEVICE_ATLAS_ID`\n- `AFFISE_DEVICE_ID`\n- `AFFISE_ALT_DEVICE_ID`\n- `ANDROID_ID`\n- `ANDROID_ID_MD5`\n- `MAC_SHA1`\n- `MAC_MD5`\n- `GAID_ADID`\n- `GAID_ADID_MD5`\n- `OAID`\n- `OAID_MD5`\n- `ALTSTR_ADID`\n- `FIREOS_ADID`\n- `COLOROS_ADID`\n- `REFTOKEN`\n- `REFTOKENS`\n- `REFERRER`\n- `USER_AGENT`\n- `MCCODE`\n- `MNCODE`\n- `ISP`\n- `REGION`\n- `COUNTRY`\n- `LANGUAGE`\n- `DEVICE_NAME`\n- `DEVICE_TYPE`\n- `OS_NAME`\n- `PLATFORM`\n- `SDK_PLATFORM`\n- `API_LEVEL_OS`\n- `AFFISE_SDK_VERSION`\n- `OS_VERSION`\n- `RANDOM_USER_ID`\n- `AFFISE_SDK_POS`\n- `TIMEZONE_DEV`\n- `AFFISE_EVENT_TOKEN`\n- `LAST_TIME_SESSION`\n- `TIME_SESSION`\n- `AFFISE_SESSION_COUNT`\n- `LIFETIME_SESSION_COUNT`\n- `AFFISE_DEEPLINK`\n- `AFFISE_PART_PARAM_NAME`\n- `AFFISE_PART_PARAM_NAME_TOKEN`\n- `AFFISE_EVENT_NAME`\n- `AFFISE_APP_TOKEN`\n- `LABEL`\n- `AFFISE_SDK_SECRET_ID`\n- `UUID`\n- `AFFISE_APP_OPENED`\n- `PUSHTOKEN`\n- `IS_EMULATOR`\n\n### Advertising\n\n- `ADID`\n\n## Event send control\n\nThere are two ways to send events\n\n1. Cache event to later scheduled send in batch\n\n```swift\nAddToCartEvent()\n    .send()\n```\n\n2. Send event right now\n\n```swift\nAddToCartEvent()\n    .sendNow({\n        // handle event send success\n    }) { errorResponse in\n        // handle event send failed\n        // 🟥Warning🟥: event is NOT cached for later send\n    }\n```\n\n## Events tracking\n\nFor example, we want to track what items usually user adds to shopping cart. To send event first create it with\nfollowing code\n\n```swift\nclass Presenter {\n    func onUserAddsItemsToCart(items: String) {\n        let items = [\n            (\"items\", \"cookies, potato, milk\")\n        ]\n\n        AddToCartEvent(\"groceries\")\n            .addPredefinedParameter(PredefinedString.DESCRIPTION, string: \"best before 2029\")\n            .addPredefinedParameter(PredefinedObject.CONTENT, object: items)\n            .send() // Send event\n    }\n}\n```\n\nFor `objective-c` use:\n\n```objective-c\n- (void)onUserAddsItemsToCart:(NSString *)itemsToCart {\n    NSArray *items = @[\n        @{\"items\", itemsToCart}\n    ];\n\n    Event *event = [[AddToCartEvent alloc] init:@\"groceries\"];\n    [event addPredefinedParameter:PredefinedStringADREV_AD_TYPE value:@\"best before 2029\"];\n    [event addPredefinedParameter:PredefinedObjectCONTENT object:items];\n    // Send event\n    [event send];\n}\n```\n\nWith above example you can implement other events:\n\n- `AchieveLevel`\n- `AddPaymentInfo`\n- `AddToCart`\n- `AddToWishlist`\n- `AdRevenue`\n- `ClickAdv`\n- `CompleteRegistration`\n- `CompleteStream`\n- `CompleteTrial`\n- `CompleteTutorial`\n- `Contact`\n- `ContentItemsView`\n- `CustomizeProduct`\n- `DeepLinked`\n- `Donate`\n- `FindLocation`\n- `InitiateCheckout`\n- `InitiatePurchase`\n- `InitiateStream`\n- `Invite`\n- `LastAttributedTouch`\n- `Lead`\n- `ListView`\n- `Login`\n- `OpenedFromPushNotification`\n- `Order`\n- `OrderItemAdded`\n- `OrderItemRemove`\n- `OrderCancel`\n- `OrderReturnRequest`\n- `OrderReturnRequestCancel`\n- `Purchase`\n- `Rate`\n- `ReEngage`\n- `Reserve`\n- `Sales`\n- `Schedule`\n- `Search`\n- `Share`\n- `SpendCredits`\n- `StartRegistration`\n- `StartTrial`\n- `StartTutorial`\n- `SubmitApplication`\n- `Subscribe`\n- `TravelBooking`\n- `UnlockAchievement`\n- `Unsubscribe`\n- `Update`\n- `ViewAdv`\n- `ViewCart`\n- `ViewContent`\n- `ViewItem`\n- `ViewItems`\n- `InitialSubscription`\n- `InitialTrial`\n- `InitialOffer`\n- `ConvertedTrial`\n- `ConvertedOffer`\n- `TrialInRetry`\n- `OfferInRetry`\n- `SubscriptionInRetry`\n- `RenewedSubscription`\n- `FailedSubscriptionFromRetry`\n- `FailedOfferFromRetry`\n- `FailedTrialFromRetry`\n- `FailedSubscription`\n- `FailedOfferise`\n- `FailedTrial`\n- `ReactivatedSubscription`\n- `RenewedSubscriptionFromRetry`\n- `ConvertedOfferFromRetry`\n- `ConvertedTrialFromRetry`\n- `Unsubscription`\n\n## Custom events tracking\n\nUse any of custom events if default doesn't fit your scenario:\n\n- `CustomId01`\n- `CustomId02`\n- `CustomId03`\n- `CustomId04`\n- `CustomId05`\n- `CustomId06`\n- `CustomId07`\n- `CustomId08`\n- `CustomId09`\n- `CustomId10`\n\nIf above event functionality still limits your usecase, you can use `UserCustomEvent`\n\n```swift\nUserCustomEvent(eventName: \"MyCustomEvent\")\n    .send()   \n```\n\n## Predefined event parameters\n\nTo enrich your event with another dimension, you can use predefined parameters for most common cases.\nAdd it to any event:\n\n```swift\nclass Presenter {\n    func onUserAddsItemsToCart(items: String) {\n        let items = [\n            (\"items\", \"cookies, potato, milk\")\n        ]\n\n        AddToCartEvent(\"groceries\")\n            .addPredefinedParameter(PredefinedString.DESCRIPTION, string: \"best before 2029\")\n            .addPredefinedParameter(PredefinedObject.CONTENT, object: items)\n            .send() // Send event  \n    }\n}\n```\n\nFor `objective-c` use:\n\n```objective-c\n- (void)onUserAddsItemsToCart:(NSString *)itemsToCart {\n    NSArray *items = @[\n        @{\"items\", itemsToCart}\n    ];\n\n    Event *event = [[AddToCartEvent alloc] init:@\"groceries\"];\n    [event addPredefinedParameter:PredefinedStringADREV_AD_TYPE value:@\"best before 2029\"];\n    [event addPredefinedParameter:PredefinedObjectCONTENT object:items];\n    // Send event\n    [event send];\n}\n```\n\nIn examples above `PredefinedParameters.DESCRIPTION` and `PredefinedObject.CONTENT` is used, but many others is available:\n\n| PredefinedParameter                           | Type             |\n|-----------------------------------------------|------------------|\n| [PredefinedString](#predefinedstring)         | String           |\n| [PredefinedLong](#predefinedlong)             | Int64            |\n| [PredefinedFloat](#predefinedfloat)           | Float            |\n| [PredefinedObject](#predefinedobject)         | [(String, Any)]  |\n| [PredefinedListObject](#predefinedlistobject) | [[(String, Any)]]|\n| [PredefinedListString](#predefinedliststring) | [String]         |\n\n### PredefinedString\n\n- `ACHIEVEMENT_ID`\n- `ADREV_AD_TYPE`\n- `BRAND`\n- `BRICK`\n- `CATALOGUE_ID`\n- `CHANNEL_TYPE`\n- `CITY`\n- `CLASS`\n- `CONTENT_ID`\n- `CONTENT_NAME`\n- `CONTENT_TYPE`\n- `CONVERSION_ID`\n- `COUNTRY`\n- `COUPON_CODE`\n- `CURRENCY`\n- `CUSTOMER_SEGMENT`\n- `CUSTOMER_TYPE`\n- `CUSTOMER_USER_ID`\n- `DEEP_LINK`\n- `DESCRIPTION`\n- `DESTINATION_A`\n- `DESTINATION_B`\n- `DESTINATION_LIST`\n- `NEW_VERSION`\n- `OLD_VERSION`\n- `ORDER_ID`\n- `PARAM_01`\n- `PARAM_02`\n- `PARAM_03`\n- `PARAM_04`\n- `PARAM_05`\n- `PARAM_06`\n- `PARAM_07`\n- `PARAM_08`\n- `PARAM_09`\n- `PARAM_10`\n- `PAYMENT_INFO_AVAILABLE`\n- `PREFERRED_NEIGHBORHOODS`\n- `PRODUCT_ID`\n- `PRODUCT_NAME`\n- `PURCHASE_CURRENCY`\n- `RECEIPT_ID`\n- `REGION`\n- `REGISTRATION_METHOD`\n- `REVIEW_TEXT`\n- `SEARCH_STRING`\n- `SEGMENT`\n- `STATUS`\n- `SUBSCRIPTION_ID`\n- `SUCCESS`\n- `SUGGESTED_DESTINATIONS`\n- `SUGGESTED_HOTELS`\n- `TUTORIAL_ID`\n- `UTM_CAMPAIGN`\n- `UTM_MEDIUM`\n- `UTM_SOURCE`\n- `VALIDATED`\n- `VERTICAL`\n- `VIRTUAL_CURRENCY_NAME`\n- `VOUCHER_CODE`\n\n### PredefinedLong\n\n- `AMOUNT`\n- `DATE_A`\n- `DATE_B`\n- `DEPARTING_ARRIVAL_DATE`\n- `DEPARTING_DEPARTURE_DATE`\n- `HOTEL_SCORE`\n- `LEVEL`\n- `MAX_RATING_VALUE`\n- `NUM_ADULTS`\n- `NUM_CHILDREN`\n- `NUM_INFANTS`\n- `PREFERRED_NUM_STOPS`\n- `PREFERRED_STAR_RATINGS`\n- `QUANTITY`\n- `RATING_VALUE`\n- `RETURNING_ARRIVAL_DATE`\n- `RETURNING_DEPARTURE_DATE`\n- `SCORE`\n- `TRAVEL_START`\n- `TRAVEL_END`\n- `USER_SCORE`\n- `EVENT_START`\n- `EVENT_END`\n\n### PredefinedFloat\n\n- `PREFERRED_PRICE_RANGE`\n- `PRICE`\n- `REVENUE`\n- `LAT`\n- `LONG`\n\n### PredefinedObject\n\n- `CONTENT`\n\n### PredefinedListObject\n\n- `CONTENT_LIST`\n\n### PredefinedListString\n\n- `CONTENT_IDS`\n\n## Events buffering\n\nAffise library will send any pending events with first opportunity,\nbut if there is no network connection or device is disabled, events are kept locally for 7 days before deletion.\n\n## Push token tracking\n\nTo let affise track push token you need to receive it from your push service provider, and pass to Affise library.\nFirst add firebase integration to your app completing theese steps: [Firebase Docs](https://firebase.google.com/docs/cloud-messaging/ios/client)\n\nAfter you have done with firebase inegration, add to your cloud messaging service `onNewToken` method `Affise.addPushToken(token)`\n\n```swift\nfunc messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {\n  print(\"Firebase registration token: \\(String(describing: fcmToken))\")\n\n  // New token generated\n  Affise.addPushToken(fcmToken)\n}\n```\n\n## Reinstall Uninstall tracking\n\nAffise automaticly track reinstall events by using silent-push technology, to make this feature work, pass push token when it is recreated by user and on you application starts up\n\n```swift\nAffise.addPushToken(token)\n```\n\n## Links\n\n### Deeplinks\n\n\u003e **Warning**\n\u003e\n\u003e 🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥\n\u003e\n\u003e Deeplinks support only **CUSTOM** scheme **NOT** `http` or `https`\n\u003e\n\u003e For `http` or `https` read how to setup [AppLinks](#applinks)\n\u003e\n\u003e 🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥\n\nTo integrate deeplink support you need:\n\n- Follow how to set up deeplinks in the [official documentation](https://developer.apple.com/documentation/xcode/defining-a-custom-url-scheme-for-your-app).\n\n- Register deeplink callback right after `Affise.settings(..).start(..)`\n\n```swift\nAffise.settings(affiseAppId:affiseAppId, secretKey:secretKey).start(app:app, launchOptions: launchOptions)\nAffise.registerDeeplinkCallback { url in\n    // full uri \"scheme://host/path?parameters\"   \n    let deeplink = value.deeplink\n\n    // separated for convenience \n    let scheme = value.scheme\n    let host = value.host\n    let path = value.path\n    let queryParametersMap = value.parameters\n\n    if queryParametersMap[\"\u003cyour_uri_key\u003e\"].contains(\"\u003cyour_uri_key_value\u003e\") == true {\n        // handle value\n    }\n}\n```\n\n- Add deeplink handler to [`AppDelegate.swift`](example/app/app/AppDelegate.swift)\n\n```swift\nfunc application(\n    _ app: UIApplication,\n    open url: URL,\n    options: [UIApplication.OpenURLOptionsKey : Any] = [:]\n) -\u003e Bool {\n    Affise.handleDeeplink(url)\n    return true\n}\n```\n\nAdd key `CFBundleURLTypes` to `Info.plist`\n\nExample: [`example/app/app/Info.plist`](example/app/app/Info.plist)\n\nExample: `YOUR_SCHEME://YOUR_DOMAIN` (`myapp://mydomain.com`)\n\n```xml\n\u003ckey\u003eCFBundleURLTypes\u003c/key\u003e\n\u003carray\u003e\n    \u003cdict\u003e\n        \u003ckey\u003eCFBundleTypeRole\u003c/key\u003e\n        \u003cstring\u003eEditor\u003c/string\u003e\n        \u003ckey\u003eCFBundleURLName\u003c/key\u003e\n        \u003cstring\u003eYOUR_DOMAIN\u003c/string\u003e\n        \u003ckey\u003eCFBundleURLSchemes\u003c/key\u003e\n        \u003carray\u003e\n            \u003cstring\u003eYOUR_SCHEME\u003c/string\u003e\n        \u003c/array\u003e\n    \u003c/dict\u003e\n\u003c/array\u003e\n```\n\nTest DeepLink via terminal command:\n\n```terminal\nxcrun simctl openurl booted \"YOUR_SCHEME://YOUR_DOMAIN/somepath?param=1\u0026list=some\u0026list=other\u0026list=1\"\n```\n\n### AppLinks\n\n\u003e **Warning**\n\u003e\n\u003e 🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥\n\u003e\n\u003e You must owne website domain.\n\u003e\n\u003e And has ability to add file `https://yoursite/.well-known/apple-app-site-association`\n\u003e\n\u003e 🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥\n\nTo integrate applink support you need:\n\n- Follow how to set up applink in the [official documentation](https://developer.apple.com/documentation/xcode/supporting-universal-links-in-your-app).\n\n- Associate your app with your website. [Supporting associated domains](https://developer.apple.com/documentation/xcode/supporting-associated-domains)\n\n- [Configuring an associated domain](https://developer.apple.com/documentation/xcode/configuring-an-associated-domain/)\n\n- Register deeplink callback right after `Affise.settings(..).start(..)`\n\n```swift\nAffise.settings(affiseAppId:affiseAppId, secretKey:secretKey).start(app:app, launchOptions: launchOptions)\nAffise.registerDeeplinkCallback { url in\n    // full uri \"scheme://host/path?parameters\"   \n    let deeplink = value.deeplink\n\n    // separated for convenience \n    let scheme = value.scheme\n    let host = value.host\n    let path = value.path\n    let queryParametersMap = value.parameters\n\n    if queryParametersMap[\"\u003cyour_uri_key\u003e\"].contains(\"\u003cyour_uri_key_value\u003e\")  == true {\n        // handle value\n    }\n}\n```\n\n- Add deeplink handler to `AppDelegate.swift`\n\n```swift\nfunc application(\n    _ application: UIApplication,\n    continue userActivity: NSUserActivity,\n    restorationHandler: @escaping ([UIUserActivityRestoring]?) -\u003e Void\n) -\u003e Bool {\n    Affise.handleUserActivity(userActivity)\n    return true\n}\n```\n\nAdd key `com.apple.developer.associated-domains` to `Info.plist`\n\nExample: `https://YOUR_DOMAIN` (`https://mydomain.com`)\n\n```xml\n\u003ckey\u003ecom.apple.developer.associated-domains\u003c/key\u003e\n\u003carray\u003e\n\t\u003cstring\u003eapplinks:YOUR_DOMAIN\u003c/string\u003e\n\u003c/array\u003e\n```\n\nTest DeepLink via terminal command:\n\n```terminal\nxcrun simctl openurl booted \"https://YOUR_DOMAIN/somepath?param=1\u0026list=some\u0026list=other\u0026list=1\"\n```\n\n### Get deferred deeplink\n\n\u003e **Note**\n\u003e\n\u003e Requires [Affise Status Module](#modules)\n\nUse the next public method of SDK to deferred deeplink from server\n\n```swift\nAffise.getDeferredDeeplink { deferredDeeplink in\n  // handle deferred deeplink\n}\n```\n\n### Get deferred deeplink value\n\n\u003e **Note**\n\u003e\n\u003e Requires [Affise Status Module](#modules)\n\nUse the next public method of SDK to deferred deeplink value from server\n\n```swift\nAffise.getDeferredDeeplinkValue(ReferrerKey.CLICK_ID) { deferredDeeplinkValue in\n  // handle deferred deeplink value\n}\n```\n\n## Get random user Id\n\n```swift\nAffise.getRandomUserId()\n```\n\n## Get random device Id\n\n\u003e **Note**\n\u003e\n\u003e Use [Affise Persistent Module](#modules) to make `device id` more persistent on application reinstall\n\n```swift\nAffise.getRandomDeviceId()\n```\n\n## Get providers\n\nReturns providers map with [ProviderType](#providertype-identifiers-collection) as key\n\n```swift\nlet providers: [ProviderType: Any?] = Affise.getProviders()\nlet key = ProviderType.AFFISE_APP_TOKEN\nlet value = providers[key]\n```\n\n## Is first run\n\n```swift\nAffise.isFirstRun()\n```\n\n## Get referrer\n\n- Add referrer handler to `AppDelegate.swift`\n\n```swift\nfunc application(\n    _ application: UIApplication,\n    continue userActivity: NSUserActivity,\n    restorationHandler: @escaping ([UIUserActivityRestoring]?) -\u003e Void\n) -\u003e Bool {\n    Affise.handleUserActivity(userActivity)\n    return true\n}\n```\n\nUse the next public method of SDK\n\n```swift\nAffise.getReferrerUrl { referrer in\n  // handle referrer\n}\n```\n\n## Get referrer parameter\n\n- Add referrer handler to `AppDelegate.swift`\n\n```swift\nfunc application(\n    _ application: UIApplication,\n    continue userActivity: NSUserActivity,\n    restorationHandler: @escaping ([UIUserActivityRestoring]?) -\u003e Void\n) -\u003e Bool {\n    Affise.handleUserActivity(userActivity)\n    return true\n}\n```\n\nUse the next public method of SDK to get referrer parameter by\n\n```swift\nAffise.getReferrerUrlValue(ReferrerKey.CLICK_ID) { value in\n  // handle referrer value\n}\n```\n\n## Referrer keys\n\nIn examples above `ReferrerKey.CLICK_ID` is used, but many others is available:\n\n- `AD_ID`\n- `CAMPAIGN_ID`\n- `CLICK_ID`\n- `AFFISE_AD`\n- `AFFISE_AD_ID`\n- `AFFISE_AD_TYPE`\n- `AFFISE_ADSET`\n- `AFFISE_ADSET_ID`\n- `AFFISE_AFFC_ID`\n- `AFFISE_CHANNEL`\n- `AFFISE_CLICK_LOOK_BACK`\n- `AFFISE_COST_CURRENCY`\n- `AFFISE_COST_MODEL`\n- `AFFISE_COST_VALUE`\n- `AFFISE_DEEPLINK`\n- `AFFISE_KEYWORDS`\n- `AFFISE_MEDIA_TYPE`\n- `AFFISE_MODEL`\n- `AFFISE_OS`\n- `AFFISE_PARTNER`\n- `AFFISE_REF`\n- `AFFISE_SITE_ID`\n- `AFFISE_SUB_SITE_ID`\n- `AFFISE_SUB_1`\n- `AFFISE_SUB_2`\n- `AFFISE_SUB_3`\n- `AFFISE_SUB_4`\n- `AFFISE_SUB_5`\n- `AFFC`\n- `PID`\n- `SUB_1`\n- `SUB_2`\n- `SUB_3`\n- `SUB_4`\n- `SUB_5`\n\n## Get module state\n\nGet state of the module:\n\n```swift\nAffise.Module.getStatus(AffiseModules.STATUS) { response in \n    // handle status response\n};\n```\n\n## WebView tracking\n\n### Initialize WebView\n\nTo integrate the library into the JavaScript environment, we added a bridge between JavaScript and the native SDK. Now you can send events and use the functionality of the native library directly from Webview.\nHere are step by step instructions:\n\n```swift\n// retreive WebView from view hierarhy\n@IBOutlet weak var webView: WKWebView!\n\n// make sure javascript is enabled\noverride func viewDidLoad() {\n    super.viewDidLoad()\n\n    webView.configuration.preferences.javaScriptEnabled = true\n}\n\n// initialize WebView with Affise native library\nAffise.registerWebView(webView)\n\n```\n\nOther Javascript enviroment features is described below.\n\n### Events tracking JS\n\n\u003e Demo app [example/app/app/index.html](example/app/app/index.html)\n\nAfter WebView is initialized you send events from JavaScript enviroment\n\n```javascript\nlet data = { card: 4138, type: 'phone' };\n\nnew AddPaymentInfoEvent({\n  userData: 'taxi',\n})\n    .addPredefinedParameter(PredefinedString.PURCHASE_CURRENCY, 'USD')\n    .addPredefinedParameter(PredefinedFloat.PRICE, 2.19)\n    .addPredefinedParameter(PredefinedObject.CONTENT, data);\n    .send() // Send event\n```\n\nJust like with native SDK, javascript enviroment also provides default events that can be passed from WebView:\n\n- `AchieveLevelEvent`\n- `AddPaymentInfoEvent`\n- `AddToCartEvent`\n- `AddToWishlistEvent`\n- `AdRevenueEvent`\n- `ClickAdvEvent`\n- `CompleteRegistrationEvent`\n- `CompleteStreamEvent`\n- `CompleteTrialEvent`\n- `CompleteTutorialEvent`\n- `ContactEvent`\n- `ContentItemsViewEvent`\n- `CustomId01Event`\n- `CustomId02Event`\n- `CustomId03Event`\n- `CustomId04Event`\n- `CustomId05Event`\n- `CustomId06Event`\n- `CustomId07Event`\n- `CustomId08Event`\n- `CustomId09Event`\n- `CustomId10Event`\n- `CustomizeProductEvent`\n- `DeepLinkedEvent`\n- `DonateEvent`\n- `FindLocationEvent`\n- `InitiateCheckoutEvent`\n- `InitiatePurchaseEvent`\n- `InitiateStreamEvent`\n- `InviteEvent`\n- `LastAttributedTouchEvent`\n- `LeadEvent`\n- `ListViewEvent`\n- `LoginEvent`\n- `OpenedFromPushNotificationEvent`\n- `OrderEvent`\n- `OrderItemAddedEvent`\n- `OrderItemRemoveEvent`\n- `OrderCancelEvent`\n- `OrderReturnRequestEvent`\n- `OrderReturnRequestCancelEvent`\n- `PurchaseEvent`\n- `RateEvent`\n- `ReEngageEvent`\n- `ReserveEvent`\n- `SalesEvent`\n- `ScheduleEvent`\n- `SearchEvent`\n- `ShareEvent`\n- `SpendCreditsEvent`\n- `StartRegistrationEvent`\n- `StartTrialEvent`\n- `StartTutorialEvent`\n- `SubmitApplicationEvent`\n- `SubscribeEvent`\n- `TravelBookingEvent`\n- `UnlockAchievementEvent`\n- `UnsubscribeEvent`\n- `UpdateEvent`\n- `ViewAdvEvent`\n- `ViewCartEvent`\n- `ViewContentEvent`\n- `ViewItemEvent`\n- `ViewItemsEvent`\n- `InitialSubscriptionEvent`\n- `InitialTrialEvent`\n- `InitialOfferEvent`\n- `ConvertedTrialEvent`\n- `ConvertedOfferEvent`\n- `TrialInRetryEvent`\n- `OfferInRetryEvent`\n- `SubscriptionInRetryEvent`\n- `RenewedSubscriptionEvent`\n- `FailedSubscriptionFromRetryEvent`\n- `FailedOfferFromRetryEvent`\n- `FailedTrialFromRetryEvent`\n- `FailedSubscriptionEvent`\n- `FailedOfferiseEvent`\n- `FailedTrialEvent`\n- `ReactivatedSubscriptionEvent`\n- `RenewedSubscriptionFromRetryEvent`\n- `ConvertedOfferFromRetryEvent`\n- `ConvertedTrialFromRetryEvent`\n- `UnsubscriptionEvent`\n\n### Predefined event parameters JS\n\nEach event can be extended with custom event parameters. By calling `addPredefinedParameter` function you can pass  [predefined parameters](#predefinedstring)\n\nFor example:\n\n```javascript\nlet event = ...\n\nevent\n    .addPredefinedParameter(PredefinedString.PURCHASE_CURRENCY, 'USD')\n    .addPredefinedParameter(PredefinedFloat.PRICE, 2.19)\n    .addPredefinedParameter(PredefinedLong.QUANTITY, 1)\n    .addPredefinedParameter(PredefinedObject.CONTENT, { card: 4138, type: 'phone' })\n    .addPredefinedParameter(PredefinedListObject.CONTENT_LIST, [{content:'songs'}, {content:'videos'}])\n    .send(); // Send event\n```\n\n### Custom events JS\n\nIf above event functionality still limits your usecase, you can allways extend `Event` class to override fields you are missing\n\n```javascript\nclass MyCustomEvent extends Event {\n    constructor(args) {\n        super('MyCustom', args)\n    }\n}\n```\n\n## SDK to SDK integrations\n\n### AdMob\n\nFor more information how to setup, please check [official docs](https://developers.google.com/admob/ios/impression-level-ad-revenue#implementing_paid_event_handler)\n\n```swift\nvar rewardedAd: GADRewardedAd?\n\nfunc requestRewardedAd() {\n    GADRewardedAd.load(withAdUnitID: \"AD_UNIT_ID\", request: GADRequest()) { (ad, error) in\n        if let error = error {\n            print(\"Rewarded ad failed to load with error: \\(error.localizedDescription)\")\n            return\n        }\n        rewardedAd = ad\n        rewardedAd?.paidEventHandler = { adValue in\n            let responseInfo = ad?.responseInfo\n            let loadedAdNetworkResponseInfo = responseInfo?.loadedAdNetworkResponseInfo\n\n            // Send AdRevenue info\n            AffiseAdRevenue(AffiseAdSource.ADMOB)\n                .setRevenue(adValue.value / 1000000, adValue.currencyCode)\n                .setNetwork(loadedAdNetworkResponseInfo?.adSourceName)\n                .setUnit(ad?.adUnitID)\n                .send()\n        }\n    }\n}\n```\n\n### AppLovin MAX\n\nFor more information how to setup, please check [official docs](https://dash.applovin.com/documentation/mediation/ios/getting-started/advanced-settings#impression-level-user-revenue-api)\n\n```swift\nfunc didPayRevenue(_ ad: MAAd)\n{\n    // Send AdRevenue info\n    AffiseAdRevenue(AffiseAdSource.APPLOVIN_MAX)\n        .setRevenue(ad.revenue, \"USD\")\n        .setNetwork(ad.networkName)\n        .setUnit(ad.adUnitIdentifier)\n        .setPlacement(ad.placement)\n        .send()\n}\n```\n\n### Helium by Chartboost\n\nFor more information how to setup, please check [official docs](https://developers.chartboost.com/docs/mediation-ios-configure-helium#implementation)\n\n```swift\nfunc ilrdObserverInit() {\n    NotificationCenter.default.addObserver(\n        self,\n        selector: #selector(didReceiveILRDNotification),\n        name: .heliumDidReceiveILRD,\n        object: nil\n    )\n}\n\n@objc \nfunc didReceiveILRDNotification(notification: Notification) {\n    // Extract the ILRD payload.\n    guard let ilrd = notification.object as? HeliumImpressionData else {\n        return\n    }\n\n    let json = ilrd.jsonData\n\n    guard let revenue = json[\"ad_revenue\"] else {\n        return\n    }\n\n    guard let currency = json[\"currency_type\"] else {\n        return\n    }\n\n    // Send AdRevenue info\n    AffiseAdRevenue(AffiseAdSource.HELIUM_CHARTBOOST)\n        .setRevenue(revenue, currency)\n        .setNetwork(json[\"network_name\"])\n        .setUnit(json[\"placement_name\"])\n        .setPlacement(json[\"line_item_name\"])\n        .send()\n}\n```\n\n### ironSource\n\nFor more information how to setup, please check [official docs](https://developers.is.com/ironsource-mobile/ios/ad-revenue-measurement-integration/#step-2)\n\n```swift\nfunc impressionDataDidSucceed(impressionData: ISImpressionData) {\n    guard let revenue: NSNumber = impressionData.revenue else {\n        return\n    }\n    let ad_network: String? = impressionData.ad_network\n    let all_data: NSDictionary? = impressionData.all_data\n\n    // Send AdRevenue info\n    AffiseAdRevenue(AffiseAdSource.IRONSOURCE)\n        .setRevenue(revenue.doubleValue, \"USD\")\n        .setNetwork(impressionData.ad_network)\n        .setUnit(impressionData.ad_unit)\n        .setPlacement(impressionData.placement)\n        .send()\n}\n```\n\n## Custom\n\n### ConversionId\n\nAdds 3 PredefinedString values: `PredefinedString.CONVERSION_ID`, `PredefinedString.ORDER_ID`, `PredefinedString.PRODUCT_ID`\n\n\u003e `CONVERSION_ID` = `ORDER_ID`_`PRODUCT_ID`\n\n```swift\nlet event = AddToCartEvent()\n\nlet conversionId = event.customPredefined().conversionId(\"ORDER_ID\", \"PRODUCT_ID\")\n\nAffise.sendEvent(event)\n```\n\n# Debug\n\n## Validate credentials\n\n\u003e **Warning**\n\u003e\n\u003e 🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥\n\u003e \n\u003e Debug methods WON'T work on Production\n\u003e\n\u003e 🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥\n\nValidate your credentials by receiving `ValidationStatus` values:\n\n- `VALID` - your credentials are valid\n- `INVALID_APP_ID` - your app id is not valid \n- `INVALID_SECRET_KEY` - your SDK secretKey is not valid\n- `PACKAGE_NAME_NOT_FOUND` - your application package name not found\n- `NOT_WORKING_ON_PRODUCTION` - you using debug method on production\n- `NETWORK_ERROR` - network or server not available (for example `Airoplane mode` is active)\n\n```swift\nAffise\n    .settings(\n        affiseAppId: \"Your appId\",\n        secretKey: \"Your secretKey\" \n    )\n    .setProduction(false) //To enable debug methods set Production to false\n    .start(app: application, launchOptions: launchOptions) // Start Affise SDK\n\nAffise.Debug.validate { status in\n    // Handle validation status\n}\n```\n\n## Version\n\nGet Affise library version\n\n```swift\nAffise.Debug.version()\n```\n\n# Troubleshoots\n\n\u003e **Warning**\n\u003e \n\u003e 🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥\n\u003e\n\u003e This app has crashed because it attempted to access privacy-sensitive data without a usage description.\n\u003e \n\u003e The app's `Info.plist` must contain an `NSUserTrackingUsageDescription` key with a string value explaining\n\u003e \n\u003e to the user how the app uses this data.\n\u003e \n\u003e 🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥\n\nOpen `info.plist` and add key `NSUserTrackingUsageDescription` with string value. For more information [read requirements](#requirements)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faffise%2Fsdk-ios","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faffise%2Fsdk-ios","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faffise%2Fsdk-ios/lists"}