Installation
This guide adds the Positive User iOS SDK to your app, connects it to your workspace and checks that contacts, events, push notifications and in-app messages reach the panel.
The package and pod are called UserSDK, the module you import is UserComSDK, and the main class is UserSDK.
Requirements
- iOS 13.0 or later
- Xcode 26 or later
- Swift Package Manager or CocoaPods
- A Mobile SDK key and your workspace domain, see Setup & Configuration
- For push notifications and in-app messages: Firebase Cloud Messaging in your app, an APNs key uploaded to Firebase, and a physical device for testing
The SDK has no external dependencies. It does not bundle Firebase: your app owns Firebase and passes the FCM token to the SDK. This model is called BYOT (bring your own token).
Step 1: Prepare the panel and Firebase
Complete Setup & Configuration. You need:
- A Mobile SDK key (64 characters).
- Your workspace domain, for example
your-domain.user.com. - A Firebase service account key uploaded to the panel.
- An APNs authentication key uploaded to your Firebase project, see the Firebase guide.
You have the Mobile SDK key and the domain at hand, and the Firebase project in the panel is the same project your iOS app uses.
Step 2: Add the SDK
Swift Package Manager
- In Xcode, open File → Add Package Dependencies.
- Enter
https://github.com/UserEngage/iOS-SDK.git. - Set Dependency Rule to Exact Version
1.3.0. - Add the
UserComSDKproduct to your app target.
CocoaPods
Add the pod to your Podfile and run pod install:
platform :ios, '13.0'
target 'YourApp' do
use_frameworks!
pod 'UserSDK', :git => 'https://github.com/UserEngage/iOS-SDK.git', :tag => '1.3.0'
end
Open the generated .xcworkspace from now on.
import UserComSDK compiles in your app target. If Xcode reports No such module 'UserComSDK', the package was added without the UserComSDK product linked to the target.
Step 3: Initialize the SDK
Create the SDK instance once per launch in application(_:didFinishLaunchingWithOptions:), then call ping() to create or update the contact. The initializer does not send anything to the backend by itself.
- Swift
- Objective-C
import UIKit
import UserComSDK
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
UserSDK.default = UserSDK(
application: application,
apiKey: "YOUR_MOBILE_SDK_KEY",
baseURL: "your-domain.user.com",
shouldTrackActivities: false
)
UserSDK.default?.ping()
return true
}
}
@import UserComSDK;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UserSDK *sdk = [[UserSDK alloc] initWithApplication:application
apiKey:@"YOUR_MOBILE_SDK_KEY"
baseURL:@"your-domain.user.com"
shouldTrackActivities:NO
fcmToken:nil];
[sdk ping];
return YES;
}
| Parameter | Value |
|---|---|
apiKey | Your 64 character Mobile SDK key. Not the REST API key. |
baseURL | Your workspace domain, for example your-domain.user.com. https:// is added when missing. |
shouldTrackActivities | Deprecated, has no effect. Pass false. |
fcmToken | Optional. The FCM token, if you already have it at launch. |
The initializer sets UserSDK.default itself, so assigning the result is optional. SwiftUI apps call this code from an app delegate attached with UIApplicationDelegateAdaptor.
Run the app. In the Positive User panel, a new anonymous contact appears in the contact list, with your device on its contact profile. UserSDK.default?.userKey is no longer nil.
Step 4: Enable push capabilities
In Xcode, open your app target and select Signing & Capabilities:
- Add Push Notifications.
- Add Background Modes and select Remote notifications.
In-app messages arrive as silent (data only) pushes. Without the Remote notifications background mode they are not delivered to the SDK. See Apple's guide to registering your app with APNs.
The Info.plist of the built app contains UIBackgroundModes with remote-notification. Check the built product, not only the source file, because build settings can generate or override it.
Step 5: Pass the FCM token
Add Firebase Cloud Messaging to your app as described in the Firebase guide, then give the token to the SDK whenever Firebase reports it:
import FirebaseMessaging
extension AppDelegate: MessagingDelegate {
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
guard let fcmToken else { return }
UserSDK.default?.setFcmToken(fcmToken)
}
}
setFcmToken(_:) stores the token and sends a ping, which registers the device for push notifications on the current contact. Token rotation, login, logout and Firebase method swizzling are covered in Firebase and FCM Token.
The contact appears when you filter Data → Contacts by FCM key with has any value. The panel does not show the token itself.
Step 6: Forward notifications to the SDK
The SDK needs to see incoming notifications to count push clicks and to show in-app messages. Pass taps to handleNotificationClick(_:) and received notifications to handleNotification(_:), from both places below. The first method belongs to your UNUserNotificationCenterDelegate, so set UNUserNotificationCenter.current().delegate in application(_:didFinishLaunchingWithOptions:).
// A tap on a notification: the SDK counts the click
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void) {
UserSDK.default?.handleNotificationClick(response.notification.request.content.userInfo)
completionHandler()
}
// A received notification, including in-app messages: never a click
func application(_ application: UIApplication,
didReceiveRemoteNotification userInfo: [AnyHashable: Any],
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
UserSDK.default?.handleNotification(userInfo)
completionHandler(.noData)
}
The SDK acts only on Positive User payloads. handleNotification(_:) returns false for any other notification, so your own notifications keep working. If your app has no notification code yet, the SDK can request permission and act as the notification center delegate for you, see Push Notifications.
Both methods are in the class that is actually set as the app delegate and as the UNUserNotificationCenter delegate. A method in a class iOS never calls is the most common reason in-app messages do not appear.
Test your integration
Test on a physical device. Silent pushes are not delivered reliably to the simulator.
-
Contact. Launch the app. A contact with your device appears in the panel.
-
Event. Send a test event and check the completion result:
UserSDK.default?.sendEvent(name: "sdk_test", attributes: ["source": "installation"]) { success, error inprint("sdk_test sent: \(success), \(String(describing: error))")}The event appears on the contact's timeline.
-
Push notification. Send a push notification to this contact from the panel, see how to launch a push notification campaign. Tap it. The click is counted in the campaign statistics.
-
In-app message. Send an in-app message to this contact while the app is open. It appears on screen and is counted as displayed. See in-app messages.
Common errors
| Symptom | Cause | Fix |
|---|---|---|
No such module 'UserComSDK' | The package is added, but the UserComSDK product is not linked to the target. | Add the product in the target's Frameworks, Libraries, and Embedded Content. |
'UserSDK' is unavailable in application extensions | UserSDK is used in an app extension. | In a Notification Service Extension use only NotificationExtensionHelper. |
| No contact appears in the panel | ping() is never called, or the key or domain is wrong. | Call ping() after initialization and read its completion. A 401 means a wrong or inactive Mobile SDK key. |
sendEvent fails at once with notIdentified ("No user exists yet") | The event was sent before the first successful ping. | Call ping() first. See Sending Events. |
| The contact cannot be selected in a push campaign | No FCM token was passed to the SDK. | Repeat Step 5. See Troubleshooting. |
| The push notification is sent, but never arrives on the device | No APNs key in Firebase, a different Firebase project in the panel, the Push Notifications capability missing, or notifications turned off for the app. | Repeat Step 1 and Step 4. See Troubleshooting. |
| Push notifications work, in-app messages do not | application(_:didReceiveRemoteNotification:fetchCompletionHandler:) is missing or not forwarded, or the background mode is missing. | Repeat Step 4 and Step 6. |
Next steps
- Firebase and FCM Token
- Contacts
- Sending Events
- Push Notifications
- In-App Messages
- Opening App Screens
- Migration Guide, if you are upgrading from an earlier version
Need help?
Contact Positive User support through the chat widget in your workspace or on user.com, or your Customer Success Manager. Include:
- SDK version and installation method (SPM or CocoaPods)
- iOS version and device model
- The contact key from
UserSDK.default?.userKey - The time of the test and what you expected to see in the panel
- The
error.localizedDescriptionfrom the completion handler orUserSDK.errorHandler, if any - Whether your app uses its own notification center delegate and whether Firebase method swizzling is enabled