> ## Documentation Index
> Fetch the complete documentation index at: https://docs.nemu.com.br/llms.txt
> Use this file to discover all available pages before exploring further.

# Swift SDK (iOS)

## 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:

### Via Xcode (Recommended)

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):

```swift theme={null}
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 Xcode** → `Info.plist`. In your `Info.plist`, add:

```xml theme={null}
<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:

```swift theme={null}
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

<Info>
  For total security and integrity of your application user data,
  all UIDs registered by our SDK are encrypted before being
  stored on our servers.
</Info>

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:

```swift theme={null}
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.

```swift theme={null}
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.

### 2. Click on a **deep link** that redirects to the app with UTMs

If your application is **not yet configured to receive deep links**, follow our guide to configure [Universal Links on iOS](/en/app-tracking/deeplinks). 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:

```bash theme={null}
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.

```swift theme={null}
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.
