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

<View title="Developer" />

<View title="Federal docs" />

<View title="EU docs" />

<Note>
  **Recent major versions**

  **Version 9 of the iOS SDK introduces optional automatic collection of environment attributes**. To learn more about upgrading, read [iOS SDK 8.x to 9.0 migration guide](/docs/sdk/client-side/ios/migration-8-to-9).
</Note>

This topic documents how to get started with the iOS SDK, and links to reference information on all of the supported features.

<Note>
  **SDK quick links**

  LaunchDarkly's SDKs are open source. In addition to this reference guide, we provide source, API reference documentation, and sample applications:

  <table>
    <thead>
      <tr>
        <th>Resource</th>
        <th>Location</th>
      </tr>
    </thead>

    <tbody>
      <tr>
        <td>SDK API documentation</td>
        <td>[SDK API docs](https://launchdarkly.github.io/ios-client-sdk/)</td>
      </tr>

      <tr>
        <td>Supported SDK Versions</td>
        <td>[iOS SDK](/docs/sdk/concepts/supported-versions#ios-sdk)</td>
      </tr>

      <tr>
        <td>GitHub repository</td>
        <td>[ios-client-sdk](https://github.com/launchdarkly/ios-client-sdk/)</td>
      </tr>

      <tr>
        <td>Sample applications</td>
        <td>[iOS (Objective-C)](https://github.com/launchdarkly/hello-ios)<br /> [iOS (Swift)](https://github.com/launchdarkly/hello-ios-swift) <br />[macOS](https://github.com/launchdarkly/hello-macos)<br />[tvOS](https://github.com/launchdarkly/hello-tvos)</td>
      </tr>

      <tr>
        <td>Published module</td>
        <td>[CocoaPods](https://cocoapods.org/pods/LaunchDarkly)</td>
      </tr>
    </tbody>
  </table>
</Note>

<Note>
  **SDK version compatibility**

  The LaunchDarkly iOS SDK, version 4.0.0 and higher, is compatible with applications written in either Swift or Objective-C. The inline code samples include both languages. The SDK is written in Swift.
</Note>

## Get started

After you complete the [Get started](/docs/home/getting-started) process, follow these instructions to start using the LaunchDarkly SDK in your application:

* [Install the SDK](#install-the-sdk)
* [Import the SDK](#import-the-sdk)
* [Initialize the client](#initialize-the-client)
* [Evaluate a flag](#evaluate-a-flag)

### Install the SDK

The first step is to install the LaunchDarkly SDK as a dependency in your application.

We recommend making the LaunchDarkly [observability plugin](/docs/sdk/observability) available as well. This plugin collects and sends observability data to LaunchDarkly. This means you can review error monitoring and logs from within the LaunchDarkly UI. It requires the iOS SDK version 9.14 or later, and is only available if you are using Swift.

LaunchDarkly supports multiple methods for installing the SDK. Each method is explained below.

<AccordionGroup>
  <Accordion title="Expand Use the Swift Package Manager">
    #### Use the Swift Package Manager

    If you use the [Swift Package Manager](https://swift.org/package-manager/), you can install the SDK through Xcode or include it as a dependency in your `Package.swift` file.

    To add a package dependency to your Xcode project, select "File," "Swift Packages," "Add Package Dependency" and enter the [iOS SDK repository URL](https://github.com/launchdarkly/ios-client-sdk) clone URL, then select your desired version constraints.

    Including the SDK as a dependency in a `Package.swift` file looks like this:

    <CodeGroup>
      ```swift title="Package.swift" lines wrap theme={null}
      //...
          dependencies: [
              .package(url: "https://github.com/launchdarkly/ios-client-sdk.git", .upToNextMinor("9.0.0")),
              // optional observability plugin, requires iOS SDK v9.14+
              .package(url: "https://github.com/launchdarkly/swift-launchdarkly-observability.git", .upToNextMajor("1.0.0")),
          ],
          targets: [
              .target(
                  name: "YOUR_TARGET",
                  dependencies: ["LaunchDarkly"]
              )
          ],
      //...
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Expand Use CocoaPods">
    #### Use CocoaPods

    If you use [CocoaPods](https://cocoapods.org/), you can install the SDK by adding the following to your `Podfile`. To identify the latest version, read the [SDK releases page](https://github.com/launchdarkly/ios-client-sdk/releases).

    Here is the code to add to your `Podfile`:

    <CodeGroup>
      ```ruby title="Podfile" lines wrap theme={null}
      use_frameworks!
      target 'YourTargetName' do
        pod 'LaunchDarkly', '~> 9.0'
        # optional observability plugin, requires iOS SDK v9.14+
        pod 'LaunchDarklyObservability', '~> 1.0'
      end
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Expand Use Carthage">
    #### Use Carthage

    If you use [Carthage](https://github.com/Carthage/Carthage), you can install the SDK by specifying it in your `Cartfile`. To identify the latest version, read the [SDK releases page](https://github.com/launchdarkly/ios-client-sdk/releases).

    Here is the code to include in your `Cartfile`:

    <CodeGroup>
      ```swift title="Cartfile" lines wrap theme={null}
      github "launchdarkly/ios-client" ~> 9.0
      // optional observability plugin, requires iOS SDK v9.14+
      github "launchdarkly/swift-launchdarkly-observability" ~> 1.0
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Expand Install the SDK manually">
    #### Install the SDK manually

    For instructions on installing the SDK without CocoaPods or Carthage, read the [SDK readme](https://github.com/launchdarkly/ios-client-sdk/blob/master/README.md).
  </Accordion>
</AccordionGroup>

### Import the SDK

After you install the SDK as a dependency, import the LaunchDarkly client in your application code:

<CodeGroup>
  ```swift title="Swift" lines wrap theme={null}
  import LaunchDarkly
  // optional observability plugin, requires iOS SDK v9.14+
  import LaunchDarklyObservability
  ```

  ```objectivec title="Objective-C" lines wrap theme={null}
  @import LaunchDarkly;
  ```
</CodeGroup>

### Initialize the client

After importing the SDK, configure and initialize the client. To do this, you need your environment's mobile key and the context for which you want to evaluate flags. This authorizes your application to connect to a particular environment within LaunchDarkly.

<Warning>
  **iOS SDK credentials**

  The iOS SDK uses a mobile key. Keys are specific to each project and environment. They are available on the **SDK keys** page under **Settings**. To learn more about key types, read [Keys](/docs/sdk/concepts/client-side-server-side#keys-and-credentials).

  Mobile keys are not secret and you can expose them in your client-side code without risk. However, never embed a server-side SDK key into a client-side application.
</Warning>

The following example shows how to configure the SDK, specify your mobile key, and initialize the client.

We recommend calling the client initialization method with a timeout of five seconds or fewer. The SDK provides a `timedOut` boolean to the `completion` closure, indicating whether the connection timed out.

Here's how:

<CodeGroup>
  ```swift title="iOS SDK v9.x (Swift)" expandable lines wrap theme={null}
  let config = LDConfig(mobileKey: "example-mobile-key", autoEnvAttributes: .enabled)
  // optional observability plugin, requires iOS SDK v9.14+
  config.plugins = [
        Observability(
            options: .init(
                resourceAttributes: [
                    "my-attribute": .string("new-value")
                ],
                isDebug: true,
                logs: .enabled,
                traces: .enabled,
                metrics: .enabled
            )
        )
    ]

  // You'll need this context later, but you can ignore it for now.
  let contextBuilder = LDContextBuilder(key: "example-context-key")
  guard case .success(let context) = contextBuilder.build()
  else { return }

  LDClient.start(config: config, context: context, startWaitSeconds: 5) { timedOut in
      if timedOut {
          // Client may not have the most recent flags for the configured context
      } else {
          // Client has received flags for the configured context
      }
  }
  ```

  ```objectivec title="iOS SDK v9.x (Objective-C)" lines wrap theme={null}
    LDConfig *config = [[LDConfig alloc] initWithMobileKey:@"example-mobile-key" autoEnvAttributes:AutoEnvAttributesEnabled];

    // You'll need this context later, but you can ignore it for now.
    LDContextBuilder *builder = [[LDContextBuilder alloc] initWithKey:@"example-context-key"];
    [builder kindWithKind:@"user"];
    [builder nameWithName:@"Sandy"];
    ContextBuilderResult *result = [builder build];

    [LDClient startWithConfiguration:config context:context startWaitSeconds:5.0 completion:^(BOOL timedOut) {
      if(timedOut) {
          // Client may not have the most recent flags for the configured context
      } else {
          // Client has received flags for the configured context
      }
    }];
  ```
</CodeGroup>

To learn more about the specific configuration options available in this SDK, read [`LDConfig`](https://launchdarkly.github.io/ios-client-sdk/Structs/LDConfig.html).

<Warning>
  **LDClient must be a singleton**

  It's important to make `LDClient` a singleton for each LaunchDarkly project. The client instance maintains internal state that allows LaunchDarkly to serve feature flags without making any remote requests. Do not instantiate a new client with every request.

  If you have multiple LaunchDarkly projects, you should use the multiple environments feature. To learn more, read [Multiple environments](/docs/sdk/features/multiple-environments#ios).
</Warning>

### Evaluate a flag

After calling `start`, you can retrieve the `LDClient` instance with the static method `LDClient.get()`:

<CodeGroup>
  ```swift title="Swift" lines wrap theme={null}
  let client = LDClient.get()!
  ```

  ```objectivec title="Objective-C" lines wrap theme={null}
  LDClient *client = [LDClient get];
  ```
</CodeGroup>

Then, use the `client` to check which variation a particular context will receive for a given feature flag.

Here's how:

<CodeGroup>
  ```swift title="Swift" lines wrap theme={null}
  let showFeature = client.boolVariation(forKey: "example-flag-key", defaultValue: false)

  if showFeature {
    // Application code to show the feature
  } else {
    // The code to run if the feature is off
  }
  ```

  ```objectivec title="Objective-C" lines wrap theme={null}
  BOOL showFeature = [client boolVariationForKey:@"example-flag-key" defaultValue:NO];
  if (showFeature) {
      // Application code to show the feature
  } else {
      // The code to run if the feature is off
  }
  ```
</CodeGroup>

<Warning>
  **Making feature flags available to this SDK**

  You must make feature flags available to mobile SDKs before the SDK can evaluate those flags. If an SDK tries to evaluate a feature flag that is not available, the context will receive the fallback value for that flag.

  To make a flag available to this SDK, check the **SDKs using Mobile key** checkbox during flag creation, or toggle on the option in the flag's right sidebar. To make all of a project's flags available to this SDK by default, check the **SDKs using Mobile key** checkbox on your project's [Flag settings page](/docs/home/account/edit-project).
</Warning>

## Background fetch

When the app is backgrounded, the SDK does not receive real-time events.

Unlike other mobile SDKs, the iOS SDK does not support background fetch, so devices on the iOS operating system will not fetch flags from the background. However, devices on MacOS will update flag values opportunistically, according to the iOS SDK standard background polling defaults.

To change the background polling default for flags in your app, add the following code in your `LDConfig`:

<CodeGroup>
  ```swift title="iOS SDK v9.0 (Swift)" lines wrap theme={null}
  var ldConfig = LDConfig(mobileKey: "example-mobile-key", autoEnvAttributes: .enabled)
  ldConfig.backgroundFlagPollingInterval = 3600
  ```

  ```objectivec title="iOS SDK v9.0 (Objective-C)" lines wrap theme={null}
  LDConfig *config = [[LDConfig alloc] initWithMobileKey:@"example-mobile-key", autoEnvAttributes:AutoEnvAttributesEnabled];
  config.backgroundFlagPollingInterval = 3600;
  ```
</CodeGroup>

## Shut down the client

Shut down the client when your application terminates. To learn more, read [Shutting down](/docs/sdk/features/shutdown#ios).

## Data collection

The data collected by the iOS SDK persists until the number of cached contexts exceeds a limit. When you call `identify`, the number of cached contexts increments. Eventually, the number of cached contexts exceeds `maxCachedContexts`. When that happens, the SDK deletes context data in excess of `maxCachedContexts`, starting with the oldest context first. To learn more, read [Caching contexts to local storage](/docs/sdk/features/local-storage).

To learn more about data collection within this SDK and implications on submissions to the Apple App Store, read the [Apple App Store data collection policy](/docs/sdk/concepts/apple-app-store).

## Supported features

This SDK supports the following features:

* [SDK configuration](/docs/sdk/features/config#ios), including
  * [Application metadata configuration](/docs/sdk/features/app-config#ios)
  * [Service endpoint configuration](/docs/sdk/features/service-endpoint-configuration#ios)
* [Anonymous contexts and users](/docs/sdk/features/anonymous#ios)
* [Automatic environment attributes](/docs/sdk/features/environment-attributes#ios)
* [Caching contexts to local storage](/docs/sdk/features/local-storage#ios)
* [Context configuration](/docs/sdk/features/context-config#ios)
* [Experimentation](/docs/sdk/features/experimentation#ios)
* [Flag variation evaluation](/docs/sdk/features/evaluating#ios)
* [Flag variation evaluation details](/docs/sdk/features/evaluation-reasons#ios)
* [Flushing events](/docs/sdk/features/flush#ios)
* [Getting all flags](/docs/sdk/features/all-flags#ios)
* [Hooks](/docs/sdk/features/hooks#ios)
* [Identifying and changing contexts](/docs/sdk/features/identify#ios)
* [Logging configuration](/docs/sdk/features/logging#ios)
* [Monitoring SDK status](/docs/sdk/features/monitoring#ios)
* [Multiple environments](/docs/sdk/features/multiple-environments#ios)
* [Observability](/docs/sdk/observability/ios)
* [Offline mode](/docs/sdk/features/offline-mode#ios)
* [Private attributes](/docs/sdk/features/private-attributes#ios)
* [Relay Proxy configuration, using proxy mode](/docs/sdk/features/relay-proxy-configuration/proxy-mode#ios)
* [Tracking custom events](/docs/sdk/features/events#ios)
* [Shutting down](/docs/sdk/features/shutdown#ios)
* [Subscribing to flag changes](/docs/sdk/features/flag-changes#ios)
