Skip to main content

Apply iOS Agent

Prerequisites

Before installing the iOS agent, check the following requirements.

  • iOS 15.0 or higher
  • Xcode 15.0 or higher
  • Swift 5.9 or higher or Objective-C

Install Agent

The agent can be installed in three ways.

  • Automatic installation using Swift Package Manager (recommended)
  • Manual installation using XCFramework
  • Closed-network installation using a local file
  1. Open the project in Xcode and select File → Add Package Dependencies.

  2. Enter the package URL.

    https://github.com/whatap/WhatapIOSAgent-Release

  3. Select version 2.7.3 or later, and click Add Package.

Method 2: Manual XCFramework Installation

  1. Download the XCFramework.

    curl -O https://repo.whatap-mobile-agent.io/uploads/2.7.3/WhatapAgent.xcframework.zip
    unzip WhatapAgent.xcframework.zip
  2. Add it to your Xcode project.

    • Select the project target → General tab
    • Go to the Frameworks, Libraries, and Embedded Content section
    • Click the + button → Add OtherAdd Files
    • Select WhatapAgent.xcframework
    • Verify the Embed & Sign setting

Method 3: Local File Installation (closed network / internal network)

In environments where access to external repositories is restricted, download the zip file provided by WhaTap, unzip it, and add it to your project. Then add it in Xcode with Embed & Sign, the same as in Method 2.

unzip whatap-ios-agent-2.7.3.zip
mv WhatapAgent.xcframework /path/to/YourApp/

Agent Initialization

The WhaTap iOS SDK must be initialized at app startup to collect the app's performance data. SDK initialization should run as early as possible when the app starts, so events that occur throughout the app's entire lifecycle can be tracked.

Note

Initialization timing

  • SwiftUI: init() of the @main struct - when the app struct is created
  • UIKit: application:willFinishLaunchingWithOptions: - called before didFinishLaunching

If initialization is delayed, critical performance data at app startup (such as pre-main time and initial memory usage) may be missed.

Swift

In a SwiftUI app, initialize the SDK in the init() of the @main struct.

import SwiftUI
import WhatapAgent

@main
struct MyApp: App {
init() {
// Initialize SDK at startup
let agent = WhatapAgentBuilder()
.setProjectKey("<YOUR_PROJECT_ACCESS_KEY>")
.setPCode(<YOUR_PCODE>)
.setServerUrl("<YOUR_SERVER_URL>")
.build()

agent.initialize()
}

var body: some Scene {
WindowGroup {
ContentView()
}
}
}

In UIKit-based apps, we recommend initializing the SDK in the application:willFinishLaunchingWithOptions: of AppDelegate.

import UIKit
import WhatapAgent

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

func application(_ application: UIApplication,
willFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

// Initialize SDK at the earliest possible point (recommended)
let agent = WhatapAgentBuilder()
.setProjectKey("<YOUR_PROJECT_ACCESS_KEY>")
.setServerUrl("<YOUR_SERVER_URL>")
.setPCode(<YOUR_PCODE>)
.build()

agent.initialize()

return true
}
}

Objective-C

Using willFinishLaunchingWithOptions (recommended)

AppDelegate.m
#import "AppDelegate.h"
@import WhatapAgent;

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application
willFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

// Initialize SDK, which runs before didFinishLaunching
WhatapAgentBuilder *builder = [[WhatapAgentBuilder alloc] init];
[builder setProjectKey:@"<YOUR_PROJECT_ACCESS_KEY>"];
[builder setServerUrl:@"<YOUR_SERVER_URL>"];
[builder setPCode:<YOUR_PCODE>];

WhatapIOSAgent *agent = [builder build];
[agent initialize];

return YES;
}
@end

Builder Options

Transmission and buffer options

  • setFlushInterval(_:): 10.0 seconds
  • setQueueSize(_:): 1,000
  • setMaxDiskBytes(_:): 500 × 1024
  • setMaxDiskFiles(_:): 5

Collection and HTTP options

Caution

Network collection is opt-in

Starting with iOS SDK 2.7.3, automatic network collection defaults to false. When enabled, requests are instrumented through URLProtocol, so if your app relies on certificate pinning, a custom URLSessionDelegate, its own cookies or auth headers, or HTTP/2 negotiation, check the impact first. For security-sensitive requests, we recommend separating them into a dedicated custom URLSession.

  • setCollectScreenLoading(_:): true
  • setCollectNetwork(_:): false
  • setKeepAlive(_:): true
  • setMaxConnectionsPerHost(_:): 4

Custom endpoints

  • setLogServerUrl(_:): serverUrl + "/log"
  • setSpanServerUrl(_:): serverUrl + "/trace"

ScreenGroup and tracking options

  • setGroupWaitingInterval(_:): 3.0 seconds
  • setExcludeLifecycleEventsFromScreenGroup(_:): false
  • enableMethodTracing(_:): false
  • setSamplingRate(_:): 1.0
WhatapAgentBuilder()
.setFlushInterval(120)
.setMaxDiskBytes(2 * 1024 * 1024)
.setMaxDiskFiles(5)
.setQueueSize(1000)
.setKeepAlive(true)
.setMaxConnectionsPerHost(4)
.setGroupWaitingInterval(3.0)
.build()

Automatically Collected Items

  • App start performance (Cold/Warm start, pre-main)
  • Screen transitions based on the UIViewController lifecycle and per-screen loading time
  • Crashes, exceptions, signals, CPU/memory/battery/thermal state

Screen Tracking

Swift
final class CheckoutViewController: UIViewController {
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
WhatapIOSAgent.trackViewController(self)
}
}

struct CheckoutView: View {
var body: some View {
ContentView()
.onAppear {
WhatapIOSAgent.trackViewController(UIHostingController(rootView: self))
}
}
}
Objective-C
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[WhatapIOSAgent trackViewController:self];
}

Manual Instrumentation

Manual Task API

You can record an asynchronous task within a single screen, such as a payment or image load, as a separate span.

WhatapIOSAgent.startTask("checkout", taskId: "task-001")
WhatapIOSAgent.endTask("task-001")

Method Tracing

Method Tracing is an opt-in feature. Add enableMethodTracing(true) to the Builder during SDK initialization, then record the performance of the methods you need.

  • methodStart / methodEnd
func validateBiometric(
agent: WhatapIOSAgent,
validate: () throws -> Void
) rethrows {
agent.methodStart(className: "AuthService", methodName: "validateBiometric")
defer {
agent.methodEnd(className: "AuthService", methodName: "validateBiometric")
}

try validate()
}
  • StackSpan
func charge(
agent: WhatapIOSAgent,
operation: () async throws -> Void
) async rethrows {
let stackSpan = agent.start(className: "PaymentService", methodName: "charge")

do {
try await operation()
stackSpan.end()
} catch {
stackSpan.endWithError(error)
throw error
}
}

Global Context

Values stored in ExtrasStore are automatically attached to every log and span.

Swift
import WhatapAgent

ExtrasStore.shared.setExtra(key: "user_id", value: userId)
ExtrasStore.shared.removeExtra(key: "user_id")
ExtrasStore.shared.clearExtras()
Objective-C
[[ExtrasStore shared] setExtraValue:userId forKey:@"user_id"];
Tip

For Android compatibility, keys stored in ExtrasStore automatically get a .c suffix when transmitted. Example: user_iduser_id.c

ChainView
ChainView.shared.startChain(chainName: "LoginFlow")

ChainView.shared.endChain()

Network & Crash

Network Security Settings

HTTPS collection endpoints don't require an App Transport Security exception. If you must use a legacy HTTP endpoint, apply a separate exception only to the single domain you need, and don't allow subdomains or arbitrary loads.

Crash Reporting

Crashes are automatically collected and sent the next time the app runs. The built-in reporter is the default; using PLCrashReporter requires a separate library.

WhatapAgentBuilder()
.useNativeCrashReporter()
.build()

WhatapAgentBuilder()
.usePLCrashReporter()
.build()

Installation Verification & Debug

After running the app, check the initialization log in the Xcode Console. If data isn't collected, check the project key, PCode, server URL, the initialize() call, the sampling rate, and the disk buffer.

#if DEBUG
WhatapLogger.isDebug = true
#endif

Troubleshooting & Support

Troubleshooting

SDK Initialization Failure

If SDK initialization fails, check the following.

  • Verify the project key and PCode: Confirm the correct values are set.
  • Check network connectivity: Confirm the device is connected to the internet.
  • Verify the server URL: Confirm the provided collector server address is correct.

Data Not Collected

If monitoring data isn't displayed on the dashboard, check the following.

  • Check the sampling rate: Confirm it's set to setSamplingRate(1.0) for 100% collection.
  • Check network permissions in Info.plist: Confirm the App Transport Security settings are correct.

Crash Reports Not Sent

If crash data isn't collected, check the following.

  • The app must be restarted for a prior crash to be sent: Prior crash information is sent when the app runs again after a crash.
  • Some crashes may not be captured in the simulator: Testing on a real device is recommended.

Support

If issues occur, contact us through the following channels.

When requesting technical support, providing the following information can lead to a faster resolution.

  • Project key
  • iOS version
  • Xcode version
  • SDK version
  • Error messages or logs
  • Steps to reproduce the issue