Latest SDK version is 2.7.0
Migration Guide: Blitzllama to Wingify User Feedback iOS SDK
Overview
This guide helps you migrate your application from the Blitzllama SDK to the Wingify User Feedback SDK for in-app surveys. Both SDKs provide similar functionality, but there are key differences in initialization, configuration, and API methods.
Minimum Requirements:
- iOS 12.0 and above
- Wingify dashboard access (to obtain Account ID and SDK Key)
Migration Summary
| Feature | Blitzllama SDK | Wingify User Feedback SDK |
|---|---|---|
| Dependency | BlitzLlamaSDK | VWO_Insights |
| API Key Location | AppDelegate.swift | AppDelegate.swift |
| User Creation | Separate createUser() call | Passed during initialization (optional), then use setUserId() to switch users |
| User Switching | logout() | setUserId(randomString, completion) |
| Trigger Method | triggerEvent() | trackEvent() |
| SDK Manager | BlitzLlamaSDK.getSdkManager() | VWO.getSurveyManager() |
| User Attributes | setUserAttribute() | setAttribute() |
Step 1: Update Dependencies
Remove Blitzllama Dependency
Before (Blitzllama):
# Podfile
pod 'Blitzllama-ios', '1.6.29'Add Wingify User Feedback Dependency
After (Wingify User Feedback):
# Podfile
pod 'VWO-Insights', '~> 2.7.0'Step 2: Update Configuration
Remove Blitzllama Configuration
Blitzllama does not use Info.plist for API keys. The API key is set programmatically via setBlitzLlamaAPIKey(). Wingify User Feedback also uses programmatic configuration but passes credentials during initialization.
Wingify Configuration
The most significant change is in how the SDK is initialized and how users are identified using VWO.configure().
Step 3: Update SDK Initialization
The most significant change is in how the SDK is initialized and how users are identified.
Key Points:
- User ID can be passed during initialization in
VWO.configure()(optional) - Use
setUserId()later to switch users or identify users after they log in - For anonymous users, you can pass nil, or "" or a random string with
setUserId()
Blitzllama Approach (Before)
import BlitzLlamaSDK
import UIKit
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Initialize Blitzllama SDK with API key
BlitzLlamaSDKController.getSDKManager.setBlitzLlamaAPIKey("API_KEY")
// Create user separately
BlitzLlamaSDKController.getSDKManager.createUser("user_id")
return true
}
}Wingify User Feedback Approach (After)
import VWO_Insights
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// User ID is optional during initialization
// Pass nil or "" for anonymous users, or actual user ID if known
VWO.configure(
accountId: "your_account_id", // Account ID from Wingify dashboard
sdkKey: "your_sdk_key", // SDK Key from Wingify dashboard
userId: nil // User ID (optional) - use nil for anonymous, or "user_id" if known
) { result in
switch result {
case .success(_):
print("VWO SDK initialized successfully")
// Safe to trigger surveys now
VWO.startSessionRecording()
// If user logs in later, use setUserId() to identify them:
// VWO.setUserId("user_id") { result in ... }
case .failure(let error):
print("VWO SDK initialization failed: \(error)")
}
}
return true
}
}Key Changes
- No longer extend SDK class - Your Application class extends
UIResponderandUIApplicationDelegateinstead of extending Blitzllama SDK - User ID is optional at initialization - User identifier can be passed in
VWO.configure()(usenilor""for anonymous users), or set later usingsetUserId() - Use
setUserId()to switch users - CallsetUserId()when user logs in or switches accounts (no separatecreateUser()orlogout()methods) - Callback-based initialization - Wingify uses explicit success/failure callbacks
Step 4: Update Survey Triggers
Blitzllama (Before)
// Trigger survey without properties
BlitzLlamaSDKController.getSDKManager.fetchSurvey(triggerName: "trigger_name")
// Trigger survey with properties
let eventProperties: [String: Any] = [
"eventKey1": "eventValue1",
"eventKey2": "eventValue2"
]
BlitzLlamaSDKController.getSDKManager().fetchSurvey(triggerName: "trigger_name", properties: eventProperties)Wingify User Feedback (After)
// Get Survey SDK manager
let surveySDK = VWO.getSurveyManager()
// Track event (trigger survey)
surveySDK.trackEvent(
eventName: "trigger_name",
properties: ["key": "value"], // Optional
viewController: self // Optional, for presentation context
)Method Mapping
| Blitzllama | Wingify User Feedback |
|---|---|
triggerEvent("name") | trackEvent("name") |
triggerEvent("name", properties) | trackEvent("name", properties) |
triggerEvent("name", properties, listener) | trackEvent("name", properties, listener) |
Step 5: Update User Attributes
Setting Email and Name
Blitzllama (Before):
BlitzLlamaSDKController.getSDKManager.updateUserEmail("[email protected]")
BlitzLlamaSDKController.getSDKManager.updateUserName("user_name")Wingify User Feedback (After):
In Wingify, use setAttribute() to set user email and name:
let surveySDK = VWO.getSurveyManager()
// Supports different value types (String, Int, Bool, etc.)
let attributes: [String: Any] = [
"user_email": "[email protected]",
"user_name": "John Doe"
]
surveySDK.setAttribute(attributes: attributes)
Note: You don't need to includeuser_idinsetAttribute()— the SDK automatically uses the current user ID set via initialization orsetUserId().
Setting Custom User Attributes
Blitzllama (Before):
// Set individual attributes with data type
BlitzLlamaSDKController.getSDKManager.updateUserAttributes("plan_type", attributeValue: "premium", dataType: "string")
BlitzLlamaSDKController.getSDKManager.updateUserAttributes("user_level", attributeValue: "5", dataType: "number")
BlitzLlamaSDKController.getSDKManager.updateUserAttributes("is_active", attributeValue: "true", dataType: "boolean")Wingify User Feedback (After):
let surveySDK = VWO.getSurveyManager()
// Supports different value types (String, Int, Bool, etc.)
let attributes: [String: Any] = [
"plan_type": "premium",
"user_level": 5, // Can use actual number type
"is_active": true // Can use boolean
]
surveySDK.setAttribute(attributes: attributes)
Note: Wingify usessetAttribute()instead ofupdateUserAttributes(). Data types are automatically inferred, so you don't need to specify them explicitly. You can pass multiple attributes in a single dictionary. The SDK automatically associates attributes with the current user ID.
Step 6: Update Survey Language Setting
Blitzllama (Before):
BlitzLlamaSDKController.getSDKManager.setLanguageCode("en")Wingify User Feedback (After):
let surveySDK = VWO.getSurveyManager()
surveySDK.setLanguageCode("en")This API remains largely the same.
Step 7: Handle User Switching
Blitzllama (Before)
BlitzLlamaSDK.logout()Wingify User Feedback (After)
Wingify User Feedback does not have a logout() method. Instead, use setUserId() to switch between users. To create anonymous sessions (equivalent to logout), pass a random string as the user ID.
Switching to a New User
Use setUserId() when your user logs in or switches accounts:
import VWO_Insights
// When user logs in or switches account
VWO.setUserId("new_user_id") { result in
switch result {
case .success(let message):
print("User switch complete: \(message)")
// Recording resumes automatically if it was active before
case .failure(let error):
print("User switch failed: \(error.localizedDescription)")
}
}Switching to Anonymous User (Logout)
If your user logs out and you want to track them as anonymous, generate a random user ID:
import Foundation
// When user logs out
let randomUserId = UUID().uuidString
VWO.setUserId(randomUserId) { result in
switch result {
case .success(let message):
print("Now tracking as anonymous user")
case .failure(let error):
print("Failed to switch to anonymous: \(error.localizedDescription)")
}
}Key Differences
| Blitzllama | Wingify User Feedback |
|---|---|
BlitzLlamaSDK.logout() | No direct logout method |
| - | VWO.setUserId(userId, completion) |
| Logout clears session | Use random string for anonymous tracking |
| Requires re-initialization | setUserId() handles session refresh internally |
Note:setUserId()automatically stops the current session, refreshes configuration, and resumes recording if it was active before the switch.
Step 8: Update Event/Trigger Names in Wingify Dashboard
If you're using triggers configured in the Blitzllama dashboard, you may need to recreate them in the Wingify dashboard:
- Log in to your Wingify dashboard
- Navigate to Data360 → Events → Create
- Create events with the same names you used as trigger names in Blitzllama
- Configure these events in Surveys → Custom Triggers
Import Statement Changes
Update all your import statements:
| Before | After |
|---|---|
import BlitzLlamaSDK | import VWO_Insights |
BlitzLlamaSDKController.getSDKManager | VWO.getSurveyManager() |
Complete Migration Example
Before (Blitzllama)
import UIKit
import BlitzLlamaSDK
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Initialize SDK with API key
BlitzLlamaSDKController.getSDKManager.setBlitzLlamaAPIKey("API_KEY")
// Create user
BlitzLlamaSDKController.getSDKManager.createUser("user_123")
// Set user attributes
BlitzLlamaSDKController.getSDKManager.updateUserEmail("[email protected]")
BlitzLlamaSDKController.getSDKManager.updateUserAttributes("plan", attributeValue: "premium", dataType: "string")
BlitzLlamaSDKController.getSDKManager.setLanguageCode("en")
return true
}
}
// In your ViewController
class ViewController: UIViewController {
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
// Trigger survey with properties
let eventProperties: [String: Any] = [
"screen": "home"
]
BlitzLlamaSDKController.getSDKManager().fetchSurvey(triggerName: "home_screen_loaded", properties: eventProperties)
}
}After (Wingify User Feedback)
import UIKit
import VWO_Insights
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Initialize SDK with user ID
VWO.configure(
accountId: "your_account_id",
sdkKey: "your_sdk_key",
userId: "user_123" // User ID now here
) { result in
switch result {
case .success(_):
print("VWO SDK initialized")
VWO.startSessionRecording()
// Set attributes after initialization
let surveySDK = VWO.getSurveyManager()
surveySDK.setAttribute(attributes: ["plan": "premium"])
surveySDK.setLanguageCode("en")
case .failure(let error):
print("Initialization failed: \(error)")
}
}
return true
}
}
// In your ViewController
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Wait for SDK initialization before triggering
// Best practice: Trigger in viewDidAppear or after initialization callback
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
// Trigger survey
let surveySDK = VWO.getSurveyManager()
surveySDK.trackEvent(
triggerName: "home_screen_loaded",
properties: ["screen": "home"],
viewController: self
)
}
}Troubleshooting
Survey not showing after migration?
- Verify initialization: Ensure the success callback is received before triggering surveys
- Check event names: Event names must match exactly with Wingify dashboard configuration
- Verify credentials: Confirm Account ID and SDK Key are correct from Wingify dashboard
- Check initialization timing: Wait for the initialization callback before calling survey methods
Race condition on first screen?
Use the initialization callback to trigger surveys:
VWO.configure(
accountId: "your_account_id",
sdkKey: "your_sdk_key",
userId: "user_id"
) { result in
switch result {
case .success(_):
// Safe to trigger survey here
DispatchQueue.main.async {
let surveySDK = VWO.getSurveyManager()
surveySDK.trackEvent(triggerName: "app_launched")
}
case .failure(let error):
print("Initialization failed: \(error)")
}
}Migration Checklist
- Updated Podfile dependency from
Blitzllama-iostoVWO-Insights - Updated Application class initialization
- Replaced
createUser()withsetUserId()for user identification - Changed
triggerEvent()calls totrackEvent() - Updated
setUserAttribute()tosetAttribute() - Updated import statements
- Configured events in Wingify dashboard
- Tested survey triggering in the app
Version Information
| Component | Version |
|---|---|
| Wingify User Feedback SDK Version | 2.7.0 |
| Minimum iOS Version | 12.0 |
| Swift Version | 5.0+ |
| Blitzllama SDK Version (migrating from) | 1.6.29 |