# Analytics-Swift Implementation Guide

Once you've installed the Analytics-Swift library, you can start collecting data through Segment's tracking methods:

* [Identify](#identify)
* [Track](#track)
* [Screen](#screen)
* [Group](#group)
* [Alias](#alias)

## Identify

The [Identify](/docs/segment/connections/spec/identify/) method lets you tie a user to their actions and record traits about them. This includes a unique user ID and any optional traits you know about them like their email, name, or address. The traits option can include any information you want to tie to the user. When using any of the reserved traits, be sure the information reflects the name of the trait. For example, `email`  should always be a string of the user's email address.

## Method signature

```swift
// These signatures provide for a typed version of user traits
func identify<T: Codable>(userId: String, traits: T)
func identify<T: Codable>(traits: T)
func identify(userId: String)
```

## Swift

```swift
struct MyTraits: Codable {
        let favoriteColor: String
}

analytics.identify(userId: "a user's id", MyTraits(favoriteColor: "fuscia"))
```

## Objective-C

```objc
[self.analytics identify:@"a user's id"
                                traits:@{ @"email": @"fuscia" }];
```

The Identify method has these fields:

| Field               | Details                                                                                                                                                                                                          |
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `userId` *optional* | The database ID for this user. If you don't know who the user is yet, you can omit the `userId` and just record `traits`. You can read more in the [identify reference](/docs/segment/connections/spec/identify) |
| `traits` *optional* | A dictionary of traits you know about the user, like their `email` or `name`. You can read more about traits in the [identify reference](/docs/segment/connections/spec/identify).                               |

## Track

The [Track](/docs/segment/connections/spec/track/) method lets you record the actions your users perform. Every action triggers an event, which also has associated properties that the track method records.

## Method signature

```swift
func track(name: String)
// This signature provides a typed version of properties.
func track<P: Codable>(name: String, properties: P?)
```

## Swift

```swift
struct TrackProperties: Codable {
        let someValue: String
}

analytics.track(name: "My Event", properties: TrackProperties(someValue: "Hello"))
```

## Objective-C

```objc
[ self.analytics track:@"My Event"
                            properties:@{ @"someValue": @"Hello" }];
```

The Track method has these fields:

| Field                   | Details                                                                                                                                   |
| ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `name` *required*       | The name of the event. Segment recommends you to use human-readable names like *Song Played* or *Status Updated*.                         |
| `properties` *optional* | The structure of properties for the event. If the event was Product Added to cart, it may have properties like `price` and `productType`. |

## Screen

The [Screen](/docs/segment/connections/spec/screen/) method lets you record whenever a user sees a screen in your mobile app, along with optional extra information about the page being viewed.

You can record a Screen event whenever the user opens a screen in your app. This could be a view, fragment, dialog or activity depending on your app.

Not all integrations support Screen, so when it's not supported explicitly, the Screen method tracks as an event with the same parameters.

## Method signature

```swift
func screen(title: String, category: String? = nil)
func screen<P: Codable>(title: String, category: String? = nil, properties: P?)
```

## Swift

```swift
analytics.screen(title: "SomeScreen")
```

## Objective-C

```objc
[self.analytics screen:@"SomeScreen"
                            properties:@{ @"Feed Type": @"private" }];
```

The Screen method has these fields:

| Field                   | Details                                                                                                                  |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| `name` *required*       | The name of the screen, for example *Signup* or *Home*.                                                                  |
| `properties` *optional* | A dictionary of properties for the screen. A screen *Photo Feed* might have properties like `Feed Type` or `Sort Order`. |

You can enable automatic screen tracking by using this [example plugin](https://github.com/segmentio/analytics-swift/blob/main/Examples/other_plugins/UIKitScreenTracking.swift).

Once you add the plugin to your project, add it to your Analytics instance:

```swift
 analytics.add(plugin: UIKitScreenTracking())
```

## Group

The [Group](/docs/segment/connections/spec/group/) method lets you associate an individual user with a group — whether it's a company, organization, account, project, or team. This includes a unique group identifier and any additional group traits you may have, like company name, industry, or number of employees. You can include any information you want to associate with the group in the traits option. When using any of the [reserved group traits](/docs/segment/connections/spec/group/#traits), be sure the information reflects the name of the trait. For example, email should always be a string of the user's email address.

## Method signature

```swift
func group(groupId: String)
func group<T: Codable>(groupId: String, traits: T?)
```

## Swift

```swift
struct MyTraits: Codable {
        let username: String
        let email: String
        let plan: String
}

// ...

analytics.group(groupId: "group123", traits: MyTraits(
        username: "MisterWhiskers",
        email: "hello@test.com",
        plan: "premium"))
```

## Objective-C

```objc
[self.analytics group:@"group123"
traits:@{ @"name": @"MisterWhiskers", @"plan": @"premium" }];
```

The Group method has these fields:

| Field                | Details                                                                            |
| -------------------- | ---------------------------------------------------------------------------------- |
| `userId` *required*  | The ID for this user in your database.                                             |
| `groupId` *required* | The ID for this group in your database.                                            |
| `traits` *optional*  | A dictionary of traits you know about the group. Things like: `name` or `website`. |

## Alias

The [Alias](/docs/segment/connections/spec/alias/) method is used to merge two user identities, effectively connecting two sets of user data as one. When this method is called, the `newId` value overwrites the old `userId`. If no `userId` is currently set, the `newId` associates with future events as the `userId`. This is an advanced method and may not be supported across the entire destination catalog.

## Method signature

```swift
func alias(newId: String)
```

## Swift

```swift
analytics.alias(newId: "user-123")
```

## Objective-C

```objc
[self.analytics alias:@"some new id"];
```

The Alias call has the following fields:

| Field              | Details                                   |
| ------------------ | ----------------------------------------- |
| `newId` *required* | The newId of the user you want to map to. |

## Utility methods

The Analytics Swift utility methods help you work with [plugins](/docs/segment/connections/sources/catalog/libraries/mobile/apple/swift-plugin-architecture#plugin-architecture) from the analytics timeline. They include:

* [Add](#add)
* [Find](#find)
* [Remove](#remove)
* [Reset](#reset)

There's also the [Flush](#flush) method to help you manage the current queue of events.

## Add

The Add method allows you to add a plugin to the analytics timeline.

## Method signature

```swift
@discardableResult func add(plugin: Plugin) -> String
```

## Example use

```swift
analytics.add(plugin: UIKitScreenTracking(name: "ScreenTracking"))
```

## Find

The Find method lets you find a registered plugin from the analytics timeline.

## Method signature

```swift
func find<T: Plugin>(pluginType: T.Type) -> Plugin?
```

## Example use

```java
let plugin = analytics.find(SomePlugin.self)
```

## Remove

The Remove methods lets you remove a registered plugin from the analytics timeline.

## Method signature

```swift
func remove(plugin: Plugin)
```

## Example use

```swift
analytics.remove(somePluginInstance)
```

## Flush

The Flush method lets you force flush the current queue of events regardless of what the `flushAt` and `flushInterval` is set to.

## Method signature

```swift
public func flush()
```

## Example use

```swift
analytics.flush()
```

## Reset

The Reset method clears the SDK's internal stores for the current user and group. This is useful for apps where users log in and out with different identities on the same device over time.

## Method signature

```swift
public func reset()
```

## Example use

```swift
analytics.reset()
```

> \[!NOTE]
>
> The reset method doesn't clear the `userId` from connected client-side integrations. If you want to clear the `userId` from connected client-side destination plugins, you'll need to call the equivalent reset method for that library.

## OpenURL

Since there a various deep linking scenarios you may want to account for, the `analytics.openURL(...)` method was added so you can track deep links in any situation. Where and how you implement the method will depend on your app lifecycle setup (for example, UIApplicationDelegate vs. UISceneDelegate or UIKit vs. SwiftUI). The following snippets outline what your implementation might look like in a few different scenarios.

> \[!WARNING]
>
> `Analytics iOS` only captures the `UIApplicationDidFinishLaunchingNotification` notification.

**UIApplicationDelegate**

```swift
// captures if app is closed and launching
application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]?) -> Bool {
    // ...
    if let url = launchOptions?[.url] {
        analytics.openURL(url)
    }
}
// captures if an app was already open and returning to the foreground
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any]) -> Bool {
    analytics.openURL(url)
}
```

**UISceneDelegate**

```swift
// captures if app is closed and launching
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    // NOTE: There could be multiple URLs.  This example only handles the first one.
    if let url = connectionOptions.urlContexts.first?.url {
        analytics.openURL(url)
    }
}

// captures if an app was already open and returning to the foreground
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
    // NOTE: There could be multiple URLs.  This example only handles the first one.
    if let url = URLContexts.first?.url else {
        analytics.openURL(url)
    }
}
```

**SwiftUI**

```swift
// in the app's Scene code ...
var body: some Scene {
    WindowGroup {
        ContentView()
            .onOpenURL { url in
                analytics.openURL(url)
            }
        }
    }
}
```

If you call this method with a valid URL parameter, a Segment `Deep Link Opened` track event triggers.

## Configuration options

## anonymousIdGenerator

To generate custom anonymousIds instead of relying on the ones Segment creates, you can use the following configuration option:

```swift
class MyAnonymousIdGenerator: AnonymousIdGenerator {
  func newAnonymousId -> String {
    return UUID.uuidString
  }
}

// in the apps config:
let config = Configuration(writeKey: "WRITEKEY")
  .anonymousIdGenerator(MyAnonymousIdGenerator())

let analytics = Analytics(configuration: config)

```

## Changelog

[View the Analytics Swift changelog on GitHub](https://github.com/segmentio/analytics-swift/releases).
