Caution
π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯
This is archived repository for compatibility
Please use https://github.com/affise/affise-mmp-sdk-ios repository
π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯
| Pod | Version |
|---|---|
AffiseAttributionLib |
1.6.53 |
AffiseSKAdNetwork |
1.6.53 |
AffiseModule/AdService |
1.6.53 |
AffiseModule/Advertising |
1.6.53 |
AffiseModule/AppsFlyer |
1.6.53 |
AffiseModule/Link |
1.6.53 |
AffiseModule/Persistent |
1.6.53 |
AffiseModule/Status |
1.6.53 |
AffiseModule/Subscription |
1.6.53 |
- Affise Attribution iOS Library
- Description
- Features
- ProviderType identifiers collection
- Event send control
- Events tracking
- Custom events tracking
- Predefined event parameters
- Events buffering
- Push token tracking
- Reinstall Uninstall tracking
- Links
- Get random user Id
- Get random device Id
- Get providers
- Is first run
- Get referrer
- Get referrer parameter
- Referrer keys
- Get module state
- WebView tracking
- SDK to SDK integrations
- Custom
- Debug
- Troubleshoots
Affise SDK is a software you can use to collect app usage statistics, device identifiers, deeplink usage, track install referrer.
Xcode14.2+iOS12+
To add the SDK using Cocoapods, specify the version you want to use in your Podfile:
affise_version = '1.6.53'
# Affise SDK library
pod 'AffiseAttributionLib', affise_version
# Affise modules
pod 'AffiseModule/AdService', affise_version
pod 'AffiseModule/Advertising', affise_version
pod 'AffiseModule/Link', affise_version
pod 'AffiseModule/Status', affise_version
pod 'AffiseModule/Subscription', affise_versionGet source directly from GitHub
affise_version = '1.6.53'
# Affise SDK library
pod 'AffiseAttributionLib', :git => 'https://github.com/affise/sdk-ios.git', :tag => affise_version
# Affise modules
pod 'AffiseModule/AdService', :git => 'https://github.com/affise/sdk-ios.git', :tag => affise_version
pod 'AffiseModule/Advertising', :git => 'https://github.com/affise/sdk-ios.git', :tag => affise_version
pod 'AffiseModule/Link', :git => 'https://github.com/affise/sdk-ios.git', :tag => affise_version
pod 'AffiseModule/Status', :git => 'https://github.com/affise/sdk-ios.git', :tag => affise_version
pod 'AffiseModule/Subscription', :git => 'https://github.com/affise/sdk-ios.git', :tag => affise_versionTo add the SDK using SPM:
-
Open XCode project, navigate to
File / Add Packages. -
In the
Add New Packagewindow enterhttps://github.com/affise/sdk-iosinsearchfield. -
Click on the
Add Packagebutton. -
In
Choose Package Productswindow select required packages and clickAdd Package, and it will be added to your iOS project and linked automatically.
After library is added as dependency sync project with gradle files and initialize.
For swift use:
Demo app AppDelegate.swift
import AffiseAttributionLib
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
Affise
.settings(
affiseAppId: "Your appId", //Change to your app id
secretKey: "Your secretKey" //Change to your appToken
)
.start(app: application, launchOptions: launchOptions) // Start Affise SDK
return true
}
}For objective-c use:
Demo app AppDelegate.m
#import "AppDelegate.h"
#import <AffiseAttributionLib/AffiseAttributionLib-Swift.h>
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
AffiseSettings *affise = [Affise settingsWithAffiseAppId:@"Your appId" //Change to your app id
secretKey:@"Your secretKey" //Change to your appToken
];
[affise setProduction:false]; //To enable debug methods set Production to false
[affise startWithApp:application launchOptions:launchOptions]; // Start Affise SDK
return YES;
}
@endCheck if library is initialized
Affise
.settings(
affiseAppId: "Your appId",
secretKey: "Your secretKey"
)
.setOnInitSuccess {
// Called then library is initialized
}
.start(app: application, launchOptions: launchOptions)Set SDK server doamin:
Affise
.settings(
affiseAppId: "Your appId",
secretKey: "Your secretKey"
)
.setDomain("https://YourCustomDomain") // Set custom domain
.start(app: application, launchOptions: launchOptions)Warning
π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯
How to install modules read in Integration section
π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯
| Module | Version | Start |
|---|---|---|
AdService |
1.6.53 |
Auto |
Advertising |
1.6.53 |
Manual |
AppsFlyer |
1.6.53 |
Auto |
Link |
1.6.53 |
Auto |
Persistent |
1.6.53 |
Auto |
Status |
1.6.53 |
Auto |
Subscription |
1.6.53 |
Auto |
If module start type is manual, then call:
Affise.Module.moduleStart(.Advertising)Get list of installed modules:
Affise.Module.getModulesInstalled()iOS 14.3+
Sends attributionToken from AdServices AAAttribution.attributionToken() to Affise server
Warning
π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯
π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯
Affise.Module.moduleStart(.Advertising)This module required to Use IDFA (Identifier for advertisers)
Warning
π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯
Module Advertising requires
NSUserTrackingUsageDescriptionkey ininfo.plistApplication will crash if key not present
π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯
Open info.plist and add key NSUserTrackingUsageDescription with string value. For more information read requirements
Send AppsFlyer event data to Affise
//AppsFlyer event data
let eventValues: [String: Any] = [
AFEventParamPrice: 1234.56,
AFEventParamContentId : "1234567",
]
// Send AppsFlyer event
AppsFlyerLib.shared().logEvent(
name: AFEventAddToWishlist,
values: eventValues
)
// Send AppsFlyer data to Affise
Affise.Module.AppsFlyer.logEvent(AFEventAddToWishlist, withValues: eventValues)Is Module present:
Affise.Module.AppsFlyer.hasModule()Return last url in chan of redirection
π₯Support MAX 10 redirectionsπ₯
Affise.Module.Link.resolve("SITE_WITH_REDIRECTION") { redirectUrl in
// handle redirect url
}Is Module present:
Affise.Module.Link.hasModule()Affise.Module.getStatus(AffiseModules.STATUS) { response in
// handle status response
};Get products by ids:
let ids = ["exampple.product.id_1", "exampple.product.id_2"]
Affise.Module.Subscription.fetchProducts(ids) { result in
switch result {
case .failure(let error):
print("\(error)")
case .success(let result):
let products: [AffiseProduct] = result.products
let invalidIds: [String] = result.invalidIds
}
}Purchase product:
// Specify product type for correct affise event
Affise.Module.Subscription.purchase(product, .CONSUMABLE) { result in
switch result {
case .failure(let error):
print("\(error)")
case .success(let purchasedInfo):
let info: AffisePurchasedInfo = purchasedInfo
}
}Is Module present:
Affise.Module.Subscription.hasModule()Affise Advertising module uses AppTrackingTransparency framework to get advertisingIdentifier
For working functionality your app needs to declare NSUserTrackingUsageDescription permission:
Open XCode project info.plist and add key NSUserTrackingUsageDescription with string value
<plist version="1.0">
<dict>
...
<key>NSUserTrackingUsageDescription</key>
<string>Youre permission text</string>
</dict>To add the SDK using Cocoapods, specify the version you want to use in your Podfile:
# Wrapper for StoreKit Ad Network
pod 'AffiseSKAdNetwork', '1.6.53'Get source directly from GitHub
# Wrapper for StoreKit Ad Network
pod 'AffiseSKAdNetwork', :git => 'https://github.com/affise/sdk-ios.git', :tag => '1.6.53'For swift use:
Demo app AppDelegate.swift
Note
π¦π¦π¦π¦π¦π¦π¦π¦π¦π¦π¦π¦π¦π¦π¦
For ios prior
16.1first callπ¦π¦π¦π¦π¦π¦π¦π¦π¦π¦π¦π¦π¦π¦π¦
import AffiseSKAdNetwork
AffiseSKAd.register { error in
// Handle error
}For objective-c use:
Demo app AppDelegate.m
#import <AffiseSKAdNetwork/AffiseSKAdNetwork-Swift.h>
[AffiseSKAd registerWithCompletionHandler:^(NSString * error) {
// Handle error
}];Updates the fine and coarse conversion values, and calls a completion handler if the update fails.
Note
π¦π¦π¦π¦π¦π¦π¦π¦π¦π¦π¦π¦π¦π¦π¦
Second argument
coarseValueis available in iOS16.1+π¦π¦π¦π¦π¦π¦π¦π¦π¦π¦π¦π¦π¦π¦π¦
AffiseSKAd.updatePostbackConversionValue(fineValue: 1, coarseValue: CoarseConversionValue.medium) { error in
// Handle error
}For objective-c use:
#import <AffiseSKAdNetwork/AffiseSKAdNetwork-Swift.h>
[AffiseSKAd updatePostbackWithFineValue:1
coarseValue:[CoarseConversionValue medium]
completionHandler:^(NSString * error) {
// Handle error
}];Configure your app to send postback copies to Affise:
Add key NSAdvertisingAttributionReportEndpoint to Info.plist
Set key value to https://affise-skadnetwork.com/
Example: example/ios/Runner/Info.plist
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>NSAdvertisingAttributionReportEndpoint</key>
<string>https://affise-skadnetwork.com/</string>
</dict>
</array>To match users with events and data library is sending, these ProviderType identifiers are collected:
AFFISE_APP_IDAFFISE_PKG_APP_NAMEAFF_APP_NAME_DASHBOARDAPP_VERSIONAPP_VERSION_RAWSTORETRACKER_TOKENTRACKER_NAMEFIRST_TRACKER_TOKENFIRST_TRACKER_NAMELAST_TRACKER_TOKENLAST_TRACKER_NAMEOUTDATED_TRACKER_TOKENINSTALLED_TIMEFIRST_OPEN_TIMEINSTALLED_HOURFIRST_OPEN_HOURINSTALL_FIRST_EVENTINSTALL_BEGIN_TIMEINSTALL_FINISH_TIMEREFERRAL_TIMECREATED_TIMECREATED_TIME_MILLICREATED_TIME_HOURUNINSTALL_TIMEREINSTALL_TIMELAST_SESSION_TIMECONNECTION_TYPECPU_TYPEHARDWARE_NAMENETWORK_TYPEDEVICE_MANUFACTURERPROXY_IP_ADDRESSDEEPLINK_CLICKDEVICE_ATLAS_IDAFFISE_DEVICE_IDAFFISE_ALT_DEVICE_IDANDROID_IDANDROID_ID_MD5MAC_SHA1MAC_MD5GAID_ADIDGAID_ADID_MD5OAIDOAID_MD5ALTSTR_ADIDFIREOS_ADIDCOLOROS_ADIDREFTOKENREFTOKENSREFERRERUSER_AGENTMCCODEMNCODEISPREGIONCOUNTRYLANGUAGEDEVICE_NAMEDEVICE_TYPEOS_NAMEPLATFORMSDK_PLATFORMAPI_LEVEL_OSAFFISE_SDK_VERSIONOS_VERSIONRANDOM_USER_IDAFFISE_SDK_POSTIMEZONE_DEVAFFISE_EVENT_TOKENLAST_TIME_SESSIONTIME_SESSIONAFFISE_SESSION_COUNTLIFETIME_SESSION_COUNTAFFISE_DEEPLINKAFFISE_PART_PARAM_NAMEAFFISE_PART_PARAM_NAME_TOKENAFFISE_EVENT_NAMEAFFISE_APP_TOKENLABELAFFISE_SDK_SECRET_IDUUIDAFFISE_APP_OPENEDPUSHTOKENPUSHTOKEN_SERVICEIS_EMULATOR
AD_SERVICE_ATTRIBUTION
ADID
There are two ways to send events
- Cache event to later scheduled send in batch
AddToCartEvent()
.send()- Send event right now
AddToCartEvent()
.sendNow({
// handle event send success
}) { errorResponse in
// handle event send failed
// π₯Warningπ₯: event is NOT cached for later send
}For example, we want to track what items usually user adds to shopping cart. To send event first create it with following code
class Presenter {
func onUserAddsItemsToCart(items: String) {
let items = [
("items", "cookies, potato, milk")
]
AddToCartEvent("groceries")
.addPredefinedParameter(PredefinedString.DESCRIPTION, string: "best before 2029")
.addPredefinedParameter(PredefinedObject.CONTENT, object: items)
.send() // Send event
}
}For objective-c use:
- (void)onUserAddsItemsToCart:(NSString *)itemsToCart {
NSArray *items = @[
@{"items", itemsToCart}
];
Event *event = [[AddToCartEvent alloc] init:@"groceries"];
[event addPredefinedParameter:PredefinedStringADREV_AD_TYPE value:@"best before 2029"];
[event addPredefinedParameter:PredefinedObjectCONTENT object:items];
// Send event
[event send];
}With above example you can implement other events:
AchieveLevelAddPaymentInfoAddToCartAddToWishlistAdRevenueClickAdvCompleteRegistrationCompleteStreamCompleteTrialCompleteTutorialContactContentItemsViewCustomizeProductDeepLinkedDonateFindLocationInitiateCheckoutInitiatePurchaseInitiateStreamInviteLastAttributedTouchLeadListViewLoginOpenedFromPushNotificationOrderOrderItemAddedOrderItemRemoveOrderCancelOrderReturnRequestOrderReturnRequestCancelPurchaseRateReEngageReserveSalesScheduleSearchShareSpendCreditsStartRegistrationStartTrialStartTutorialSubmitApplicationSubscribeTravelBookingUnlockAchievementUnsubscribeUpdateViewAdvViewCartViewContentViewItemViewItemsInitialSubscriptionInitialTrialInitialOfferConvertedTrialConvertedOfferTrialInRetryOfferInRetrySubscriptionInRetryRenewedSubscriptionFailedSubscriptionFromRetryFailedOfferFromRetryFailedTrialFromRetryFailedSubscriptionFailedOfferiseFailedTrialReactivatedSubscriptionRenewedSubscriptionFromRetryConvertedOfferFromRetryConvertedTrialFromRetryUnsubscription
Use any of custom events if default doesn't fit your scenario:
CustomId01CustomId02CustomId03CustomId04CustomId05CustomId06CustomId07CustomId08CustomId09CustomId10
If above event functionality still limits your usecase, you can use UserCustomEvent
UserCustomEvent(eventName: "MyCustomEvent")
.send() To enrich your event with another dimension, you can use predefined parameters for most common cases. Add it to any event:
class Presenter {
func onUserAddsItemsToCart(items: String) {
let items = [
("items", "cookies, potato, milk")
]
AddToCartEvent("groceries")
.addPredefinedParameter(PredefinedString.DESCRIPTION, string: "best before 2029")
.addPredefinedParameter(PredefinedObject.CONTENT, object: items)
.send() // Send event
}
}For objective-c use:
- (void)onUserAddsItemsToCart:(NSString *)itemsToCart {
NSArray *items = @[
@{"items", itemsToCart}
];
Event *event = [[AddToCartEvent alloc] init:@"groceries"];
[event addPredefinedParameter:PredefinedStringADREV_AD_TYPE value:@"best before 2029"];
[event addPredefinedParameter:PredefinedObjectCONTENT object:items];
// Send event
[event send];
}In examples above PredefinedParameters.DESCRIPTION and PredefinedObject.CONTENT is used, but many others is available:
| PredefinedParameter | Type |
|---|---|
| PredefinedString | String |
| PredefinedLong | Int64 |
| PredefinedFloat | Float |
| PredefinedObject | [(String, Any)] |
| PredefinedListObject | [[(String, Any)]] |
| PredefinedListString | [String] |
ACHIEVEMENT_IDADREV_AD_TYPEBRANDBRICKCATALOGUE_IDCHANNEL_TYPECITYCLASSCONTENT_IDCONTENT_NAMECONTENT_TYPECONVERSION_IDCOUNTRYCOUPON_CODECURRENCYCUSTOMER_SEGMENTCUSTOMER_TYPECUSTOMER_USER_IDDEEP_LINKDESCRIPTIONDESTINATION_ADESTINATION_BDESTINATION_LISTNEW_VERSIONOLD_VERSIONORDER_IDPARAM_01PARAM_02PARAM_03PARAM_04PARAM_05PARAM_06PARAM_07PARAM_08PARAM_09PARAM_10PAYMENT_INFO_AVAILABLEPREFERRED_NEIGHBORHOODSPRODUCT_IDPRODUCT_NAMEPURCHASE_CURRENCYRECEIPT_IDREGIONREGISTRATION_METHODREVIEW_TEXTSEARCH_STRINGSEGMENTSTATUSSUBSCRIPTION_IDSUCCESSSUGGESTED_DESTINATIONSSUGGESTED_HOTELSTUTORIAL_IDUTM_CAMPAIGNUTM_MEDIUMUTM_SOURCEVALIDATEDVERTICALVIRTUAL_CURRENCY_NAMEVOUCHER_CODE
AMOUNTDATE_ADATE_BDEPARTING_ARRIVAL_DATEDEPARTING_DEPARTURE_DATEHOTEL_SCORELEVELMAX_RATING_VALUENUM_ADULTSNUM_CHILDRENNUM_INFANTSPREFERRED_NUM_STOPSPREFERRED_STAR_RATINGSQUANTITYRATING_VALUERETURNING_ARRIVAL_DATERETURNING_DEPARTURE_DATESCORETRAVEL_STARTTRAVEL_ENDUSER_SCOREEVENT_STARTEVENT_END
PREFERRED_PRICE_RANGEPRICEREVENUELATLONG
CONTENT
CONTENT_LIST
CONTENT_IDS
Affise library will send any pending events with first opportunity, but if there is no network connection or device is disabled, events are kept locally for 7 days before deletion.
To let affise track push token you need to receive it from your push service provider, and pass to Affise library.
Using Apple Push Notification service Docs
First step enable push notifications capability
Then register your app and retrieve your app's device token
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions:[UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// ...
UIApplication.shared.registerForRemoteNotifications()
return true
}
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
let pushToken = deviceToken.map { String(format: "%02.2hhx", $0) }.joined()
Affise.addPushToken(pushToken, .APPLE)
}Using Firebase Docs
First add firebase integration to your app
After you have done with firebase inegration, add to your cloud messaging service onNewToken method Affise.addPushToken(token, service)
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
print("Firebase registration token: \(String(describing: fcmToken))")
// New token generated
Affise.addPushToken(fcmToken, .FIREBASE)
}Affise 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
Affise.addPushToken(token)Warning
π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯
Deeplinks support only CUSTOM scheme NOT
httporhttpsFor
httporhttpsread how to setup AppLinksπ₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯
To integrate deeplink support you need:
-
Follow how to set up deeplinks in the official documentation.
-
Register deeplink callback right after
Affise.settings(..).start(..)
Affise.settings(affiseAppId:affiseAppId, secretKey:secretKey).start(app:app, launchOptions: launchOptions)
Affise.registerDeeplinkCallback { url in
// full uri "scheme://host/path?parameters"
let deeplink = value.deeplink
// separated for convenience
let scheme = value.scheme
let host = value.host
let path = value.path
let queryParametersMap = value.parameters
if queryParametersMap["<your_uri_key>"].contains("<your_uri_key_value>") == true {
// handle value
}
}- Add deeplink handler to
AppDelegate.swift
func application(
_ app: UIApplication,
open url: URL,
options: [UIApplication.OpenURLOptionsKey : Any] = [:]
) -> Bool {
Affise.handleDeeplink(url)
return true
}Add key CFBundleURLTypes to Info.plist
Example: example/app/app/Info.plist
Example: YOUR_SCHEME://YOUR_DOMAIN (myapp://mydomain.com)
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLName</key>
<string>YOUR_DOMAIN</string>
<key>CFBundleURLSchemes</key>
<array>
<string>YOUR_SCHEME</string>
</array>
</dict>
</array>Test DeepLink via terminal command:
xcrun simctl openurl booted "YOUR_SCHEME://YOUR_DOMAIN/somepath?param=1&list=some&list=other&list=1"
Warning
π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯
You must owne website domain.
And has ability to add file
https://yoursite/.well-known/apple-app-site-associationπ₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯
To integrate applink support you need:
-
Follow how to set up applink in the official documentation.
-
Associate your app with your website. Supporting associated domains
-
Register deeplink callback right after
Affise.settings(..).start(..)
Affise.settings(affiseAppId:affiseAppId, secretKey:secretKey).start(app:app, launchOptions: launchOptions)
Affise.registerDeeplinkCallback { url in
// full uri "scheme://host/path?parameters"
let deeplink = value.deeplink
// separated for convenience
let scheme = value.scheme
let host = value.host
let path = value.path
let queryParametersMap = value.parameters
if queryParametersMap["<your_uri_key>"].contains("<your_uri_key_value>") == true {
// handle value
}
}- Add deeplink handler to
AppDelegate.swift
func application(
_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void
) -> Bool {
Affise.handleUserActivity(userActivity)
return true
}Add key com.apple.developer.associated-domains to Info.plist
Example: https://YOUR_DOMAIN (https://mydomain.com)
<key>com.apple.developer.associated-domains</key>
<array>
<string>applinks:YOUR_DOMAIN</string>
</array>Test DeepLink via terminal command:
xcrun simctl openurl booted "https://YOUR_DOMAIN/somepath?param=1&list=some&list=other&list=1"
Note
Requires Affise Status Module
Use the next public method of SDK to deferred deeplink from server
Affise.getDeferredDeeplink { deferredDeeplink in
// handle deferred deeplink
}Note
Requires Affise Status Module
Use the next public method of SDK to deferred deeplink value from server
Affise.getDeferredDeeplinkValue(ReferrerKey.CLICK_ID) { deferredDeeplinkValue in
// handle deferred deeplink value
}Affise.getRandomUserId()Note
Use Affise Persistent Module to make
device idmore persistent on application reinstall
Affise.getRandomDeviceId()Returns providers map with ProviderType as key
let providers: [ProviderType: Any?] = Affise.getProviders()
let key = ProviderType.AFFISE_APP_TOKEN
let value = providers[key]Affise.isFirstRun()- Add referrer handler to
AppDelegate.swift
func application(
_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void
) -> Bool {
Affise.handleUserActivity(userActivity)
return true
}Use the next public method of SDK
Affise.getReferrerUrl { referrer in
// handle referrer
}- Add referrer handler to
AppDelegate.swift
func application(
_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void
) -> Bool {
Affise.handleUserActivity(userActivity)
return true
}Use the next public method of SDK to get referrer parameter by
Affise.getReferrerUrlValue(ReferrerKey.CLICK_ID) { value in
// handle referrer value
}In examples above ReferrerKey.CLICK_ID is used, but many others is available:
AD_IDCAMPAIGN_IDCLICK_IDAFFISE_ADAFFISE_AD_IDAFFISE_AD_TYPEAFFISE_ADSETAFFISE_ADSET_IDAFFISE_AFFC_IDAFFISE_CHANNELAFFISE_CLICK_LOOK_BACKAFFISE_COST_CURRENCYAFFISE_COST_MODELAFFISE_COST_VALUEAFFISE_DEEPLINKAFFISE_KEYWORDSAFFISE_MEDIA_TYPEAFFISE_MODELAFFISE_OSAFFISE_PARTNERAFFISE_REFAFFISE_SITE_IDAFFISE_SUB_SITE_IDAFFISE_SUB_1AFFISE_SUB_2AFFISE_SUB_3AFFISE_SUB_4AFFISE_SUB_5AFFCPIDSUB_1SUB_2SUB_3SUB_4SUB_5
Get state of the module:
Affise.Module.getStatus(AffiseModules.STATUS) { response in
// handle status response
};To 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. Here are step by step instructions:
// retreive WebView from view hierarhy
@IBOutlet weak var webView: WKWebView!
// make sure javascript is enabled
override func viewDidLoad() {
super.viewDidLoad()
webView.configuration.preferences.javaScriptEnabled = true
}
// initialize WebView with Affise native library
Affise.registerWebView(webView)Other Javascript enviroment features is described below.
Demo app example/app/app/index.html
After WebView is initialized you send events from JavaScript enviroment
let data = { card: 4138, type: 'phone' };
new AddPaymentInfoEvent({
userData: 'taxi',
})
.addPredefinedParameter(PredefinedString.PURCHASE_CURRENCY, 'USD')
.addPredefinedParameter(PredefinedFloat.PRICE, 2.19)
.addPredefinedParameter(PredefinedObject.CONTENT, data);
.send() // Send eventJust like with native SDK, javascript enviroment also provides default events that can be passed from WebView:
AchieveLevelEventAddPaymentInfoEventAddToCartEventAddToWishlistEventAdRevenueEventClickAdvEventCompleteRegistrationEventCompleteStreamEventCompleteTrialEventCompleteTutorialEventContactEventContentItemsViewEventCustomId01EventCustomId02EventCustomId03EventCustomId04EventCustomId05EventCustomId06EventCustomId07EventCustomId08EventCustomId09EventCustomId10EventCustomizeProductEventDeepLinkedEventDonateEventFindLocationEventInitiateCheckoutEventInitiatePurchaseEventInitiateStreamEventInviteEventLastAttributedTouchEventLeadEventListViewEventLoginEventOpenedFromPushNotificationEventOrderEventOrderItemAddedEventOrderItemRemoveEventOrderCancelEventOrderReturnRequestEventOrderReturnRequestCancelEventPurchaseEventRateEventReEngageEventReserveEventSalesEventScheduleEventSearchEventShareEventSpendCreditsEventStartRegistrationEventStartTrialEventStartTutorialEventSubmitApplicationEventSubscribeEventTravelBookingEventUnlockAchievementEventUnsubscribeEventUpdateEventViewAdvEventViewCartEventViewContentEventViewItemEventViewItemsEventInitialSubscriptionEventInitialTrialEventInitialOfferEventConvertedTrialEventConvertedOfferEventTrialInRetryEventOfferInRetryEventSubscriptionInRetryEventRenewedSubscriptionEventFailedSubscriptionFromRetryEventFailedOfferFromRetryEventFailedTrialFromRetryEventFailedSubscriptionEventFailedOfferiseEventFailedTrialEventReactivatedSubscriptionEventRenewedSubscriptionFromRetryEventConvertedOfferFromRetryEventConvertedTrialFromRetryEventUnsubscriptionEvent
Each event can be extended with custom event parameters. By calling addPredefinedParameter function you can pass predefined parameters
For example:
let event = ...
event
.addPredefinedParameter(PredefinedString.PURCHASE_CURRENCY, 'USD')
.addPredefinedParameter(PredefinedFloat.PRICE, 2.19)
.addPredefinedParameter(PredefinedLong.QUANTITY, 1)
.addPredefinedParameter(PredefinedObject.CONTENT, { card: 4138, type: 'phone' })
.addPredefinedParameter(PredefinedListObject.CONTENT_LIST, [{content:'songs'}, {content:'videos'}])
.send(); // Send eventIf above event functionality still limits your usecase, you can allways extend Event class to override fields you are missing
class MyCustomEvent extends Event {
constructor(args) {
super('MyCustom', args)
}
}For more information how to setup, please check official docs
var rewardedAd: GADRewardedAd?
func requestRewardedAd() {
GADRewardedAd.load(withAdUnitID: "AD_UNIT_ID", request: GADRequest()) { (ad, error) in
if let error = error {
print("Rewarded ad failed to load with error: \(error.localizedDescription)")
return
}
rewardedAd = ad
rewardedAd?.paidEventHandler = { adValue in
let responseInfo = ad?.responseInfo
let loadedAdNetworkResponseInfo = responseInfo?.loadedAdNetworkResponseInfo
// Send AdRevenue info
AffiseAdRevenue(AffiseAdSource.ADMOB)
.setRevenue(adValue.value / 1000000, adValue.currencyCode)
.setNetwork(loadedAdNetworkResponseInfo?.adSourceName)
.setUnit(ad?.adUnitID)
.send()
}
}
}For more information how to setup, please check official docs
func didPayRevenue(_ ad: MAAd)
{
// Send AdRevenue info
AffiseAdRevenue(AffiseAdSource.APPLOVIN_MAX)
.setRevenue(ad.revenue, "USD")
.setNetwork(ad.networkName)
.setUnit(ad.adUnitIdentifier)
.setPlacement(ad.placement)
.send()
}For more information how to setup, please check official docs
func ilrdObserverInit() {
NotificationCenter.default.addObserver(
self,
selector: #selector(didReceiveILRDNotification),
name: .heliumDidReceiveILRD,
object: nil
)
}
@objc
func didReceiveILRDNotification(notification: Notification) {
// Extract the ILRD payload.
guard let ilrd = notification.object as? HeliumImpressionData else {
return
}
let json = ilrd.jsonData
guard let revenue = json["ad_revenue"] else {
return
}
guard let currency = json["currency_type"] else {
return
}
// Send AdRevenue info
AffiseAdRevenue(AffiseAdSource.HELIUM_CHARTBOOST)
.setRevenue(revenue, currency)
.setNetwork(json["network_name"])
.setUnit(json["placement_name"])
.setPlacement(json["line_item_name"])
.send()
}For more information how to setup, please check official docs
func impressionDataDidSucceed(impressionData: ISImpressionData) {
guard let revenue: NSNumber = impressionData.revenue else {
return
}
let ad_network: String? = impressionData.ad_network
let all_data: NSDictionary? = impressionData.all_data
// Send AdRevenue info
AffiseAdRevenue(AffiseAdSource.IRONSOURCE)
.setRevenue(revenue.doubleValue, "USD")
.setNetwork(impressionData.ad_network)
.setUnit(impressionData.ad_unit)
.setPlacement(impressionData.placement)
.send()
}Adds 3 PredefinedString values: PredefinedString.CONVERSION_ID, PredefinedString.ORDER_ID, PredefinedString.PRODUCT_ID
CONVERSION_ID=ORDER_ID_PRODUCT_ID
let event = AddToCartEvent()
let conversionId = event.customPredefined().conversionId("ORDER_ID", "PRODUCT_ID")
Affise.sendEvent(event)Warning
π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯
Debug methods WON'T work on Production
π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯
Validate your credentials by receiving ValidationStatus values:
VALID- your credentials are validINVALID_APP_ID- your app id is not validINVALID_SECRET_KEY- your SDK secretKey is not validPACKAGE_NAME_NOT_FOUND- your application package name not foundNOT_WORKING_ON_PRODUCTION- you using debug method on productionNETWORK_ERROR- network or server not available (for exampleAiroplane modeis active)
Affise
.settings(
affiseAppId: "Your appId",
secretKey: "Your secretKey"
)
.setProduction(false) //To enable debug methods set Production to false
.start(app: application, launchOptions: launchOptions) // Start Affise SDK
Affise.Debug.validate { status in
// Handle validation status
}Get Affise library version
Affise.Debug.version()Warning
π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯
This app has crashed because it attempted to access privacy-sensitive data without a usage description.
The app's
Info.plistmust contain anNSUserTrackingUsageDescriptionkey with a string value explainingto the user how the app uses this data.
π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯
Open info.plist and add key NSUserTrackingUsageDescription with string value. For more information read requirements