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

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

**Developer**

**Federal docs**

**EU docs**

This topic explains how to adapt Swift code that currently uses a 5.x version of the [iOS client-side SDK](https://launchdarkly.com/docs/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.

```swift title="6.0 syntax" lines wrap 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]]
```

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

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

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

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:

```swift title="5.x syntax" lines wrap 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" lines wrap 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)
```

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

```swift title="5.x syntax" lines wrap 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" lines wrap 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
```

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

```swift title="5.x syntax" lines wrap 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" lines wrap theme={null}
let boolValue = LDClient.get()!.boolVariation(forKey: "boolFlag", defaultValue: false)
let arrayValue = LDClient.get()!.jsonVariation(forKey: "arrayFlag", defaultValue: ["abc", "def"])
```

## Changes to variationDetail 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:

```swift title="5.x syntax" lines wrap 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" lines wrap 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
```

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

```swift title="5.x syntax" lines wrap 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" lines wrap theme={null}
let customData: LDValue = ["abc": 123]
LDClient.get()!.track(key: "key", data: customData)
```
