> ## 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 Objective-C

<View title="Developer" />

<View title="Federal docs" />

<View title="EU docs" />

This topic explains how to adapt Objective-C code that currently uses a 5.x version of the [iOS client-side SDK](/docs/sdk/client-side/ios) to use version 6.0 or later. The sections in this topic address different changes and updates between versions 5.x and 6.0 of the SDK.

The Objective-C bridging types for the iOS SDK are implemented in Swift, where names are prefixed by `Objc`. This document refers to the types by the names exposed to Objective-C.

## 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, read the [generated documentation](https://launchdarkly.github.io/ios-client-sdk/Classes/ObjcLDValue.html). You can initialize the `LDValue` type with different types of values to support arbitrary JSON data.

Here is an example:

<CodeGroup>
  ```objectivec title="6.0 syntax" lines wrap theme={null}
  LDValue *nullValue = [LDValue ofNull];
  LDValue *boolValue = [LDValue ofBool:YES];
  LDValue *numericValue = [LDValue ofNumber:@5.5];
  LDValue *stringValue = [LDValue ofString:@"beta_testers"];
  LDValue *complexValue = [LDValue ofDict:@{@"groups": [LDValue ofArray:@[[LDValue ofBool:YES]]]}];
  ```
</CodeGroup>

## Understanding the changes to creating users

The `LDUser.custom` property has changed in type from `NSDictionary<NSString*, id> * _Nullable` to `NSDictionary<NSString*, LDValue*> * _Nonnull`.

Here is an example of the change:

<CodeGroup>
  ```objectivec title="5.x syntax" lines wrap theme={null}
  LDUser *user = [[LDUser alloc] initWithKey:@"example-user-key"];
  user.custom = @{@"group": @"beta"};
  ```

  ```objectivec title="6.0 syntax" lines wrap theme={null}
  LDUser *user = [[LDUser alloc] initWithKey:@"example-user-key"];
  user.custom = @{@"group": [LDValue ofString:@"beta"]};
  ```
</CodeGroup>

The `isEqual` function on `LDUser` has changed. It no longer only compares the `key` property, and now compares all properties of the instance.

<CodeGroup>
  ```objectivec title="5.x syntax" lines wrap theme={null}
  LDUser *user1 = [[LDUser alloc] initWithKey:@"example-user-key"];
  user1.name = @"Jane Smith";
  LDUser *user2 = [[LDUser alloc] initWithKey:@"example-user-key"];
  user2.name = @"John Smith";
  // Results in true
  [user1 isEqual:user2]
  ```

  ```objectivec title="6.0 syntax" lines wrap theme={null}
  LDUser *user1 = [[LDUser alloc] initWithKey:@"example-user-key"];
  user1.name = @"Jane Smith";
  LDUser *user2 = [[LDUser alloc] initWithKey:@"example-user-key"];
  user2.name = @"John Smith";
  // Results in false
  [user1 isEqual:user2]
  ```
</CodeGroup>

Setting `"custom"` as a private attribute no longer sets all custom attributes as private. The SDK considers only the custom attribute with the key `"custom"` as private.

## Changes to variation functions

The `LDClient` functions `arrayVariation` and `dictionaryVariation` have been removed. The new `jsonVariation` function lets you evaluate flags with any value type.

<CodeGroup>
  ```objectivec title="5.x syntax" lines wrap theme={null}
  NSArray *result = [[LDClient get] arrayVariationForKey:@"example-flag-key" defaultValue:@[]];
  ```

  ```objectivec title="6.0 syntax" lines wrap theme={null}
  LDValue* result = [[LDClient get] jsonVariationForKey:@"example-flag-key" defaultValue:[LDValue ofArray:@[]]];
  ```
</CodeGroup>

## Understanding changes to variationDetail functions

The `LDClient` functions `arrayVariationDetail` and `dictionaryVariationDetail` have been removed. The new `jsonVariationDetail` function allows evaluating flags with any resultant value type. The `LDJSONEvaluationDetail` type is used to store the resultant variation and detailed evaluation information.

The `reason` property of the detailed evaluation result types has also changed from `NSDictionary<NSString*, id> * _Nullable` to `NSDictionary<NSString*, LDValue*> * _Nullable`.

<CodeGroup>
  ```objectivec title="5.x syntax" lines wrap theme={null}
  LDArrayEvaluationDetail *result = [[LDClient get] arrayVariationDetailForKey:@"example-flag-key" defaultValue:@[]];
  NSArray* resultValue = result.value;
  NSDictionary<NSString*, id> *reason = result.reason;
  ```

  ```objectivec title="6.0 syntax" lines wrap theme={null}
  LDJSONEvaluationDetail *result = [[LDClient get] jsonVariationDetailForKey:@"example-flag-key" defaultValue:[LDValue ofArray:@[]]];
  LDValue* resultValue = result.value;
  NSDictionary<NSString*, LDValue*> *reason = result.reason;
  ```
</CodeGroup>

## Understanding the changes to flag value observers

The `LDClient` previously provided per-type functions for registering observers for flag values. These have been replaced with a single `observe` function you can use with flag variations of any JSON type.

<CodeGroup>
  ```objectivec title="5.x syntax" lines wrap theme={null}
  [[LDClient get] observeBool:@"example-flag-key" owner:self handler:^(LDBoolChangedFlag * _Nonnull changedFlag) {
      Bool newValue = changedFlag.newValue;
  }];
  ```

  ```objectivec title="6.0 syntax" lines wrap theme={null}
  [[LDClient get] observe:@"example-flag-key" owner:self handler:^(LDChangedFlag * _Nonnull changedFlag) {
      LDValue* newValue = changedFlag.newValue;
  }];
  ```
</CodeGroup>

## Recording custom events

If your application uses `track` to record `custom` events, you must remove the `error` parameter. The `track` functions no longer have the potential to error from invalid custom event data, because the `data` parameter is now restricted to the `LDValue` type. Change provided `data` types to `LDValue` instances.

Here is an example of the required changes:

<CodeGroup>
  ```objectivec title="5.x syntax" lines wrap theme={null}
  NSError* err = nil;
  NSDictionary* data = @{@"abc": @123};
  [[LDClient get] trackWithKey:@"key" data:data error:&err];
  if (err != nil) {
      // Do something with the error
  }
  ```

  ```objectivec title="6.0 syntax" lines wrap theme={null}
  LDValue* data = [LDValue ofDict:@{@"abc": [LDValue ofNumber:@123]}];
  [[LDClient get] trackWithKey: @"key" data:data];
  ```
</CodeGroup>
