iOS V2 V1

Integrate SDK into your iOS project. As an example, use ready-made demo apps in Objective-C and Swift.

Basic requirements

Earliest iOS version supported — 8.0 since version SDK 2.0 of December 23, 2019.

Integration

Using CocoaPods

Add myTrackerSDK dependency to your Podfile:

pod 'myTrackerSDK'

Run pod install.

Manually

  • Download latest version myTracker iOS SDK and unzip.

  • Add MyTrackerSDK.framework to project.

  • Add UIKit, AdSupport, SystemConfiguration, CoreTelephony, CoreData, iAd, StoreKit frameworks to your project.

  • Add libz.tbd library to your project.

Initialization

For correct myTracker SDK operation, set up an instance and initialize inside of the application:didFinishLaunchingWithOptions method of anAppDelegate class of the app. To initialize SDK, you have to enter SDK_KEY. And before that, you may set different settings for the tracker (configurations, parameters, deep links, etc.).

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{

    // Setting up the configuration if needed
    MRMyTrackerParams *trackerParams = [MRMyTracker trackerParams];
    // …
    // Setting up params
    // …
    // Initialize the tracker
    [MRMyTracker setupTracker:SDK_KEY];

   return YES;
}

@end
import MyTrackerSDK

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool
{

    // Setting up the configuration if needed
    let trackerConfig = MRMyTracker.trackerConfig()
    // ...
    // Setting up params
    // ...
    // Initialize the tracker
    MRMyTracker.setupTracker(SDK_KEY)

    return true
}        

API

Tracker configuration

Configuration can be set up in MRMyTrackerConfig class instance available through [MRMyTracker trackerConfig] method. Currently available:

trackLaunch: app launch tracking. "YES" by default.

@property(nonatomic) BOOL trackLaunch;
var trackLaunch: Bool

launchTimeout: an interval (in seconds) during which a new launch is not tracked and a session is not interrupted while app is in background. 30 seconds by default. Possible values range: 30-7200 seconds.

@property(nonatomic) NSTimeInterval launchTimeout;
var launchTimeout: NSTimeInterval

bufferingPeriod: the time during which events are accumulated locally on the device before being sent to the myTracker server. The default value is 900 seconds, allowed values are: 1-86400 seconds (1 day).

@property(nonatomic) NSTimeInterval bufferingPeriod;
var bufferingPeriod: NSTimeInterval

forcingPeriod: an interval (in seconds) starting from application install/update during which any new event will be send to the server immediately, without local buffering. Default value is set to 0 (immediate sending is disabled), allowed values are 0-432000 seconds (5 days).

@property(nonatomic) NSTimeInterval forcingPeriod;
var forcingPeriod: NSTimeInterval

autotrackPurchase: if inApp purchase events should be tracked automatically. "YES" by default.

@property(nonatomic) BOOL autotrackPurchase;
var autotrackPurchase: Bool

locationTrackingMode: geolocation tracking. Tracking modes:

  • MRLocationTrackingModeNone — location tracking is not available

  • MRLocationTrackingModeCached — system cached value is used

  • MRLocationTrackingModeActive — current location request is used (by default)

No matter what the mode, myTracker can track user geolocation only if the app already has this permission.

@property(nonatomic) MRLocationTrackingMode locationTrackingMode;
var locationTrackingMode: MRLocationTrackingMode

region, where the data collection server is located. Choose a region based, for example, on current legislation. Available values:

  • MRRegionNotSet — default value

  • MRRegionRu — server on the territory of Russian Federation

  • MRRegionEu — server on the territory of Europe

@property(nonatomic) MRRegion region
var region: MRRegion

registerForSKAdAttribution: SKAdNetwork attribution support. "YES" by default.

SKAdNetwork is Apple's solution to attribute app installations to a particular campaign while maintaining user privacy.

By default, when a user first launches the app on iOS 14.5+ devices, myTracker SDK v2.1.2 and above calls the SKAdNetwork method — registerAppForAdNetworkAttribution, to pass advertisement-driven install notifications to ad networks. For its parts, the ad network can send data to myTracker.

You can choose to turn this parameter off and set up SKAdNetwork methods on your own. Without SKAdNetwork, you will not be able to track attribution on devices if the user denied permission.

For more details, refer to the Apple documentation

@property(nonatomic) BOOL registerForSKAdAttribution;
var registerForSKAdAttribution: Bool

Enable/disable debug mode

Enabling and disabling debug mode can be done via MyTracker class static methods. "false" by default.

+ (void)setDebugMode:(BOOL)enabled;
+ (BOOL)isDebugMode;
static func setDebugMode(_ enabled: Bool)static func isDebugMode() -> Bool

Track users

Set the customUserId parameter to track user stats, not only device. It's a unique user identifier in the project, that you specify at the time of registration. The identifier should remain unchanged even when user switch devices. The parameter allows you to estimate the size and activity of user base, regardless of the number of user devices. Also you can keep your customer data consistent if a user changes a device.

Tracker parameters can be set up in MRMyTrackerParams class instance available through [MRMyTracker trackerParams] method. It's essential to set the parameter before tracking events to pass user identifier with every event.

-(void)setUserInfo
{
    MRMyTrackerParams *trackerParams = [MRMyTracker trackerParams];

    // Set user id
    trackerParams.customUserId = @"user_id";

}
func setUserInfo()
{
    let trackerParams = MRMyTracker.trackerParams()

    // Set user id
    trackerParams.customUserId = "user_id"
}

If customUserId was set to the application with an existing registered users, myTracker can't calculate exact Lifetime metrics without registration time. For pre-registered users, Lifetime statistic will be count on the date of the first tracked event with customUserId.

To turn off user tracking, pass an empty value in the customUserId parameter.

Track events

Events can be sent via MRMyTracker class static methods. Before you call methods, set the customUserId parameter to pass user identifier with every tracked event.

The following methods for event tracking are available:

Registration event. You should call the method right after user registered in the app. Pass the user identifier in the parameter userId.

+ (void)trackRegistrationEvent:(NSString *)userId;
static func trackRegistrationEvent(_ userId: String) 

userId is a required parameter since SDK version 2.0.6

Login event. You should call the method right after user successfully authorized in the app. Pass the user identifier in the parameter userId.

+ (void)trackLoginEvent:(NSString *)userId;
static func trackLoginEvent(_ userId: String)

userId is a required parameter since SDK version 2.0.6

Invite event. Any optional parameters can be passed with event as "key-value" by optional parameter eventParams. Max key or value length — 255 chars.

+ (void)trackInviteEvent;
+ (void)trackInviteEventWithParams:(NSDictionary<NSString *, NSString *>*)eventParams;
static func trackInviteEvent()
static func trackInviteEvent(withParams: [String: String]?)

Level up event. Level parameter is optional. Any optional parameters can be passed with event as "key-value" by optional parameter eventParams. Max key or value length — 255 chars.

+ (void)trackLevelAchieved;
+ (void)trackLevelAchievedWithLevel:(NSNumber *)level;
+ (void)trackLevelAchievedWithLevel:(NSNumber *)level eventParams:(NSDictionary<NSString*, NSString *> *)eventParams;
static func trackLevelAchieved()
static func trackLevelAchieved(withLevel: NSNumber?)
static func trackLevelAchieved(withLevel: NSNumber?, eventParams:[String: String]?)

Any user defined event with a custom name. Any optional parameters can be passed with event as "key-value" by optional parameter eventParams. Max name, key or value length — 255 chars.

+ (void)trackEventWithName:(NSString *)name;
+ (void)trackEventWithName:(NSString *)name eventParams:(NSDictionary<NSString*, NSString *> *)eventParams;
static func trackEvent(withName: NSString)
static func trackEvent(withName: NSString, eventParams: [String: String]?)

Example:

NSDictionary *eventCustomParams = @{
    @"someParamKey1" : @"someParamValue1",
    @"someParamKey2" : @"someParamValue2"
  };
[MRMyTracker trackEventWithName:@"eventName" eventParams:eventCustomParams];
let eventCustomParams = ["someParamKey1": "someParamValue1",
                         "someParamKey2": "someParamValue2"]
MRMyTracker.trackEvent(withName: "eventName", eventParams:eventCustomParams)

Force sending events from local buffer to server and reset buffering timers.

The SDK, which reduces channel load and lowers impact on app performance, collects all data on the device before sending it off to the server and regularly does so in a compressed format. By default, data is sent every 15 minutes. The interval can be changed to anywhere from 1 second to 1 day through the bufferingPeriod property. If the user has quit the app, the events will be sent during next launch. It's extremely important to analyse certain events as soon as possible, especially in the first sessions since installing the app. Theflush() method will help.

+ (void)flush;
static func flush()

Track in-app purchases

All in-app purchases will be tracked automatically, unless you manually change this behavior by setting autotrackPurchase property to "NO" (autotrackPurchase = NO). In this case, to track in-app purchases you could use methods below:

+ (void)trackPurchaseWithProduct:(SKProduct *)product transaction:(SKPaymentTransaction *)transaction;
+ (void)trackPurchaseWithProduct:(SKProduct *)product transaction:(SKPaymentTransaction *)transaction eventParams:(NSDictionary<NSString *, NSString *> *)eventParams;
static func trackPurchase(withProduct: SKProduct, transaction: SKPaymentTransaction)
static func trackPurchase(withProduct: SKProduct, transaction: SKPaymentTransaction, eventParams: [String: String]?)

If automatic in-app purchase tracking is enabled (autotrackPurchase = YES) this methods calls will be ignored. Required parameters:

Any optional parameters can be passed with event as "key-value" by optional parameter eventParams. Max key or value length — 255 chars. Returns false, if it’s not added to queue for sending.

Track in-app advertising

To collect data on AdMob monetization, use individual object type for each advertising event: click, impression, and revenue.

Click event. To track clicks on advertising, create the click object using method [[MRAdEventBuilder newClickBuilder:...] build] for Objective-С and MRAdEventBuilder.newClickBuilder(...).build() for Swift.

- (void)trackAdClickEvent
{
    // create builder for the click event
    MRAdEventBuilder *builder = [MRAdEventBuilder newClickBuilder:Admob];

    // all with* calls are optional and allow to detail the event
    [[[[builder withSource:@"SOURCE"] // set source of the ad creative
                withAdId:@"ADVERTISING_ID"] // set creative identifier
                withPlacementId:@"PLACEMENT_ID"] // set placement identifier
                withAdFormat:MRAdFormat.banner]; // set format:
    // you can use one of the following format:
             // withAdFormat:MRAdFormat.interstitial];
             // withAdFormat:MRAdFormat.native];
             // withAdFormat:MRAdFormat.rewarded];
    // or set your own format:
             // withAdFormat:@"FORMAT"];

    // create an instance of the event and call the trackAdEvent method:
    MRAdEvent *event = [builder build];
    [MRMyTracker trackAdEvent:event];
}
func trackAdClickEvent()
{
    // create builder for the click event
    let builder = MRAdEventBuilder.newClickBuilder(.Admob)

    // all with* calls are optional and allow to detail the event
    builder.withSource("SOURCE") // set source of the ad creative
           .withAdId("ADVERTISING_ID") // set creative identifier
           .withPlacementId("PLACEMENT_ID") // set placement identifier
           .withAdFormat(MRAdFormat.banner) // set format:
    // you can use one of the following format:
         //.withAdFormat(MRAdFormat.interstitial)
         //.withAdFormat(MRAdFormat.native)
         //.withAdFormat(MRAdFormat.rewarded)
    // or set your own format:
         //.withAdFormat("FORMAT")

    // create an instance of the event and call the MyTracker.trackAdEvent() method:
    let event = builder.build()
    MRMyTracker.trackAdEvent(event)
}

Impression event. To track an in-app impression, create the impression object using method [[MRAdEventBuilder newImpressionBuilder:...] build] for Objective-С and MRAdEventBuilder.newImpressionBuilder(...).build() for Swift.

- (void)trackAdImpressionEvent
{
    // create builder for in-app impression
    MRAdEventBuilder *builder = [MRAdEventBuilder newImpressionBuilder:Admob];

    // all with* calls are optional and allow to detail the event
    [[[[builder withSource:@"SOURCE"] // set source of the ad creative
                withAdId:@"ADVERTISING_ID"] // set creative identifier
                withPlacementId:@"PLACEMENT_ID"] // set placement identifier
                withAdFormat:MRAdFormat.banner]; // set format:
     // you can use one of the following format:
             // withAdFormat:MRAdFormat.interstitial];
             // withAdFormat:MRAdFormat.native];
             // withAdFormat:MRAdFormat.rewarded];
    // or set your own format:
             // withAdFormat:@"FORMAT"];

    // create an instance of the event and call the trackAdEvent method:
    MRAdEvent *event = [builder build];
    [MRMyTracker trackAdEvent:event];
}
func trackAdImpressionEvent()
{
    // create builder for in-app impression
    let builder = MRAdEventBuilder.newImpressionBuilder(.Admob)

    // all with* calls are optional and allow to detail the event
    builder.withSource("SOURCE") // set source of the ad creative
           .withAdId("ADVERTISING_ID") // set creative identifier
           .withPlacementId("PLACEMENT_ID") // set placement identifier
           .withAdFormat(MRAdFormat.banner) // set format:
    // you can use one of the following format:
         //.withAdFormat(MRAdFormat.interstitial)
         //.withAdFormat(MRAdFormat.native)
         //.withAdFormat(MRAdFormat.rewarded)
    // or set your own format:
         //.withAdFormat("FORMAT")

    // create an instance of the event and call the MyTracker.trackAdEvent() method:
    let event = builder.build()
    MRMyTracker.trackAdEvent(event)
}

Revenue event. To track your ad revenue, create the revenue object using method [[MRAdEventBuilder newRevenueBuilder:...] build] for Objective-С and MRAdEventBuilder.newRevenueBuilder(...).build() for Swift.

- (void)trackAdRevenueEvent
{
    // create builder for the revenue event
    MRAdEventBuilder *builder = [MRAdEventBuilder newRevenueBuilder:Admob revenue:100.0 currency:@"USD"];

    // all with* calls are optional and allow to detail the event
    [[[[builder withSource:@"SOURCE"] // set source of the ad creative
                withAdId:@"ADVERTISING_ID"] // set creative identifier
                withPlacementId:@"PLACEMENT_ID"] // set placement identifier
                withAdFormat:MRAdFormat.banner]; // set format:
    // you can use one of the following format:
             // withAdFormat:MRAdFormat.interstitial];
             // withAdFormat:MRAdFormat.native];
             // withAdFormat:MRAdFormat.rewarded];
    // or set your own format:
             // withAdFormat:@"FORMAT"];

    // create an instance of the event and call the trackAdEvent method:
    MRAdEvent *event = [builder build];
    [MRMyTracker trackAdEvent:event];
}
func trackAdRevenueEvent()
{
    // create builder for the revenue event
    let builder = MRAdEventBuilder.newRevenueBuilder(.Admob, revenue: 100.0, currency: "USD")

    // all with* calls are optional and allow to detail the event
    builder.withSource("SOURCE") // set source of the ad creative
           .withAdId("ADVERTISING_ID") // set creative identifier
           .withPlacementId("PLACEMENT_ID") // set placement identifier
           .withAdFormat(MRAdFormat.banner) // set format:
     // you can use one of the following format:
         //.withAdFormat(MRAdFormat.interstitial)
         //.withAdFormat(MRAdFormat.native)
         //.withAdFormat(MRAdFormat.rewarded)
    // or set your own format:
         //.withAdFormat("FORMAT")

    // create an instance of the event and call the MyTracker.trackAdEvent() method:
    let event = builder.build()
    MRMyTracker.trackAdEvent(event)
}

S2S tracking

To send data from your server to myTracker (for example, untracked data, offline events, etc.), you may need a special device identifiers — instanceId. The instanceId is a device identifier (UUID v4), that generated at the first app launch and unchanged until a user delete the app (or app data) from device.

The instanceId can get via MRMyTracker class static method (you shouldn't use it in the main thread).

+ (NSString *)instanceId;
static let instanceId: String

It's essential to collect instanceId as soon as possible and send the identifier to your server if you use this ID to work with S2S API.
Making API requests instead of instanceId, you can use customUserID or any device ID: idfa, iosVendorId.

Deep links allow sending additional parameters to the app. So a user can go to a specific app screen. There are two types of deep links: regular when parameters to be sent on a launch of the app and deferred when parameters to be sent on a launch of the app after the install. For more details, see the Deep Links section.

To support regular and deferred deep links in your app you need to install a delegate which executes the protocol MRMyTrackerAttributionDelegate. If a deferred deep link is found for the install, the delegate will be called out at the first launch of the app (just once). Also it will be called out at every launch of the app that was triggered by regular deep link.

As a parameter to the didReceiveAttribution method, the MRMyTrackerAttribution attribution object containing the deep link function would be passed.

@interface AppDelegate () <MRMyTrackerAttributionDelegate>
@end


@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{

    // Setting up the configuration if needed
    MRMyTrackerParams *trackerParams = [MRMyTracker trackerParams];
    // …
    // Setting up params
    // …

    // Install a delegate to receive the deferred deep link
    [MRMyTracker setAttributionDelegate:self];

    // Initialize the tracker
    [MRMyTracker setupTracker:SDK_KEY];

   return YES;
}

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(nullable NSString *)sourceApplication annotation:(id)annotation
{
    return [MRMyTracker handleOpenURL:url sourceApplication:sourceApplication annotation:annotation];
}

- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options
{
    return [MRMyTracker handleOpenURL:url options:options];
}

- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void(^)(NSArray * __nullable restorableObjects))restorationHandler
{
    return [MRMyTracker continueUserActivity:userActivity restorationHandler:restorationHandler];
}

#pragma mark - MRMyTrackerAttributionDelegate

- (void)didReceiveAttribution:(MRMyTrackerAttribution *)attribution
{
    NSString *deeplink = attribution.deeplink;

    // Processing the deep link
    // ...
}

@end
import MyTrackerSDK

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, MRMyTrackerAttributionDelegate
{
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool
    {

        // Setting up the configuration if needed
        let trackerConfig = MRMyTracker.trackerConfig()
        // ...
        // Setting up params
        // ...

        // Install a delegate to receive the deferred deep link
        MRMyTracker.setAttributionDelegate(self)

        // Initialize the tracker
        MRMyTracker.setupTracker(SDK_KEY)

        return true
    }

    func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool
    {
        return MRMyTracker.handleOpen(url, sourceApplication: sourceApplication, annotation: annotation)
    }

    func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool
    {
        return MRMyTracker.handleOpen(url, options: options)
    }

    func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool
    {
        let handler: ([Any]?) -> Void = {_ in }
        return MRMyTracker.continue(userActivity, restorationHandler: handler)
    }

    // MARK: MRMyTrackerAttributionDelegate

    func didReceive(_ attribution: MRMyTrackerAttribution)
    {
        let deeplink = attribution.deeplink

        // Processing the deep link
        // ...
    }
}

You may set up a queue NSOperationQueue for method execution when installing the delegate with the setAttributionDelegate:delegateQueue method. If no queue is set up when installing the delegate then the didReceiveAttribution method would be called out in the main flow.