# OptiView Ads SDK on React Native

On React Native, the OptiView Ads SDK bridges the native Android and iOS SDKs behind a typed JavaScript API. All timing-sensitive break scheduling runs natively, so playback stays smooth regardless of the JavaScript thread's load.

## Prerequisites

1. Retrieve the channel's Break Manifest URL. See [Retrieving the required values](https://docs-preview.optiview.dolby.com/pr-894/ads/player-integration/optiview-ads-sdk.md#retrieving-the-required-values).
2. For [Google Pod Serving](https://docs-preview.optiview.dolby.com/pr-894/ads/integrations/google/pod-serving.md), have your Google Ad Manager `networkCode` and the channel's `customAssetKey` at hand.
3. Install the SDK and make its native dependencies resolvable for your platforms (see [Installation](#installation)).

## Installation

Install the SDK alongside your host player (`react-native-theoplayer` or `react-native-video`):

```bash
npm install @dolby-optiview/ads-sdk-react-native
```

The package requires React Native 0.76 or later with the new architecture (TurboModules / Fabric). It links the native Android and iOS/tvOS SDKs automatically; the only setup left is to make the native artifacts resolvable.

### Android

Add the THEOplayer Maven repository to the repositories in `android/build.gradle`, keeping Google and Maven Central:

```groovy
// android/build.gradle
allprojects {
    repositories {
        maven { url "https://maven.theoplayer.com/releases" }
        google()
        mavenCentral()
    }
}
```

### iOS and tvOS

Add the THEOplayer CocoaPods source next to the default one in your `Podfile`, then run `pod install`:

```ruby
source 'https://github.com/THEOplayer/cocoapods-specs.git'
source 'https://cdn.cocoapods.org/'
```

## Integration

Attach the SDK to your host player once it is ready, then start a session with the channel's Break Manifest URL. The example below uses the OptiView Player (`react-native-theoplayer`):

```tsx
import { THEOplayerView } from 'react-native-theoplayer';
import { createOptiViewAds } from '@dolby-optiview/ads-sdk-react-native';

const onPlayerReady = async (player) => {
  player.source = { sources: [{ src: CONTENT_URL, type: 'application/x-mpegurl' }] };
  const ads = createOptiViewAds(player, { gam: { networkCode: 'NETWORK-CODE' } });
  await ads.startSession({
    manifestUrl: 'https://us.markers.optiview.dolby.com/manifest/v1/ORG-ID/channels/CHANNEL-ID',
  });
};

<THEOplayerView config={{ license: THEOPLAYER_LICENSE }} onPlayerReady={onPlayerReady} />;
```

From this point the SDK polls the [Break Manifest](https://docs-preview.optiview.dolby.com/pr-894/ads/concepts/break-manifest.md), schedules the breaks against your player's timeline, plays the ads, and reports the impressions. To verify the integration, schedule a break through the API or dashboard and confirm that it plays out.

All configuration options, session settings, and ad events are documented in the [React Native API reference](https://docs-preview.optiview.dolby.com/pr-894/ads/v2/api-reference/react-native), starting from the [`createOptiViewAds`](https://docs-preview.optiview.dolby.com/pr-894/ads/v2/api-reference/react-native/variables/createOptiViewAds) function.

## Supported players

### OptiView Player (react-native-theoplayer)

The SDK attaches to a `THEOplayerView` through the `player` it hands to `onPlayerReady`; pass that player to `createOptiViewAds` as shown above.

**Limitations:**

* Requires a valid THEOplayer license.

### react-native-video

`react-native-video` does not expose its native player handle directly. Use the `useReactVideoHandle` hook: attach its `onVideoEvent` callback to the `<Video>` component's `onLoad`, and pass the `player` it returns to `createOptiViewAds` once it is defined:

```tsx
import Video from 'react-native-video';
import { createOptiViewAds, useReactVideoHandle } from '@dolby-optiview/ads-sdk-react-native';

const { player, onVideoEvent } = useReactVideoHandle();

useEffect(() => {
  if (!player) return;
  const ads = createOptiViewAds(player, { gam: { networkCode: 'NETWORK-CODE' } });
  void ads.startSession({ manifestUrl: MANIFEST_URL });
  return () => void ads.destroy();
}, [player]);

<Video source={{ uri: CONTENT_URL }} disableFocus onLoad={onVideoEvent} />;
```

**Limitations:**

* Requires `react-native-video` v6.
* On Android, set `RNVideo_useExoplayerIMA=true` in `android/gradle.properties` so `react-native-video` uses the real IMA integration instead of its stub classes, which conflict with the IMA SDK shipped by the OptiView runtime.
