This project is currently in open beta while we continue to add additional features and seek feedback from users.
The release is stable and publicly available, with no known critical bugs or issues.
Overview
KlaviyoSwift is an SDK, written in Swift that can be integrated into your iOS App. The SDK enables you to engage with your customers using push notifications. In addition you will be able to take advantage of Klaviyo’s identification and event tracking functionality. Once integrated, your marketing team will be able to better understand your app users’ needs and send them timely messages via APNs.
The create method takes an event object as an argument. The event can be constructed with the following arguments:
name: The name of the event you want to track, as a EventName enum. The are a number of commonly used event names provided by default. If you need to log an event with a different name use CustomEvent with a string of your choosing. This argument is required to track an event.
profile: An dictionary of properties that belong to the person who did the action you’re tracking. Including an $email, $phone_number or $id key associates the event with particular profile in Klaviyo. In addition the SDK will retain these properties for use in future sdk calls, therefore if they are not included previously set identifiers will be used to log the event. This argument is optional.
properties: An dictionary of properties that are specific to the event. This argument is optional.
time: This is the timestamp, as an Date, when the event occurred. This argument is optional but recommended if you are tracking past events. If you’re tracking real- time activity, you can ignore this argument.
value: A numeric value (Double) to associate with this event. For example, the dollar amount of a purchase.
Identifying traits of people
If you app collects additional identifying traits about your users you can provide this to Klaviyo via the set(profileAttribute:value:) or `set(profile:) methods and via the . In both cases we’ve provided a wide array of commonly used profile properties you can use. If you need something more custom though you can always pass us those properties via the properties dictionary when you create your profile object.
Note that the only argument set(profile:) takes is a dictionary representing a customer’s attributes. This is different from trackEvent, which can take multiple arguments.
Anonymous Tracking Notice
By default, Klaviyo will begin tracking unidentified users in your app once the SDK is initialized. This means you will be able to track events from users in your app without any user information provided. When an email or other primary identifier is provided, Klaviyo will merge the data from the anonymous user to a new identified user.
Prior to version 1.7.0, the Klaviyo SDK used the Apple identifier for vendor (IDFV) to facilitate anonymous tracking. Starting with version 1.7.0, the SDK will use a cached UUID that is generated when the SDK is initialized. For existing anonymous profiles using IDFV, the SDK will continue to use IDFV, instead of generating a new UUID.
Profile properties and Identifiers
Whenever an email (or other identifier) is provided to use via our APIs we will retain that information for future calls so that new data is tracked against the right profile. However, you are always free to override the current identifiers by passing new ones into a customer properties dictionary.
KlaviyoSDK().set(email: "junior@blob.com")
Push Notifications
Implementing push notifications requires a few additional snippets of code to enable.:
Registering users for push notifications.
Sending resulting push tokens to Klaviyo.
Handlinge when users attempt to open your push notifications.
Sending push notifications
Add the following code to your application wherever you would like to prompt users to register for push notifications. This is often included within application:didFinishLaunchingWithOptions:, but it can be placed elsewhere as well. When this code is called, ensure that the Klaviyo SDK is configured and that set(email:) is called. This enables Klaviyo to match app tokens with profiles in Klaviyo customers.
import UserNotifications
...
let center = UNUserNotificationCenter.current()
center.delegate = self as? UNUserNotificationCenterDelegate // the type casting can be removed once the delegate has been implemented
let options: UNAuthorizationOptions = [.alert, .sound, .badge]
// use the below options if you are interested in using provisional push notifications. Note that using this will not
// show the push notifications prompt to the user.
// let options: UNAuthorizationOptions = [.alert, .sound, .badge, .provisional]
center.requestAuthorization(options: options) { granted, error in
if let error = error {
// Handle the error here.
print("error = ", error)
}
// Enable or disable features based on the authorization status.
}
UIApplication.shared.registerForRemoteNotifications()
Add the following code to the application delegate file in application:didRegisterForRemoteNotificationsWithDeviceToken. You may need to add this code to your application delegate if you have not done so already.
The following code example allows you to track when a user opens a push notification.
Add the following code that extends your app delegate:
extension AppDelegate: UNUserNotificationCenterDelegate {
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
let handled = KlaviyoSDK().handle(notificationResponse: response, completionHandler: completionHandler)
if not handled {
// not a klaviyo notification should be handled by other app code
}
}
}
Once your first push notifications are sent and opened, you should start to see Opened Push metrics within your Klaviyo dashboard.
Foreground push handling
The following code example allows push notifications to be displayed when your app is running:
If a user taps on the notification with the application open, this event is tracked as an Opened Push event.
Handling deep linking
Your app needs to use version 1.7.2 at a minimum in order for the below steps to work.
There are two use cases for deep linking that can be relevant here:
When you push a notification to your app with a deep link.
Any other cases where you may want to deep link into your app via SMS, email, web browser etc.
In order for deep linking to work, there are a few configurations that are needed and these are no different from what are required for handling deep linking in general and Apple documentation on this can be followed in conjunction with the steps highlighted here:
Option 1: Modify Open Tracking
If you plan to use universal links in your app for deep linking you will need to modify the push open tracking as described below:
extension AppDelegate: UNUserNotificationCenterDelegate {
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
let handled = KlaviyoSDK().handle(notificationResponse: response, completionHandler: completionHandler) { url in
// parse deep link and navigate here.
}
if not handled {
// not a klaviyo notification should be handled by other app code
}
}
}
Note that the deep link handler will be called back on the main thread. If you want to handle uri schemes in addition to universal links you implement them as described below.
Option 2: Use URL Schemes
If you do not need universal link support you can instead implement url schemes for your app and the deepLinkHandler as indicated in Option 1 can be omitted. The Klaviyo SDK will follow all url automatically in this case.
Step 1: Register the URL scheme
In order for Apple to route a deep link to your application you need to register a URL scheme in your application’s Info.plist file. This can be done using the editor that xcode provides from the Info tab of your project settings or by editing the Info.plist directly.
The required fields are as following:
Identifier - The identifier you supply with your scheme distinguishes your app from others that declare support for the same scheme. To ensure uniqueness, specify a reverse DNS string that incorporates your company’s domain and app name. Although using a reverse DNS string is a best practice, it doesn’t prevent other apps from registering the same scheme and handling the associated links.
URL schemes - In the URL Schemes box, specify the prefix you use for your URLs.
Role - Since your app will be editing the role select the role as editor.
In order to edit the Info.plist directly, just fill in your app specific details and paste this in your plist.
Since iOS 9 Apple has mandated that the URL schemes that your app can open need to also be listed in the Info.plist. This is in addition to Step 1 above. Even if your app isn’t opening any other apps, you still need to list your app’s URL scheme in order for deep linking to work.
Finally, we have an example app (Examples/KlaviyoSwiftExamples) in the SDK repo that you can reference to get an example of how to implement deep links in your app.
If you are using SwiftUI, then you can implement onOpenURL(perform:) as a view modifier in the view you intent to handle deep links. This may or may not be the root of your scene.
Example:
@main
struct MyApplication: App {
var body: some Scene {
WindowGroup {
ContentView()
.onOpenURL { url in
// handle the URL that must be opened
}
}
}
}
Once the above steps are complete, you can send push notifications from the Klaviyo Push editor within the Klaviyo website. Here you can build and send a push notification through Klaviyo to make sure that the URL shows up in the handler you implemented in Step 3.
Additionally, you can also locally trigger a deep link to make sure your code is working using the below command in the terminal.
xcrun simctl openurl booted {your_URL_here}
SDK Data Transfer
Starting with version 1.7.0, the SDK will cache incoming data and flush it back to the Klaviyo API on an interval. The interval is based on the network link currently in use by the app. The table below shows the flush interval used for each type of connection:
Network
Interval
WWAN/Wifi
10 seconds
Cellular
30 seconds
Connection determination is based on notifications from our reachability service. When there is no network available, the SDK will cache data until the network becomes available again. All data sent by the SDK should be available shortly after it is flushed by the SDK.
Retries
The SDK will retry API requests that fail under certain conditions. For example, if a network timeout occurs, the request will be retried on the next flush interval. In addition, if the SDK receives a rate limiting error 429 from the Klaviyo API, it will use exponential backoff with jitter to retry the next request.
License
KlaviyoSwift is available under the MIT license. See the LICENSE file for more info.
KlaviyoSwift
DISCLAIMER
This project is currently in open beta while we continue to add additional features and seek feedback from users. The release is stable and publicly available, with no known critical bugs or issues.
Overview
KlaviyoSwift is an SDK, written in Swift that can be integrated into your iOS App. The SDK enables you to engage with your customers using push notifications. In addition you will be able to take advantage of Klaviyo’s identification and event tracking functionality. Once integrated, your marketing team will be able to better understand your app users’ needs and send them timely messages via APNs.
Installation options
Install with SPM
KlaviyoSwift is available via Swift Package Manager (SPM). Follow the steps below to install.
https://github.com/klaviyo/klaviyo-swift-sdk
in the text field and click Next.KlaviyoSwift
package.Install with CocoaPods
KlaviyoSwift is available through CocoaPods.
pod install
to complete the integration.The library can be kept up-to-date via
pod update
.Event tracking
After the SDK is installed you can begin tracking events in your app.
application:didFinishLaunchingWithOptions
:create(event:)
method in the relevant location.Arguments
The
create
method takes an event object as an argument. The event can be constructed with the following arguments:name
: The name of the event you want to track, as a EventName enum. The are a number of commonly used event names provided by default. If you need to log an event with a different name useCustomEvent
with a string of your choosing. This argument is required to track an event.profile
: An dictionary of properties that belong to the person who did the action you’re tracking. Including an$email
,$phone_number
or$id
key associates the event with particular profile in Klaviyo. In addition the SDK will retain these properties for use in future sdk calls, therefore if they are not included previously set identifiers will be used to log the event. This argument is optional.properties
: An dictionary of properties that are specific to the event. This argument is optional.time
: This is the timestamp, as anDate
, when the event occurred. This argument is optional but recommended if you are tracking past events. If you’re tracking real- time activity, you can ignore this argument.value
: A numeric value (Double
) to associate with this event. For example, the dollar amount of a purchase.Identifying traits of people
If you app collects additional identifying traits about your users you can provide this to Klaviyo via the
set(profileAttribute:value:)
or `set(profile:) methods and via the . In both cases we’ve provided a wide array of commonly used profile properties you can use. If you need something more custom though you can always pass us those properties via the properties dictionary when you create your profile object.Note that the only argument
set(profile:)
takes is a dictionary representing a customer’s attributes. This is different fromtrackEvent
, which can take multiple arguments.Anonymous Tracking Notice
By default, Klaviyo will begin tracking unidentified users in your app once the SDK is initialized. This means you will be able to track events from users in your app without any user information provided. When an email or other primary identifier is provided, Klaviyo will merge the data from the anonymous user to a new identified user.
Prior to version 1.7.0, the Klaviyo SDK used the Apple identifier for vendor (IDFV) to facilitate anonymous tracking. Starting with version 1.7.0, the SDK will use a cached UUID that is generated when the SDK is initialized. For existing anonymous profiles using IDFV, the SDK will continue to use IDFV, instead of generating a new UUID.
Profile properties and Identifiers
Whenever an email (or other identifier) is provided to use via our APIs we will retain that information for future calls so that new data is tracked against the right profile. However, you are always free to override the current identifiers by passing new ones into a customer properties dictionary.
Push Notifications
Implementing push notifications requires a few additional snippets of code to enable.:
Sending push notifications
application:didFinishLaunchingWithOptions:
, but it can be placed elsewhere as well. When this code is called, ensure that the Klaviyo SDK is configured and thatset(email:)
is called. This enables Klaviyo to match app tokens with profiles in Klaviyo customers.application:didRegisterForRemoteNotificationsWithDeviceToken
. You may need to add this code to your application delegate if you have not done so already.Any users that enable/accept push notifications from your app now will be eligible to receive your custom notifications.
To read more about sending push notifications, check out our additional push notification guides.
Tracking push notifications
The following code example allows you to track when a user opens a push notification.
Once your first push notifications are sent and opened, you should start to see Opened Push metrics within your Klaviyo dashboard.
Foreground push handling
The following code example allows push notifications to be displayed when your app is running:
If a user taps on the notification with the application open, this event is tracked as an Opened Push event.
Handling deep linking
There are two use cases for deep linking that can be relevant here:
In order for deep linking to work, there are a few configurations that are needed and these are no different from what are required for handling deep linking in general and Apple documentation on this can be followed in conjunction with the steps highlighted here:
Option 1: Modify Open Tracking
If you plan to use universal links in your app for deep linking you will need to modify the push open tracking as described below:
Note that the deep link handler will be called back on the main thread. If you want to handle uri schemes in addition to universal links you implement them as described below.
Option 2: Use URL Schemes
If you do not need universal link support you can instead implement url schemes for your app and the deepLinkHandler as indicated in Option 1 can be omitted. The Klaviyo SDK will follow all url automatically in this case.
Step 1: Register the URL scheme
In order for Apple to route a deep link to your application you need to register a URL scheme in your application’s Info.plist file. This can be done using the editor that xcode provides from the Info tab of your project settings or by editing the Info.plist directly.
The required fields are as following:
In order to edit the Info.plist directly, just fill in your app specific details and paste this in your plist.
Step 2: Whitelist supported URL schemes
Since iOS 9 Apple has mandated that the URL schemes that your app can open need to also be listed in the Info.plist. This is in addition to Step 1 above. Even if your app isn’t opening any other apps, you still need to list your app’s URL scheme in order for deep linking to work.
This needs to be done in the Info.plist directly:
Step 3: Implement handling deep links in your app
Steps 1 & 2 set your app up for receiving deep links but now is when you need to figure out how to handle them within your app.
If you are using UIKit, you need to implement
application:openURL:options:
in your application’s app delegate.Finally, we have an example app (
Examples/KlaviyoSwiftExamples
) in the SDK repo that you can reference to get an example of how to implement deep links in your app.Example:
If you are using SwiftUI, then you can implement
onOpenURL(perform:)
as a view modifier in the view you intent to handle deep links. This may or may not be the root of your scene.Example:
Once the above steps are complete, you can send push notifications from the Klaviyo Push editor within the Klaviyo website. Here you can build and send a push notification through Klaviyo to make sure that the URL shows up in the handler you implemented in Step 3.
Additionally, you can also locally trigger a deep link to make sure your code is working using the below command in the terminal.
xcrun simctl openurl booted {your_URL_here}
SDK Data Transfer
Starting with version 1.7.0, the SDK will cache incoming data and flush it back to the Klaviyo API on an interval. The interval is based on the network link currently in use by the app. The table below shows the flush interval used for each type of connection:
Connection determination is based on notifications from our reachability service. When there is no network available, the SDK will cache data until the network becomes available again. All data sent by the SDK should be available shortly after it is flushed by the SDK.
Retries
The SDK will retry API requests that fail under certain conditions. For example, if a network timeout occurs, the request will be retried on the next flush interval. In addition, if the SDK receives a rate limiting error
429
from the Klaviyo API, it will use exponential backoff with jitter to retry the next request.License
KlaviyoSwift is available under the MIT license. See the LICENSE file for more info.