> ## Documentation Index
> Fetch the complete documentation index at: https://launchdarkly-preview.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# iOS SDK 5.x to 6.0 migration guide for Swift

> This topic explains the API changes made in the iOS SDK 6 release and how to migrate to that version.

> For the complete documentation index, see [llms.txt](/llms.txt). For the full documentation snapshot, see [llms-full.txt](/llms-full.txt).

## Overview

This topic explains how to adapt Swift code that currently uses a 5.x version of the [iOS client-side SDK](/sdk/client-side/ios) to use version 6.0 or later.

Sections in this topic address different changes and updates between versions 5.x and 6.0 of the SDK.

## Understanding the new LDValue type

The 6.0 release of the iOS client-side SDK introduces a new type that represents a value of any valid JSON type: `LDValue`. To learn more about the new type, read the  [generated documentation](https://launchdarkly.github.io/ios-client-sdk/Enums/LDValue.html). The `LDValue` `enum` implements several `ExpressibleBy` protocols allowing constants to be created the same as other Swift types, as shown below.

<CodeGroup>
  ```swift title="6.0 syntax" theme={null}
      let nullValue: LDValue = nil
      let boolValue: LDValue = true
      let numericValue: LDValue = 5.5
      let stringValue: LDValue = "abc"
      let complexValue: LDValue = ["abc": 123, "def": [false, true]]
  ```
</CodeGroup>

## Understanding the changes to configuration

The `LDConfig` class only requires changes if the application specifies the `privateUserAttributes` property. The type of the property has changed from `[String]` to `[UserAttribute]`.

Here is an example that highlights the changes:

<CodeGroup>
  ```swift title="5.x syntax" theme={null}
      var config = LDConfig(mobileKey: "example-mobile-key")
      config.privateUserAttributes = ["name", "premium"]
  ```

  ```swift title="6.0 syntax" theme={null}
      var config = LDConfig(mobileKey: "example-mobile-key")
      config.privateUserAttributes = [UserAttribute.BuiltIn.name, UserAttribute.forName("premium")]
  ```
</CodeGroup>

Setting `"custom"` as a private attribute no longer sets all custom attributes private. Only the custom attribute with the key `"custom"` would be considered private by the SDK.

## Understanding the changes to creating users

Similarly to `LDConfig.privateUserAttributes`, `LDUser.privateAttributes` has been updated to use `UserAttribute`. Additionally `LDUser.custom` now user the `LDValue` type rather than `Any` for specifying the value of custom attributes.

Here is an example that highlights the changes:

<CodeGroup>
  ```swift title="5.x syntax" theme={null}
      let privateAttributes: [String] = ["name", "jobFunction"]
      let customAttributes: [String: Any] = ["jobFunction": ["doctor"]]
      let user = LDUser(key: "example-user-key", custom: customAttributes, privateAttributes: privateAttributes)
  ```

  ```swift title="6.0 syntax" theme={null}
      let privateAttributes: [UserAttribute] = [UserAttribute.BuiltIn.name, UserAttribute.forName("jobFunction")]
      let customAttributes: [String: LDValue] = ["jobFunction": ["doctor"]]
      let user = LDUser(key: "example-user-key", custom: customAttributes, privateAttributes: privateAttributes)
  ```
</CodeGroup>

The `Equatable` instance for `LDUser` has also changed. It now compares all properties, rather than only the `key` property.

<CodeGroup>
  ```swift title="5.x syntax" theme={null}
      let user1 = LDUser(key: "example-user-key", name: "Sandy Smith")
      let user2 = LDUser(key: "example-user-key", name: "Jesse Smith")
      // Results in true
      user1 == user2
  ```

  ```swift title="6.0 syntax" theme={null}
      let user1 = LDUser(key: "example-user-key", name: "Sandy Smith")
      let user2 = LDUser(key: "example-user-key", name: "Jesse Smith")
      // Results in false
      user1 == user2
  ```
</CodeGroup>

## Changes to variation functions

The iOS SDK now provides functions per-type for retrieving the variation for a given flag. To retrieve variation values that are complex (JSON arrays or objects), use the new `jsonVariation` function.

Here is an example:

<CodeGroup>
  ```swift title="5.x syntax" theme={null}
      let boolValue: Bool = LDClient.get()!.variation(forKey: "boolFlag", defaultValue: false)
      let arrayValue: [Any] = LDClient.get()!.variation(forKey: "arrayFlag", defaultValue: ["abc", "def"] as [Any])
  ```

  ```swift title="6.0 syntax" theme={null}
      let boolValue = LDClient.get()!.boolVariation(forKey: "boolFlag", defaultValue: false)
      let arrayValue = LDClient.get()!.jsonVariation(forKey: "arrayFlag", defaultValue: ["abc", "def"])
  ```
</CodeGroup>

## Changes to variation

Detail functions

The iOS SDK now provides function per-type for retrieving the detailed variation result for a given flag. To retrieve variation values that are complex, such as JSON arrays or objects, use the new `jsonVariation` function. The `reason` information associated with a `LDEvaluationDetail` has also changed from `[String: Any]?` to `[String: LDValue]?`.

Here is an example:

<CodeGroup>
  ```swift title="5.x syntax" theme={null}
      let boolValue: LDEvaluationDetail<Bool> = LDClient.get()!.variationDetail(forKey: "boolFlag", defaultValue: false)
      let arrayValue: LDEvaluationDetail<[Any]> = LDClient.get()!.variationDetail(forKey: "arrayFlag", defaultValue: ["abc", "def"] as [Any])
      let arrayReason: [String: Any]? = arrayValue.reason
  ```

  ```swift title="6.0 syntax" theme={null}
      let boolValue: LDEvaluationDetail<Bool> = LDClient.get()!.boolVariationDetail(forKey: "boolFlag", defaultValue: false)
      let arrayValue: LDEvaluationDetail<LDValue> = LDClient.get()!.jsonVariationDetail(forKey: "arrayFlag", defaultValue: ["abc", "def"])
      let arrayReason: [String: LDValue]? = arrayValue.reason
  ```
</CodeGroup>

## Recording custom events

If your application uses `track` to record `custom` events, remove `try` statements. This function no longer throws an error. Additionally, the `data` parameter type has changed from `Any?` to `LDValue?`. If your application provides the `data` parameter, you may need to update it to provide an `LDValue` type.

Here is an example:

<CodeGroup>
  ```swift title="5.x syntax" theme={null}
      do {
          let customData: Any = ["abc": 123]
          try LDClient.get()!.track(key: "key", data: customData)
      } catch let error as LDInvalidArgumentError {
          // Do something with the error
      } catch {}
  ```

  ```swift title="6.0 syntax" theme={null}
      let customData: LDValue = ["abc": 123]
      LDClient.get()!.track(key: "key", data: customData)
  ```
</CodeGroup>
