Skip to content

iOS SDK Integration

FirstHive SDK is a comprehensive analytics and engagement platform that provides:

  • Event tracking and analytics
  • Push notification management
  • User behavior analytics
  • E-commerce tracking
  • Custom dimension support

Installation

Using CocoaPods

Add the following to your Podfile:

target ‘YourAppName’ do pod ‘FHSDK’ end

Then run:

pod install

Import Required Frameworks

Import the required frameworks in your Swift files:

import Foundation import UIKit import FHSDK import UserNotifications // Import Firebase if using FCM import Firebase import FirebaseMessaging

Configuration

FHConfiguration

The SDK requires configuration with the following parameters:

public struct FHConfiguration { let siteId: String let baseURL: String let subscriptionAPIURL: String let fcmToken: String let visitDimensionIndexes: FHVisitDimensionIndexes }

Configuration Parameters

  • siteId: Your FirstHive project/site identifier
  • baseURL: Your FirstHive analytics base URL
  • subscriptionAPIURL: API endpoint for push notification subscriptions (optional)
  • fcmToken: Firebase Cloud Messaging token
  • visitDimensionIndexes: Custom dimension mapping configuration (uses defaults)

Initialization

Basic Initialization

Initialize the SDK in your AppDelegate or SceneDelegate:

import UIKit

class AppDelegate: UIResponder, UIApplicationDelegate {

func application(\_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: \[UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Configure FirstHive SDK
let config = FHConfiguration(
siteId: "YOUR\_SITE\_ID",
baseURL: "\<https\://your-analytics-domain.com>",
subscriptionAPIURL: "\<https\://v25.firsthive.com/engage/mobile/doAppUserSubscription>",
fcmToken: "INITIAL\_FCM\_TOKEN", // Will be updated later
visitDimensionIndexes: .defaults
)
do {
try FHSDK.shared.initialize(config: config)
// Setup automatic app lifecycle tracking
FHSDK.shared.setupAutomaticTracking()
print("FirstHive SDK initialized successfully")
} catch {
print("SDK initialization failed: \\\\(error)")
}
return true
}

}

User Management

User Model

The FHUser struct represents user information:

public struct FHUser { let email: String? let mobileNo: String let userId: String?

public init(email: String? = nil, mobileNo: String, userId: String? = nil) {
self.email = email
self.mobileNo = mobileNo
self.userId = userId
}

}

Setting User Information

Set user information after login:

// Example: After successful login let user = FHUser( email: “user@example.com”, mobileNo: “+1234567890”, userId: “user123” )

FHSDK.shared.setUser(user)

User Logout

Clear user information on logout:

// Create empty user to clear session let emptyUser = FHUser(mobileNo: "") FHSDK.shared.setUser(emptyUser)

Push Notification Setup

Step-by-Step Push Notification Implementation

Step 1: Setup Firebase Cloud Messaging

First, configure Firebase in your project and obtain FCM tokens. Add this to your AppDelegate:

import Firebase import FirebaseMessaging

class AppDelegate: UIResponder, UIApplicationDelegate, MessagingDelegate {

func application(\_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: \[UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Initialize Firebase
FirebaseApp.configure()
// Set FCM delegate
Messaging.messaging().delegate = self
// Request notification permissions
requestNotificationPermissions()
// Initialize FirstHive SDK (as shown above)
// ...
return true
}
private func requestNotificationPermissions() {
let authOptions: UNAuthorizationOptions = \[.alert, .badge, .sound]
UNUserNotificationCenter.current().requestAuthorization(
options: authOptions,
completionHandler: { granted, error in
print("Notification permission granted: \\\\(granted)")
if granted {
DispatchQueue.main.async {
UIApplication.shared.registerForRemoteNotifications()
}
}
}
)
}
// MARK: - MessagingDelegate
func messaging(\_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
print("FCM Token received: \\\\(String(describing: fcmToken))")
guard let token = fcmToken else { return }
// Step 2: Update FCM token in FirstHive SDK
FHSDK.shared.updateFCMToken(token)
// Step 3: If user is already logged in, subscribe immediately
if let currentUser = FHSDK.shared.getCurrentUser(), currentUser.isValid {
subscribeToFirstHivePush(for: currentUser)
}
}
private func subscribeToFirstHivePush(for user: FHUser) {
Task {
do {
try await FHSDK.shared.subscribeToPushNotifications(mobileNumber: user.mobileNo)
print("Successfully subscribed to FirstHive push notifications")
} catch {
print("Push subscription failed: \\\\(error)")
}
}
}

}

Step 2: Update FCM Token

Update the FCM token whenever it changes:

// In your MessagingDelegate implementation func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) { guard let token = fcmToken else { return }

// Update token in FirstHive SDK
FHSDK.shared.updateFCMToken(token)
// If user is logged in, resubscribe with new token
if let user = FHSDK.shared.getCurrentUser(), user.isValid {
Task {
try await FHSDK.shared.subscribeToPushNotifications(mobileNumber: user.mobileNo)
}
}

}

Step 3: Subscribe After Login

When user logs in and all variables are aligned, call the subscribe method:

class LoginViewController: UIViewController {

func handleSuccessfulLogin(email: String, mobileNumber: String, userId: String) {
// Step 1: Create user object
let user = FHUser(
email: email,
mobileNo: mobileNumber,
userId: userId
)
// Step 2: Set user in SDK (this sets visit dimensions and starts new session)
FHSDK.shared.setUser(user)
// Step 3: Subscribe to push notifications
Task {
do {
try await FHSDK.shared.subscribeToPushNotifications(mobileNumber: mobileNumber)
print("Push notification subscription successful")
// Track successful login
FHSDK.shared.track(event: .login(
phoneNumber: mobileNumber,
email: email,
userId: userId
))
} catch {
print("Push subscription failed: \\\\(error)")
// Handle error appropriately
}
}
}

}

Step 4: Handle Push Notifications

The SDK automatically handles push notification events, but you can also track custom events:

// In your UNUserNotificationCenterDelegate func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {

let notification = response.notification
let userInfo = notification.request.content.userInfo
// Track notification click
FHSDK.shared.track(event: .custom(
category: "Push Notification",
action: "Clicked",
name: notification.request.content.title
))
// Handle deep linking or custom actions here
handleNotificationAction(userInfo: userInfo)
completionHandler()

}

private func handleNotificationAction(userInfo: [AnyHashable: Any]) { // Implement your custom notification handling logic if let deepLink = userInfo[“deepLink”] as? String { // Navigate to specific screen } }

Complete Push Notification Flow

// 1. Initialize SDK with initial FCM token let config = FHConfiguration( siteId: “YOUR_SITE_ID”, baseURL: “<https://your-domain.com>”, fcmToken: “initial_token”, // Will be updated visitDimensionIndexes: .defaults )

// 2. Update token when received from Firebase FHSDK.shared.updateFCMToken(newToken)

// 3. Set user after login let user = FHUser(email: “user@example.com”, mobileNo: “+1234567890”, userId: “123”) FHSDK.shared.setUser(user)

// 4. Subscribe to push notifications Task { try await FHSDK.shared.subscribeToPushNotifications(mobileNumber: user.mobileNo) }

Event Tracking

Standard Events

The SDK provides predefined events for common user actions:

Search Events

FHSDK.shared.track(event: .searchKeyword( keyword: “iPhone”, category: “Electronics”, product: “iPhone 15” ))

Product Events

// Product view FHSDK.shared.track(event: .productViewed( productSKU: “SKU123”, productName: “iPhone 15 Pro”, category: “Smartphones”, price: 999.99, quantity: 1 ))

// Product purchase FHSDK.shared.track(event: .productPurchased( productSKU: “SKU123”, productName: “iPhone 15 Pro”, category: “Smartphones”, price: 999.99, quantity: 1 ))

// Add to cart FHSDK.shared.track(event: .addedToCart( orderId: “ORDER123”, grandTotal: 999.99, tax: 89.99, shipping: 9.99, discount: 50.00 ))

User Authentication Events

// Sign up FHSDK.shared.track(event: .signUp( phoneNumber: “+1234567890”, name: “John Doe”, email: “john@example.com” ))

// Login FHSDK.shared.track(event: .login( phoneNumber: “+1234567890”, email: “john@example.com”, userId: “user123” ))

// Logout FHSDK.shared.track(event: .logoff( phoneNumber: “+1234567890”, email: “john@example.com”, userId: “user123” ))

Payment Events

// Payment success FHSDK.shared.track(event: .paymentSuccess( amount: 999.99, gateway: “Stripe”, method: “Credit Card”, mode: “Online” ))

// Payment failure FHSDK.shared.track(event: .paymentFailure( amount: 999.99, gateway: “PayPal”, method: “PayPal”, mode: “Online” ))

User Interaction Events

// Button click FHSDK.shared.track(event: .buttonClick( buttonName: “Purchase Now”, whoClick: “user123” ))

// Page scroll FHSDK.shared.track(event: .scrollDown( numberOfScrolled: 5, pageName: “Product Details” ))

Custom Events

Create custom events for specific business needs:

FHSDK.shared.track(event: .custom( category: “User Engagement”, action: “Video Watch”, name: “Product Demo Video”, value: 120.5 // Duration in seconds ))

Custom Dimensions

Add additional context to events with custom dimensions:

let customDimensions = [ 6: “Premium User”, 7: “iOS”, 8: “Version 2.1.0” ]

FHSDK.shared.track( event: .productViewed( productSKU: “SKU123”, productName: “Premium Product”, category: “Premium”, price: 199.99 ), customDimensions: customDimensions )

Advanced Features

Page View Tracking

Track screen or page views:

// Simple page view FHSDK.shared.trackPageView(“home/products/electronics”)

// Page view with URL let url = URL(string: “<https://yourapp.com/products/electronics>”) FHSDK.shared.trackPageView(“products/electronics”, url: url)

// Convenience method for screen tracking FHSDK.shared.trackScreenView(“ProductDetailsViewController”)

E-commerce Tracking

Track complete orders with multiple items:

let orderItems = [ OrderItem(sku: “SKU001”, name: “iPhone 15”, category: “Smartphones”, price: 999.99, quantity: 1), OrderItem(sku: “SKU002”, name: “iPhone Case”, category: “Accessories”, price: 29.99, quantity: 1) ]

FHSDK.shared.trackOrder( orderId: “ORDER123”, items: orderItems, revenue: 1029.98, subTotal: 1029.98, tax: 92.70, shipping: 10.00 )

Goal Tracking

Track conversion goals:

// Goal completion FHSDK.shared.trackGoal(goalId: 1, revenue: 999.99)

// Goal without revenue FHSDK.shared.trackGoal(goalId: 2)

Campaign Tracking

Track marketing campaigns:

FHSDK.shared.trackCampaign( name: “Summer Sale 2024”, keyword: “discount smartphones” )

Content Tracking

Track content engagement:

// Content impression FHSDK.shared.trackContentImpression( name: “Product Banner”, piece: “iPhone 15 Banner”, target: “product-page” )

// Content interaction FHSDK.shared.trackContentInteraction( name: “Product Banner”, interaction: “click”, piece: “iPhone 15 Banner”, target: “product-page” )

Session Management

Control user sessions:

// Start new session (automatically called on app launch) FHSDK.shared.startNewSession()

// Set user opt-out status FHSDK.shared.setOptOut(true) // User opted out FHSDK.shared.setOptOut(false) // User opted in

Debug Features

Enable verbose logging for development:

#if DEBUG FHSDK.shared.enableVerboseLogging() #endif

Manual event dispatch (normally automatic):

FHSDK.shared.dispatch()

Best Practices

1. Initialize Early

Initialize the SDK as early as possible in your app lifecycle:

// In AppDelegate.didFinishLaunchingWithOptions try FHSDK.shared.initialize(config: config) FHSDK.shared.setupAutomaticTracking()

2. Handle Token Updates

Always update FCM tokens when they change:

func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) { guard let token = fcmToken else { return } FHSDK.shared.updateFCMToken(token) }

3. Proper User Management

Set and clear users appropriately:

// On login FHSDK.shared.setUser(loggedInUser)

// On logout FHSDK.shared.setUser(FHUser(mobileNo: "")) // Empty user

4. Error Handling

Always handle errors in async operations:

Task { do { try await FHSDK.shared.subscribeToPushNotifications(mobileNumber: user.mobileNo) } catch SDKError.tokenNotAvailable { // Handle token not available } catch SDKError.subscriptionFailed { // Handle subscription failure } catch { // Handle other errors } }

5. Event Batching

For multiple related events, use batch tracking:

let events: [FHEvents] = [ .productViewed(productSKU: “SKU1”, productName: “Product 1”, category: “Category A”), .productViewed(productSKU: “SKU2”, productName: “Product 2”, category: “Category A”), .addedToCart(orderId: “ORDER123”, grandTotal: 199.98) ]

FHSDK.shared.trackEvents(events)

Troubleshooting

Common Issues and Solutions

1. SDK Not Initialized

Error: “FirstHive SDK not initialized” Solution: Ensure you call initialize(config:) before any other SDK methods.

2. Push Subscription Fails

Error: “Push notification subscription failed” Solutions:

  • Verify FCM token is updated
  • Ensure user has valid mobile number
  • Check network connectivity
  • Verify subscription API URL

3. Events Not Tracking

Solutions:

  • Check if SDK is initialized
  • Verify user is set (for user-specific events)
  • Enable verbose logging to debug
  • Manually call dispatch() to force send events

4. Invalid Configuration

Error: “SDK configuration error” Solutions:

  • Verify all required configuration parameters
  • Check base URL format
  • Ensure site ID is correct

Debugging Tips

  1. Enable Verbose Logging:

#if DEBUG FHSDK.shared.enableVerboseLogging() #endif

  1. Check Current User:

if let user = FHSDK.shared.getCurrentUser() { print(“Current user: \\(user)”) } else { print(“No user set”) }

  1. Manual Event Dispatch:

// Force send queued events FHSDK.shared.dispatch()

  1. Verify Token Updates:

// Add logging in token update method FHSDK.shared.updateFCMToken(newToken) print(“Token updated: \\(newToken)“)

Error Codes

ErrorDescriptionSolution
invalidBaseURLBase URL format is incorrectCheck URL format includes protocol
invalidUserUser information is missingProvide valid user with mobile number
permissionDeniedNotification permission deniedRequest permissions again
tokenNotAvailableFCM token not setUpdate token using updateFCMToken()
userNotSetUser not configuredCall setUser() with valid user
configurationErrorSDK configuration invalidCheck all configuration parameters
subscriptionFailedPush subscription API failedCheck network and API endpoint

Quick Reference

SDK Methods Overview

MethodPurposeUsage
initialize(config:)Initialize SDK with configurationMust be called first before any other method
updateFCMToken(_:)Update Firebase Cloud Messaging tokenCall when FCM token is received or refreshed
setUser(_:)Set current user informationCall after login/logout to track user context
getCurrentUser()Get current user informationReturns current user or nil if not set
subscribeToPushNotifications(mobileNumber:)Subscribe user to push notificationsCall after login when token and user are set
track(event:customDimensions:)Track predefined or custom eventsMain method for event tracking
trackPageView(_:url:)Track page/screen viewsTrack navigation and screen views
trackSearch(query:category:resultCount:)Track search activitiesTrack user search behavior
trackOrder(orderId:items:revenue:subTotal:tax:shipping:)Track e-commerce ordersTrack complete purchase transactions
trackGoal(goalId:revenue:)Track conversion goalsTrack achievement of specific goals
trackCampaign(name:keyword:)Track marketing campaignsTrack campaign effectiveness
trackContentImpression(name:piece:target:)Track content viewsTrack when content is displayed
trackContentInteraction(name:interaction:piece:target:)Track content interactionsTrack user interaction with content
setCustomDimension(_:forIndex:)Set visit-level custom dimensionsAdd custom context to all events
startNewSession()Start a new analytics sessionManually start new session (auto on app launch)
setOptOut(_:)Set user opt-out preferenceHandle user privacy preferences
dispatch()Manually send queued eventsForce send events (normally automatic)
enableVerboseLogging()Enable debug loggingEnable detailed logs for troubleshooting

Convenience Methods

MethodPurposeUsage
setupAutomaticTracking()Enable automatic app lifecycle trackingSetup automatic app launch/background tracking
trackAppLaunch()Track app launch eventAutomatically called with setupAutomaticTracking
trackAppBackground()Track app background eventAutomatically called with setupAutomaticTracking
trackScreenView(_:)Track screen view (alias for trackPageView)Convenient method for screen tracking
trackUserAction(_:on:value:)Track generic user actionsQuick method for user interaction tracking
trackEvents(_:)Track multiple events in batchEfficient way to track multiple events

Essential Implementation Flow

// 1. Initialize SDK try FHSDK.shared.initialize(config: config)

// 2. Setup automatic tracking FHSDK.shared.setupAutomaticTracking()

// 3. Update FCM token when received FHSDK.shared.updateFCMToken(newToken)

// 4. Set user after login FHSDK.shared.setUser(user)

// 5. Subscribe to push notifications try await FHSDK.shared.subscribeToPushNotifications(mobileNumber: user.mobileNo)

// 6. Track events throughout app usage FHSDK.shared.track(event: .custom(category: “Action”, action: “ButtonClick”))

// 7. Track page views FHSDK.shared.trackPageView(“screen/name”)

Notification Permission Request

UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) { granted, error in if granted { DispatchQueue.main.async { UIApplication.shared.registerForRemoteNotifications() } } }

This documentation provides a complete guide for implementing the FirstHive SDK with proper push notification setup following the specified workflow.