Skip to main content

Requirements

  • iOS Target: 13+
  • Swift Version: 5.1
  • Minimum Xcode: XCode 11

Installation

To install our SDK in your Swift application, there are 2 options:
  1. Go to File > Add Packages…
  2. Enter the SDK repository URL https://github.com/nemu-brazil/nemu-swift-sdk.git
  3. Choose version From 1.0.0
Xcode will automatically import the library and allow the import: import NemuTrackingLib

Or via Package.swift (When using SPM in the manifest):

dependencies: [
    .package(url: "https://github.com/your-org/MyTrackingSDK.git", from: "1.0.0")
]
After including the SDK in the project, initialize the SDK in your main application file, passing the Nemu pixel ID and your Nemu SDK key as arguments. ⚠️ Note: For security measures, we recommend that your Nemu SDK key be stored as an environment variable. As a recommendation, we can use Info.plist to find it: build settings in XcodeInfo.plist. In your Info.plist, add:
<key>SDK_TOKEN</key>
<string>my-secret-sdk-token</string>

<key>PIXEL_ID</key>
<string>my-pixel-id</string>
In your code, add environment variables as in the example below:
import UIKit
import NemuTrackingLib

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    func application(_ application: UIApplication,
                    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    let sdkKey = Bundle.main.object(forInfoDictionaryKey: "SDK_TOKEN") as? String
    let pixelId = Bundle.main.object(forInfoDictionaryKey: "PIXEL_ID") as? String

        NemuTrackingManager.shared.initialize(widthPixelId: pixelId, withSdkKey: sdkKey)

        return true
    }

    // other methods...
}

Registering UID to the SDK session

For total security and integrity of your application user data, all UIDs registered by our SDK are encrypted before being stored on our servers.
During the application login process, add a call to the setUserId() method, passing the defined UID of the user who just completed the login process as an argument. Example:
import Foundation
import NemuTrackingLib

func authenticateUser(email: String, password: String) {
    loginUser(
        email: email,
        password: password,
        onSuccess: { userId in
            TrackingManager.shared.setUserId(userId)
            print("NemuTracking: User registered: \(userId)")
        },
        onError: {
            print("NemuTracking: Failed to authenticate user.")
        }
    )
}
It is important to ensure that users who were already logged in before the SDK installation or update are also correctly tracked. To do this, you can define the UID as soon as it is available in the application, normally right after loading the locally saved user.

Example: UIKit applications with AppDelegate

In AppDelegate, after recovering the user from the session (for example, via UserSessionManager), call the SDK’s setUserId method:
import UIKit
import NemuTrackingLib

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

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

        // Recover the logged-in user, if any
        if let userId = UserSessionManager.shared.currentUserId {
            NemuTrackingManager.shared.setUserId(userId)
        }

        return true
    }
}

Retrieving UTMs when sending sale event to Nemu API

The getLastSessionHistory() method returns an object containing the UTMs from the user’s last session. Use this object when sending the sale information to the Nemu API.
import Foundation
import NemuTrackingLib

func sendPurchaseWithUtms() {
    guard let session = TrackingManager.shared.getLastSessionHistory() else {
        print("No session found")
        return
    }

    let payload: [String: Any?] = [
        "transactionId": "123",
        "netValue": 10,
        "status": "paid",
        "utm_campaign": session.utmCampaign ?? NSNull(),
        "utm_content": session.utmContent ?? NSNull(),
        "utm_medium": session.utmMedium ?? NSNull(),
        "utm_source": session.utmSource ?? NSNull(),
        "utm_term": session.utmTerm ?? NSNull()
    ]

    guard let url = URL(string: "https://developers.nemu.com.br/api/v1") else {
        print("Invalid URL")
        return
    }

    var request = URLRequest(url: url)
    request.httpMethod = "POST"
    request.addValue("application/json", forHTTPHeaderField: "Content-Type")

    do {
        request.httpBody = try JSONSerialization.data(withJSONObject: payload, options: [])
    } catch {
        print("Failed to serialize JSON: \(error.localizedDescription)")
        return
    }

    let task = URLSession.shared.dataTask(with: request) { data, response, error in
        if let error = error {
            print("Error sending request: \(error.localizedDescription)")
            return
        }

        if let httpResponse = response as? HTTPURLResponse {
            print("API response: \(httpResponse.statusCode)")
        }
    }

    task.resume()
}

Testing the SDK and ensuring everything is right – Swift SDK

To test the complete integration flow and ensure everything is working correctly with Nemu’s SDK in Swift, follow the steps below:

1. Initialize the SDK in Debug mode

To view detailed SDK logs, enable debug mode when initializing it. Simply pass the isDebugMode parameter as true during initialization:
NemuTrackingManager.shared.initialize(
    withPixelId: "YOUR_PIXEL_ID",
    withApiKey: "YOUR_SDK_TOKEN",
    isDebugMode: true
)
⚠️ Make sure to call this method at the start of the application, for example in AppDelegate or in the SwiftUI @main struct. If your application is not yet configured to receive deep links, follow our guide to configure Universal Links on iOS. Use a link like this (with UTMs) to perform the test:
https://myapp.com?utm_source=nemu&utm_medium=medium-test&utm_campaign=campaign-test&utm_content=content-test
You can simulate the access in the device’s Safari or in a terminal with the command:
xcrun simctl openurl booted "https://myapp.com?utm_source=nemu&utm_medium=medium-test&utm_campaign=campaign-test&utm_content=content-test"

3. Check application logs

With the SDK correctly configured and debug mode enabled, you should see the following logs in the console when opening the app via deep link:
2025-05-22 14:55:02 [DEBUG] [NemuTracking] Application successfully connected with Nemu services

2025-05-22 14:55:03 [DEBUG] [NemuTracking] UTM parameters successfully extracted from deeplink - {"utm_source": "nemu","utm_medium": "medium-test","utm_campaign": "campaign-test","utm_content": "content-test"}

2025-05-22 14:56:00 [DEBUG] [NemuTracking] UID registered by the application - { "userId": "example@email.com" }

Log explanation:

  1. Connection to Nemu: The SDK was successfully initialized and validated the token and pixel ID.
  2. UTM Extraction: The SDK correctly read and stored the deep link parameters.
  3. UID Registered: The app passed the user’s unique identifier using setUserId.

4. Check the recovery of UTMs with getLastSessionHistory()

As a final step, call the getLastSessionHistory() method and validate if the UTM data is being correctly retrieved.
func sendPurchaseWithUtms() {
    guard let session = TrackingManager.shared.getLastSessionHistory() else {
        print("No sessions found")
        return
    }

    print("utmSource: \(session.utmSource ?? "nil")")
    print("utmCampaign: \(session.utmCampaign ?? "nil")")
    print("utmMedium: \(session.utmMedium ?? "nil")")
    print("utmContent: \(session.utmContent ?? "nil")")
    print("utmTerm: \(session.utmTerm ?? "nil")")
}
In debug mode, the SDK also automatically prints:
2025-05-22 15:00:02 [DEBUG] [NemuTracking] Last session history retrieved - {"utm_source": "nemu","utm_medium": "medium-test","utm_campaign": "campaign-test","utm_content": "content-test||nemu_xiI85afzrP"}
Note: The value "||nemu_xiI85afzrP" at the end of utm_content is Nemu’s internal session identifier. It must be sent exactly like this when registering sales in the Nemu API.