Code Samples

This page shows best practices of integrating Apphud SDK into your iOS project.

Main

Initialize Apphud SDK

Make sure you entered correct shared secret and added all subscription products in Apphud settings.

In your AppDelegate add just one line of code:

import ApphudSDK
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
Apphud.start(apiKey: "APPHUD_API_KEY")
}
}

Purchase Subscription

In your subscription purchase controller:

import ApphudSDK
class SubscriptionPurchaseController: UIViewController{
deinit {
NotificationCenter.default.removeObserver(self)
}
override func viewDidLoad() {
super.viewDidLoad()
if Apphud.products() != nil {
reloadUI()
} else {
NotificationCenter.default.addObserver(self, selector: #selector(reloadUI), name: Apphud.didFetchProductsNotification(), object: nil)
}
}
@objc func reloadUI(){
if let product = Apphud.product(productIdentifier: "YOUR_PRODUCT_ID") {
// set up pricing for this product
}
}
func purchaseProduct(product : SKProduct) {
Apphud.purchase(product) { (subscription, error) in
if let subscription = subscription {
// subscription is purchased, dismiss your controller
} else {
// user cancelled purchase
}
}
}
}

Purchase Non-Consumable Product or Non-Renewing Subscription

Currently Apphud supports only auto-renewable subscriptions. However, you can still use Apphud SDK to purchase products of any type. The only difference is that Apphud SDK will return nil in callback:

func purchaseProduct(product : SKProduct) {
Apphud.purchase(product) { (subscription, error) in
// subscription is nil. Check error instead
if error == nil {
// purchase is successful
}
}
}

Restore Subscriptions

func restore(){
Apphud.restoreSubscriptions { _ in
if Apphud.hasActiveSubscription() {
// success, dismiss purchase screen and unlock premium content
} else {
// no active subscription, do not unlock premium content
}
}
}

Restore Other Purchases

Currently Apphud supports only auto-renewable subscriptions. If you want to restore non-renewing or non-consumable purchases, you should add more code to restore() function. The easiest way is to validate App Store Receipt manually as described here (See "Receipt validation example code"). After you get JSON you should check in_app array and search all subjson receipts for product_id value of non-consumables and non-renewing subscriptions.

Non-consumable purchase is valid if corresponding receipt presents in in_app array.

Non-renewing subscription is valid if corresponding receipt presents in in_app array and it's not yet expired. However there's no expires date in the receipt – you should calculate it manually by adding subscription length to the receipt purchase date.

Set Up Push Notifications

Make sure Push Notifications are present in Signing & Capabilities tab in your project target.

In your AppDelegate add following:

import ApphudSDK
import UserNotifications
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
#if DEBUG
Apphud.setIntegrationsTestMode()
#endif
Apphud.start(apiKey: APPHUD_API_KEY)
registerForPushNotifications()
}
func registerForPushNotifications(){
UNUserNotificationCenter.current().delegate = self
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) { _,_ in}
UIApplication.shared.registerForRemoteNotifications()
}
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
Apphud.submitPushNotificationsToken(token: deviceToken, callback: {_ in})
}
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
Apphud.handlePushNotification(apsInfo: response.notification.request.content.userInfo)
completionHandler()
}
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
Apphud.handlePushNotification(apsInfo: notification.request.content.userInfo)
completionHandler([])
}
}

Integrations

These examples below show how to add integrations with your analytics platform. You can easily add multiple integrations, they will not conflict.

Amplitude

In your AppDelegate add following:

import Amplitude_iOS
import ApphudSDK
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, ApphudDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
#if DEBUG
Apphud.setIntegrationsTestMode()
#endif
Apphud.start(apiKey: "APPHUD_API_KEY")
Apphud.setDelegate(self)
Amplitude.instance()?.initializeApiKey("AMPLITUDE_KEY", userId: Apphud.userID())
}
func apphudDidChangeUserID(_ userID: String) {
Amplitude.instance()?.setUserId(userID)
}
}

Mixpanel

In your AppDelegate add following:

import Mixpanel
import ApphudSDK
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, ApphudDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
#if DEBUG
Apphud.setIntegrationsTestMode()
let mixpanel_token = "TEST_MIXPANEL_TOKEN"
#else
let mixpanel_token = "LIVE_MIXPANEL_TOKEN"
#endif
Apphud.start(apiKey: "APPHUD_API_KEY")
Apphud.setDelegate(self)
Mixpanel.initialize(token: mixpanel_token)
Mixpanel.mainInstance().identify(distinctId: Apphud.userID())
}
func apphudDidChangeUserID(_ userID: String) {
Mixpanel.mainInstance().identify(distinctId: Apphud.userID())
}
}

AppsFlyer

In your AppDelegate add following:

import AppsFlyerLib
import ApphudSDK
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, AppsFlyerTrackerDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
#if DEBUG
Apphud.setIntegrationsTestMode()
#endif
Apphud.start(apiKey: "APPHUD_API_KEY")
AppsFlyerTracker.shared().appsFlyerDevKey = "APPSFLYER_DEV_KEY"
#if DEBUG
AppsFlyerTracker.shared().appleAppID = "TEST_APP_ID"
#else
AppsFlyerTracker.shared().appleAppID = "LIVE_APP_ID"
#endif
AppsFlyerTracker.shared().delegate = self
}
func applicationDidBecomeActive(_ application: UIApplication) {
AppsFlyerTracker.shared().trackAppLaunch()
}
// in AppsFlyer SDK v5.0 or higher:
func onConversionDataSuccess(_ conversionInfo: [AnyHashable : Any]!) {
Apphud.addAttribution(data: conversionInfo, from: .appsFlyer, identifer: AppsFlyerTracker.shared()?.getAppsFlyerUID()) { _ in }
}
func onConversionDataFail(_ error: Error!) {
}
// in lower versions of AppsFlyer SDK:
func onConversionDataReceived(_ installData: [AnyHashable: Any]) {
Apphud.addAttribution(data: installData, from: .appsFlyer, identifer: AppsFlyerTracker.shared()?.getAppsFlyerUID(), callback: nil)
}
}

Branch

Make sure branch_key is added to your Info.plist with live and test keys.

import Branch
import ApphudSDK
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
#if DEBUG
Apphud.setIntegrationsTestMode()
Branch.setUseTestBranchKey(true)
#endif
Apphud.start(apiKey: "APPHUD_API_KEY")
Branch.getInstance()?.initSession(launchOptions: launchOptions, andRegisterDeepLinkHandler: {_, _ in })
}
}

Objective-C Sample Code

This code shows Apphud SDK initialization with all integrations added. You can safely remove code related to integrations that you don't need.

#import <ApphudSDK-Swift.h>
#import <Branch/Branch.h>
#import <Mixpanel/Mixpanel.h>
#import <AppsFlyerLib/AppsFlyerTracker.h>
#import <Amplitude_iOS/Amplitude.h>
@interface AppDelegate () <UNUserNotificationCenterDelegate, ApphudDelegate, AppsFlyerTrackerDelegate>
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
[Apphud startWithApiKey:@"APPHUD_API_KEY" userID:nil];
[Apphud setDelegate:self];
[Amplitude.instance initializeApiKey:@"AMPLITUDE_API_KEY" userId:Apphud.userID];
[Mixpanel sharedInstanceWithToken:@"MIXPANEL_TOKEN"];
[Mixpanel.sharedInstance identify:Apphud.userID];
[AppsFlyerTracker sharedTracker].appsFlyerDevKey = @"APPSFLYER_DEV_KEY";
[AppsFlyerTracker sharedTracker].appleAppID = @"APP_ID";
[AppsFlyerTracker sharedTracker].delegate = self;
[[Branch getInstance] initSessionWithLaunchOptions:launchOptions];
return YES;
}
- (void)onConversionDataReceived:(NSDictionary *)installData {
[Apphud addAttributionWithData:installData from:ApphudAttributionProviderAppsFlyer identifer:AppsFlyerTracker.sharedTracker.getAppsFlyerUID callback:^(BOOL callback) {}];
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
[AppsFlyerTracker.sharedTracker trackAppLaunch];
}
- (void)apphudDidChangeUserID:(NSString *)userID {
[Amplitude.instance setUserId:userID];
[Mixpanel.sharedInstance identify:Apphud.userID];
}