iOS Integration Reference

System Requirements

ApptentiveKit is written entirely in Swift, but features that are not directly available in Objective-C (due to the use of value types or generics) have Objective-C-friendly wrappers.

The current version of ApptentiveKit is primarily intended for use with UIKit-based apps on iOS and iPadOS. Apps using SwiftUI may be able to make use of ApptentiveKit, but currently can’t provide support for this use case.

  • Minimum Deployment Target: iOS 11.0
  • Minimum Xcode Version: 13.0
  • No external dependencies required

SDK Size

The SDK is estimated to add approximately 2.3MB to the size of your app.

Supported Languages

We have translated all hard-coded strings in our SDK into the following languages. The content of all Interactions comes from our server, and you may translate the text for each Interaction by visiting the Translations Page.

Please note that you must also specify the target language in your Xcode project by selecting the project, clicking Info, and then, under Localizations, click the Add button for the desired language.

Locale Qualifier Language Name
None English
ar Arabic
el Greek
da Danish
de German
es Spanish
fr French
fr-CA French Canadian
it Italian
ja Japanese
ko Korean
nl Dutch
pl Polish
pt-BR Brazilian Portuguese
ru Russian
sv Swedish
tr Turkish
zh-Hant Chinese (Traditional)
zh-Hans Chinese (Simplified)

Adding ApptentiveKit

There are several ways to add the ApptentiveKit dependency to your app. We recommend using Swift Package Manager.

Swift Package Manager

In Xcode, choose Add Packages… from the File menu, and enter in the search field.

Select the apptentive-kit-ios package from the list. We recommend using the “Up to Next Minor Version” dependency rule to make it easy to update to the latest fully-compatible release of the SDK. When you are finished, click Add Package.


If you are using CocoaPods to manage your project’s dependencies, add the following line for your app target in your Podfile:

pod 'ApptentiveKit', '~>6.0.8'

We recommend the above version specifier to make it easy to update to the latest fully-compatible release of the SDK.

If you were previously using the apptentive-ios pod, be sure to remove it.


If you are using Carthage to manage your project’s dependency,

  1. Add github "apptentive/apptentive-kit-ios" ~> 6.0.8 to your Cartfile. We recommend this version specifier to make it easy to update to the latest fully-compatible release.
  2. Run carthage update --use-xcframeworks.
  3. On your application targets’ General settings tab, in the Frameworks, Libraries, and Embedded Content section, drag and drop the Apptentive.xcframework folder from the Carthage/Build folder on disk.


You can download the latest release as a pre-built framework from our Github releases page and drag it into your project. This requires that you manually download any new releases of ApptentiveKit to keep your project up to date.


You can also clone the ApptentiveKit repository and drag the ApptentiveKit.xcodeproj file into your project in Xcode. This requires that you manually pull any new code from the ApptentiveKit repository to keep your project up to date.

Updating ApptentiveKit

Please refer to our Release Notes for information on the latest version. We recommend using our latest version whenever possible.

Depending on how you originally configured your dependency, you may have to edit the dependency before your dependency manager will allow the update.

Swift Package Manager

In Xcode, select your project in the Project Navigator, select the project in the editor sidebar, and select the Package Dependencies tab.

If your update settings will allow an update, you can right-click the ApptentiveKit package and choose Update Package.

If your update settings will not allow an update, double-click the ApptentiveKit package and set the minimum version to the version you’d like to update to, and consider changing the dropdown to Up to Next Minor, which will allow you to more easily receive updates for bug fixes and non-breaking changes.


If your Podfile is configured to allow an update, you can run pod update 'ApptentiveKit' in the same directory as your Podfile.

If your Podfile is not configured to allow an update, edit the line for the ApptentiveKit pod with the version you would like to update to. We recommend a setting like '~>6.0.8' which will allow you to more easily receive updates for bug fixes and non-breaking changes. You can then run pod update 'ApptentiveKit' as described above.


If your Cartfile is configured to allow an update, run carthage update ApptentiveKit --use-xcframeworks from the same directory as your Cartfile.

If your Cartfile is not configured to allow an update, edit the line for the ApptentiveKit framework with the version you would like to update to. We recommend a setting like '~>6.0.8' which will allow you to more easily receive updates for bug fixes and non-breaking changes. You can then run carthage update ApptentiveKit --use-xcframeworks as described above.


If you integrate via our pre-built XCFramework, you will have to manually download the latest framework from our Github releases page to replace the one included in your project.


If you integrate ApptentiveKit as a subproject, you will have to manually pull or download the latest release from our GitHub repository.

Import ApptentiveKit


Add import ApptentiveKit to each Swift file where you plan to reference Apptentive methods and properties (typically where you would also import the UIKit or Foundation frameworks).


Add @import ApptentiveKit; to each implementation file where you plan to reference Apptentive methods and properties (typically where you would import its corresponding header file).

Initialize the SDK

Early in your app’s lifecycle, it should call Apptentive’s register(with:completion:) method. For example:

import UIKit
import ApptentiveKit

class AppDelegate: UIResponder, UIApplicationDelegate {

  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    Apptentive.shared.register(with: .init(key: "<#Your Apptentive App Key#>", signature: "<#Your Apptentive App Signature#>"))
    // Set the log level to debug Apptentive
    ApptentiveLogger.default.logLevel = .debug

    // Other app initialization...

    return true

CAUTION: The app credentials (Apptentive App Key and Apptentive App Signature) passed to the register(with:completion:) are saved to the SDK’s data store in the app’s Application Support directory and cannot be changed unless the app is fully uninstalled from the device/simulator. Installing a build with different app credentials without first uninstalling will result in a mismatchedCredentials error being passed to the completion handler, and, in development builds, an assertion failure.

NOTE: The easiest way to get started with ApptentiveKit is to use the shared instance of the Apptentive class (Apptentive.shared) to call its methods and access its properties. If you prefer, you can also explicitly create an instance of the Apptentive class (let myApptentiveInstance = Apptentive()) and manage the process of passing it to the places in your app that it will be used. In this case your app must never access the shared static property of the Apptentive class. Doing so will result in an assertion failure in debug builds and unpredictable behavior in release builds.

Engage Events

Events record user interaction. You can use them to determine if and when an Interaction will be shown to your customer. You will use these Events later to target Interactions, and to determine whether an Interaction can be shown. You trigger an Event with the engage(event:from:) method. This will record the Event, and then check to see if any Interactions targeted to that Event are allowed to be displayed, based on the logic you set up in the Apptentive Dashboard.

One good place to engage an event is when a view controller appears, for example in the view controller’s viewDidAppear(_:) method:

override func viewDidAppear(animated: Bool) {

    // Engage the "viewed_list" event.
    Apptentive.shared.engage(event: "viewed_list", from: self)

Another good place to engage events is from the action methods in your view controllers:

@IBAction func likeArticle(_ sender: AnyObject?) {
    // ...

    // Engage the "liked_article" event.
    Apptentive.shared.engage(event: "liked_article", from: self)

If you want to engage an event when a modal view is dismissed, you will want to call the engage method in the completion block, and pass the presenting view controller as the from parameter:

@IBAction func save(_ sender: AnyObject?) {
    // save the item...

    self.dismiss(animated: true) { 
        // Engage the "saved_item" event.
        Apptentive.shared.engage(event: "saved_item", from: self.presentingViewController)

This ensures that the view controller you pass in will still be visible if the event you engage results in an interaction being displayed.

Finally, you can engage an event when your app encounters an error:

do {
} catch let error as NSError {
    print("Error saving context: \(error)")

    // Engage the "core_data_save_failed" event.
    Apptentive.shared.engage(event: "core_data_save_failed", from: self)

This may allow you to let users know if there is a workaround or app update that fixes the problem.

Using a Variable as the Event Name

The engage(event:from:) method accepts an Event object as its first argument (the Event object conforms to the ExpressibleByStringLiteral protocol, so in most cases you can treat events as strings). If you are passing a non-literal string, you will have to wrap it in an Event object:

engage(event: .init(name: myEventName), from: self)

We recommend that your app engage at least 10 distinct Events. This gives you the flexibility to choose the best place for Interactions to display after your app is live, without having to update your app.

Our web dashboard works best for up to several dozen unique event names. It does not work well if you auto-generate thousands of unique event names. If you plan to target users based on viewing a piece of content out of a collection of hundreds or thousands (say, SKUs in an online retail app), do not create event names for each piece of content. Instead, you can use Custom Person Data for item viewed.

For example, you could set a key of viewed_item with a value 123456. You could then target users for whom that key matches, or is not null.

Monitoring Events

The SDK will post a notification (Notification.Name.apptentiveEventEngaged) to the default NotificationCenter when an event is engaged, whether the source of that event is your app or the SDK itself.

Your app can listen to this notification and then examine the values in the userInfo dictionary for the following keys:

  • eventType: the extended name of the event, for example com.apptentive#Survey#submit
  • interactionType: the type of the interaction that engaged the event, or app if not applicable
  • interactionID: the internal identifier of the interaction that engaged the event, if applicable
  • eventSource: the source of the event, either com.apptentive (for events that are engaged by the SDK itself) or (for events that are engaged by your app)

List of Internal Events

  • com.apptentive#<InteractionType>#launch (when an interaction is launched)
  • com.apptentive#<InteractionType>#cancel (when an interaction is dismissed)
  • com.apptentive#app#launch (when the app enters the foreground, or the SDK is first initialized following the app being terminated)
  • com.apptentive#app#exit (when the app enters the background)
  • com.apptentive#Survey#submit
  • com.apptentive#Survey#continue_partial (when a user continues with a survey after an action sheet is displayed that explains that they will discard any answers that they entered)
  • com.apptentive#Survey#cancel_partial (when a user exits a survey after the aforementioned action sheet is displayed)
  • com.apptentive#MessageCenter#read (when a previously-unread message in Message Center is displayed to the user)
  • com.apptentive#AppleRatingDialog#request (when requestReview is called on SKStoreReviewController)
  • com.apptentive#AppleRatingDialog#shown (when the above method call results in a review request being presented)
  • com.apptentive#AppleRatingDialog#not_shown (when the above method call does not result in a review request being presented)
  • com.apptentive#EnjoymentDialog#yes (when the user taps Yes in the Love Dialog)
  • com.apptentive#EnjoymentDialog#no (when the user taps No in the Love Dialog)
  • com.apptentive#NavigateToLink#navigate (when the SDK has opened a URL from a Note button)
  • com.apptentive#TextModal#interaction (when the SDK launches an interaction from a Note button)
  • com.apptentive#TextModal#dismiss (when the user taps the dismiss button in a Note)

Message Center

With the Apptentive Message Center your customers can send feedback, and you can reply, all without making them leave the app. Handling support inside the app will increase the number of support messages received and ensure a better customer experience.

Message Center lets customers see all the messages they have sent you, read all of your replies, and even send screenshots that may help debug issues.

⚠️ Note: Message Center uses a QLPreviewController instance to display attachments, which includes a default share sheet that allows saving images to the device’s photo library.

This feature requires a key to be added to the app’s Info.plist file under the “Privacy – Photo Library Usage Description” key. We suggest setting the value to something like “This will enable the Save Image feature for attachments.”

If this key is not present, iOS 15 devices will omit the Save Image option from the share sheet. Versions prior to iOS 15 will crash (in development builds) or fail silently (in release builds) if a photo library usage description is not set and the user chooses the Save Image option from the share sheet.

Showing Message Center

Find a place in your app for a button that will launch Message Center. This will allow customers to contact you with feedback, or questions if they are having trouble using your app, as well as allow them to see your responses.

import UIKit
import ApptentiveKit

class SettingsViewController: UIViewController {

  // ...

  @IBAction func openMessageCenter(sender: UIButton) {
    Apptentive.shared.presentMessageCenter(from: self)

Checking Unread Message Count

You can also check to see how many messages are waiting to be read in the customer’s Message Center using Apptentive’s unreadMessageCount property. This property is compatible with Key-Value Observing (KVO), so your app can monitor it and be notified when it changes:

var observation = Apptentive.shared.observe(\.unreadMessageCount, options: [.new]) { _, change in
    print("Unread message count changed to: \(change.newValue!)")


Attachments are messages that you can send from the SDK programmatically, which will be visible to you in the Conversation View, but will not be visible to your customers in Message Center. They are great for sending contextual information or logs from rare crash events.

Hidden File Attachments

let fileData = try Data(contentsOf: fileURL)

sendAttachment(fileData, mediaType: "application/zip")

Hidden Image Messages

let image = UIImage(named: "my image")


Hidden Text Messages

sendAttachment("Error creating file: \(error)")

Customer Information

Set Customer Contact Information

If you already know the customer’s email address or name, you can pass them to us to display in the conversation view on your Apptentive dashboard.

Apptentive.shared.personEmailAddress = <#Email Address#>
Apptentive.shared.personName = <#Person Name#>

Message Center provides dialogs that allow your customers to set their name and email as well. Calling the above methods will overwrite what your customer enters. If you don’t want to overwrite what they enter, you can check their values first, using Apptentive.shared.personEmailAddress and Apptentive.shared.personName.

Custom Data

You can send Custom Data associated with a person’s profile that is using the app, or the device. In particular, this is useful for sending a Customer ID and other information that helps you understand and support your users better. Custom Data can also be used for configuring when Interactions will run. You can add custom data of type String, Int, and Bool.

In general, Custom Data can be sent as Person Custom Data or Device Custom Data. However, if sending a Customer ID, you must send it as Person Custom Data. For more on the benefits of setting a Customer ID, see here.

After the Custom Data field has been set, it will appear on the targeting screen for any Interaction within a few minutes. You may need to refresh your browser to see recent changes.

Apptentive.shared.personCustomData["CustomerID"] = "1234321"
Apptentive.shared.personCustomData["city"] = "Seattle"
Apptentive.shared.personCustomData["points"] = 500
Apptentive.shared.personCustomData["is_premium"] = true

Apptentive.shared.deviceCustomData["primary_account"] = ""
Apptentive.shared.deviceCustomData["user_count"] = 5
Apptentive.shared.deviceCustomData["full_version"] = false

Because the CustomData type is a struct, you will need to use these alternative methods in Objective-C:

[Apptentive.shared addCustomPersonDataString: @"1234321", withKey: @"CustomerID"];
[Apptentive.shared addCustomPersonDataString: @"Seattle", withKey: @"city"];
[Apptentive.shared addCustomPersonDataNumber: @500, withKey: @"points"];
[Apptentive.shared addCustomPersonDataBool: true, withKey: @"is_premium"];

[Apptentive.shared addCustomDeviceDataString: @"", withKey: @"primary_account"];
[Apptentive.shared addCustomDeviceDataNumber: @5, withKey: @"user_count"];
[Apptentive.shared addCustomDeviceDataBool: false, withKey: @"full_version"];

Theming and Customization

There are several different options for customizing the look and feel of ApptentiveKit’s interactions.


The SDK will ordinarily apply a styling theme using Apptentive’s default colors alongside system fonts and symbols. This theme is designed to look consistent across our iOS and Android SDKs, but may differ from your app’s look and feel and the rest of the iOS system.

By setting the Apptentive class’s theme property to .none (note: this must be done before calling the register(with:completion:) method), the interactions take on a more native iOS look and feel, but it will differ substantially from the Android SDK.

Setting the theme to .none may also provide an easier starting point for customizing the user interface to your liking.


With the use of the .none theme, the ApptentiveKit interaction UI will pick up certain UIAppearance overrides that your app has set (for example, navigation bar tint).

If an appearance setting in your app makes ApptentiveKit interactions unattractive or unreadable, you can use appearance(whenContainedInInstancesOf: [ApptentiveNavigationController.self]) to make a corrective appearance change to ApptentiveKit interactions (specifically those, like Message Center and Surveys, that use view controllers other than UIAlertController).

UIKit Extensions

For styling changes that aren’t amenable to UIAppearance, ApptentiveKit defines a number of extensions to common UIKit classes to allow setting colors, fonts, images, and more. For more information, see our forthcoming Customization Guide.

Overriding InteractionPresenter

For particularly extensive customizations, we recommend subclassing the InteractionPresenter class and setting your subclass as the value for Apptentive’s interactionPresenter property. You can override the methods that present each interaction type, instantiating your own view controllers and presenting them as you see fit. A view model for each interaction is provided to configure your view controllers for displaying the interaction and reacting to user input. More information on this technique will be added soon.

Updated on November 18, 2022

Was this article helpful?

Related Articles