iOS Classic Installation


Remember to replace your app ID with the ID of the environment to which you want to send data. You can find this ID on the Account > Manage > Projects page by clicking on the project and pulling it up in the side menu.


For notes on the latest SDK versions, see our iOS changelog.


Heap will continue to support this Classic SDK with critical bug fixes and security updates.

Base Installation

There are two options for installing the Heap iOS SDK. We recommend installing via Swift Package Manager or CocoaPods, although manual installation is also an option.

Before you get started with the instructions below, we recommend you first review Before Installing: Key Considerations in our Help Center.

Requirements and Known Limitations

The Heap iOS SDK supports iOS 10 and up.

Option 1: Install via Swift Package Manager (recommended)

Swift Package Manager is a dependency manager built into Xcode 11 and above.

  1. In Xcode, select File → Add packages… to open Swift Package Manager.

  1. In the search field in the top right corner, enter and press Return.
  2. The “heap-ios-sdk” project will appear in the package manager. Select the “Up to Next Major Version” dependency rule if not already selected.
  3. Click “Add Package”.

  1. Confirm that the application target is selected in the following dialog and click “Add Package” again.
  2. Initialize Heap with your app ID. We recommend doing this in application:didFinishLaunchingWithOptions: within your application delegate as follows:
import Heap

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    return true
#import <Heap/Heap.h>

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
	  [Heap initialize:@"YOUR_APP_ID"];
    return YES;

Alternatively, you can use this snippet to set specific initialization options:

import Heap

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    let options = HeapOptions()
    options.debug = true
    options.disableTextCapture = true
    Heap.initialize("YOUR_APP_ID", with: options)
    return true
#import <Heap/Heap.h>

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    HeapOptions *options = [[HeapOptions alloc] init];
    options.debug = YES;
    options.disableTextCapture = YES;
    [Heap initialize:@"YOUR_APP_ID" withOptions:options];
    return YES;

Option 2: Install via CocoaPods

CocoaPods is a Ruby-based dependency manager for iOS projects. Heap requires CocoaPods 1.11.0 or later.

  1. To get started, follow the instructions for installing CocoaPods at
  2. Save the following line to your Podfile:
pod 'Heap', '~> 8.0'
  1. Run pod install within your project directory.
  2. If you were not already using CocoaPods or a Workspace, close your project and open the new file with the .xcworkspace extension.
  3. Initialize Heap using the the instructions from step 6 of the Swift Package Manager instructions.



If you use CocoaPods and your data does not appear in the dashboard, please check that Other Linker Flags is set per the manual instructions below (step 4), and that all libraries below are correctly linked (step 5).

Option 3: Install Manually

Installing the Heap iOS SDK without CocoaPods takes a bit longer.

  1. Download the Heap iOS library (clicking this link will start the download).
  2. Unzip the downloaded file and drag Heap.xcframework into your Xcode project. Make sure to select Copy items if needed and that the framework is added to your app targets.
  3. Click on the project (via the blue project icon), and select “Build Settings”.
  4. Within General, find Heap.xcframework in the "Frameworks, Libraries, and Embedded Content" section and change its Embed behavior from "Do Not Embed" to "Embed & Sign".

  1. Initialize Heap using the the instructions from step 6 of the Swift Package Manager instructions.

Updating your privacy manifest

To combat user fingerprinting, Apple now requires apps to include privacy manifests describing usage of certain system APIs. The classic iOS library uses two of these SDKs:

  • UserDefaults, for storing information around upgrade/install events and for migrating data from legacy applications. This falls under reason CA92.1.
  • creationDate, for determining the app's installation date for the initial install event. This falls under reason C617.1.

When adding Heap to your app, you will need to add these two reasons to your privacy manifest, if they are not already present. This will appear as follows:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "">
<plist version="1.0">

Using Heap in iMessage Apps

Heap should work with standalone iMessage apps if you override didBecomeActive in your MSMessagesAppViewController.

func didBecomeActive(with conversation: MSConversation) {

Enable Visual labeling Mode Pairing

Heap’s Visual labeling interface for iOS allows you to easily define iOS events from within Heap. You can then use these events in your analysis to look for opportunities to optimize your user experience on iOS.

As part of setting up Heap for iOS, we strongly recommend completing the step below.

Step 1: Register the URL Type


You will need to repeat this step for every Heap environment that you want to associate with your iOS app.

Navigate to the Info tab of your Xcode project settings page and look for the URL Types section. Add a new URL type matching the following parameters:

Identifier: This is simply a unique string. Your app’s bundle ID should suffice.

URL Scheme: This is based on your environment ID. Set this to exactly heap-<environment_id>.

For example, for Heap environment 89742597891, the URL Types section might look like this:

Feel free to leave the Role and Icon parameters as-is, as they won’t impact your setup.

Step 2: Handle Inbound URLs

Now that the URL type is set up, your application should be launched when iOS sees a URL matching the heap-<environment_id> scheme. The next (and final) step is to handle these URLs in your app delegate and pass them to the Heap library.

If your app delegate already contains an application(_:open:options:) or application:openURL:options: method, add the following line to it:

Heap.handleOpen(url, options: options)
[Heap handleOpenURL:url options:options];

If not, create it:

func application(_ app: UIApplication,
      open url: URL,
      options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
  Heap.handleOpen(url, options: options)
  return true
- (BOOL)application:(UIApplication *)app
        openURL:(NSURL *)url
        options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options {
  [Heap handleOpenURL:url options:options];
  return true;

Alternatively, if your app uses a scene delegate instead of an app delegate, you can add something like:

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    for context in connectionOptions.urlContexts {
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
    for context in URLContexts {

Even more simply, if you're using the Heap iOS SDK 9.0.0 or newer, you can add:

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {

Your app is now ready to receive a pairing request from Heap's Visual labeling mode via a QR code.

We highly recommend defining a couple of test events to ensure this is set up properly. To do so, see Define Events with Visual labeling.

Verify Your Installation

Once installed, run your app to begin capturing data. In the Heap app, select the environment your data is being sent to and check the following to ensure your installation was successful.

Using Live View

  1. Navigate to the Live page within your Heap account.
  2. Filter for your IP address so you can see your specific data flowing into Heap.
  3. Start interacting with your iOS app and see the raw data come in!

How to use Visual Labeling

  1. Navigate to the Visual labeling interface within your Heap account.
  2. Pair your device with iOS Visual labeling.
  3. Begin performing actions within your app through Visual labeling and watch as Heap captures and displays the corresponding events in the web interface.

For full steps to use the Visual labeling for iOS, review the iOS platform section of our Visual labeling guide.

Graph Sessions by Source

  1. Navigate to the Graph analysis module (Analyze > Graph).
  2. Graph Count of Sessions and group by the Source property. Click the Run Query button.
  3. You should see the Source property populated with values ‘ios’, ‘android’, ‘web’, or ‘server’ depending on where Heap is receiving data from.

Note that interactions on mobile web will have Source set to web. To differentiate between desktop and mobile web browsers, add an additional group-by clause using the Platform or Browser property. Events originating from webviews embedded within iOS applications will have the Browser property set to a value such as Safari UIWebView. You can use this value to distinguish these events from Mobile Safari events.

What does your data look like?

As you take the time to test your installation, observe the data coming in. What kind of events are there? What properties are attached to them and what values are they populated with? This is important to note early on, as event definition relies on these property values. The key is to ensure the event can be defined by a set of properties that specifically refer to that particular interaction in the intended context.

Note: If you’re unable to define an event for a specific user action, or an event you’ve defined does not have all the properties you require, you will need to do one or both of the following:

  • Define additional element attributes in code. Review Autocaptured Data for the complete set of properties captured by Heap.
  • Review our docs on Autocaptured Data for iOS for the complete set of properties captured by Heap.
  • Enrich the autocaptured data using our APIs. For additional details, see the Enrich Your Dataset Via APIs page of the Setting Up Heap guide.

Ignoring Sensitive Data and PII


To hide elements, use defined runtime attributes to set heapIgnore to a boolean and make sure it’s enabled. For example:

passwordTextField.heapIgnore = true;
passwordTextField.heapIgnore = YES;

Alternatively, this helpful answer on StackOverflow outlines a clean, reusable approach using Swift property wrappers.

Note that you may need to set heapIgnore on the containing view if the element you’d like to ignore is nested in a deep hierarchy. We encourage you to check that values are ignored as expected before shipping changes to production


Setting disableTextCapture will prevent Heap from capturing target text. By default, Heap does not capture the contents of input fields, but does capture text from other rendered page elements. For limited disabling of text capture, heapIgnore may be sufficient.

For reference, this snippet can be used in your initialization code:

let options = HeapOptions();
options.disableTextCapture = true;
Heap.initialize(“YOUR_APP_ID”, with: options);
HeapOptions *options = [[HeapOptions alloc] init];
options.disableTextCapture = YES;
[Heap initialize:@"YOUR_APP_ID" withOptions:options];

For more information on Heap's data privacy options, see How do I use Heap to comply with data privacy legislation?


iOS SDK version 7.1.0+ allows you to give your end-users the option to opt-out of tracking. There are two ways to set this up.

Prior to initializing Heap, use a HeapOptions object, set the value of the disableTracking property to YES, then pass this object as an argument using + (void)initialize:(NSString *)envId withOptions:(HeapOptions *)options.

After Heap has been initialized, call the new + (void)setTrackingEnabled:(BOOL)trackingEnabled; method with an argument of NO.

Note: The tracking status does not persist between application launches, and your application is responsible for setting the proper enabled/disabled state for each user session.


You can use the code snippet below to prevent Heap from capturing the advertiser ID. If you are only looking to block the advertiser ID, remove the disableVendorIdCapture line.

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        let options = HeapOptions()
            options.disableAdvertiserIdCapture = true
            options.disableVendorIdCapture = true
            Heap.initialize("YOUR_APP_ID", with: options)
            return true

For more information about the latest iOS privacy updates, review Preparing Your App For iOS 14.


Using the Heap iOS SDK is designed to be effortless, though occasionally installation issues arise for some installations.

If you’ve run into an issue, first update the SDK by pulling down the latest version. We adhere to the SemVer specification, so MINOR versions will always maintain backwards compatibility. We recommend keeping the SDK up to date with the MINOR version at all times, and the MAJOR version, if possible.

If a version update does not address your issue, please email us at [email protected].

CocoaPods Undefined symbols for architecture armv7s: _OBJCCLASS$_Heap

This compiler error means that the Heap static library isn’t being linked into your app. The most common cause of this is an overridden LIBRARY_SEARCH_PATHS in your build settings. If you have any values in this setting, make sure $(inherited) is the last entry.

Empty screen views and no events

This can occur when parts of the Heap iOS SDK library aren’t loaded at runtime. Add the -ObjC flag Other Linker Flags to resolve this issue.

Crash logs include heap_sendEvent

To capture all events, Heap installs a method swizzle on UIApplication that captures events before passing them to the original listener. If the event listener crashes, Heap will appear in the stack trace even if Heap is not responsible.

If you have reason to believe the Heap iOS SDK is causing a crash, send us a crash report and a reproducible test project to [email protected].

Library not loaded: @rpath/Heap.framework/Heap

If your app loads correctly in a debug session but instantly crashes when launch from Springboard, you are likely running into an issue where Heap isn’t embedded in your application bundle. If you are installing the framework manually, check the instructions on how to embed the framework in your project.

Upgrading from Heap 7.5.1 and earlier

Starting in Heap 8.0.0, the library is now bundled as an XCFramework rather than a universal static library. When using Cocoapods, updating the pod will automatically switch to the new format. When installing manually, you will want to remove Heap.h and libHeap.a from your project and follow the installation instructions above.

If you were using Heap from Objective-C, you will simply need to replace #import "Heap.h" statements with #import <Heap/Heap.h>.

If you were using Heap from Swift, you can either replace the #import "Heap.h" statement in your bridging header with #import <Heap/Heap.h> or remove the statement from your bridging header completely and use import Heap directly from Swift as shown in the installation instructions.

Performance Impact

  • Event size: There is no maximum event size on iOS.
  • SDK size: The Heap iOS SDK adds approximately 200 KB to app bundles.
  • Cross-platform testing: We test the Heap iOS SDK on all major iOS versions 10.0 and above, as well as on all iPhone/iPad and 32-bit/64-bit device combinations.
  • Network impact: The Heap iOS SDK batches all events and submits a request to our servers every 15 seconds. This interval can be adjusted. Events are cached locally if no network connection is present. We also cache the first 200 request batches, each of which can have one or multiple events. A cached event can be any one of:
    • 15 seconds of events
    • One pageview of events (the events in the pageview)
    • One “metadata” request (the new user / new session / new pageview request)
    • One identify request
    • One AUP call
  • Performance: The Heap iOS SDK adds virtually zero performance overhead. Because all processing is done off the main thread, user interactivity and UI rendering are remain unaffected.


For notable updates to the Heap iOS SDK, see the iOS Changelog.