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: - MessagingDelegatefunc 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 SDKFHSDK.shared.updateFCMToken(token)
// If user is logged in, resubscribe with new tokenif 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.notificationlet userInfo = notification.request.content.userInfo
// Track notification clickFHSDK.shared.track(event: .custom( category: "Push Notification", action: "Clicked", name: notification.request.content.title))
// Handle deep linking or custom actions herehandleNotificationAction(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
- Enable Verbose Logging:
#if DEBUG FHSDK.shared.enableVerboseLogging() #endif
- Check Current User:
if let user = FHSDK.shared.getCurrentUser() { print(“Current user: \\(user)”) } else { print(“No user set”) }
- Manual Event Dispatch:
// Force send queued events FHSDK.shared.dispatch()
- Verify Token Updates:
// Add logging in token update method FHSDK.shared.updateFCMToken(newToken) print(“Token updated: \\(newToken)“)
Error Codes
Error | Description | Solution |
---|---|---|
invalidBaseURL | Base URL format is incorrect | Check URL format includes protocol |
invalidUser | User information is missing | Provide valid user with mobile number |
permissionDenied | Notification permission denied | Request permissions again |
tokenNotAvailable | FCM token not set | Update token using updateFCMToken() |
userNotSet | User not configured | Call setUser() with valid user |
configurationError | SDK configuration invalid | Check all configuration parameters |
subscriptionFailed | Push subscription API failed | Check network and API endpoint |
Quick Reference
SDK Methods Overview
Method | Purpose | Usage |
---|---|---|
initialize(config:) | Initialize SDK with configuration | Must be called first before any other method |
updateFCMToken(_:) | Update Firebase Cloud Messaging token | Call when FCM token is received or refreshed |
setUser(_:) | Set current user information | Call after login/logout to track user context |
getCurrentUser() | Get current user information | Returns current user or nil if not set |
subscribeToPushNotifications(mobileNumber:) | Subscribe user to push notifications | Call after login when token and user are set |
track(event:customDimensions:) | Track predefined or custom events | Main method for event tracking |
trackPageView(_:url:) | Track page/screen views | Track navigation and screen views |
trackSearch(query:category:resultCount:) | Track search activities | Track user search behavior |
trackOrder(orderId:items:revenue:subTotal:tax:shipping:) | Track e-commerce orders | Track complete purchase transactions |
trackGoal(goalId:revenue:) | Track conversion goals | Track achievement of specific goals |
trackCampaign(name:keyword:) | Track marketing campaigns | Track campaign effectiveness |
trackContentImpression(name:piece:target:) | Track content views | Track when content is displayed |
trackContentInteraction(name:interaction:piece:target:) | Track content interactions | Track user interaction with content |
setCustomDimension(_:forIndex:) | Set visit-level custom dimensions | Add custom context to all events |
startNewSession() | Start a new analytics session | Manually start new session (auto on app launch) |
setOptOut(_:) | Set user opt-out preference | Handle user privacy preferences |
dispatch() | Manually send queued events | Force send events (normally automatic) |
enableVerboseLogging() | Enable debug logging | Enable detailed logs for troubleshooting |
Convenience Methods
Method | Purpose | Usage |
---|---|---|
setupAutomaticTracking() | Enable automatic app lifecycle tracking | Setup automatic app launch/background tracking |
trackAppLaunch() | Track app launch event | Automatically called with setupAutomaticTracking |
trackAppBackground() | Track app background event | Automatically called with setupAutomaticTracking |
trackScreenView(_:) | Track screen view (alias for trackPageView) | Convenient method for screen tracking |
trackUserAction(_:on:value:) | Track generic user actions | Quick method for user interaction tracking |
trackEvents(_:) | Track multiple events in batch | Efficient 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.