diff --git a/.github/workflows/pr_ios.yml b/.github/workflows/pr_ios.yml
index 8912f231..e4754129 100644
--- a/.github/workflows/pr_ios.yml
+++ b/.github/workflows/pr_ios.yml
@@ -69,7 +69,7 @@ jobs:
- name: Run pod install & update dependencies
working-directory: apps/e2e/ios
run: |
- RCT_NEW_ARCH_ENABLED=${{ matrix.newArchEnabled }} bundle exec pod install
+ RCT_NEW_ARCH_ENABLED=${{ matrix.newArchEnabled }} bundle exec pod update
- name: Start iOS simulator
uses: futureware-tech/simulator-action@v4
diff --git a/README.md b/README.md
index 6f10153a..9d6722b1 100644
--- a/README.md
+++ b/README.md
@@ -15,8 +15,10 @@ the official THEOplayer React Native video player.
| Content protection (DRM) | [](https://www.npmjs.com/package/%40theoplayer%2Freact-native-drm) | [`DRM`](https://github.com/THEOplayer/react-native-connectors/tree/main/drm) |
| Conviva analytics | [](https://www.npmjs.com/package/%40theoplayer%2Freact-native-analytics-conviva) | [`Conviva`](https://github.com/THEOplayer/react-native-connectors/tree/main/conviva) |
| Engage | [](https://www.npmjs.com/package/%40theoplayer%2Freact-native-engage) | [`Engage`](https://github.com/THEOplayer/react-native-connectors/tree/main/engage) |
+| Gemius | [](https://www.npmjs.com/package/%40theoplayer%2Freact-native-analytics-engage) | [`Gemius`](https://github.com/THEOplayer/react-native-connectors/tree/main/engage) |
| Mux analytics | [](https://www.npmjs.com/package/%40theoplayer%2Freact-native-analytics-mux) | [`Mux`](https://github.com/THEOplayer/react-native-connectors/tree/main/mux) |
| Nielsen analytics | [](https://www.npmjs.com/package/%40theoplayer%2Freact-native-analytics-nielsen) | [`Nielsen`](https://github.com/THEOplayer/react-native-connectors/tree/main/nielsen) |
+| Nielsen AdScript analytics | [](https://www.npmjs.com/package/%40theoplayer%2Freact-native-analytics-adscript) | [`AdScript`](https://github.com/THEOplayer/react-native-connectors/tree/main/adscript) |
| Yospace SSAI | [](https://www.npmjs.com/package/%40theoplayer%2Freact-native-yospace) | [`Yospace`](https://github.com/THEOplayer/react-native-connectors/tree/main/yospace) |
| Youbora analytics | [](https://www.npmjs.com/package/%40theoplayer%2Freact-native-analytics-youbora) | [`Youbora`](https://github.com/THEOplayer/react-native-connectors/tree/main/youbora) |
diff --git a/adscript/.gitignore b/adscript/.gitignore
new file mode 100644
index 00000000..75356714
--- /dev/null
+++ b/adscript/.gitignore
@@ -0,0 +1,70 @@
+# OSX
+#
+.DS_Store
+
+# XDE
+.expo/
+
+# VSCode
+.vscode/
+jsconfig.json
+
+# Xcode
+#
+build/
+*.pbxuser
+!default.pbxuser
+*.mode1v3
+!default.mode1v3
+*.mode2v3
+!default.mode2v3
+*.perspectivev3
+!default.perspectivev3
+xcuserdata
+*.xccheckout
+*.moved-aside
+DerivedData
+*.hmap
+*.ipa
+*.xcuserstate
+project.xcworkspace
+
+# Android/IJ
+#
+.classpath
+.cxx
+.gradle
+.idea
+.project
+.settings
+local.properties
+android.iml
+
+# Cocoapods
+#
+example/ios/Pods
+
+# Ruby
+example/vendor/
+
+# node.js
+#
+node_modules/
+npm-debug.log
+yarn-debug.log
+yarn-error.log
+
+# BUCK
+buck-out/
+\.buckd/
+android/app/libs
+android/keystores/debug.keystore
+
+# Expo
+.expo/
+
+# Turborepo
+.turbo/
+
+# generated by bob
+lib/
diff --git a/adscript/CHANGELOG.md b/adscript/CHANGELOG.md
new file mode 100644
index 00000000..b6f31266
--- /dev/null
+++ b/adscript/CHANGELOG.md
@@ -0,0 +1,7 @@
+# @theoplayer/react-native-analytics-adscript
+
+## 1.0.0
+
+### ✨ Features
+
+- Initial release
diff --git a/adscript/README.md b/adscript/README.md
new file mode 100644
index 00000000..783d77f5
--- /dev/null
+++ b/adscript/README.md
@@ -0,0 +1,123 @@
+# THEOplayer React-Native AdScript Connector
+
+A [Nielsen AdScript](https://adscript.admosphere.cz/) analytics connector for `@theoplayer/react-native`.
+
+## Installation
+
+```sh
+npm install @theoplayer/react-native-analytics-adscript
+```
+
+[//]: # (npm install @theoplayer/react-native-analytics-adscript)
+
+## Prerequisites
+
+### Android
+
+On Android, the connector requires downloading the private
+[AdScript client library](https://adscript.admosphere.cz/download/AdScriptApiClient_v1.0.10.aar.gz)
+module into the app's `libs/` folder. Pass the SDK location to the connector
+by setting the `adScriptSdkDir` in your app's `gradle.properties` file:
+
+```bash
+# Location of the AdScript SDK
+adScriptSdkDir=./app/libs/
+```
+
+### iOS & tvOS
+
+On Apple platforms, the connector requires downloading the private `AdScriptAPIClient` archive.
+
+Create a `Frameworks` folder in your app's `ios` folder, copy the Adscript SDK XCFramework in it
+and add this `AdScriptApiClient.podspec` file inside, which describes the structure and metadata of Adscript's CocoaPod:
+
+```ruby
+Pod::Spec.new do |spec|
+ spec.name = "AdScriptApiClient"
+ spec.version = "1.0.8"
+ spec.summary = "The Adscript Api Client for iOS"
+
+ spec.homepage = 'https://github.com/THEOplayer/iOS-Connector'
+ spec.license = { :type => 'MIT', :file => 'LICENSE' }
+ spec.author = "THEO technologies"
+ spec.source = { :git => 'https://github.com/THEOplayer/iOS-Connector.git', :tag => spec.version.to_s }
+
+ spec.source_files = "Classes", "Classes/**/*.{h,m}"
+ spec.ios.vendored_frameworks = "AdScriptApiClient.xcframework"
+end
+```
+
+To enable IDFA (Identifier for Advertisers), replace the framework reference:
+
+```
+spec.ios.vendored_frameworks = "AdScriptApiClient.xcframework"
+```
+
+with
+
+```
+spec.ios.vendored_frameworks = "AdScriptApiClient_withidfa.xcframework"
+```
+
+Finally, include the AdScript SDK as dependency in your app's `Podfile`:
+
+```ruby
+ pod 'AdScriptApiClient', :path => 'Frameworks/'
+```
+
+## Usage
+
+### Configuring the connector
+
+Create the connector by providing the `THEOplayer` instance, an `implementationId`, and a `metadata` object.
+
+```tsx
+import { useAdScript, AdScriptMetadata } from '@theoplayer/react-native-analytics-adscript';
+
+const adscriptImplementationId = "myImplementionId";
+const adscriptContentMetadata: AdScriptMetadata = {
+ assetId: "abc98731568435405",
+ type: "content"
+};
+
+const App = () => {
+ const [adscript, initAdScript] = useAdScript(adscriptImplementationId, adscriptContentMetadata, true /*debug*/);
+
+ const onPlayerReady = (player: THEOplayer) => {
+ // Initialize AdScript connector
+ initAdScript(player);
+ };
+
+ return ;
+};
+```
+
+### Passing metadata dynamically
+
+The connector allows passing or updating the current asset's metadata at any time:
+
+```typescript
+const onUpdateMetadata = () => {
+ adscript.current?.updateMetadata({
+ assetId: 'updatedId',
+ type: "content",
+ // ...
+ });
+}
+```
+
+### Passing additional information
+
+Additional information about the logged-in user from the client database:
+
+```typescript
+const onUpdateUser = () => {
+ adscript.current?.updateUser([
+ "866d3a3c-aa87-4fe7-9066-8286641edd17", // client-side user identifier (customerId)
+ "cf895a00-a987-4501-ac00-6adb57014129", // client-side user device identifier (Android_ID)
+ "9530321a-d3d0-4bda-8704-1eb94a5940c3", // client-side profile identifier of the logged-in user (profileId)
+ "jsg75682-k276t-kw82-k8d5-8926sh6528j2", // optional - SW device identifier for a situation where there are multiple device IDs in the client DB (typically a) HW ID - fill in i2, b) SW ID - fill in i4).
+ "ef3c6dc72a26912f07f0e733d51b46c771d807bf" // fingerprint of the user's email address
+ ]);
+}
+```
diff --git a/adscript/android/build.gradle b/adscript/android/build.gradle
new file mode 100644
index 00000000..969bfdd4
--- /dev/null
+++ b/adscript/android/build.gradle
@@ -0,0 +1,125 @@
+import java.util.zip.GZIPInputStream
+
+buildscript {
+ // Buildscript is evaluated before everything else so we can't use getExtOrDefault
+ def kotlin_version = rootProject.ext.has("kotlinVersion") ? rootProject.ext.get("kotlinVersion") : '1.9.10'
+
+ repositories {
+ google()
+ mavenCentral()
+ }
+
+ dependencies {
+ classpath "com.android.tools.build:gradle:7.2.2"
+ // noinspection DifferentKotlinGradleVersion
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+ }
+}
+
+def isNewArchitectureEnabled() {
+ return rootProject.hasProperty("newArchEnabled") && rootProject.getProperty("newArchEnabled") == "true"
+}
+
+apply plugin: 'com.android.library'
+apply plugin: 'kotlin-android'
+
+if (isNewArchitectureEnabled()) {
+ apply plugin: "com.facebook.react"
+}
+
+def safeExtGet(prop, fallback) {
+ rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
+}
+
+android {
+ namespace = "com.theoplayer.reactnative.adscript"
+ compileSdkVersion safeExtGet("THEOplayerAdScript_compileSdkVersion", 35)
+
+ defaultConfig {
+ minSdkVersion safeExtGet("THEOplayerAdScript_minSdkVersion", 21)
+ targetSdkVersion safeExtGet("THEOplayerAdScript_targetSdkVersion", 35)
+ buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
+ versionCode 1
+ versionName "1.0"
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ }
+ }
+
+ lintOptions {
+ disable "GradleCompatible"
+ }
+
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+}
+
+repositories {
+ mavenLocal()
+ google()
+ mavenCentral()
+ // Local Maven repo
+ maven { url("local") }
+ maven { url "https://maven.theoplayer.com/releases" }
+}
+
+rootProject.allprojects {
+ repositories {
+ maven { url("$rootDir/../node_modules/@theoplayer/react-native-analytics-adscript/android/local") }
+ }
+}
+
+// The AdScript connector requires at least THEOplayer SDK v5.11.0.
+def theoplayer_sdk_version = safeExtGet('THEOplayer_sdk', '[5.11.0, 10.0.0)')
+def kotlin_version = safeExtGet("THEOplayerAdScript_kotlinVersion", "1.9.10")
+def adscript_version = safeExtGet("THEOplayerAdScript_adscriptVersion", "1.0.10")
+
+dependencies {
+ // For < 0.71, this will be from the local maven repo
+ // For > 0.71, this will be replaced by `com.facebook.react:react-android:$version` by react gradle plugin
+ //noinspection GradleDynamicVersion
+ implementation "com.facebook.react:react-native"
+ implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
+ implementation 'androidx.lifecycle:lifecycle-process:2.5.1'
+
+ // THEOplayer dependencies
+ compileOnly "com.theoplayer.theoplayer-sdk-android:core:$theoplayer_sdk_version"
+ compileOnly "com.theoplayer.theoplayer-sdk-android:integration-ads-ima:$theoplayer_sdk_version"
+ implementation project(':react-native-theoplayer')
+
+ // TEMP: replace this once the native connector has been published
+// implementation "com.theoplayer.android-connector:adscript:$adscript_version"
+ implementation files("./libs/adscript.aar")
+ def aarFileName = "AdScriptApiClient_v${adscript_version}.aar"
+ def adScriptSdkDir = rootProject.properties['adScriptSdkDir']
+ if (!adScriptSdkDir) {
+ logger.warn("⚠️ WARNING: adScriptSdkDir not set.")
+ } else if (!rootProject.file(adScriptSdkDir).exists()) {
+ logger.warn("⚠️ WARNING: adScriptSdkDir does not exist at: ${adScriptSdkDir}")
+ } else {
+ def aarFile = new File(adScriptSdkDir, aarFileName)
+
+ // The AdScript aar file is typically provided as .gz, check if we still need to extract.
+ def gzFile = new File("${aarFile}.gz")
+ if (!aarFile.exists() && gzFile.exists()) {
+ new FileInputStream(gzFile).withCloseable { fis ->
+ new GZIPInputStream(fis).withCloseable { gis ->
+ new FileOutputStream(aarFile).withCloseable { fos ->
+ fos << gis
+ }
+ }
+ }
+ }
+ dependencies {
+ implementation fileTree(dir: "${rootProject.file(adScriptSdkDir)}/$aarFileName", include: ['*.aar', '*.jar'], exclude: [])
+ }
+ }
+
+ // Align the Kotlin SDK libraries with the same version.
+ implementation(platform("org.jetbrains.kotlin:kotlin-bom:$kotlin_version"))
+}
diff --git a/adscript/android/gradle/wrapper/gradle-wrapper.jar b/adscript/android/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 00000000..41d9927a
Binary files /dev/null and b/adscript/android/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/adscript/android/gradle/wrapper/gradle-wrapper.properties b/adscript/android/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 00000000..2733ed5d
--- /dev/null
+++ b/adscript/android/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/adscript/android/gradlew b/adscript/android/gradlew
new file mode 100755
index 00000000..1b6c7873
--- /dev/null
+++ b/adscript/android/gradlew
@@ -0,0 +1,234 @@
+#!/bin/sh
+
+#
+# Copyright © 2015-2021 the original authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+#
+# Gradle start up script for POSIX generated by Gradle.
+#
+# Important for running:
+#
+# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
+# noncompliant, but you have some other compliant shell such as ksh or
+# bash, then to run this script, type that shell name before the whole
+# command line, like:
+#
+# ksh Gradle
+#
+# Busybox and similar reduced shells will NOT work, because this script
+# requires all of these POSIX shell features:
+# * functions;
+# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
+# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
+# * compound commands having a testable exit status, especially «case»;
+# * various built-in commands including «command», «set», and «ulimit».
+#
+# Important for patching:
+#
+# (2) This script targets any POSIX shell, so it avoids extensions provided
+# by Bash, Ksh, etc; in particular arrays are avoided.
+#
+# The "traditional" practice of packing multiple parameters into a
+# space-separated string is a well documented source of bugs and security
+# problems, so this is (mostly) avoided, by progressively accumulating
+# options in "$@", and eventually passing that to Java.
+#
+# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
+# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
+# see the in-line comments for details.
+#
+# There are tweaks for specific operating systems such as AIX, CygWin,
+# Darwin, MinGW, and NonStop.
+#
+# (3) This script is generated from the Groovy template
+# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+# within the Gradle project.
+#
+# You can find Gradle at https://github.com/gradle/gradle/.
+#
+##############################################################################
+
+# Attempt to set APP_HOME
+
+# Resolve links: $0 may be a link
+app_path=$0
+
+# Need this for daisy-chained symlinks.
+while
+ APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
+ [ -h "$app_path" ]
+do
+ ls=$( ls -ld "$app_path" )
+ link=${ls#*' -> '}
+ case $link in #(
+ /*) app_path=$link ;; #(
+ *) app_path=$APP_HOME$link ;;
+ esac
+done
+
+APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
+
+APP_NAME="Gradle"
+APP_BASE_NAME=${0##*/}
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD=maximum
+
+warn () {
+ echo "$*"
+} >&2
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+} >&2
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "$( uname )" in #(
+ CYGWIN* ) cygwin=true ;; #(
+ Darwin* ) darwin=true ;; #(
+ MSYS* | MINGW* ) msys=true ;; #(
+ NONSTOP* ) nonstop=true ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD=$JAVA_HOME/jre/sh/java
+ else
+ JAVACMD=$JAVA_HOME/bin/java
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD=java
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
+ case $MAX_FD in #(
+ max*)
+ MAX_FD=$( ulimit -H -n ) ||
+ warn "Could not query maximum file descriptor limit"
+ esac
+ case $MAX_FD in #(
+ '' | soft) :;; #(
+ *)
+ ulimit -n "$MAX_FD" ||
+ warn "Could not set maximum file descriptor limit to $MAX_FD"
+ esac
+fi
+
+# Collect all arguments for the java command, stacking in reverse order:
+# * args from the command line
+# * the main class name
+# * -classpath
+# * -D...appname settings
+# * --module-path (only if needed)
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if "$cygwin" || "$msys" ; then
+ APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
+ CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
+
+ JAVACMD=$( cygpath --unix "$JAVACMD" )
+
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ for arg do
+ if
+ case $arg in #(
+ -*) false ;; # don't mess with options #(
+ /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
+ [ -e "$t" ] ;; #(
+ *) false ;;
+ esac
+ then
+ arg=$( cygpath --path --ignore --mixed "$arg" )
+ fi
+ # Roll the args list around exactly as many times as the number of
+ # args, so each arg winds up back in the position where it started, but
+ # possibly modified.
+ #
+ # NB: a `for` loop captures its iteration list before it begins, so
+ # changing the positional parameters here affects neither the number of
+ # iterations, nor the values presented in `arg`.
+ shift # remove old arg
+ set -- "$@" "$arg" # push replacement arg
+ done
+fi
+
+# Collect all arguments for the java command;
+# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
+# shell script including quotes and variable substitutions, so put them in
+# double quotes to make sure that they get re-expanded; and
+# * put everything else in single quotes, so that it's not re-expanded.
+
+set -- \
+ "-Dorg.gradle.appname=$APP_BASE_NAME" \
+ -classpath "$CLASSPATH" \
+ org.gradle.wrapper.GradleWrapperMain \
+ "$@"
+
+# Use "xargs" to parse quoted args.
+#
+# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
+#
+# In Bash we could simply go:
+#
+# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
+# set -- "${ARGS[@]}" "$@"
+#
+# but POSIX shell has neither arrays nor command substitution, so instead we
+# post-process each arg (as a line of input to sed) to backslash-escape any
+# character that might be a shell metacharacter, then use eval to reverse
+# that process (while maintaining the separation between arguments), and wrap
+# the whole thing up as a single "set" statement.
+#
+# This will of course break if any of these variables contains a newline or
+# an unmatched quote.
+#
+
+eval "set -- $(
+ printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
+ xargs -n1 |
+ sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
+ tr '\n' ' '
+ )" '"$@"'
+
+exec "$JAVACMD" "$@"
diff --git a/adscript/android/gradlew.bat b/adscript/android/gradlew.bat
new file mode 100644
index 00000000..107acd32
--- /dev/null
+++ b/adscript/android/gradlew.bat
@@ -0,0 +1,89 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/adscript/android/libs/adscript.aar b/adscript/android/libs/adscript.aar
new file mode 100644
index 00000000..ff3cffb7
Binary files /dev/null and b/adscript/android/libs/adscript.aar differ
diff --git a/adscript/android/src/main/AndroidManifest.xml b/adscript/android/src/main/AndroidManifest.xml
new file mode 100644
index 00000000..cc947c56
--- /dev/null
+++ b/adscript/android/src/main/AndroidManifest.xml
@@ -0,0 +1 @@
+
diff --git a/adscript/android/src/main/java/com/theoplayer/reactnative/adscript/ReactTHEOplayerAdScriptModule.kt b/adscript/android/src/main/java/com/theoplayer/reactnative/adscript/ReactTHEOplayerAdScriptModule.kt
new file mode 100644
index 00000000..d826269f
--- /dev/null
+++ b/adscript/android/src/main/java/com/theoplayer/reactnative/adscript/ReactTHEOplayerAdScriptModule.kt
@@ -0,0 +1,94 @@
+package com.theoplayer.reactnative.adscript
+
+import android.util.Log
+import com.facebook.react.bridge.*
+import com.theoplayer.ReactTHEOplayerView
+import com.theoplayer.android.api.THEOplayerView
+import com.theoplayer.android.connector.analytics.adscript.AdscriptConfiguration
+import com.theoplayer.android.connector.analytics.adscript.AdscriptConnector
+import com.theoplayer.util.ViewResolver
+import com.nad.adscriptapiclient.AdScriptDataObject
+import com.nad.adscriptapiclient.AdScriptI12n
+import org.json.JSONException
+
+private const val TAG = "AdScriptModule"
+
+class ReactTHEOplayerAdScriptModule(context: ReactApplicationContext) :
+ ReactContextBaseJavaModule(context) {
+
+ private val viewResolver: ViewResolver = ViewResolver(context)
+
+ private var adscriptConnectors: HashMap = HashMap()
+
+ override fun getName(): String {
+ return TAG
+ }
+
+ @ReactMethod
+ fun initialize(tag: Int, implementationId: String, contentMetadata: ReadableMap, debug: Boolean) {
+ viewResolver.resolveViewByTag(tag) { view: ReactTHEOplayerView? ->
+ view?.playerContext?.playerView?.let { playerView ->
+ adscriptConnectors[tag] =
+ initializeAdScript(playerView, implementationId, contentMetadata, debug)
+ }
+ }
+ }
+
+ private fun initializeAdScript(
+ view: THEOplayerView,
+ implementationId: String,
+ contentMetadata: ReadableMap,
+ debug: Boolean
+ ): AdscriptConnector {
+ return AdscriptConnector(
+ activity = reactApplicationContext.currentActivity!!,
+ playerView = view,
+ configuration = AdscriptConfiguration(implementationId, debug),
+ contentMetadata = buildContentMetadata(contentMetadata),
+ adProcessor = null)
+ }
+
+ private fun buildContentMetadata(contentMetadata: ReadableMap): AdScriptDataObject {
+ return AdScriptDataObject().apply {
+ for (entry in contentMetadata.toHashMap().entries) {
+ try {
+ when (entry.value) {
+ is String -> set(entry.key, entry.value as String)
+ is Boolean -> set(entry.key, entry.value as Boolean)
+ is Int -> set(entry.key, entry.value as Int)
+ is Long -> set(entry.key, entry.value as Long)
+ }
+ } catch (e: Exception) {
+ Log.e(TAG, "Failed to add contentMetadata value ${entry.key}: ${e.message}")
+ }
+ }
+ }
+ }
+
+ private fun buildUser(user: ReadableArray): AdScriptI12n {
+ return AdScriptI12n().apply {
+ try {
+ for (i in 0 until user.size()) {
+ set(i, user.getString(i))
+ }
+ } catch (e: JSONException) {
+ Log.e(TAG, "Failed to build user: ${e.message}")
+ }
+ }
+ }
+
+ @ReactMethod
+ fun updateMetadata(tag: Int, contentMetadata: ReadableMap) {
+ adscriptConnectors[tag]?.updateMetadata(buildContentMetadata(contentMetadata))
+ }
+
+ @ReactMethod
+ fun updateUser(tag: Int, user: ReadableArray) {
+ adscriptConnectors[tag]?.updateUser(buildUser(user))
+ }
+
+ @ReactMethod
+ fun destroy(tag: Int) {
+ adscriptConnectors[tag]?.destroy()
+ }
+}
diff --git a/adscript/android/src/main/java/com/theoplayer/reactnative/adscript/ReactTHEOplayerAdScriptPackage.kt b/adscript/android/src/main/java/com/theoplayer/reactnative/adscript/ReactTHEOplayerAdScriptPackage.kt
new file mode 100644
index 00000000..1ced5e35
--- /dev/null
+++ b/adscript/android/src/main/java/com/theoplayer/reactnative/adscript/ReactTHEOplayerAdScriptPackage.kt
@@ -0,0 +1,16 @@
+package com.theoplayer.reactnative.adscript
+
+import com.facebook.react.ReactPackage
+import com.facebook.react.bridge.NativeModule
+import com.facebook.react.bridge.ReactApplicationContext
+import com.facebook.react.uimanager.ViewManager
+
+class ReactTHEOplayerAdScriptPackage : ReactPackage {
+ override fun createNativeModules(reactContext: ReactApplicationContext): List {
+ return listOf(ReactTHEOplayerAdScriptModule(reactContext))
+ }
+
+ override fun createViewManagers(reactContext: ReactApplicationContext): List> {
+ return emptyList()
+ }
+}
diff --git a/adscript/babel.config.js b/adscript/babel.config.js
new file mode 100644
index 00000000..f842b77f
--- /dev/null
+++ b/adscript/babel.config.js
@@ -0,0 +1,3 @@
+module.exports = {
+ presets: ['module:metro-react-native-babel-preset'],
+};
diff --git a/adscript/ios/Source/AdScriptConnector.swift b/adscript/ios/Source/AdScriptConnector.swift
new file mode 100644
index 00000000..d29e694d
--- /dev/null
+++ b/adscript/ios/Source/AdScriptConnector.swift
@@ -0,0 +1,37 @@
+import THEOplayerSDK
+#if canImport(AdScriptApiClient)
+import AdScriptApiClient
+#endif
+
+public struct AdScriptConfiguration {
+ let implementationId: String
+ let debug: Bool
+
+ public init(implementationId: String, debug: Bool) {
+ self.implementationId = implementationId
+ self.debug = debug
+ }
+}
+
+public struct AdScriptConnector {
+ private let adapter: AdScriptAdapter
+ private let player: THEOplayer
+
+
+ public init(configuration: AdScriptConfiguration, player: THEOplayer, metadata: AdScriptDataObject) {
+ self.player = player
+ self.adapter = AdScriptAdapter(configuration: configuration, player: player, metadata: metadata)
+ }
+
+ public func sessionStart() {
+ self.adapter.sessionStart()
+ }
+
+ public func update(metadata: AdScriptDataObject) {
+ self.adapter.update(metadata: metadata)
+ }
+
+ public func updateUser(i12n: AdScriptI12n) {
+ self.adapter.updateUser(i12n: i12n)
+ }
+}
diff --git a/adscript/ios/Source/integration/AdScriptAdapter.swift b/adscript/ios/Source/integration/AdScriptAdapter.swift
new file mode 100644
index 00000000..1b8f7e99
--- /dev/null
+++ b/adscript/ios/Source/integration/AdScriptAdapter.swift
@@ -0,0 +1,450 @@
+import THEOplayerSDK
+import Collections
+#if canImport(AdScriptApiClient)
+import AdScriptApiClient
+#endif
+
+public struct LogPoint {
+ let name: AdScriptEventName;
+ let cue: Double;
+}
+
+let LOG_PLAYER_EVENTS = false
+let LOG_ADSCRIPT_EVENTS = false
+
+public class AdScriptAdapter {
+ private let player: THEOplayer
+ private var contentMetadata: AdScriptDataObject
+ private var contentLogPoints: Deque = Deque()
+ private var adMetadata: AdScriptDataObject? = nil
+ private var waitingForFirstSecondOfAd = false
+ private var waitingForFirstSecondOfSsaiAdSince: Double? = nil
+ private let configuration: AdScriptConfiguration
+ private let adscriptCollector: AdScriptCollector
+
+ private var playEventListener: EventListener?
+ private var playingEventListener: EventListener?
+ private var errorEventListener: EventListener?
+ private var sourceChangeEventListener: EventListener?
+ private var endedEventListener: EventListener?
+ private var durationChangeEventListener: EventListener?
+ private var timeUpdateEventListener: EventListener?
+ private var volumeChangeEventListener: EventListener?
+ private var rateChangeEventListener: EventListener?
+ private var presentationModeChangeEventListener: EventListener?
+
+ private var adBreakBeginListener: EventListener?
+ private var adBeginListener: EventListener?
+ private var adFirstQuartileListener: EventListener?
+ private var adMidpointListener: EventListener?
+ private var adThirdQuartileListener: EventListener?
+ private var adCompletedListener: EventListener?
+ private var adBreakEndedListener: EventListener?
+
+
+ public init(configuration: AdScriptConfiguration, player: THEOplayer, metadata: AdScriptDataObject) {
+ self.player = player
+ self.contentMetadata = metadata
+ self.configuration = configuration
+
+ self.adscriptCollector = AdScriptCollector(implementationId: configuration.implementationId, isDebug: configuration.debug && LOG_ADSCRIPT_EVENTS)
+
+ reportPlayerState()
+ addEventListeners()
+ }
+
+ public func sessionStart() {
+ self.adscriptCollector.sessionStart()
+ }
+
+ public func update(metadata: AdScriptDataObject) {
+ self.contentMetadata = metadata
+ }
+
+ public func updateUser(i12n: AdScriptI12n) {
+ self.adscriptCollector.i12n = i12n
+ }
+
+ private func reportPlayerState() {
+ reportFullscreen(isFullscreen: player.presentationMode == PresentationMode.fullscreen)
+ reportDimensions(width: player.videoWidth, height: player.videoHeight)
+ reportPlaybackSpeed(playbackRate: player.playbackRate)
+ reportVolumeAndMuted(isMuted: player.muted, volume: player.volume)
+ reportTriggeredByUser(autoplayEnabled: player.autoplay)
+ reportVisibility()
+ }
+
+ private func reportFullscreen(isFullscreen: Bool) {
+ _ = self.adscriptCollector.playerState.set(key: AdScriptPlayerStateKey.fullscreen, value: isFullscreen ? 1 : 0)
+ }
+
+ private func reportDimensions(width: Int, height: Int) {
+ _ = self.adscriptCollector.playerState.set(key: AdScriptPlayerStateKey.width, value: width)
+ _ = self.adscriptCollector.playerState.set(key: AdScriptPlayerStateKey.height, value: height)
+ }
+
+ private func reportPlaybackSpeed(playbackRate: Double) {
+ _ = self.adscriptCollector.playerState.set(key: AdScriptPlayerStateKey.normalSpeed, value: playbackRate == 1 ? 1 : 0)
+ }
+
+ private func reportVolumeAndMuted(isMuted: Bool, volume: Float) {
+ _ = self.adscriptCollector.playerState.set(key: AdScriptPlayerStateKey.muted, value: (isMuted || volume == 0) ? 1 : 0)
+ _ = self.adscriptCollector.playerState.set(key: AdScriptPlayerStateKey.volume, value: Int(volume))
+ }
+ private func reportTriggeredByUser(autoplayEnabled: Bool) {
+ _ = self.adscriptCollector.playerState.set(key: AdScriptPlayerStateKey.triggeredByUser, value: autoplayEnabled ? 1 : 0)
+ }
+
+ private func reportVisibility() {
+ // TODO
+ }
+
+ private func handlePlaying(event: PlayingEvent) {
+ if (self.configuration.debug && LOG_PLAYER_EVENTS) {
+ print("[AdScriptConnector] Player Event: \(event.type) : currentTime = \(event.currentTime)")
+ }
+ if (self.player.ads.playing) {
+ if let adMetadata = self.adMetadata {
+ if (self.configuration.debug) {
+ print("[AdScriptConnector] Push .start event with adMetadata \(adMetadata.toJsonString())")
+ }
+ self.adscriptCollector.push(event: .start, data: adMetadata)
+ }
+ } else {
+ if (self.configuration.debug) {
+ print("[AdScriptConnector] Push .start event with contentMetadata \(contentMetadata.toJsonString())")
+ }
+ self.adscriptCollector.push(event: .start, data: self.contentMetadata)
+ // TODO check if flag is needed or just one playing event is dispatched on iOS
+ }
+ if let playingEventListener: THEOplayerSDK.EventListener = self.playingEventListener {
+ self.player.removeEventListener(type: THEOplayerSDK.PlayerEventTypes.PLAYING, listener: playingEventListener)
+ }
+ }
+
+ private func addLogPoints(duration: Double?) {
+ if let duration = duration {
+ if (duration.isFinite) {
+ self.contentLogPoints.append(LogPoint(name: .progress1 , cue: 1.0))
+ self.contentLogPoints.append(LogPoint(name: .firstQuartile , cue: 0.25 * duration))
+ self.contentLogPoints.append(LogPoint(name: .midpoint , cue: 0.5 * duration))
+ self.contentLogPoints.append(LogPoint(name: .thirdQuartile , cue: 0.75 * duration))
+ } else {
+ self.contentLogPoints.append(LogPoint(name: .progress1, cue: 1.0))
+ }
+ if (self.configuration.debug) {
+ print("[AdScriptConnector] Stored \(self.contentLogPoints.count) logPoints : \(self.contentLogPoints.debugDescription)")
+ }
+ }
+
+ }
+
+ private func reportLogPoint(name: AdScriptEventName) {
+ if (self.configuration.debug) {
+ print("[AdScriptConnector] Push .\(name.rawValue) event with contentMetadata \(contentMetadata.toJsonString())")
+ }
+ self.adscriptCollector.push(event: name, data: self.contentMetadata)
+ }
+
+ private func maybeReportAdProgress(currentTime: Double) {
+ if (!self.waitingForFirstSecondOfAd) { return }
+ if let currentAd = player.ads.currentAds.first {
+ switch currentAd.integration {
+ case .google_ima:
+ if let adMetadata = self.adMetadata, currentTime >= 1 {
+ if (self.configuration.debug) {
+ print("[AdScriptConnector] Push .progress1 event with adMetadata \(adMetadata.toJsonString())")
+ }
+ self.adscriptCollector.push(event: .progress1, data: adMetadata)
+ self.waitingForFirstSecondOfAd = false
+ }
+ case .google_dai:
+ if let waitingSince = self.waitingForFirstSecondOfSsaiAdSince,
+ let adMetadata = self.adMetadata,
+ currentTime >= waitingSince + 1.0 {
+ if (self.configuration.debug) {
+ print("[AdScriptConnector] Push .progress1 event with adMetadata \(adMetadata.toJsonString())")
+ }
+ self.adscriptCollector.push(event: .progress1, data: adMetadata)
+ self.waitingForFirstSecondOfAd = false
+ self.waitingForFirstSecondOfSsaiAdSince = nil
+ }
+ case .theoads:
+ if (self.configuration.debug) { print("[AdScriptConnector] Ad Integration is not supported (maybeReportAdProgress)") }
+ case .custom:
+ if (self.configuration.debug) { print("[AdScriptConnector] Ad Integration is not supported (maybeReportAdProgress)") }
+ @unknown default:
+ if (self.configuration.debug) { print("[AdScriptConnector] Ad Integration is not supported (maybeReportAdProgress)") }
+ }
+ }
+ }
+
+ private func maybeReportProgress(currentTime: Double) {
+ if (player.ads.playing) {
+ maybeReportAdProgress(currentTime: currentTime)
+ return
+ }
+
+ let nextLogPoint = contentLogPoints.first
+ if (nextLogPoint != nil && currentTime >= nextLogPoint!.cue) {
+ reportLogPoint(name: nextLogPoint!.name)
+ contentLogPoints.removeFirst()
+ }
+ }
+
+ private func getAdType(offset: Int) -> AdScriptDataValueType {
+ if (offset == 0) {
+ return .preroll
+ } else if (offset == -1) {
+ return .postroll
+ } else if let duration = player.duration, offset >= Int(floor(duration)) {
+ return .postroll
+ } else {
+ return .midroll
+ }
+ }
+
+ private func buildAdMetadata(ad: THEOplayerSDK.Ad) {
+ if (false) {
+ // TODO provide adProcessor
+ } else {
+ var currentAdMetadata = AdScriptDataObject()
+ if let id = ad.id {
+ _ = currentAdMetadata.set(key: .assetId, value: id)
+ _ = currentAdMetadata.set(key: .title, value: id)
+
+ }
+// _ = currentAdMetadata.set(key: .asmea, value: "TODO")
+ _ = currentAdMetadata.set(key: .attribute, value: .commercial)
+ _ = currentAdMetadata.set(key: .type, value: self.getAdType(offset: ad.adBreak.timeOffset))
+ if let duration = ad.duration {
+ _ = currentAdMetadata.set(key: .length, value: duration)
+ }
+
+ adMetadata = currentAdMetadata
+ }
+ }
+
+
+ private func addEventListeners() {
+ self.playEventListener = player.addEventListener(type: THEOplayerSDK.PlayerEventTypes.PLAY, listener: { [weak self] event in
+ guard let welf: AdScriptAdapter = self else { return }
+ if (welf.configuration.debug && LOG_PLAYER_EVENTS) {
+ print("[AdScriptConnector] Player Event: \(event.type) : currentTime = \(event.currentTime)")
+ }
+ })
+ self.playingEventListener = player.addEventListener(type: THEOplayerSDK.PlayerEventTypes.PLAYING, listener: { [weak self] event in self?.handlePlaying(event: event) })
+ self.errorEventListener = player.addEventListener(type: THEOplayerSDK.PlayerEventTypes.ERROR, listener: { [weak self] event in
+ guard let welf: AdScriptAdapter = self else { return }
+ if let code = event.errorObject?.code, let cause = event.errorObject?.cause, welf.configuration.debug && LOG_PLAYER_EVENTS {
+ print("[AdScriptConnector] Player Event: \(event.type) : code = \(code) ; cause = \(cause)")
+ }
+ })
+ self.sourceChangeEventListener = player.addEventListener(type: THEOplayerSDK.PlayerEventTypes.SOURCE_CHANGE, listener: { [weak self] event in
+ guard let welf: AdScriptAdapter = self else { return }
+ if (welf.configuration.debug && LOG_PLAYER_EVENTS) {
+ print("[AdScriptConnector] Player Event: \(event.type) : source = \(event.source.debugDescription)")
+ }
+
+ if let playingEventListener: THEOplayerSDK.EventListener = welf.playingEventListener {
+ welf.player.removeEventListener(type: THEOplayerSDK.PlayerEventTypes.PLAYING, listener: playingEventListener)
+ }
+ welf.contentLogPoints = Deque()
+ welf.playingEventListener = welf.player.addEventListener(type: THEOplayerSDK.PlayerEventTypes.PLAYING, listener: { [weak self] event in self?.handlePlaying(event: event) })
+ })
+ self.endedEventListener = player.addEventListener(type: THEOplayerSDK.PlayerEventTypes.ENDED, listener: { [weak self] event in
+ guard let welf: AdScriptAdapter = self else { return }
+ if (welf.configuration.debug && LOG_PLAYER_EVENTS) {
+ print("[AdScriptConnector] Player Event: \(event.type) : currentTime = \(event.currentTime)")
+ }
+ if (welf.configuration.debug) {
+ print("[AdScriptConnector] Push .complete event with contentMetadata \(welf.contentMetadata.toJsonString())")
+ }
+ welf.adscriptCollector.push(event: .complete, data: welf.contentMetadata)
+ })
+ self.durationChangeEventListener = player.addEventListener(type: THEOplayerSDK.PlayerEventTypes.DURATION_CHANGE, listener: { [weak self] event in
+ guard let welf: AdScriptAdapter = self else { return }
+ if let duration = event.duration, welf.configuration.debug && LOG_PLAYER_EVENTS {
+ print("[AdScriptConnector] Player Event: \(event.type) : duration = \(duration)")
+ }
+ welf.addLogPoints(duration: event.duration)
+ })
+ self.timeUpdateEventListener = player.addEventListener(type: THEOplayerSDK.PlayerEventTypes.TIME_UPDATE, listener: { [weak self] event in
+ guard let welf: AdScriptAdapter = self else { return }
+ if (welf.configuration.debug && LOG_PLAYER_EVENTS) {
+ print("[AdScriptConnector] Player Event: \(event.type) : currentTime = \(event.currentTime)")
+ }
+ welf.maybeReportProgress(currentTime: event.currentTime)
+ })
+ self.volumeChangeEventListener = player.addEventListener(type: THEOplayerSDK.PlayerEventTypes.VOLUME_CHANGE, listener: { [weak self] event in
+ guard let welf: AdScriptAdapter = self else { return }
+ if (welf.configuration.debug && LOG_PLAYER_EVENTS) {
+ print("[AdScriptConnector] Player Event: \(event.type) : volume = \(event.volume)")
+ }
+ welf.reportVolumeAndMuted(isMuted: welf.player.muted, volume: event.volume)
+ })
+ self.rateChangeEventListener = player.addEventListener(type: THEOplayerSDK.PlayerEventTypes.RATE_CHANGE, listener: { [weak self] event in
+ guard let welf: AdScriptAdapter = self else { return }
+ if (welf.configuration.debug && LOG_PLAYER_EVENTS) {
+ print("[AdScriptConnector] Player Event: \(event.type) : playbackRate = \(event.playbackRate)")
+ }
+ welf.reportPlaybackSpeed(playbackRate: event.playbackRate)
+ })
+ self.presentationModeChangeEventListener = player.addEventListener(type: THEOplayerSDK.PlayerEventTypes.PRESENTATION_MODE_CHANGE, listener: { [weak self] event in
+ guard let welf: AdScriptAdapter = self else { return }
+ if (welf.configuration.debug && LOG_PLAYER_EVENTS) {
+ print("[AdScriptConnector] Player Event: \(event.type) : presentationMode = \(event.presentationMode._rawValue)")
+ }
+ welf.reportFullscreen(isFullscreen: event.presentationMode == PresentationMode.fullscreen)
+ })
+
+
+ if (hasAdIntegration()) {
+ self.adBreakBeginListener = player.ads.addEventListener(type: THEOplayerSDK.AdsEventTypes.AD_BREAK_BEGIN, listener: { [weak self] event in
+ guard let welf: AdScriptAdapter = self else { return }
+ if let offset = event.ad?.timeOffset, welf.configuration.debug && LOG_PLAYER_EVENTS {
+ print("[AdScriptConnector] Player Event: \(event.type) : offset = \(offset)")
+ }
+ })
+ self.adBeginListener = player.ads.addEventListener(type: THEOplayerSDK.AdsEventTypes.AD_BEGIN, listener: { [weak self] event in
+ guard let welf: AdScriptAdapter = self else { return }
+ if let id = event.ad?.id, welf.configuration.debug && LOG_PLAYER_EVENTS {
+ print("[AdScriptConnector] Player Event: \(event.type) : id = \(id)")
+ }
+ guard let ad = event.ad else { return }
+ welf.buildAdMetadata(ad: ad)
+ welf.waitingForFirstSecondOfAd = true
+ if (event.ad?.integration == .google_dai) {
+ welf.waitingForFirstSecondOfSsaiAdSince = welf.player.currentTime
+ }
+ guard let adMetadata = self?.adMetadata else { return }
+ if (welf.configuration.debug) {
+ print("[AdScriptConnector] Push .start event with adMetadata \(adMetadata.toJsonString())")
+ }
+ welf.adscriptCollector.push(event: .start, data: adMetadata)
+ })
+ self.adFirstQuartileListener = player.ads.addEventListener(type: THEOplayerSDK.AdsEventTypes.AD_FIRST_QUARTILE, listener: { [weak self] event in
+ guard let welf: AdScriptAdapter = self else { return }
+ if let id = event.ad?.id, welf.configuration.debug && LOG_PLAYER_EVENTS {
+ print("[AdScriptConnector] Player Event: \(event.type) : id = \(id)")
+ }
+ guard let adMetadata = welf.adMetadata else { return }
+ if (welf.configuration.debug) {
+ print("[AdScriptConnector] Push .firstQuartile event with adMetadata \(adMetadata.toJsonString())")
+ }
+ welf.adscriptCollector.push(event: .firstQuartile, data: adMetadata)
+ })
+ self.adMidpointListener = player.ads.addEventListener(type: THEOplayerSDK.AdsEventTypes.AD_MIDPOINT, listener: { [weak self] event in
+ guard let welf: AdScriptAdapter = self else { return }
+ if let id = event.ad?.id, welf.configuration.debug && LOG_PLAYER_EVENTS {
+ print("[AdScriptConnector] Player Event: \(event.type) : id = \(id)")
+ }
+ guard let adMetadata = welf.adMetadata else { return }
+ if (welf.configuration.debug) {
+ print("[AdScriptConnector] Push .midpoint event with adMetadata \(adMetadata.toJsonString())")
+ }
+ welf.adscriptCollector.push(event: .midpoint, data: adMetadata)
+ })
+ self.adThirdQuartileListener = player.ads.addEventListener(type: THEOplayerSDK.AdsEventTypes.AD_THIRD_QUARTILE, listener: { [weak self] event in
+ guard let welf: AdScriptAdapter = self else { return }
+ if let id = event.ad?.id, welf.configuration.debug {
+ print("[AdScriptConnector] Player Event: \(event.type) : id = \(id)")
+ }
+ guard let adMetadata = welf.adMetadata else { return }
+ if (welf.configuration.debug) {
+ print("[AdScriptConnector] Push .thirdQuartile event with adMetadata \(adMetadata.toJsonString())")
+ }
+ welf.adscriptCollector.push(event: .thirdQuartile, data: adMetadata)
+ })
+ self.adCompletedListener = player.ads.addEventListener(type: THEOplayerSDK.AdsEventTypes.AD_END, listener: { [weak self] event in
+ guard let welf: AdScriptAdapter = self else { return }
+ if let id = event.ad?.id, welf.configuration.debug && LOG_PLAYER_EVENTS {
+ print("[AdScriptConnector] Player Event: \(event.type) : id = \(id)")
+ }
+ guard let adMetadata = welf.adMetadata else { return }
+ if (welf.configuration.debug) {
+ print("[AdScriptConnector] Push .complete event with adMetadata \(adMetadata.toJsonString())")
+ }
+ welf.adscriptCollector.push(event: .complete, data: adMetadata)
+ })
+ self.adBreakEndedListener = player.ads.addEventListener(type: THEOplayerSDK.AdsEventTypes.AD_BREAK_END, listener: { [weak self] event in
+ guard let welf: AdScriptAdapter = self else { return }
+ if let offset = event.ad?.timeOffset, welf.configuration.debug && LOG_PLAYER_EVENTS {
+ print("[AdScriptConnector] Player Event: \(event.type) : offset = \(offset)")
+ }
+ if (event.ad?.timeOffset == 0) {
+ welf.playingEventListener = welf.player.addEventListener(type: THEOplayerSDK.PlayerEventTypes.PLAYING, listener: { [weak self] event in self?.handlePlaying(event: event) })
+ }
+ })
+ }
+ }
+
+ private func removeEventListeners() {
+ if let playEventListener: THEOplayerSDK.EventListener = self.playEventListener {
+ self.player.removeEventListener(type: THEOplayerSDK.PlayerEventTypes.TIME_UPDATE, listener: playEventListener)
+ }
+ if let playingEventListener: THEOplayerSDK.EventListener = self.playingEventListener {
+ self.player.removeEventListener(type: THEOplayerSDK.PlayerEventTypes.PLAYING, listener: playingEventListener)
+ }
+ if let errorEventListener: THEOplayerSDK.EventListener = self.errorEventListener {
+ self.player.removeEventListener(type: THEOplayerSDK.PlayerEventTypes.ERROR, listener: errorEventListener)
+ }
+ if let sourceChangeEventListener: THEOplayerSDK.EventListener = self.sourceChangeEventListener {
+ self.player.removeEventListener(type: THEOplayerSDK.PlayerEventTypes.SOURCE_CHANGE, listener: sourceChangeEventListener)
+ }
+ if let endedEventListener: THEOplayerSDK.EventListener = self.endedEventListener {
+ self.player.removeEventListener(type: THEOplayerSDK.PlayerEventTypes.ENDED, listener: endedEventListener)
+ }
+ if let durationChangeEventListener: THEOplayerSDK.EventListener = self.durationChangeEventListener {
+ self.player.removeEventListener(type: THEOplayerSDK.PlayerEventTypes.DURATION_CHANGE, listener: durationChangeEventListener)
+ }
+ if let timeUpdateEventListener: THEOplayerSDK.EventListener = self.timeUpdateEventListener {
+ self.player.removeEventListener(type: THEOplayerSDK.PlayerEventTypes.TIME_UPDATE, listener: timeUpdateEventListener)
+ }
+ if let volumeChangeEventListener: THEOplayerSDK.EventListener = self.volumeChangeEventListener {
+ self.player.removeEventListener(type: THEOplayerSDK.PlayerEventTypes.VOLUME_CHANGE, listener: volumeChangeEventListener)
+ }
+ if let rateChangeEventListener: THEOplayerSDK.EventListener = self.rateChangeEventListener {
+ self.player.removeEventListener(type: THEOplayerSDK.PlayerEventTypes.RATE_CHANGE, listener: rateChangeEventListener)
+ }
+ if let presentationModeChangeEventListener: THEOplayerSDK.EventListener = self.presentationModeChangeEventListener {
+ self.player.removeEventListener(type: THEOplayerSDK.PlayerEventTypes.PRESENTATION_MODE_CHANGE, listener: presentationModeChangeEventListener)
+ }
+ if let adBreakBeginListener: THEOplayerSDK.EventListener = self.adBreakBeginListener {
+ self.player.removeEventListener(type: THEOplayerSDK.AdsEventTypes.AD_BREAK_BEGIN, listener: adBreakBeginListener)
+ }
+ if let adBeginListener: THEOplayerSDK.EventListener = self.adBeginListener {
+ self.player.removeEventListener(type: THEOplayerSDK.AdsEventTypes.AD_BEGIN, listener: adBeginListener)
+ }
+ if let adFirstQuartileListener: THEOplayerSDK.EventListener = self.adFirstQuartileListener {
+ self.player.removeEventListener(type: THEOplayerSDK.AdsEventTypes.AD_FIRST_QUARTILE, listener: adFirstQuartileListener)
+ }
+ if let adMidpointListener: THEOplayerSDK.EventListener = self.adMidpointListener {
+ self.player.removeEventListener(type: THEOplayerSDK.AdsEventTypes.AD_MIDPOINT, listener: adMidpointListener)
+ }
+ if let adThirdQuartileListener: THEOplayerSDK.EventListener = self.adThirdQuartileListener {
+ self.player.removeEventListener(type: THEOplayerSDK.AdsEventTypes.AD_THIRD_QUARTILE, listener: adThirdQuartileListener)
+ }
+ if let adCompletedListener: THEOplayerSDK.EventListener = self.adCompletedListener {
+ self.player.removeEventListener(type: THEOplayerSDK.AdsEventTypes.AD_END, listener: adCompletedListener)
+ }
+ if let adBreakEndedListener: THEOplayerSDK.EventListener = self.adBreakEndedListener {
+ self.player.removeEventListener(type: THEOplayerSDK.AdsEventTypes.AD_BREAK_END, listener: adBreakEndedListener)
+ }
+ }
+
+ private func hasAdIntegration() -> Bool {
+ let hasAdIntegration = player.getAllIntegrations().contains { integration in
+ switch integration.kind {
+ case IntegrationKind.GOOGLE_DAI:
+ return true
+ case IntegrationKind.GOOGLE_IMA:
+ return true
+ default:
+ print("[AdScriptConnector] no supported ad integration was found")
+ return false
+ }
+ }
+ return hasAdIntegration
+ }
+}
diff --git a/adscript/ios/THEOplayerAdScriptRCTAdScriptAPI.swift b/adscript/ios/THEOplayerAdScriptRCTAdScriptAPI.swift
new file mode 100644
index 00000000..852be794
--- /dev/null
+++ b/adscript/ios/THEOplayerAdScriptRCTAdScriptAPI.swift
@@ -0,0 +1,116 @@
+import Foundation
+import THEOplayerSDK
+import UIKit
+import react_native_theoplayer
+import AdScriptApiClient
+
+@objc(THEOplayerAdScriptRCTAdScriptAPI)
+class THEOplayerAdScriptRCTAdScriptAPI: NSObject, RCTBridgeModule {
+ @objc var bridge: RCTBridge!
+
+ var connectors = [NSNumber: AdScriptConnector]()
+
+ static func moduleName() -> String! {
+ return "AdScriptModule"
+ }
+
+ static func requiresMainQueueSetup() -> Bool {
+ return false
+ }
+
+ @objc(initialize:implementationId:contentMetadata:debug:)
+ func initialize(
+ _ node: NSNumber, implementationId: NSString, contentMetadata: NSDictionary, debug: Bool
+ ) {
+ log("initialize triggered.")
+
+ DispatchQueue.main.async {
+ if let view = self.view(for: node), let player = view.player {
+ self.connectors[node] = AdScriptConnector(
+ configuration: AdScriptConfiguration(implementationId: implementationId as String, debug: debug),
+ player: player,
+ metadata: self.buildMetadata(contentMetadata)
+ )
+ log("Added connector to view \(node)")
+ } else {
+ log("Cannot find THEOPlayer for node \(node)")
+ }
+ }
+ }
+
+ @objc(updateMetadata:metadata:)
+ func updateMetadata(_ node: NSNumber, metadata: NSDictionary) {
+ log("updateMetadata triggered.")
+ DispatchQueue.main.async {
+ if let connector = self.connectors[node] {
+ connector
+ .update(
+ metadata: self.buildMetadata(metadata)
+ )
+ }
+ }
+ }
+
+ @objc(updateUser:user:)
+ func updateUser(_ node: NSNumber, user: NSArray) {
+ log("updateUser triggered.")
+ DispatchQueue.main.async {
+ if let connector = self.connectors[node] {
+ connector
+ .updateUser(
+ i12n: self.buildUser(user)
+ )
+ }
+ }
+ }
+
+ private func buildMetadata(_ metadata: NSDictionary) -> AdScriptDataObject {
+ let data = AdScriptDataObject()
+
+ metadata.forEach { key, value in
+ guard let keyString = key as? String,
+ let stringValue = value as? String else { return }
+
+ if let dataKey = AdScriptDataKey(rawValue: keyString) {
+ _ = data.set(key: dataKey, value: stringValue)
+ } else {
+ // custom param
+ _ = data.set(key: keyString, value: stringValue)
+ }
+ }
+ return data
+ }
+
+ private func buildUser(_ user: NSArray) -> AdScriptI12n {
+ let data = AdScriptI12n()
+ for i in 0.. THEOplayerRCTView? {
+ self.bridge.uiManager.view(forReactTag: node) as? THEOplayerRCTView
+ }
+
+ func player(for node: NSNumber) -> THEOplayer? {
+ view(for: node)?.player
+ }
+}
+
+func log(_ text: String) {
+#if DEBUG
+ print("[react-native-theoplayer-adscript bridge]", text)
+#endif
+}
diff --git a/adscript/ios/THEOplayerAdScriptRCTBridge.m b/adscript/ios/THEOplayerAdScriptRCTBridge.m
new file mode 100644
index 00000000..ba7bb74b
--- /dev/null
+++ b/adscript/ios/THEOplayerAdScriptRCTBridge.m
@@ -0,0 +1,23 @@
+#import
+#import
+#import
+
+// ----------------------------------------------------------------------------
+// AdScript Module
+// ----------------------------------------------------------------------------
+@interface RCT_EXTERN_REMAP_MODULE(AdScriptModule, THEOplayerAdScriptRCTAdScriptAPI, NSObject)
+
+RCT_EXTERN_METHOD(initialize:(nonnull NSNumber *)node
+ implementationId:(nonnull NSString *)implementationId
+ contentMetadata:(nonnull NSString *)contentMetadata
+ debug:(BOOL)debug)
+
+RCT_EXTERN_METHOD(updateMetadata:(nonnull NSNumber *)node
+ metadata:(NSDictionary)metadata)
+
+RCT_EXTERN_METHOD(updateUser:(nonnull NSNumber *)node
+ user:(NSArray)user)
+
+RCT_EXTERN_METHOD(destroy:(nonnull NSNumber *)node)
+
+@end
diff --git a/adscript/ios/TheoplayerAdScript-Bridging-Header.h b/adscript/ios/TheoplayerAdScript-Bridging-Header.h
new file mode 100644
index 00000000..7ecf415d
--- /dev/null
+++ b/adscript/ios/TheoplayerAdScript-Bridging-Header.h
@@ -0,0 +1,4 @@
+#import
+#import
+#import
+#import
diff --git a/adscript/ios/TheoplayerAdScript.xcodeproj/project.pbxproj b/adscript/ios/TheoplayerAdScript.xcodeproj/project.pbxproj
new file mode 100644
index 00000000..4b879855
--- /dev/null
+++ b/adscript/ios/TheoplayerAdScript.xcodeproj/project.pbxproj
@@ -0,0 +1,283 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 46;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 5E555C0D2413F4C50049A1A2 /* TheoplayerAdScript.m in Sources */ = {isa = PBXBuildFile; fileRef = B3E7B5891CC2AC0600A0062D /* TheoplayerAdScript.m */; };
+ F4FF95D7245B92E800C19C63 /* TheoplayerAdScript.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4FF95D6245B92E800C19C63 /* TheoplayerAdScript.swift */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+ 58B511D91A9E6C8500147676 /* CopyFiles */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = "include/$(PRODUCT_NAME)";
+ dstSubfolderSpec = 16;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+ 134814201AA4EA6300B7C361 /* libTheoplayerAdScript.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libTheoplayerAdScript.a; sourceTree = BUILT_PRODUCTS_DIR; };
+ B3E7B5891CC2AC0600A0062D /* TheoplayerAdScript.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TheoplayerAdScript.m; sourceTree = ""; };
+ F4FF95D5245B92E700C19C63 /* TheoplayerAdScript-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "TheoplayerAdScript-Bridging-Header.h"; sourceTree = ""; };
+ F4FF95D6245B92E800C19C63 /* TheoplayerAdScript.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TheoplayerAdScript.swift; sourceTree = ""; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 58B511D81A9E6C8500147676 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 134814211AA4EA7D00B7C361 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 134814201AA4EA6300B7C361 /* libTheoplayerAdScript.a */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+ 58B511D21A9E6C8500147676 = {
+ isa = PBXGroup;
+ children = (
+ F4FF95D6245B92E800C19C63 /* TheoplayerAdScript.swift */,
+ B3E7B5891CC2AC0600A0062D /* TheoplayerAdScript.m */,
+ F4FF95D5245B92E700C19C63 /* TheoplayerAdScript-Bridging-Header.h */,
+ 134814211AA4EA7D00B7C361 /* Products */,
+ );
+ sourceTree = "";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 58B511DA1A9E6C8500147676 /* TheoplayerAdScript */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "TheoplayerAdScript" */;
+ buildPhases = (
+ 58B511D71A9E6C8500147676 /* Sources */,
+ 58B511D81A9E6C8500147676 /* Frameworks */,
+ 58B511D91A9E6C8500147676 /* CopyFiles */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = TheoplayerAdScript;
+ productName = RCTDataManager;
+ productReference = 134814201AA4EA6300B7C361 /* libTheoplayerAdScript.a */;
+ productType = "com.apple.product-type.library.static";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 58B511D31A9E6C8500147676 /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastUpgradeCheck = 0920;
+ ORGANIZATIONNAME = Facebook;
+ TargetAttributes = {
+ 58B511DA1A9E6C8500147676 = {
+ CreatedOnToolsVersion = 6.1.1;
+ };
+ };
+ };
+ buildConfigurationList = 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "TheoplayerAdScript" */;
+ compatibilityVersion = "Xcode 3.2";
+ developmentRegion = English;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ English,
+ en,
+ );
+ mainGroup = 58B511D21A9E6C8500147676;
+ productRefGroup = 58B511D21A9E6C8500147676;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 58B511DA1A9E6C8500147676 /* TheoplayerAdScript */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 58B511D71A9E6C8500147676 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ F4FF95D7245B92E800C19C63 /* TheoplayerAdScript.swift in Sources */,
+ B3E7B58A1CC2AC0600A0062D /* TheoplayerAdScript.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+ 58B511ED1A9E6C8500147676 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ "EXCLUDED_ARCHS[sdk=*]" = arm64;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 8.0;
+ MTL_ENABLE_DEBUG_INFO = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = iphoneos;
+ };
+ name = Debug;
+ };
+ 58B511EE1A9E6C8500147676 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = YES;
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ "EXCLUDED_ARCHS[sdk=*]" = arm64;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 8.0;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ SDKROOT = iphoneos;
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
+ 58B511F01A9E6C8500147676 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ HEADER_SEARCH_PATHS = (
+ "$(inherited)",
+ /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
+ "$(SRCROOT)/../../../React/**",
+ "$(SRCROOT)/../../react-native/React/**",
+ );
+ LIBRARY_SEARCH_PATHS = "$(inherited)";
+ OTHER_LDFLAGS = "-ObjC";
+ PRODUCT_NAME = TheoplayerAdScript;
+ SKIP_INSTALL = YES;
+ SWIFT_OBJC_BRIDGING_HEADER = "TheoplayerAdScript-Bridging-Header.h";
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ SWIFT_VERSION = 5.0;
+ };
+ name = Debug;
+ };
+ 58B511F11A9E6C8500147676 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ HEADER_SEARCH_PATHS = (
+ "$(inherited)",
+ /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
+ "$(SRCROOT)/../../../React/**",
+ "$(SRCROOT)/../../react-native/React/**",
+ );
+ LIBRARY_SEARCH_PATHS = "$(inherited)";
+ OTHER_LDFLAGS = "-ObjC";
+ PRODUCT_NAME = TheoplayerAdScript;
+ SKIP_INSTALL = YES;
+ SWIFT_OBJC_BRIDGING_HEADER = "TheoplayerAdScript-Bridging-Header.h";
+ SWIFT_VERSION = 5.0;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "TheoplayerAdScript" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 58B511ED1A9E6C8500147676 /* Debug */,
+ 58B511EE1A9E6C8500147676 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "TheoplayerAdScript" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 58B511F01A9E6C8500147676 /* Debug */,
+ 58B511F11A9E6C8500147676 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 58B511D31A9E6C8500147676 /* Project object */;
+}
diff --git a/adscript/manifest.js b/adscript/manifest.js
new file mode 100755
index 00000000..e7629f28
--- /dev/null
+++ b/adscript/manifest.js
@@ -0,0 +1,6 @@
+const manifest = {
+ version: process.env.npm_package_version,
+ buildDate: new Date().toISOString(),
+};
+
+console.log(JSON.stringify(manifest));
diff --git a/adscript/package.json b/adscript/package.json
new file mode 100644
index 00000000..28239582
--- /dev/null
+++ b/adscript/package.json
@@ -0,0 +1,86 @@
+{
+ "name": "@theoplayer/react-native-analytics-adscript",
+ "version": "1.0.0",
+ "description": "Nielsen AdScript analytics connector for @theoplayer/react-native",
+ "main": "lib/commonjs/index",
+ "module": "lib/module/index",
+ "types": "lib/typescript/src/index.d.ts",
+ "react-native": "src/index",
+ "source": "src/index",
+ "files": [
+ "src",
+ "lib",
+ "android",
+ "ios",
+ "cpp",
+ "*.podspec",
+ "*.tgz",
+ "CHANGELOG.md",
+ "manifest.json",
+ "!lib/typescript/example",
+ "!ios/build",
+ "!android/build",
+ "!android/gradle",
+ "!android/gradlew",
+ "!android/gradlew.bat",
+ "!android/local.properties",
+ "!**/__tests__",
+ "!**/__fixtures__",
+ "!**/__mocks__",
+ "!**/.*"
+ ],
+ "scripts": {
+ "typescript": "tsc --noEmit",
+ "build": "npm run manifest && bob build",
+ "manifest": "node manifest.js > src/manifest.json",
+ "prepare": "npm run manifest && npm run build",
+ "clean": "rimraf lib android/build example/android/build example/android/app/build example/ios/build"
+ },
+ "keywords": [
+ "react-native",
+ "THEOplayer",
+ "ios",
+ "android",
+ "nielsen",
+ "adscript"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git@github.com:THEOplayer/react-native-connectors.git"
+ },
+ "author": "THEO Technologies",
+ "license": "SEE LICENSE AT https://www.theoplayer.com/terms",
+ "homepage": "https://github.com/THEOplayer/react-native-connectors/tree/main/adscript#readme",
+ "publishConfig": {
+ "registry": "https://registry.npmjs.org/"
+ },
+ "peerDependencies": {
+ "react": "*",
+ "react-native": "*",
+ "react-native-theoplayer": "^3 || ^7 || ^8 || ^9",
+ "theoplayer": "^5 || ^6 || ^7 || ^8 || ^9"
+ },
+ "peerDependenciesMeta": {
+ "theoplayer": {
+ "optional": true
+ }
+ },
+ "eslintIgnore": [
+ "node_modules/",
+ "lib/"
+ ],
+ "react-native-builder-bob": {
+ "source": "src",
+ "output": "lib",
+ "targets": [
+ "commonjs",
+ "module",
+ [
+ "typescript",
+ {
+ "project": "tsconfig.build.json"
+ }
+ ]
+ ]
+ }
+}
diff --git a/adscript/react-native-theoplayer-adscript.podspec b/adscript/react-native-theoplayer-adscript.podspec
new file mode 100644
index 00000000..c794c2e6
--- /dev/null
+++ b/adscript/react-native-theoplayer-adscript.podspec
@@ -0,0 +1,45 @@
+require "json"
+
+package = JSON.parse(File.read(File.join(__dir__, "package.json")))
+folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32'
+
+Pod::Spec.new do |s|
+ s.name = "react-native-theoplayer-adscript"
+ s.version = package["version"]
+ s.summary = package["description"]
+ s.homepage = package["homepage"]
+ s.license = package["license"]
+ s.authors = package["author"]
+
+ s.platforms = { :ios => "13.4", :tvos => "13.4" }
+ s.source = { :git => "https://github.com/THEOplayer/react-native-connectors.git", :tag => "adscript_v#{s.version}" }
+
+ s.source_files = "ios/**/*.{h,m,mm,swift}"
+
+ s.dependency "react-native-theoplayer"
+ s.dependency "AdScriptApiClient"
+ s.dependency 'swift-collections', '~> 1.1'
+
+ # Use install_modules_dependencies helper to install the dependencies if React Native version >=0.71.0.
+ # See https://github.com/facebook/react-native/blob/febf6b7f33fdb4904669f99d795eba4c0f95d7bf/scripts/cocoapods/new_architecture.rb#L79.
+ if respond_to?(:install_modules_dependencies, true)
+ install_modules_dependencies(s)
+ else
+ s.dependency "React-Core"
+
+ # Don't install the dependencies when we run `pod install` in the old architecture.
+ if ENV['RCT_NEW_ARCH_ENABLED'] == '1' then
+ s.compiler_flags = folly_compiler_flags + " -DRCT_NEW_ARCH_ENABLED=1"
+ s.pod_target_xcconfig = {
+ "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\"",
+ "OTHER_CPLUSPLUSFLAGS" => "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1",
+ "CLANG_CXX_LANGUAGE_STANDARD" => "c++17"
+ }
+ s.dependency "React-Codegen"
+ s.dependency "RCT-Folly"
+ s.dependency "RCTRequired"
+ s.dependency "RCTTypeSafety"
+ s.dependency "ReactCommon/turbomodule/core"
+ end
+ end
+end
diff --git a/adscript/src/__tests__/index.test.tsx b/adscript/src/__tests__/index.test.tsx
new file mode 100644
index 00000000..cb0ff5c3
--- /dev/null
+++ b/adscript/src/__tests__/index.test.tsx
@@ -0,0 +1 @@
+export {};
diff --git a/adscript/src/api/AdScriptConnector.ts b/adscript/src/api/AdScriptConnector.ts
new file mode 100644
index 00000000..6a318b81
--- /dev/null
+++ b/adscript/src/api/AdScriptConnector.ts
@@ -0,0 +1,44 @@
+import type { THEOplayer } from 'react-native-theoplayer';
+import { AdScriptConnectorAdapter } from '../internal/AdScriptConnectorAdapter';
+import { AdScriptMetadata } from './AdScriptMetadata';
+import { AdScriptI12n } from './AdScriptI12n';
+
+export class AdScriptConnector {
+ private connectorAdapter: AdScriptConnectorAdapter;
+
+ /**
+ * Create AdScriptConnector
+ *
+ * @param player A React Native THEOplayer instance.
+ * @param implementationId The implementation ID you will receive from your Nielsen Admosphere representative.
+ * @param contentMetadata Content metadata.
+ * @param debug Whether to show debug logging.
+ * @public
+ */
+ constructor(player: THEOplayer, implementationId: string, contentMetadata: AdScriptMetadata, debug?: boolean) {
+ this.connectorAdapter = new AdScriptConnectorAdapter(player, implementationId, contentMetadata, debug);
+ }
+
+ /**
+ * Update metadata.
+ */
+ updateMetadata(metadata: AdScriptMetadata) {
+ this.connectorAdapter.updateMetadata(metadata);
+ }
+
+ /**
+ * Update logged-in user info.
+ */
+ updateUser(user: AdScriptI12n) {
+ this.connectorAdapter.updateUser(user);
+ }
+
+ /**
+ * Stops video and ad analytics and closes all sessions.
+ *
+ * @public
+ */
+ destroy(): void {
+ this.connectorAdapter.destroy();
+ }
+}
diff --git a/adscript/src/api/AdScriptI12n.ts b/adscript/src/api/AdScriptI12n.ts
new file mode 100644
index 00000000..5902d31a
--- /dev/null
+++ b/adscript/src/api/AdScriptI12n.ts
@@ -0,0 +1,12 @@
+/**
+ * Additional information about the logged-in user from the client database.
+ *
+ * @example
+ * ["866d3a3c-aa87-4fe7-9066-8286641edd17", // client-side user identifier (customerId)
+ * "cf895a00-a987-4501-ac00-6adb57014129", // client-side user device identifier (Android_ID)
+ * "9530321a-d3d0-4bda-8704-1eb94a5940c3", // client-side profile identifier of the logged-in user (profileId)
+ * "jsg75682-k276t-kw82-k8d5-8926sh6528j2", // optional - SW device identifier for a situation where there are multiple device IDs in the client DB (typically a) HW ID - fill in i2, b) SW ID - fill in i4).
+ * "ef3c6dc72a26912f07f0e733d51b46c771d807bf" // fingerprint of the user's email address
+ * ]
+ */
+export type AdScriptI12n = string[];
diff --git a/adscript/src/api/AdScriptMetadata.ts b/adscript/src/api/AdScriptMetadata.ts
new file mode 100644
index 00000000..e87d4206
--- /dev/null
+++ b/adscript/src/api/AdScriptMetadata.ts
@@ -0,0 +1,115 @@
+export type AdScriptMetadata = {
+ /**
+ * Unique video content identifier. Any designation according to the needs of the TV company,
+ * which ensures identification of the same content across platforms.
+ *
+ * @example "abc98731568435405".
+ */
+ assetId: string;
+
+ /**
+ * Specifies the type of content being measured. For main video content, it always has value "content".
+ *
+ * @example "content".
+ */
+ type: string;
+
+ /**
+ * Program name.
+ *
+ * @example "Welcome to freedom".
+ */
+ program?: string;
+
+ /**
+ * Detailed description of the content, episode title.
+ *
+ * @example "Part 2 - 20.6.2018 20:00".
+ */
+ title?: string;
+
+ /**
+ * Length of video content in seconds.
+ *
+ * @example For VOD: "3359", for LIVE broadcast: "86400".
+ */
+ length?: string;
+
+ /**
+ * The designation of the original program from which the online video content was created.
+ * It may happen that, for example, three separate video files with unique assetIds are inserted into the
+ * TV Internet Archive, all three of which were created from one specific program.
+ *
+ * @example "915 954 39504".
+ */
+ crossId?: string;
+
+ /**
+ * Indication of whether this is a live broadcast.
+ * "1" - yes
+ * "0" - no
+ */
+ livestream?: string;
+
+ /**
+ * TV station code for live broadcast. (If the live broadcast does not correspond to any TV station,
+ * use the code "9999").
+ *
+ * @example "4".
+ */
+ channelId?: string;
+
+ /**
+ * Item in the CMS tag reserved for an identifier allowing the attachment of an advertisement description from
+ * the RTVK system similarly to PEM TV data (ASMEA code)
+ *
+ * @example "1488725615".
+ */
+ asmea?: string;
+
+ /**
+ * More detailed categorization of the main video content. The value is the code according to the TV code list.
+ *
+ * {@link https://adscript.admosphere.cz/cz_metadata.html#line3_1}
+ *
+ * @example "1".
+ */
+ attribute?: string;
+
+ /**
+ * Name of the HbbTV application or 1st level website.
+ *
+ * @example "Homepage".
+ */
+ sec1?: string;
+
+ /**
+ * Categorization of static content within HbbTV or a website. Level 2 title.
+ *
+ * @example "Subpage2".
+ */
+ sec2?: string;
+
+ /**
+ * Categorization of static content within HbbTV or a website. Level 3 title.
+ *
+ * @example "Subpage3".
+ */
+ sec3?: string;
+
+ /**
+ * Categorization of static content within HbbTV or a website. Level 4 title.
+ *
+ * @example "Subpage4".
+ */
+ sec4?: string;
+
+ /**
+ * Static content referrer
+ *
+ * @example "redButton".
+ */
+ ref?: string;
+
+ [id: string]: string;
+};
diff --git a/adscript/src/api/hooks/useAdScript.ts b/adscript/src/api/hooks/useAdScript.ts
new file mode 100644
index 00000000..a2353358
--- /dev/null
+++ b/adscript/src/api/hooks/useAdScript.ts
@@ -0,0 +1,43 @@
+import { PlayerEventType, THEOplayer } from 'react-native-theoplayer';
+import { RefObject, useEffect, useRef } from 'react';
+import { AdScriptMetadata } from '../AdScriptMetadata';
+import { AdScriptConnector } from '../AdScriptConnector';
+
+export function useAdScript(
+ implementationId: string,
+ contentMetadata: AdScriptMetadata,
+ debug?: boolean,
+): [RefObject, (player: THEOplayer | undefined) => void] {
+ const connector = useRef();
+ const theoPlayer = useRef();
+
+ const initialize = (player: THEOplayer | undefined) => {
+ // Optionally destroy existent connector
+ onDestroy();
+
+ theoPlayer.current = player;
+ if (player) {
+ connector.current = new AdScriptConnector(player, implementationId, contentMetadata, debug);
+ player.addEventListener(PlayerEventType.DESTROY, onDestroy);
+ } else {
+ throw new Error('Invalid THEOplayer instance');
+ }
+ };
+
+ const onDestroy = () => {
+ if (connector.current) {
+ if (!theoPlayer.current) {
+ throw new Error('Invalid THEOplayer instance');
+ }
+ theoPlayer.current.removeEventListener(PlayerEventType.DESTROY, onDestroy);
+ connector.current.destroy();
+ connector.current = undefined;
+ }
+ };
+
+ useEffect(() => {
+ return onDestroy;
+ }, []);
+
+ return [connector, initialize];
+}
diff --git a/adscript/src/index.ts b/adscript/src/index.ts
new file mode 100644
index 00000000..d06978bb
--- /dev/null
+++ b/adscript/src/index.ts
@@ -0,0 +1,4 @@
+export * from './api/AdScriptConnector';
+export * from './api/AdScriptMetadata';
+export * from './api/AdScriptI12n';
+export { useAdScript } from './api/hooks/useAdScript';
diff --git a/adscript/src/internal/AdScriptConnectorAdapter.ts b/adscript/src/internal/AdScriptConnectorAdapter.ts
new file mode 100644
index 00000000..1ba949e5
--- /dev/null
+++ b/adscript/src/internal/AdScriptConnectorAdapter.ts
@@ -0,0 +1,46 @@
+import type { THEOplayer } from 'react-native-theoplayer';
+import { NativeModules } from 'react-native';
+import { AdScriptMetadata } from '../api/AdScriptMetadata';
+import { AdScriptI12n } from '../api/AdScriptI12n';
+
+const TAG = 'AdScriptConnector';
+const ERROR_MSG = 'AdScriptConnectorAdapter Error';
+
+export class AdScriptConnectorAdapter {
+ constructor(
+ private player: THEOplayer,
+ implementationId: string,
+ contentMetadata: AdScriptMetadata,
+ debug?: boolean,
+ ) {
+ try {
+ NativeModules.AdScriptModule.initialize(this.player.nativeHandle || -1, implementationId, contentMetadata, debug ?? false);
+ } catch (error: unknown) {
+ console.error(TAG, `${ERROR_MSG}: ${error}`);
+ }
+ }
+
+ updateMetadata(metadata: AdScriptMetadata) {
+ try {
+ NativeModules.AdScriptModule.updateMetadata(this.player.nativeHandle || -1, metadata);
+ } catch (error: unknown) {
+ console.error(TAG, `${ERROR_MSG}: ${error}`);
+ }
+ }
+
+ updateUser(user: AdScriptI12n) {
+ try {
+ NativeModules.AdScriptModule.updateUser(this.player.nativeHandle || -1, user);
+ } catch (error: unknown) {
+ console.error(TAG, `${ERROR_MSG}: ${error}`);
+ }
+ }
+
+ destroy(): void {
+ try {
+ NativeModules.AdScriptModule.destroy(this.player.nativeHandle || -1);
+ } catch (error: unknown) {
+ console.error(TAG, `${ERROR_MSG}: ${error}`);
+ }
+ }
+}
diff --git a/adscript/src/internal/AdScriptConnectorAdapter.web.ts b/adscript/src/internal/AdScriptConnectorAdapter.web.ts
new file mode 100644
index 00000000..d87e329b
--- /dev/null
+++ b/adscript/src/internal/AdScriptConnectorAdapter.web.ts
@@ -0,0 +1,17 @@
+import type { THEOplayer } from 'react-native-theoplayer';
+import { AdScriptMetadata } from '../api/AdScriptMetadata';
+
+export class AdScriptConnectorAdapter {
+ constructor(
+ private player: THEOplayer,
+ implementationId: string,
+ contentMetadata: AdScriptMetadata,
+ debug?: boolean,
+ ) {
+ throw new Error('AdScript connector is not supported for Web.');
+ }
+
+ updateMetadata(metadata: AdScriptMetadata) {}
+
+ destroy() {}
+}
diff --git a/adscript/src/manifest.json b/adscript/src/manifest.json
new file mode 100644
index 00000000..4efadef6
--- /dev/null
+++ b/adscript/src/manifest.json
@@ -0,0 +1 @@
+{"version":"1.3.0","buildDate":"2025-08-04T09:46:38.897Z"}
diff --git a/adscript/tsconfig.build.json b/adscript/tsconfig.build.json
new file mode 100644
index 00000000..f929194b
--- /dev/null
+++ b/adscript/tsconfig.build.json
@@ -0,0 +1,5 @@
+
+{
+ "extends": "./tsconfig",
+ "exclude": ["example", "ios", "android"]
+}
diff --git a/adscript/tsconfig.json b/adscript/tsconfig.json
new file mode 100644
index 00000000..7ae3f792
--- /dev/null
+++ b/adscript/tsconfig.json
@@ -0,0 +1,11 @@
+{
+ "extends": "../tsconfig.base.json",
+ "compilerOptions": {
+ "baseUrl": "./",
+ "paths": {
+ "@theoplayer/react-native-analytics-adscript": [
+ "./src/index"
+ ]
+ }
+ }
+}
diff --git a/adscript/typedoc.json b/adscript/typedoc.json
new file mode 100644
index 00000000..0d320987
--- /dev/null
+++ b/adscript/typedoc.json
@@ -0,0 +1,12 @@
+{
+ "$schema": "https://typedoc.org/schema.json",
+ "extends": [
+ "../typedoc.base.json"
+ ],
+ "entryPoints": [
+ "src/index.ts"
+ ],
+ "tsconfig": "tsconfig.json",
+ "readme": "README.md",
+ "name": "AdScript Connector"
+}
diff --git a/apps/e2e/android/app/build.gradle b/apps/e2e/android/app/build.gradle
index 5fa17271..ac7611e3 100644
--- a/apps/e2e/android/app/build.gradle
+++ b/apps/e2e/android/app/build.gradle
@@ -116,6 +116,8 @@ dependencies {
implementation project(path: ':react-native-theoplayer-analytics-conviva')
implementation project(path: ':react-native-theoplayer-analytics-nielsen')
implementation project(path: ':react-native-theoplayer-yospace')
+// implementation project(path: ':react-native-theoplayer-analytics-adscript')
+// implementation project(path: ':react-native-theoplayer-analytics-gemius')
implementation "com.google.android.gms:play-services-cast-framework:${safeExtGet('castFrameworkVersion', '+')}"
diff --git a/apps/e2e/android/app/libs/.gitignore b/apps/e2e/android/app/libs/.gitignore
new file mode 100644
index 00000000..94b126ff
--- /dev/null
+++ b/apps/e2e/android/app/libs/.gitignore
@@ -0,0 +1,2 @@
+*.aar
+*.aar.gz
diff --git a/apps/e2e/android/build.gradle b/apps/e2e/android/build.gradle
index f2622cc3..767a6acb 100644
--- a/apps/e2e/android/build.gradle
+++ b/apps/e2e/android/build.gradle
@@ -2,7 +2,7 @@
buildscript {
ext {
- buildToolsVersion = "34.0.0"
+ buildToolsVersion = "35.0.0"
// React Native 0.74+ needs minSdkVersion 23+
// supportsPictureInPicture and networkSecurityConfig need minSdkVersion 24+
minSdkVersion = 24
@@ -10,7 +10,7 @@ buildscript {
targetSdkVersion = 35
ndkVersion = "26.1.10909125"
castFrameworkVersion = "21.4.0"
- kotlinVersion = "1.9.24"
+ kotlinVersion = "2.0.21"
}
repositories {
google()
@@ -19,7 +19,7 @@ buildscript {
dependencies {
classpath("com.android.tools.build:gradle")
classpath("com.facebook.react:react-native-gradle-plugin")
- classpath("org.jetbrains.kotlin:kotlin-gradle-plugin")
+ classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion")
}
}
diff --git a/apps/e2e/android/gradle.properties b/apps/e2e/android/gradle.properties
index 0f561443..f3009869 100644
--- a/apps/e2e/android/gradle.properties
+++ b/apps/e2e/android/gradle.properties
@@ -73,3 +73,9 @@ THEOplayer_timeUpdateRate = com.theoplayer.TimeUpdateRate.LIMITED_TWO_HZ
# Toggle whether to use a media service for background playback
#THEOplayer_usePlaybackService = true
+
+# Location of the adscript SDK
+adscriptSdkDir=./app/libs/
+
+# Location of the gemius SDK
+gemiusSdkDir=./app/libs/
diff --git a/apps/e2e/android/settings.gradle b/apps/e2e/android/settings.gradle
index bc5ec84d..3eb5cf14 100644
--- a/apps/e2e/android/settings.gradle
+++ b/apps/e2e/android/settings.gradle
@@ -14,3 +14,7 @@ include ':react-native-theoplayer-analytics-nielsen'
project(':react-native-theoplayer-analytics-nielsen').projectDir = new File(rootProject.projectDir, '../../../nielsen/android')
include ':react-native-theoplayer-yospace'
project(':react-native-theoplayer-yospace').projectDir = new File(rootProject.projectDir, '../../../yospace/android')
+// include ':react-native-theoplayer-analytics-adscript'
+// project(':react-native-theoplayer-analytics-adscript').projectDir = new File(rootProject.projectDir, '../../../adscript/android')
+// include ':react-native-theoplayer-analytics-gemius'
+// project(':react-native-theoplayer-analytics-gemius').projectDir = new File(rootProject.projectDir, '../../../gemius/android')
diff --git a/apps/e2e/ios/Podfile.lock b/apps/e2e/ios/Podfile.lock
index b9b02fa5..f2a0bbfd 100644
--- a/apps/e2e/ios/Podfile.lock
+++ b/apps/e2e/ios/Podfile.lock
@@ -1277,13 +1277,13 @@ PODS:
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- Yoga
- - react-native-theoplayer (9.3.0):
+ - react-native-theoplayer (9.9.1):
- React-Core
- - THEOplayer-Connector-SideloadedSubtitle (~> 9.3)
- - THEOplayer-Integration-GoogleCast (~> 9.3)
- - THEOplayer-Integration-GoogleIMA (~> 9.3)
- - THEOplayer-Integration-THEOlive (~> 9.3)
- - THEOplayerSDK-core (~> 9.3)
+ - THEOplayer-Connector-SideloadedSubtitle (~> 9.9)
+ - THEOplayer-Integration-GoogleCast (~> 9.9)
+ - THEOplayer-Integration-GoogleIMA (~> 9.9)
+ - THEOplayer-Integration-THEOlive (~> 9.9)
+ - THEOplayerSDK-core (~> 9.9)
- react-native-theoplayer-comscore (1.10.0):
- DoubleConversion
- glog
@@ -1622,41 +1622,41 @@ PODS:
- SwiftSubtitles (0.9.1):
- DSFRegex (~> 3.3.1)
- TinyCSV (~> 0.6.1)
- - THEOplayer-Connector-Comscore (9.5.0):
+ - THEOplayer-Connector-Comscore (9.10.1):
- ComScore (~> 6.10.0)
- THEOplayerSDK-core (~> 9)
- - THEOplayer-Connector-Conviva (9.5.0):
+ - THEOplayer-Connector-Conviva (9.10.1):
- ConvivaSDK (= 4.0.51)
- - THEOplayer-Connector-Utilities (>= 9.5.0, ~> 9.5)
+ - THEOplayer-Connector-Utilities (>= 9.10.1, ~> 9.10)
- THEOplayerSDK-core (~> 9)
- THEOplayer-Connector-Nielsen (9.0.0):
- NielsenAppSDK-XC (~> 9)
- THEOplayer-Connector-Utilities (>= 9.0.0, ~> 9.0)
- THEOplayerSDK-core (~> 9)
- - THEOplayer-Connector-SideloadedSubtitle (9.5.0):
+ - THEOplayer-Connector-SideloadedSubtitle (9.10.1):
- Swifter (= 1.5.0)
- SwiftSubtitles (= 0.9.1)
- THEOplayerSDK-core (~> 9)
- - THEOplayer-Connector-Utilities (9.5.0):
+ - THEOplayer-Connector-Utilities (9.10.1):
- ConvivaSDK (= 4.0.51)
- THEOplayerSDK-core (~> 9)
- - THEOplayer-Integration-GoogleCast (9.5.0):
- - THEOplayer-Integration-GoogleCast/Base (= 9.5.0)
- - THEOplayer-Integration-GoogleCast/Dependencies (= 9.5.0)
- - THEOplayer-Integration-GoogleCast/Base (9.5.0)
- - THEOplayer-Integration-GoogleCast/Dependencies (9.5.0):
+ - THEOplayer-Integration-GoogleCast (9.10.1):
+ - THEOplayer-Integration-GoogleCast/Base (= 9.10.1)
+ - THEOplayer-Integration-GoogleCast/Dependencies (= 9.10.1)
+ - THEOplayer-Integration-GoogleCast/Base (9.10.1)
+ - THEOplayer-Integration-GoogleCast/Dependencies (9.10.1):
- google-cast-sdk-dynamic-xcframework (~> 4.8)
- - THEOplayer-Integration-GoogleIMA (9.5.0):
- - THEOplayer-Integration-GoogleIMA/Base (= 9.5.0)
- - THEOplayer-Integration-GoogleIMA/Dependencies (= 9.5.0)
- - THEOplayer-Integration-GoogleIMA/Base (9.5.0)
- - THEOplayer-Integration-GoogleIMA/Dependencies (9.5.0):
+ - THEOplayer-Integration-GoogleIMA (9.10.1):
+ - THEOplayer-Integration-GoogleIMA/Base (= 9.10.1)
+ - THEOplayer-Integration-GoogleIMA/Dependencies (= 9.10.1)
+ - THEOplayer-Integration-GoogleIMA/Base (9.10.1)
+ - THEOplayer-Integration-GoogleIMA/Dependencies (9.10.1):
- GoogleAds-IMA-iOS-SDK (~> 3.18)
- GoogleAds-IMA-tvOS-SDK (~> 4.8)
- - THEOplayer-Integration-THEOlive (9.5.0):
- - THEOplayer-Integration-THEOlive/Base (= 9.5.0)
- - THEOplayer-Integration-THEOlive/Base (9.5.0)
- - THEOplayerSDK-core (9.5.0)
+ - THEOplayer-Integration-THEOlive (9.10.1):
+ - THEOplayer-Integration-THEOlive/Base (= 9.10.1)
+ - THEOplayer-Integration-THEOlive/Base (9.10.1)
+ - THEOplayerSDK-core (9.10.1)
- TinyCSV (0.6.1)
- Yoga (0.0.0)
@@ -1923,83 +1923,83 @@ SPEC CHECKSUMS:
hermes-engine: ac68d6c3169772a7a7f9eeb25dbb5ff87930034f
NielsenAppSDK-XC: a32c6b55d158dde2366152fe13406dea588929d6
PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47
- RCT-Folly: 2d9ee9f24278cbaf99cfdd0720a87c3a8ff152a6
+ RCT-Folly: 4728c42e04357ad445c7048e7c542b59f3ee6b4f
RCTDeprecation: 3d8708756d84c6f6bce6b0e538bbc109ada51385
RCTRequired: 13a733ef574d5b7a99cbb6ed9d2e729aa0980383
RCTTypeSafety: 541082d481bd123e7a985ac75e04536a6b2fc591
React: af752f9ddaffdd4835b5522014db0b2bc15c7780
React-callinvoker: 196463beafe3a3db7a9382124d57d0e1bc2fafbf
- React-Core: c394313d359e3175899ef8889ff06a9d94be9f8f
- React-CoreModules: 9f4f3d996af44ff509454f87942605aae793f4f0
- React-cxxreact: bea5c7ce2c63d5a005621dbe21075afb5699246b
+ React-Core: dbd0eb507eb92ba8ccdbe9e995a253382f0d0659
+ React-CoreModules: 73750929751f3f9d6acb7dc76f73d72b2ffb736e
+ React-cxxreact: 766380b9459a5f4e1d2f9b31832e8fcff6b7be6d
React-debug: 2f519ade026b776867eca46fe4581dfe9b62e5b5
- React-defaultsnativemodule: bf7b67f632601aa3039fe8ad5adaf5675ab2207c
- React-domnativemodule: ff2731cf778ac5e0753a8341c6a9fbe5d436ee7e
- React-Fabric: b70ca05937b2d5027f1110e8b0bd799733332db4
- React-FabricComponents: 0f26d2799f7f414395d961d5b9367263ead359b9
- React-FabricImage: 6605feaddeac81ce252b68256ed4e2e5d8ac49b7
+ React-defaultsnativemodule: 06238b62515b2f45ccac59796e2be6f744e07cc4
+ React-domnativemodule: 548687bd939068141b5982dfcee11839db38c6fc
+ React-Fabric: ca8ae5c40e322a2682dc606a168547e202c0edda
+ React-FabricComponents: b0331e740462e515a3cc32ed48230ccda083ae98
+ React-FabricImage: 722eb881d0040c622f949a2a924d5d2c7e0ae374
React-featureflags: ca676d9c7d20b0dbc5f781bac2c0b3ee16619263
- React-featureflagsnativemodule: 5a8df629249ab10c6e765a41efe9ccc75e20f7d5
- React-graphics: 2df3b86d47f16e6c863defc1d9cb220c2a46111e
- React-hermes: bfb3df16e4d67a4e58d437dd07ddeab3ee8c68d1
- React-idlecallbacksnativemodule: 2796b26e146c11908bd20d3fb6c99faf4aaff0a2
- React-ImageManager: cfc12df8c28cabaf9917937ed6844d3ded0c68e1
- React-jserrorhandler: e03ceddee09d5d57ade8cf439d65a14b6cddce46
- React-jsi: e5d4658e2fe1df30ffd7be89660f997c9187ab4f
- React-jsiexecutor: 75b92bbfdeee55cc1b758574b5641c40d3e1d724
- React-jsinspector: a8266b659d73df806d8dc57d928796a8c2eb8ab1
- React-jsitracing: 17b8fe5f99910033d30c155812544bca9f2a2512
- React-logger: 42594c81767ea1f0c5341d971e8c754d3517b11f
- React-Mapbuffer: a17da7731000c79ef66ee89d9f888426d5e01635
- React-microtasksnativemodule: fbe3567e51a8c22e374e77638d681b65a5119f0a
- react-native-google-cast: 872b05bf12f7db32c2f66818fdd5406474af25f1
- react-native-slider: fc7f35c082abec47e341dfe43657a1c26f38db2f
- react-native-theoplayer: 9fb718c5f2bfe73d93d6ac4d3db9b79769f72b6f
- react-native-theoplayer-comscore: b02ae6fc53965ade5f7a6bd54170d442bd1addda
- react-native-theoplayer-conviva: 8747c7f866c71cda89b16861c64e690689fb3416
- react-native-theoplayer-nielsen: 71609b83a43224e9cd10fed334b6c1c91e6c6157
+ React-featureflagsnativemodule: 3951f061e4d16d59ffc294fdb935b0c9c52ef1e2
+ React-graphics: 582a67f03ec691d7e06a0601567c2131c977d985
+ React-hermes: f28a9afe7951bac61a9a6daa7b76c6416d3461bc
+ React-idlecallbacksnativemodule: a14afed4c635ec0f685dece2580c72719098afce
+ React-ImageManager: 08319519439571ad007ebb5592663b8bb01e442e
+ React-jserrorhandler: cff5ddef8ce3c67098b0c58ed9d6258d67e99f91
+ React-jsi: e57747fd7928672d87537a39bf1ffd031610ba3a
+ React-jsiexecutor: 6c6de186f89a5511a21c47594d173d19565768e3
+ React-jsinspector: 638786af723d5758d6ca973955b9e7ba0f1da20d
+ React-jsitracing: 43fe823d1df0218131e2f46355ba24e1a895cc8b
+ React-logger: 0d08bfa620586b8dc472f58dfbd6217b0d228f2c
+ React-Mapbuffer: d9594fa247e7866b44249d5e04a68ace76af2841
+ React-microtasksnativemodule: a3489ca37b515f6f685ec1a86c8df364343ac578
+ react-native-google-cast: d7bdfd1a0eeba84afde03b9722351ec29543e74c
+ react-native-slider: 4a0f3386a38fc3d2d955efc515aef7096f7d1ee4
+ react-native-theoplayer: ce0550e68da3288301d6292457b92adfcd730c6c
+ react-native-theoplayer-comscore: ebaa08bd40b87f0cb1e1849d94c4113db7f9861a
+ react-native-theoplayer-conviva: 064d394532404ed35ca7d1ccd689fc1de208f73a
+ react-native-theoplayer-nielsen: a8c8b98ba57e03dc662a747b4750c48a3a3f80f5
React-nativeconfig: ea22f0ab525feb865d2e0ed5d7aad156c36abe6b
- React-NativeModulesApple: eb4740b113517d23b482a5bf45ec887561fde447
+ React-NativeModulesApple: 5efee2e69aaa7ff47f40a2918f2b48534a2e431b
React-perflogger: f31660a8693c3444e1832c237ba25a13f613436e
- React-performancetimeline: 4a440850e67b0bbd3466d07f43b27cd36cbd7564
+ React-performancetimeline: dcd29523710add9e90a4f1166d67b78b955a21ce
React-RCTActionSheet: 8c6af175df9c6714ce7a5eba1d5283c0d4b3d084
- React-RCTAnimation: f5c8c43860a8669db69976bfc79e6140d5032d17
- React-RCTAppDelegate: 81c05e40089272a81d13e2c00b4dc0e43d930079
- React-RCTBlob: 5633368a4c5544e0e81f705d5c3176e774b4bc45
- React-RCTFabric: 607efda657391f6e70de8d9d767da5f0f5e82d6a
- React-RCTImage: 8d8866a5c4db6182ecc492e24800115c61882ee1
- React-RCTLinking: f4ad99fd13735cc914224c1015c5abdf7de2c295
- React-RCTNetwork: c31ad41b5485a4ef800ba0ebc56898f8da267c53
- React-RCTSettings: a47ef8bf8f0d112b994fa6e0cfc038e778cbd070
- React-RCTText: b520e0b6254f4ecd362adb9e0baa223ee817dbcc
- React-RCTVibration: 181264593f8b6fc3efa4eeb6267400ee55fa0001
+ React-RCTAnimation: 7eef1a8c9f9159e73f1c6a4c1aee2161213aabc6
+ React-RCTAppDelegate: 8f6d5bd90c1460195a945621ca6db446727327eb
+ React-RCTBlob: 454a83cc3928a4e2ec9543388fc0ad191a2fcb52
+ React-RCTFabric: f0a35f40363698cca6a4da8cc53919cb328a84d4
+ React-RCTImage: d84301136ae487b5db286d6367bb2c477d3a63b2
+ React-RCTLinking: d51889e9321851c0c1432b935495d125a2e2dbbd
+ React-RCTNetwork: 74779cdac22264f1a5d21bb5a98c47dc94d7b2ca
+ React-RCTSettings: 6e07373e02f58f0af009545245b5ada398fb50bc
+ React-RCTText: 5feef8ba6849fb2589616a6c68193a979707ae60
+ React-RCTVibration: e3f84af731628e6b48093c1edf7214449e6917e8
React-rendererconsistency: 041d8ba3309a91bf456063e649e1988eac21810c
- React-rendererdebug: b2059115d1cecb509f9b04e9eafef96d81176f56
+ React-rendererdebug: 4eaba2da7bcb7ce439098a6dfa5c411411f8d4d2
React-rncore: 81e6dabad294ad1f33c88baa760a6b5298213c73
- React-RuntimeApple: fecc3cbae6cf8e19824bc01776be318a62121aca
- React-RuntimeCore: 23a6488c6955b859512830d8a3b309e337817db4
+ React-RuntimeApple: 1e598aa4a4f64a86ec50e3487799c2c9bc1749d5
+ React-RuntimeCore: e09f9b7fa60eda245ab35c823e90f7463a901b8a
React-runtimeexecutor: afa7158e5b848205048c3afc47e828b2ebf09f7d
- React-RuntimeHermes: 46f7d8eb93d4db1263a1056f4f9fbe30d82cbe61
- React-runtimescheduler: bce052173a90c0036e2b7bed44fe6716b5fa3bf7
- React-utils: e7bf11fa100826bb5b011ded0062eccda5067a2a
- ReactCodegen: 20d036906cfefa5f9b6bb2ea5d1808aafe9201c9
- ReactCommon: 944ff65876eb80b58b039f13b5ad8b3e2ad7ef27
- RNDeviceInfo: 98bb51ba1519cd3f19f14e7236b5bb1c312c780f
- RNSVG: 46769c92d1609e617dbf9326ad8a0cff912d0982
+ React-RuntimeHermes: 6d3cbb37c6a99520b89e8f26f51de2d4cf7e053e
+ React-runtimescheduler: 2285ca64c8fa06f6ad5d8af92309d658d9ae9622
+ React-utils: 8289642e20d751967cb4e685956e5197cae2188c
+ ReactCodegen: 873a3cfea4daf5b7f86d49361cc049831a45d840
+ ReactCommon: a1cd388360d4e9545ab8e571ff293606c9ea6687
+ RNDeviceInfo: 59344c19152c4b2b32283005f9737c5c64b42fba
+ RNSVG: 669ed128ab9005090c612a0d627dbecb6ab5c76f
SocketRocket: abac6f5de4d4d62d24e11868d7a2f427e0ef940d
Swifter: e71dd674404923d7f03ebb03f3f222d1c570bc8e
SwiftSubtitles: c659af19d710a2946779015464c0577d07fe4666
- THEOplayer-Connector-Comscore: 7cdab7db28ebb7396bd6f2d11a8e7d33e26abd05
- THEOplayer-Connector-Conviva: 8fe3747ff439f40deaf6a527484bb96101d665a8
+ THEOplayer-Connector-Comscore: aa8dfa0384555041d3a8c02fd1789598e5d56fbd
+ THEOplayer-Connector-Conviva: 9e4bf09269065da5559b154f8d6104c26617a16e
THEOplayer-Connector-Nielsen: dc6d2b2c0701283fe60c1c804d3403b3d8d66181
- THEOplayer-Connector-SideloadedSubtitle: 4e03b39ac277d590fe8fcbe174a00c98635f2a9c
- THEOplayer-Connector-Utilities: 19d73a93fde9e91b165475d647c513e5e9083114
- THEOplayer-Integration-GoogleCast: 05e141d974a3c77e9fe977154354e3d2f51fe012
- THEOplayer-Integration-GoogleIMA: 90010535d28e0de15bb4c1c68977ade2f613a46c
- THEOplayer-Integration-THEOlive: 10256a337e2a249f5cac066fbe6097af5a33c70d
- THEOplayerSDK-core: 86b39a98dbcab0dd5e8ce02a4d741dbdb49551d5
+ THEOplayer-Connector-SideloadedSubtitle: f5a1edab54372c8e3b96b2ccea6fac85db3d6a92
+ THEOplayer-Connector-Utilities: 0fa21bc82f84b4523510dd16ca9cb1786d1ad307
+ THEOplayer-Integration-GoogleCast: 44a44e356f2f8d87e62da127b274d5747d7dafae
+ THEOplayer-Integration-GoogleIMA: 6b74abcebc73aab0c3dea5b2ecb2d5e44ab95b45
+ THEOplayer-Integration-THEOlive: 6ccaaf6b99f3b399b6aadb38ce3b08d539dcc982
+ THEOplayerSDK-core: 65edd54e1b40b9c82cebec53f47b2b7777d81ed9
TinyCSV: fd6228edbcf1c07466ac34b76dac5e052143eaba
- Yoga: 1eb8c4882b3018c344a2ff61c5f2e5c6b1711d82
+ Yoga: 07ebe50bd234e51e5e3e07befa14a3078a0fcbbd
PODFILE CHECKSUM: baa77347c1627215315b6f99b250aab99cddbb2e
diff --git a/apps/e2e/ios/ReactNativeTHEOplayer.xcodeproj/project.pbxproj b/apps/e2e/ios/ReactNativeTHEOplayer.xcodeproj/project.pbxproj
index 44cb66dc..6347aa58 100644
--- a/apps/e2e/ios/ReactNativeTHEOplayer.xcodeproj/project.pbxproj
+++ b/apps/e2e/ios/ReactNativeTHEOplayer.xcodeproj/project.pbxproj
@@ -11,17 +11,17 @@
13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; };
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
- 1D9FB4F5244ADB9A9476E40F /* libPods-ReactNativeTHEOplayer-tvOS-ReactNativeTHEOplayer-tvOSTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 23E00601FCEB429652C6408F /* libPods-ReactNativeTHEOplayer-tvOS-ReactNativeTHEOplayer-tvOSTests.a */; };
2D02E4BC1E0B4A80006451C7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; };
2D02E4BD1E0B4A84006451C7 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
2D02E4BF1E0B4AB3006451C7 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
2DCD954D1E0B4F2C00145EB5 /* ReactNativeTHEOplayerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* ReactNativeTHEOplayerTests.m */; };
+ 2EE1497105BEF36614E65375 /* libPods-ReactNativeTHEOplayer-ReactNativeTHEOplayerTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = CE2DA74F86530FCAA0F76894 /* libPods-ReactNativeTHEOplayer-ReactNativeTHEOplayerTests.a */; };
442BFC3895EC4E39B762450A /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = E13BF0204B80026411EC76D2 /* PrivacyInfo.xcprivacy */; };
- 7D9BA408F65A91301883B2AE /* libPods-ReactNativeTHEOplayer-ReactNativeTHEOplayerTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A1A616D4268BA584D7B7DD45 /* libPods-ReactNativeTHEOplayer-ReactNativeTHEOplayerTests.a */; };
+ 4FB1DB1E9987979DEBCC4FC4 /* libPods-ReactNativeTHEOplayer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2B1D161D72CC81D6F34B818B /* libPods-ReactNativeTHEOplayer.a */; };
+ 70CE312D16DEB809B138E59C /* libPods-ReactNativeTHEOplayer-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 86A3F444751038514D315CC6 /* libPods-ReactNativeTHEOplayer-tvOS.a */; };
81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; };
- D7D6759FBE424E107C798C00 /* libPods-ReactNativeTHEOplayer-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9B1F82D8697B6422C62C08B4 /* libPods-ReactNativeTHEOplayer-tvOS.a */; };
DC6595BC1C39D39B157BFA59 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 7740B1311B6C85C9C1C70CE2 /* PrivacyInfo.xcprivacy */; };
- EA3FB8B3CECC8EC0D507A5E6 /* libPods-ReactNativeTHEOplayer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E6461124ED8CD324BEC84C8F /* libPods-ReactNativeTHEOplayer.a */; };
+ E9DF7D274A28A97A957224C7 /* libPods-ReactNativeTHEOplayer-tvOS-ReactNativeTHEOplayer-tvOSTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C574172A94A8AACB015539FC /* libPods-ReactNativeTHEOplayer-tvOS-ReactNativeTHEOplayer-tvOSTests.a */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -46,33 +46,33 @@
00E356EE1AD99517003FC87E /* ReactNativeTHEOplayerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ReactNativeTHEOplayerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
00E356F21AD99517003FC87E /* ReactNativeTHEOplayerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ReactNativeTHEOplayerTests.m; sourceTree = ""; };
+ 06D65152529DA3A7B6EC728D /* Pods-ReactNativeTHEOplayer.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNativeTHEOplayer.release.xcconfig"; path = "Target Support Files/Pods-ReactNativeTHEOplayer/Pods-ReactNativeTHEOplayer.release.xcconfig"; sourceTree = ""; };
13B07F961A680F5B00A75B9A /* ReactNativeTHEOplayer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ReactNativeTHEOplayer.app; sourceTree = BUILT_PRODUCTS_DIR; };
13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = ReactNativeTHEOplayer/AppDelegate.h; sourceTree = ""; };
13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = ReactNativeTHEOplayer/AppDelegate.m; sourceTree = ""; };
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = ReactNativeTHEOplayer/Images.xcassets; sourceTree = ""; };
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = ReactNativeTHEOplayer/Info.plist; sourceTree = ""; };
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = ReactNativeTHEOplayer/main.m; sourceTree = ""; };
- 212158D9C4053BB12B721822 /* Pods-ReactNativeTHEOplayer.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNativeTHEOplayer.release.xcconfig"; path = "Target Support Files/Pods-ReactNativeTHEOplayer/Pods-ReactNativeTHEOplayer.release.xcconfig"; sourceTree = ""; };
- 23E00601FCEB429652C6408F /* libPods-ReactNativeTHEOplayer-tvOS-ReactNativeTHEOplayer-tvOSTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ReactNativeTHEOplayer-tvOS-ReactNativeTHEOplayer-tvOSTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
26849ED127A3FF7900FFFB02 /* ReactNativeTHEOplayer-tvOS-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ReactNativeTHEOplayer-tvOS-Bridging-Header.h"; sourceTree = ""; };
26849ED227A3FF8800FFFB02 /* ReactNativeTHEOplayer-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ReactNativeTHEOplayer-Bridging-Header.h"; sourceTree = ""; };
+ 2859932C44A7266BC9A26016 /* Pods-ReactNativeTHEOplayer-ReactNativeTHEOplayerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNativeTHEOplayer-ReactNativeTHEOplayerTests.release.xcconfig"; path = "Target Support Files/Pods-ReactNativeTHEOplayer-ReactNativeTHEOplayerTests/Pods-ReactNativeTHEOplayer-ReactNativeTHEOplayerTests.release.xcconfig"; sourceTree = ""; };
+ 2B1869737A6D3574FB9FCB91 /* Pods-ReactNativeTHEOplayer.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNativeTHEOplayer.debug.xcconfig"; path = "Target Support Files/Pods-ReactNativeTHEOplayer/Pods-ReactNativeTHEOplayer.debug.xcconfig"; sourceTree = ""; };
+ 2B1D161D72CC81D6F34B818B /* libPods-ReactNativeTHEOplayer.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ReactNativeTHEOplayer.a"; sourceTree = BUILT_PRODUCTS_DIR; };
2D02E47B1E0B4A5D006451C7 /* ReactNativeTHEOplayer-tvOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "ReactNativeTHEOplayer-tvOS.app"; sourceTree = BUILT_PRODUCTS_DIR; };
2D02E4901E0B4A5D006451C7 /* ReactNativeTHEOplayer-tvOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "ReactNativeTHEOplayer-tvOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
- 37F2476D4FFC19937969BA39 /* Pods-ReactNativeTHEOplayer-ReactNativeTHEOplayerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNativeTHEOplayer-ReactNativeTHEOplayerTests.release.xcconfig"; path = "Target Support Files/Pods-ReactNativeTHEOplayer-ReactNativeTHEOplayerTests/Pods-ReactNativeTHEOplayer-ReactNativeTHEOplayerTests.release.xcconfig"; sourceTree = ""; };
- 53B450B3183AC1FCE970C242 /* Pods-ReactNativeTHEOplayer.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNativeTHEOplayer.debug.xcconfig"; path = "Target Support Files/Pods-ReactNativeTHEOplayer/Pods-ReactNativeTHEOplayer.debug.xcconfig"; sourceTree = ""; };
- 586FDDD06EFF4AC6D6026609 /* Pods-ReactNativeTHEOplayer-tvOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNativeTHEOplayer-tvOS.debug.xcconfig"; path = "Target Support Files/Pods-ReactNativeTHEOplayer-tvOS/Pods-ReactNativeTHEOplayer-tvOS.debug.xcconfig"; sourceTree = ""; };
+ 67508AB782AB1AEF1725FF10 /* Pods-ReactNativeTHEOplayer-tvOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNativeTHEOplayer-tvOS.release.xcconfig"; path = "Target Support Files/Pods-ReactNativeTHEOplayer-tvOS/Pods-ReactNativeTHEOplayer-tvOS.release.xcconfig"; sourceTree = ""; };
7740B1311B6C85C9C1C70CE2 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xml; name = PrivacyInfo.xcprivacy; path = ReactNativeTHEOplayer/PrivacyInfo.xcprivacy; sourceTree = ""; };
81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = ReactNativeTHEOplayer/LaunchScreen.storyboard; sourceTree = ""; };
- 90DCD6370FFDC116ADAF7756 /* Pods-ReactNativeTHEOplayer-tvOS-ReactNativeTHEOplayer-tvOSTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNativeTHEOplayer-tvOS-ReactNativeTHEOplayer-tvOSTests.debug.xcconfig"; path = "Target Support Files/Pods-ReactNativeTHEOplayer-tvOS-ReactNativeTHEOplayer-tvOSTests/Pods-ReactNativeTHEOplayer-tvOS-ReactNativeTHEOplayer-tvOSTests.debug.xcconfig"; sourceTree = ""; };
- 9B1F82D8697B6422C62C08B4 /* libPods-ReactNativeTHEOplayer-tvOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ReactNativeTHEOplayer-tvOS.a"; sourceTree = BUILT_PRODUCTS_DIR; };
- A1A616D4268BA584D7B7DD45 /* libPods-ReactNativeTHEOplayer-ReactNativeTHEOplayerTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ReactNativeTHEOplayer-ReactNativeTHEOplayerTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
- D726618BE2FF02B74D4B3B33 /* Pods-ReactNativeTHEOplayer-tvOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNativeTHEOplayer-tvOS.release.xcconfig"; path = "Target Support Files/Pods-ReactNativeTHEOplayer-tvOS/Pods-ReactNativeTHEOplayer-tvOS.release.xcconfig"; sourceTree = ""; };
+ 86A3F444751038514D315CC6 /* libPods-ReactNativeTHEOplayer-tvOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ReactNativeTHEOplayer-tvOS.a"; sourceTree = BUILT_PRODUCTS_DIR; };
+ 8C4B9785AAB059DC6B233E3B /* Pods-ReactNativeTHEOplayer-tvOS-ReactNativeTHEOplayer-tvOSTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNativeTHEOplayer-tvOS-ReactNativeTHEOplayer-tvOSTests.debug.xcconfig"; path = "Target Support Files/Pods-ReactNativeTHEOplayer-tvOS-ReactNativeTHEOplayer-tvOSTests/Pods-ReactNativeTHEOplayer-tvOS-ReactNativeTHEOplayer-tvOSTests.debug.xcconfig"; sourceTree = ""; };
+ C574172A94A8AACB015539FC /* libPods-ReactNativeTHEOplayer-tvOS-ReactNativeTHEOplayer-tvOSTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ReactNativeTHEOplayer-tvOS-ReactNativeTHEOplayer-tvOSTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
+ CE2DA74F86530FCAA0F76894 /* libPods-ReactNativeTHEOplayer-ReactNativeTHEOplayerTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ReactNativeTHEOplayer-ReactNativeTHEOplayerTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
+ CEEC6FD978D0E9BD7B92494E /* Pods-ReactNativeTHEOplayer-tvOS-ReactNativeTHEOplayer-tvOSTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNativeTHEOplayer-tvOS-ReactNativeTHEOplayer-tvOSTests.release.xcconfig"; path = "Target Support Files/Pods-ReactNativeTHEOplayer-tvOS-ReactNativeTHEOplayer-tvOSTests/Pods-ReactNativeTHEOplayer-tvOS-ReactNativeTHEOplayer-tvOSTests.release.xcconfig"; sourceTree = ""; };
+ D466E8BC201BE02656CD9B59 /* Pods-ReactNativeTHEOplayer-ReactNativeTHEOplayerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNativeTHEOplayer-ReactNativeTHEOplayerTests.debug.xcconfig"; path = "Target Support Files/Pods-ReactNativeTHEOplayer-ReactNativeTHEOplayerTests/Pods-ReactNativeTHEOplayer-ReactNativeTHEOplayerTests.debug.xcconfig"; sourceTree = ""; };
E13BF0204B80026411EC76D2 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xml; name = PrivacyInfo.xcprivacy; path = ReactNativeTHEOplayer/PrivacyInfo.xcprivacy; sourceTree = ""; };
- E6461124ED8CD324BEC84C8F /* libPods-ReactNativeTHEOplayer.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ReactNativeTHEOplayer.a"; sourceTree = BUILT_PRODUCTS_DIR; };
- E94FE6E5DE0E478F2A505A3B /* Pods-ReactNativeTHEOplayer-ReactNativeTHEOplayerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNativeTHEOplayer-ReactNativeTHEOplayerTests.debug.xcconfig"; path = "Target Support Files/Pods-ReactNativeTHEOplayer-ReactNativeTHEOplayerTests/Pods-ReactNativeTHEOplayer-ReactNativeTHEOplayerTests.debug.xcconfig"; sourceTree = ""; };
+ E69795734BECC7F9A40F1181 /* Pods-ReactNativeTHEOplayer-tvOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNativeTHEOplayer-tvOS.debug.xcconfig"; path = "Target Support Files/Pods-ReactNativeTHEOplayer-tvOS/Pods-ReactNativeTHEOplayer-tvOS.debug.xcconfig"; sourceTree = ""; };
ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
ED2971642150620600B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS12.0.sdk/System/Library/Frameworks/JavaScriptCore.framework; sourceTree = DEVELOPER_DIR; };
- FC92E903EC76001BC932F05F /* Pods-ReactNativeTHEOplayer-tvOS-ReactNativeTHEOplayer-tvOSTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNativeTHEOplayer-tvOS-ReactNativeTHEOplayer-tvOSTests.release.xcconfig"; path = "Target Support Files/Pods-ReactNativeTHEOplayer-tvOS-ReactNativeTHEOplayer-tvOSTests/Pods-ReactNativeTHEOplayer-tvOS-ReactNativeTHEOplayer-tvOSTests.release.xcconfig"; sourceTree = ""; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -80,7 +80,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
- 7D9BA408F65A91301883B2AE /* libPods-ReactNativeTHEOplayer-ReactNativeTHEOplayerTests.a in Frameworks */,
+ 2EE1497105BEF36614E65375 /* libPods-ReactNativeTHEOplayer-ReactNativeTHEOplayerTests.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -88,7 +88,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
- EA3FB8B3CECC8EC0D507A5E6 /* libPods-ReactNativeTHEOplayer.a in Frameworks */,
+ 4FB1DB1E9987979DEBCC4FC4 /* libPods-ReactNativeTHEOplayer.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -96,7 +96,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
- D7D6759FBE424E107C798C00 /* libPods-ReactNativeTHEOplayer-tvOS.a in Frameworks */,
+ 70CE312D16DEB809B138E59C /* libPods-ReactNativeTHEOplayer-tvOS.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -104,7 +104,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
- 1D9FB4F5244ADB9A9476E40F /* libPods-ReactNativeTHEOplayer-tvOS-ReactNativeTHEOplayer-tvOSTests.a in Frameworks */,
+ E9DF7D274A28A97A957224C7 /* libPods-ReactNativeTHEOplayer-tvOS-ReactNativeTHEOplayer-tvOSTests.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -150,10 +150,10 @@
children = (
ED297162215061F000B7C4FE /* JavaScriptCore.framework */,
ED2971642150620600B7C4FE /* JavaScriptCore.framework */,
- E6461124ED8CD324BEC84C8F /* libPods-ReactNativeTHEOplayer.a */,
- A1A616D4268BA584D7B7DD45 /* libPods-ReactNativeTHEOplayer-ReactNativeTHEOplayerTests.a */,
- 9B1F82D8697B6422C62C08B4 /* libPods-ReactNativeTHEOplayer-tvOS.a */,
- 23E00601FCEB429652C6408F /* libPods-ReactNativeTHEOplayer-tvOS-ReactNativeTHEOplayer-tvOSTests.a */,
+ 2B1D161D72CC81D6F34B818B /* libPods-ReactNativeTHEOplayer.a */,
+ CE2DA74F86530FCAA0F76894 /* libPods-ReactNativeTHEOplayer-ReactNativeTHEOplayerTests.a */,
+ 86A3F444751038514D315CC6 /* libPods-ReactNativeTHEOplayer-tvOS.a */,
+ C574172A94A8AACB015539FC /* libPods-ReactNativeTHEOplayer-tvOS-ReactNativeTHEOplayer-tvOSTests.a */,
);
name = Frameworks;
sourceTree = "";
@@ -195,14 +195,14 @@
9B1644CBAE2FABCCC6E29A69 /* Pods */ = {
isa = PBXGroup;
children = (
- 53B450B3183AC1FCE970C242 /* Pods-ReactNativeTHEOplayer.debug.xcconfig */,
- 212158D9C4053BB12B721822 /* Pods-ReactNativeTHEOplayer.release.xcconfig */,
- E94FE6E5DE0E478F2A505A3B /* Pods-ReactNativeTHEOplayer-ReactNativeTHEOplayerTests.debug.xcconfig */,
- 37F2476D4FFC19937969BA39 /* Pods-ReactNativeTHEOplayer-ReactNativeTHEOplayerTests.release.xcconfig */,
- 586FDDD06EFF4AC6D6026609 /* Pods-ReactNativeTHEOplayer-tvOS.debug.xcconfig */,
- D726618BE2FF02B74D4B3B33 /* Pods-ReactNativeTHEOplayer-tvOS.release.xcconfig */,
- 90DCD6370FFDC116ADAF7756 /* Pods-ReactNativeTHEOplayer-tvOS-ReactNativeTHEOplayer-tvOSTests.debug.xcconfig */,
- FC92E903EC76001BC932F05F /* Pods-ReactNativeTHEOplayer-tvOS-ReactNativeTHEOplayer-tvOSTests.release.xcconfig */,
+ 2B1869737A6D3574FB9FCB91 /* Pods-ReactNativeTHEOplayer.debug.xcconfig */,
+ 06D65152529DA3A7B6EC728D /* Pods-ReactNativeTHEOplayer.release.xcconfig */,
+ D466E8BC201BE02656CD9B59 /* Pods-ReactNativeTHEOplayer-ReactNativeTHEOplayerTests.debug.xcconfig */,
+ 2859932C44A7266BC9A26016 /* Pods-ReactNativeTHEOplayer-ReactNativeTHEOplayerTests.release.xcconfig */,
+ E69795734BECC7F9A40F1181 /* Pods-ReactNativeTHEOplayer-tvOS.debug.xcconfig */,
+ 67508AB782AB1AEF1725FF10 /* Pods-ReactNativeTHEOplayer-tvOS.release.xcconfig */,
+ 8C4B9785AAB059DC6B233E3B /* Pods-ReactNativeTHEOplayer-tvOS-ReactNativeTHEOplayer-tvOSTests.debug.xcconfig */,
+ CEEC6FD978D0E9BD7B92494E /* Pods-ReactNativeTHEOplayer-tvOS-ReactNativeTHEOplayer-tvOSTests.release.xcconfig */,
);
path = Pods;
sourceTree = "";
@@ -214,12 +214,12 @@
isa = PBXNativeTarget;
buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "ReactNativeTHEOplayerTests" */;
buildPhases = (
- BF7D9DA46C8DD41F30E94E14 /* [CP] Check Pods Manifest.lock */,
+ 5526C01D810116E99F3A4679 /* [CP] Check Pods Manifest.lock */,
00E356EA1AD99517003FC87E /* Sources */,
00E356EB1AD99517003FC87E /* Frameworks */,
00E356EC1AD99517003FC87E /* Resources */,
- 5BA2B0560E7D7CE9AF0D0818 /* [CP] Embed Pods Frameworks */,
- 0B8CC744116E1B5E5B20EA04 /* [CP] Copy Pods Resources */,
+ AF252140E32770FE8BFE8D3F /* [CP] Embed Pods Frameworks */,
+ 086C153BFE3C5915E73DC4C0 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@@ -235,14 +235,14 @@
isa = PBXNativeTarget;
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "ReactNativeTHEOplayer" */;
buildPhases = (
- B9E191269F06C2C6DE0B7BEE /* [CP] Check Pods Manifest.lock */,
+ 7BBA710A33E470D2F583B9A6 /* [CP] Check Pods Manifest.lock */,
FD10A7F022414F080027D42C /* Start Packager */,
13B07F871A680F5B00A75B9A /* Sources */,
13B07F8C1A680F5B00A75B9A /* Frameworks */,
13B07F8E1A680F5B00A75B9A /* Resources */,
00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
- FFBBB750AB49D2A12D4B9411 /* [CP] Embed Pods Frameworks */,
- 748F9736B5DB84741462615C /* [CP] Copy Pods Resources */,
+ 1D15609091359AD4D3ABA416 /* [CP] Embed Pods Frameworks */,
+ 0CB8C49FAC1F771517CA3173 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@@ -257,14 +257,14 @@
isa = PBXNativeTarget;
buildConfigurationList = 2D02E4BA1E0B4A5E006451C7 /* Build configuration list for PBXNativeTarget "ReactNativeTHEOplayer-tvOS" */;
buildPhases = (
- 46AD3B3302DE9D5FAFA699CC /* [CP] Check Pods Manifest.lock */,
+ 4B57619928400C79996728F6 /* [CP] Check Pods Manifest.lock */,
FD10A7F122414F3F0027D42C /* Start Packager */,
2D02E4771E0B4A5D006451C7 /* Sources */,
2D02E4781E0B4A5D006451C7 /* Frameworks */,
2D02E4791E0B4A5D006451C7 /* Resources */,
2D02E4CB1E0B4B27006451C7 /* Bundle React Native Code And Images */,
- 3EAE09C2B98A8448EAB946E9 /* [CP] Embed Pods Frameworks */,
- 19B54E206FAAF7D707797670 /* [CP] Copy Pods Resources */,
+ B8D57C04307543F132F63F30 /* [CP] Embed Pods Frameworks */,
+ A898285FBD4906492CE0B89C /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@@ -279,12 +279,12 @@
isa = PBXNativeTarget;
buildConfigurationList = 2D02E4BB1E0B4A5E006451C7 /* Build configuration list for PBXNativeTarget "ReactNativeTHEOplayer-tvOSTests" */;
buildPhases = (
- AB3A88D1CB03C39A24F1F209 /* [CP] Check Pods Manifest.lock */,
+ B5D3C1C3CFB215CE85008475 /* [CP] Check Pods Manifest.lock */,
2D02E48C1E0B4A5D006451C7 /* Sources */,
2D02E48D1E0B4A5D006451C7 /* Frameworks */,
2D02E48E1E0B4A5D006451C7 /* Resources */,
- 683118538B5068DC1C841822 /* [CP] Embed Pods Frameworks */,
- 28E824AD327E0F20519619D8 /* [CP] Copy Pods Resources */,
+ AA539643D5EC434F1B2CA0F5 /* [CP] Embed Pods Frameworks */,
+ 16EBC9494DF6037754DC5E54 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@@ -395,7 +395,7 @@
shellPath = /bin/sh;
shellScript = "export NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh";
};
- 0B8CC744116E1B5E5B20EA04 /* [CP] Copy Pods Resources */ = {
+ 086C153BFE3C5915E73DC4C0 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -431,26 +431,28 @@
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ReactNativeTHEOplayer-ReactNativeTHEOplayerTests/Pods-ReactNativeTHEOplayer-ReactNativeTHEOplayerTests-resources.sh\"\n";
showEnvVarsInLog = 0;
};
- 19B54E206FAAF7D707797670 /* [CP] Copy Pods Resources */ = {
+ 0CB8C49FAC1F771517CA3173 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
- "${PODS_ROOT}/Target Support Files/Pods-ReactNativeTHEOplayer-tvOS/Pods-ReactNativeTHEOplayer-tvOS-resources.sh",
- "${PODS_CONFIGURATION_BUILD_DIR}/ComScore-tvOS/SCORBundle.bundle",
- "${PODS_CONFIGURATION_BUILD_DIR}/RCT-Folly-tvOS/RCT-Folly_privacy.bundle",
- "${PODS_CONFIGURATION_BUILD_DIR}/RNDeviceInfo-tvOS/RNDeviceInfoPrivacyInfo.bundle",
- "${PODS_CONFIGURATION_BUILD_DIR}/RNSVG-tvOS/RNSVGFilters.bundle",
- "${PODS_CONFIGURATION_BUILD_DIR}/React-Core-tvOS/React-Core_privacy.bundle",
- "${PODS_CONFIGURATION_BUILD_DIR}/React-cxxreact-tvOS/React-cxxreact_privacy.bundle",
- "${PODS_CONFIGURATION_BUILD_DIR}/boost-tvOS/boost_privacy.bundle",
- "${PODS_CONFIGURATION_BUILD_DIR}/glog-tvOS/glog_privacy.bundle",
+ "${PODS_ROOT}/Target Support Files/Pods-ReactNativeTHEOplayer/Pods-ReactNativeTHEOplayer-resources.sh",
+ "${PODS_CONFIGURATION_BUILD_DIR}/ComScore-iOS/SCORBundle.bundle",
+ "${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC/FBLPromises_Privacy.bundle",
+ "${PODS_CONFIGURATION_BUILD_DIR}/RCT-Folly-iOS/RCT-Folly_privacy.bundle",
+ "${PODS_CONFIGURATION_BUILD_DIR}/RNDeviceInfo-iOS/RNDeviceInfoPrivacyInfo.bundle",
+ "${PODS_CONFIGURATION_BUILD_DIR}/RNSVG-iOS/RNSVGFilters.bundle",
+ "${PODS_CONFIGURATION_BUILD_DIR}/React-Core-iOS/React-Core_privacy.bundle",
+ "${PODS_CONFIGURATION_BUILD_DIR}/React-cxxreact-iOS/React-cxxreact_privacy.bundle",
+ "${PODS_CONFIGURATION_BUILD_DIR}/boost-iOS/boost_privacy.bundle",
+ "${PODS_CONFIGURATION_BUILD_DIR}/glog-iOS/glog_privacy.bundle",
"${PODS_ROOT}/../../node_modules/react-native-theoplayer/ios/style.css",
);
name = "[CP] Copy Pods Resources";
outputPaths = (
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/SCORBundle.bundle",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FBLPromises_Privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RCT-Folly_privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNDeviceInfoPrivacyInfo.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNSVGFilters.bundle",
@@ -462,10 +464,10 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ReactNativeTHEOplayer-tvOS/Pods-ReactNativeTHEOplayer-tvOS-resources.sh\"\n";
+ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ReactNativeTHEOplayer/Pods-ReactNativeTHEOplayer-resources.sh\"\n";
showEnvVarsInLog = 0;
};
- 28E824AD327E0F20519619D8 /* [CP] Copy Pods Resources */ = {
+ 16EBC9494DF6037754DC5E54 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -499,51 +501,55 @@
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ReactNativeTHEOplayer-tvOS-ReactNativeTHEOplayer-tvOSTests/Pods-ReactNativeTHEOplayer-tvOS-ReactNativeTHEOplayer-tvOSTests-resources.sh\"\n";
showEnvVarsInLog = 0;
};
- 2D02E4CB1E0B4B27006451C7 /* Bundle React Native Code And Images */ = {
+ 1D15609091359AD4D3ABA416 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
- );
- name = "Bundle React Native Code And Images";
- outputPaths = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = /bin/sh;
- shellScript = "export NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh";
- };
- 3EAE09C2B98A8448EAB946E9 /* [CP] Embed Pods Frameworks */ = {
- isa = PBXShellScriptBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- inputPaths = (
- "${PODS_ROOT}/Target Support Files/Pods-ReactNativeTHEOplayer-tvOS/Pods-ReactNativeTHEOplayer-tvOS-frameworks.sh",
+ "${PODS_ROOT}/Target Support Files/Pods-ReactNativeTHEOplayer/Pods-ReactNativeTHEOplayer-frameworks.sh",
"${PODS_XCFRAMEWORKS_BUILD_DIR}/ComScore/Dynamic/ComScore.framework/ComScore",
+ "${PODS_XCFRAMEWORKS_BUILD_DIR}/GoogleAds-IMA-iOS-SDK/GoogleInteractiveMediaAds.framework/GoogleInteractiveMediaAds",
"${PODS_XCFRAMEWORKS_BUILD_DIR}/NielsenAppSDK-XC/NielsenAppApi.framework/NielsenAppApi",
+ "${PODS_XCFRAMEWORKS_BUILD_DIR}/THEOplayer-Integration-GoogleCast/Base/THEOplayerGoogleCastIntegration.framework/THEOplayerGoogleCastIntegration",
"${PODS_XCFRAMEWORKS_BUILD_DIR}/THEOplayer-Integration-GoogleIMA/Base/THEOplayerGoogleIMAIntegration.framework/THEOplayerGoogleIMAIntegration",
"${PODS_XCFRAMEWORKS_BUILD_DIR}/THEOplayer-Integration-THEOlive/Base/THEOplayerTHEOliveIntegration.framework/THEOplayerTHEOliveIntegration",
"${PODS_XCFRAMEWORKS_BUILD_DIR}/THEOplayerSDK-core/THEOplayerSDK.framework/THEOplayerSDK",
+ "${PODS_XCFRAMEWORKS_BUILD_DIR}/google-cast-sdk-dynamic-xcframework/GoogleCast.framework/GoogleCast",
"${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes-engine/Pre-built/hermes.framework/hermes",
- "${PODS_XCFRAMEWORKS_BUILD_DIR}/GoogleAds-IMA-tvOS-SDK/GoogleInteractiveMediaAds.framework/GoogleInteractiveMediaAds",
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ComScore.framework",
+ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleInteractiveMediaAds.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NielsenAppApi.framework",
+ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/THEOplayerGoogleCastIntegration.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/THEOplayerGoogleIMAIntegration.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/THEOplayerTHEOliveIntegration.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/THEOplayerSDK.framework",
+ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleCast.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/hermes.framework",
- "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleInteractiveMediaAds.framework",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ReactNativeTHEOplayer-tvOS/Pods-ReactNativeTHEOplayer-tvOS-frameworks.sh\"\n";
+ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ReactNativeTHEOplayer/Pods-ReactNativeTHEOplayer-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
- 46AD3B3302DE9D5FAFA699CC /* [CP] Check Pods Manifest.lock */ = {
+ 2D02E4CB1E0B4B27006451C7 /* Bundle React Native Code And Images */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Bundle React Native Code And Images";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "export NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh";
+ };
+ 4B57619928400C79996728F6 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -565,92 +571,70 @@
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
- 5BA2B0560E7D7CE9AF0D0818 /* [CP] Embed Pods Frameworks */ = {
+ 5526C01D810116E99F3A4679 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
+ inputFileListPaths = (
+ );
inputPaths = (
- "${PODS_ROOT}/Target Support Files/Pods-ReactNativeTHEOplayer-ReactNativeTHEOplayerTests/Pods-ReactNativeTHEOplayer-ReactNativeTHEOplayerTests-frameworks.sh",
- "${PODS_XCFRAMEWORKS_BUILD_DIR}/ComScore/Dynamic/ComScore.framework/ComScore",
- "${PODS_XCFRAMEWORKS_BUILD_DIR}/GoogleAds-IMA-iOS-SDK/GoogleInteractiveMediaAds.framework/GoogleInteractiveMediaAds",
- "${PODS_XCFRAMEWORKS_BUILD_DIR}/NielsenAppSDK-XC/NielsenAppApi.framework/NielsenAppApi",
- "${PODS_XCFRAMEWORKS_BUILD_DIR}/THEOplayer-Integration-GoogleCast/Base/THEOplayerGoogleCastIntegration.framework/THEOplayerGoogleCastIntegration",
- "${PODS_XCFRAMEWORKS_BUILD_DIR}/THEOplayer-Integration-GoogleIMA/Base/THEOplayerGoogleIMAIntegration.framework/THEOplayerGoogleIMAIntegration",
- "${PODS_XCFRAMEWORKS_BUILD_DIR}/THEOplayer-Integration-THEOlive/Base/THEOplayerTHEOliveIntegration.framework/THEOplayerTHEOliveIntegration",
- "${PODS_XCFRAMEWORKS_BUILD_DIR}/THEOplayerSDK-core/THEOplayerSDK.framework/THEOplayerSDK",
- "${PODS_XCFRAMEWORKS_BUILD_DIR}/google-cast-sdk-dynamic-xcframework/GoogleCast.framework/GoogleCast",
- "${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes-engine/Pre-built/hermes.framework/hermes",
+ "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
+ "${PODS_ROOT}/Manifest.lock",
+ );
+ name = "[CP] Check Pods Manifest.lock";
+ outputFileListPaths = (
);
- name = "[CP] Embed Pods Frameworks";
outputPaths = (
- "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ComScore.framework",
- "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleInteractiveMediaAds.framework",
- "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NielsenAppApi.framework",
- "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/THEOplayerGoogleCastIntegration.framework",
- "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/THEOplayerGoogleIMAIntegration.framework",
- "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/THEOplayerTHEOliveIntegration.framework",
- "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/THEOplayerSDK.framework",
- "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleCast.framework",
- "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/hermes.framework",
+ "$(DERIVED_FILE_DIR)/Pods-ReactNativeTHEOplayer-ReactNativeTHEOplayerTests-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ReactNativeTHEOplayer-ReactNativeTHEOplayerTests/Pods-ReactNativeTHEOplayer-ReactNativeTHEOplayerTests-frameworks.sh\"\n";
+ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
- 683118538B5068DC1C841822 /* [CP] Embed Pods Frameworks */ = {
+ 7BBA710A33E470D2F583B9A6 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
+ inputFileListPaths = (
+ );
inputPaths = (
- "${PODS_ROOT}/Target Support Files/Pods-ReactNativeTHEOplayer-tvOS-ReactNativeTHEOplayer-tvOSTests/Pods-ReactNativeTHEOplayer-tvOS-ReactNativeTHEOplayer-tvOSTests-frameworks.sh",
- "${PODS_XCFRAMEWORKS_BUILD_DIR}/ComScore/Dynamic/ComScore.framework/ComScore",
- "${PODS_XCFRAMEWORKS_BUILD_DIR}/NielsenAppSDK-XC/NielsenAppApi.framework/NielsenAppApi",
- "${PODS_XCFRAMEWORKS_BUILD_DIR}/THEOplayer-Integration-GoogleIMA/Base/THEOplayerGoogleIMAIntegration.framework/THEOplayerGoogleIMAIntegration",
- "${PODS_XCFRAMEWORKS_BUILD_DIR}/THEOplayer-Integration-THEOlive/Base/THEOplayerTHEOliveIntegration.framework/THEOplayerTHEOliveIntegration",
- "${PODS_XCFRAMEWORKS_BUILD_DIR}/THEOplayerSDK-core/THEOplayerSDK.framework/THEOplayerSDK",
- "${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes-engine/Pre-built/hermes.framework/hermes",
- "${PODS_XCFRAMEWORKS_BUILD_DIR}/GoogleAds-IMA-tvOS-SDK/GoogleInteractiveMediaAds.framework/GoogleInteractiveMediaAds",
+ "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
+ "${PODS_ROOT}/Manifest.lock",
+ );
+ name = "[CP] Check Pods Manifest.lock";
+ outputFileListPaths = (
);
- name = "[CP] Embed Pods Frameworks";
outputPaths = (
- "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ComScore.framework",
- "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NielsenAppApi.framework",
- "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/THEOplayerGoogleIMAIntegration.framework",
- "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/THEOplayerTHEOliveIntegration.framework",
- "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/THEOplayerSDK.framework",
- "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/hermes.framework",
- "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleInteractiveMediaAds.framework",
+ "$(DERIVED_FILE_DIR)/Pods-ReactNativeTHEOplayer-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ReactNativeTHEOplayer-tvOS-ReactNativeTHEOplayer-tvOSTests/Pods-ReactNativeTHEOplayer-tvOS-ReactNativeTHEOplayer-tvOSTests-frameworks.sh\"\n";
+ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
- 748F9736B5DB84741462615C /* [CP] Copy Pods Resources */ = {
+ A898285FBD4906492CE0B89C /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
- "${PODS_ROOT}/Target Support Files/Pods-ReactNativeTHEOplayer/Pods-ReactNativeTHEOplayer-resources.sh",
- "${PODS_CONFIGURATION_BUILD_DIR}/ComScore-iOS/SCORBundle.bundle",
- "${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC/FBLPromises_Privacy.bundle",
- "${PODS_CONFIGURATION_BUILD_DIR}/RCT-Folly-iOS/RCT-Folly_privacy.bundle",
- "${PODS_CONFIGURATION_BUILD_DIR}/RNDeviceInfo-iOS/RNDeviceInfoPrivacyInfo.bundle",
- "${PODS_CONFIGURATION_BUILD_DIR}/RNSVG-iOS/RNSVGFilters.bundle",
- "${PODS_CONFIGURATION_BUILD_DIR}/React-Core-iOS/React-Core_privacy.bundle",
- "${PODS_CONFIGURATION_BUILD_DIR}/React-cxxreact-iOS/React-cxxreact_privacy.bundle",
- "${PODS_CONFIGURATION_BUILD_DIR}/boost-iOS/boost_privacy.bundle",
- "${PODS_CONFIGURATION_BUILD_DIR}/glog-iOS/glog_privacy.bundle",
+ "${PODS_ROOT}/Target Support Files/Pods-ReactNativeTHEOplayer-tvOS/Pods-ReactNativeTHEOplayer-tvOS-resources.sh",
+ "${PODS_CONFIGURATION_BUILD_DIR}/ComScore-tvOS/SCORBundle.bundle",
+ "${PODS_CONFIGURATION_BUILD_DIR}/RCT-Folly-tvOS/RCT-Folly_privacy.bundle",
+ "${PODS_CONFIGURATION_BUILD_DIR}/RNDeviceInfo-tvOS/RNDeviceInfoPrivacyInfo.bundle",
+ "${PODS_CONFIGURATION_BUILD_DIR}/RNSVG-tvOS/RNSVGFilters.bundle",
+ "${PODS_CONFIGURATION_BUILD_DIR}/React-Core-tvOS/React-Core_privacy.bundle",
+ "${PODS_CONFIGURATION_BUILD_DIR}/React-cxxreact-tvOS/React-cxxreact_privacy.bundle",
+ "${PODS_CONFIGURATION_BUILD_DIR}/boost-tvOS/boost_privacy.bundle",
+ "${PODS_CONFIGURATION_BUILD_DIR}/glog-tvOS/glog_privacy.bundle",
"${PODS_ROOT}/../../node_modules/react-native-theoplayer/ios/style.css",
);
name = "[CP] Copy Pods Resources";
outputPaths = (
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/SCORBundle.bundle",
- "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FBLPromises_Privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RCT-Folly_privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNDeviceInfoPrivacyInfo.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNSVGFilters.bundle",
@@ -662,54 +646,74 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ReactNativeTHEOplayer/Pods-ReactNativeTHEOplayer-resources.sh\"\n";
+ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ReactNativeTHEOplayer-tvOS/Pods-ReactNativeTHEOplayer-tvOS-resources.sh\"\n";
showEnvVarsInLog = 0;
};
- AB3A88D1CB03C39A24F1F209 /* [CP] Check Pods Manifest.lock */ = {
+ AA539643D5EC434F1B2CA0F5 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
- inputFileListPaths = (
- );
inputPaths = (
- "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
- "${PODS_ROOT}/Manifest.lock",
- );
- name = "[CP] Check Pods Manifest.lock";
- outputFileListPaths = (
+ "${PODS_ROOT}/Target Support Files/Pods-ReactNativeTHEOplayer-tvOS-ReactNativeTHEOplayer-tvOSTests/Pods-ReactNativeTHEOplayer-tvOS-ReactNativeTHEOplayer-tvOSTests-frameworks.sh",
+ "${PODS_XCFRAMEWORKS_BUILD_DIR}/ComScore/Dynamic/ComScore.framework/ComScore",
+ "${PODS_XCFRAMEWORKS_BUILD_DIR}/NielsenAppSDK-XC/NielsenAppApi.framework/NielsenAppApi",
+ "${PODS_XCFRAMEWORKS_BUILD_DIR}/THEOplayer-Integration-GoogleIMA/Base/THEOplayerGoogleIMAIntegration.framework/THEOplayerGoogleIMAIntegration",
+ "${PODS_XCFRAMEWORKS_BUILD_DIR}/THEOplayer-Integration-THEOlive/Base/THEOplayerTHEOliveIntegration.framework/THEOplayerTHEOliveIntegration",
+ "${PODS_XCFRAMEWORKS_BUILD_DIR}/THEOplayerSDK-core/THEOplayerSDK.framework/THEOplayerSDK",
+ "${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes-engine/Pre-built/hermes.framework/hermes",
+ "${PODS_XCFRAMEWORKS_BUILD_DIR}/GoogleAds-IMA-tvOS-SDK/GoogleInteractiveMediaAds.framework/GoogleInteractiveMediaAds",
);
+ name = "[CP] Embed Pods Frameworks";
outputPaths = (
- "$(DERIVED_FILE_DIR)/Pods-ReactNativeTHEOplayer-tvOS-ReactNativeTHEOplayer-tvOSTests-checkManifestLockResult.txt",
+ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ComScore.framework",
+ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NielsenAppApi.framework",
+ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/THEOplayerGoogleIMAIntegration.framework",
+ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/THEOplayerTHEOliveIntegration.framework",
+ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/THEOplayerSDK.framework",
+ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/hermes.framework",
+ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleInteractiveMediaAds.framework",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
+ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ReactNativeTHEOplayer-tvOS-ReactNativeTHEOplayer-tvOSTests/Pods-ReactNativeTHEOplayer-tvOS-ReactNativeTHEOplayer-tvOSTests-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
- B9E191269F06C2C6DE0B7BEE /* [CP] Check Pods Manifest.lock */ = {
+ AF252140E32770FE8BFE8D3F /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
- inputFileListPaths = (
- );
inputPaths = (
- "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
- "${PODS_ROOT}/Manifest.lock",
- );
- name = "[CP] Check Pods Manifest.lock";
- outputFileListPaths = (
+ "${PODS_ROOT}/Target Support Files/Pods-ReactNativeTHEOplayer-ReactNativeTHEOplayerTests/Pods-ReactNativeTHEOplayer-ReactNativeTHEOplayerTests-frameworks.sh",
+ "${PODS_XCFRAMEWORKS_BUILD_DIR}/ComScore/Dynamic/ComScore.framework/ComScore",
+ "${PODS_XCFRAMEWORKS_BUILD_DIR}/GoogleAds-IMA-iOS-SDK/GoogleInteractiveMediaAds.framework/GoogleInteractiveMediaAds",
+ "${PODS_XCFRAMEWORKS_BUILD_DIR}/NielsenAppSDK-XC/NielsenAppApi.framework/NielsenAppApi",
+ "${PODS_XCFRAMEWORKS_BUILD_DIR}/THEOplayer-Integration-GoogleCast/Base/THEOplayerGoogleCastIntegration.framework/THEOplayerGoogleCastIntegration",
+ "${PODS_XCFRAMEWORKS_BUILD_DIR}/THEOplayer-Integration-GoogleIMA/Base/THEOplayerGoogleIMAIntegration.framework/THEOplayerGoogleIMAIntegration",
+ "${PODS_XCFRAMEWORKS_BUILD_DIR}/THEOplayer-Integration-THEOlive/Base/THEOplayerTHEOliveIntegration.framework/THEOplayerTHEOliveIntegration",
+ "${PODS_XCFRAMEWORKS_BUILD_DIR}/THEOplayerSDK-core/THEOplayerSDK.framework/THEOplayerSDK",
+ "${PODS_XCFRAMEWORKS_BUILD_DIR}/google-cast-sdk-dynamic-xcframework/GoogleCast.framework/GoogleCast",
+ "${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes-engine/Pre-built/hermes.framework/hermes",
);
+ name = "[CP] Embed Pods Frameworks";
outputPaths = (
- "$(DERIVED_FILE_DIR)/Pods-ReactNativeTHEOplayer-checkManifestLockResult.txt",
+ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ComScore.framework",
+ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleInteractiveMediaAds.framework",
+ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NielsenAppApi.framework",
+ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/THEOplayerGoogleCastIntegration.framework",
+ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/THEOplayerGoogleIMAIntegration.framework",
+ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/THEOplayerTHEOliveIntegration.framework",
+ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/THEOplayerSDK.framework",
+ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleCast.framework",
+ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/hermes.framework",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
+ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ReactNativeTHEOplayer-ReactNativeTHEOplayerTests/Pods-ReactNativeTHEOplayer-ReactNativeTHEOplayerTests-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
- BF7D9DA46C8DD41F30E94E14 /* [CP] Check Pods Manifest.lock */ = {
+ B5D3C1C3CFB215CE85008475 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -724,33 +728,44 @@
outputFileListPaths = (
);
outputPaths = (
- "$(DERIVED_FILE_DIR)/Pods-ReactNativeTHEOplayer-ReactNativeTHEOplayerTests-checkManifestLockResult.txt",
+ "$(DERIVED_FILE_DIR)/Pods-ReactNativeTHEOplayer-tvOS-ReactNativeTHEOplayer-tvOSTests-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
- FD10A7F022414F080027D42C /* Start Packager */ = {
+ B8D57C04307543F132F63F30 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
- inputFileListPaths = (
- );
inputPaths = (
+ "${PODS_ROOT}/Target Support Files/Pods-ReactNativeTHEOplayer-tvOS/Pods-ReactNativeTHEOplayer-tvOS-frameworks.sh",
+ "${PODS_XCFRAMEWORKS_BUILD_DIR}/ComScore/Dynamic/ComScore.framework/ComScore",
+ "${PODS_XCFRAMEWORKS_BUILD_DIR}/NielsenAppSDK-XC/NielsenAppApi.framework/NielsenAppApi",
+ "${PODS_XCFRAMEWORKS_BUILD_DIR}/THEOplayer-Integration-GoogleIMA/Base/THEOplayerGoogleIMAIntegration.framework/THEOplayerGoogleIMAIntegration",
+ "${PODS_XCFRAMEWORKS_BUILD_DIR}/THEOplayer-Integration-THEOlive/Base/THEOplayerTHEOliveIntegration.framework/THEOplayerTHEOliveIntegration",
+ "${PODS_XCFRAMEWORKS_BUILD_DIR}/THEOplayerSDK-core/THEOplayerSDK.framework/THEOplayerSDK",
+ "${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes-engine/Pre-built/hermes.framework/hermes",
+ "${PODS_XCFRAMEWORKS_BUILD_DIR}/GoogleAds-IMA-tvOS-SDK/GoogleInteractiveMediaAds.framework/GoogleInteractiveMediaAds",
);
- name = "Start Packager";
- outputFileListPaths = (
- );
+ name = "[CP] Embed Pods Frameworks";
outputPaths = (
+ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ComScore.framework",
+ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NielsenAppApi.framework",
+ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/THEOplayerGoogleIMAIntegration.framework",
+ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/THEOplayerTHEOliveIntegration.framework",
+ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/THEOplayerSDK.framework",
+ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/hermes.framework",
+ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleInteractiveMediaAds.framework",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "export RCT_METRO_PORT=\"${RCT_METRO_PORT:=8081}\"\necho \"export RCT_METRO_PORT=${RCT_METRO_PORT}\" > \"${SRCROOT}/../node_modules/react-native/scripts/.packager.env\"\nif [ -z \"${RCT_NO_LAUNCH_PACKAGER+xxx}\" ] ; then\n if nc -w 5 -z localhost ${RCT_METRO_PORT} ; then\n if ! curl -s \"http://localhost:${RCT_METRO_PORT}/status\" | grep -q \"packager-status:running\" ; then\n echo \"Port ${RCT_METRO_PORT} already in use, packager is either not running or not running correctly\"\n exit 2\n fi\n else\n open \"$SRCROOT/../node_modules/react-native/scripts/launchPackager.command\" || echo \"Can't start packager automatically\"\n fi\nfi\n";
+ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ReactNativeTHEOplayer-tvOS/Pods-ReactNativeTHEOplayer-tvOS-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
- FD10A7F122414F3F0027D42C /* Start Packager */ = {
+ FD10A7F022414F080027D42C /* Start Packager */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -769,38 +784,23 @@
shellScript = "export RCT_METRO_PORT=\"${RCT_METRO_PORT:=8081}\"\necho \"export RCT_METRO_PORT=${RCT_METRO_PORT}\" > \"${SRCROOT}/../node_modules/react-native/scripts/.packager.env\"\nif [ -z \"${RCT_NO_LAUNCH_PACKAGER+xxx}\" ] ; then\n if nc -w 5 -z localhost ${RCT_METRO_PORT} ; then\n if ! curl -s \"http://localhost:${RCT_METRO_PORT}/status\" | grep -q \"packager-status:running\" ; then\n echo \"Port ${RCT_METRO_PORT} already in use, packager is either not running or not running correctly\"\n exit 2\n fi\n else\n open \"$SRCROOT/../node_modules/react-native/scripts/launchPackager.command\" || echo \"Can't start packager automatically\"\n fi\nfi\n";
showEnvVarsInLog = 0;
};
- FFBBB750AB49D2A12D4B9411 /* [CP] Embed Pods Frameworks */ = {
+ FD10A7F122414F3F0027D42C /* Start Packager */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
+ inputFileListPaths = (
+ );
inputPaths = (
- "${PODS_ROOT}/Target Support Files/Pods-ReactNativeTHEOplayer/Pods-ReactNativeTHEOplayer-frameworks.sh",
- "${PODS_XCFRAMEWORKS_BUILD_DIR}/ComScore/Dynamic/ComScore.framework/ComScore",
- "${PODS_XCFRAMEWORKS_BUILD_DIR}/GoogleAds-IMA-iOS-SDK/GoogleInteractiveMediaAds.framework/GoogleInteractiveMediaAds",
- "${PODS_XCFRAMEWORKS_BUILD_DIR}/NielsenAppSDK-XC/NielsenAppApi.framework/NielsenAppApi",
- "${PODS_XCFRAMEWORKS_BUILD_DIR}/THEOplayer-Integration-GoogleCast/Base/THEOplayerGoogleCastIntegration.framework/THEOplayerGoogleCastIntegration",
- "${PODS_XCFRAMEWORKS_BUILD_DIR}/THEOplayer-Integration-GoogleIMA/Base/THEOplayerGoogleIMAIntegration.framework/THEOplayerGoogleIMAIntegration",
- "${PODS_XCFRAMEWORKS_BUILD_DIR}/THEOplayer-Integration-THEOlive/Base/THEOplayerTHEOliveIntegration.framework/THEOplayerTHEOliveIntegration",
- "${PODS_XCFRAMEWORKS_BUILD_DIR}/THEOplayerSDK-core/THEOplayerSDK.framework/THEOplayerSDK",
- "${PODS_XCFRAMEWORKS_BUILD_DIR}/google-cast-sdk-dynamic-xcframework/GoogleCast.framework/GoogleCast",
- "${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes-engine/Pre-built/hermes.framework/hermes",
);
- name = "[CP] Embed Pods Frameworks";
+ name = "Start Packager";
+ outputFileListPaths = (
+ );
outputPaths = (
- "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ComScore.framework",
- "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleInteractiveMediaAds.framework",
- "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NielsenAppApi.framework",
- "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/THEOplayerGoogleCastIntegration.framework",
- "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/THEOplayerGoogleIMAIntegration.framework",
- "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/THEOplayerTHEOliveIntegration.framework",
- "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/THEOplayerSDK.framework",
- "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleCast.framework",
- "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/hermes.framework",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ReactNativeTHEOplayer/Pods-ReactNativeTHEOplayer-frameworks.sh\"\n";
+ shellScript = "export RCT_METRO_PORT=\"${RCT_METRO_PORT:=8081}\"\necho \"export RCT_METRO_PORT=${RCT_METRO_PORT}\" > \"${SRCROOT}/../node_modules/react-native/scripts/.packager.env\"\nif [ -z \"${RCT_NO_LAUNCH_PACKAGER+xxx}\" ] ; then\n if nc -w 5 -z localhost ${RCT_METRO_PORT} ; then\n if ! curl -s \"http://localhost:${RCT_METRO_PORT}/status\" | grep -q \"packager-status:running\" ; then\n echo \"Port ${RCT_METRO_PORT} already in use, packager is either not running or not running correctly\"\n exit 2\n fi\n else\n open \"$SRCROOT/../node_modules/react-native/scripts/launchPackager.command\" || echo \"Can't start packager automatically\"\n fi\nfi\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
@@ -858,7 +858,7 @@
/* Begin XCBuildConfiguration section */
00E356F61AD99517003FC87E /* Debug */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = E94FE6E5DE0E478F2A505A3B /* Pods-ReactNativeTHEOplayer-ReactNativeTHEOplayerTests.debug.xcconfig */;
+ baseConfigurationReference = D466E8BC201BE02656CD9B59 /* Pods-ReactNativeTHEOplayer-ReactNativeTHEOplayerTests.debug.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
GCC_PREPROCESSOR_DEFINITIONS = (
@@ -881,7 +881,7 @@
};
00E356F71AD99517003FC87E /* Release */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = 37F2476D4FFC19937969BA39 /* Pods-ReactNativeTHEOplayer-ReactNativeTHEOplayerTests.release.xcconfig */;
+ baseConfigurationReference = 2859932C44A7266BC9A26016 /* Pods-ReactNativeTHEOplayer-ReactNativeTHEOplayerTests.release.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
COPY_PHASE_STRIP = NO;
@@ -901,7 +901,7 @@
};
13B07F941A680F5B00A75B9A /* Debug */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = 53B450B3183AC1FCE970C242 /* Pods-ReactNativeTHEOplayer.debug.xcconfig */;
+ baseConfigurationReference = 2B1869737A6D3574FB9FCB91 /* Pods-ReactNativeTHEOplayer.debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
@@ -933,7 +933,7 @@
};
13B07F951A680F5B00A75B9A /* Release */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = 212158D9C4053BB12B721822 /* Pods-ReactNativeTHEOplayer.release.xcconfig */;
+ baseConfigurationReference = 06D65152529DA3A7B6EC728D /* Pods-ReactNativeTHEOplayer.release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
@@ -957,7 +957,7 @@
};
2D02E4971E0B4A5E006451C7 /* Debug */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = 586FDDD06EFF4AC6D6026609 /* Pods-ReactNativeTHEOplayer-tvOS.debug.xcconfig */;
+ baseConfigurationReference = E69795734BECC7F9A40F1181 /* Pods-ReactNativeTHEOplayer-tvOS.debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image";
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
@@ -990,7 +990,7 @@
};
2D02E4981E0B4A5E006451C7 /* Release */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = D726618BE2FF02B74D4B3B33 /* Pods-ReactNativeTHEOplayer-tvOS.release.xcconfig */;
+ baseConfigurationReference = 67508AB782AB1AEF1725FF10 /* Pods-ReactNativeTHEOplayer-tvOS.release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image";
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
@@ -1022,7 +1022,7 @@
};
2D02E4991E0B4A5E006451C7 /* Debug */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = 90DCD6370FFDC116ADAF7756 /* Pods-ReactNativeTHEOplayer-tvOS-ReactNativeTHEOplayer-tvOSTests.debug.xcconfig */;
+ baseConfigurationReference = 8C4B9785AAB059DC6B233E3B /* Pods-ReactNativeTHEOplayer-tvOS-ReactNativeTHEOplayer-tvOSTests.debug.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CLANG_ANALYZER_NONNULL = YES;
@@ -1049,7 +1049,7 @@
};
2D02E49A1E0B4A5E006451C7 /* Release */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = FC92E903EC76001BC932F05F /* Pods-ReactNativeTHEOplayer-tvOS-ReactNativeTHEOplayer-tvOSTests.release.xcconfig */;
+ baseConfigurationReference = CEEC6FD978D0E9BD7B92494E /* Pods-ReactNativeTHEOplayer-tvOS-ReactNativeTHEOplayer-tvOSTests.release.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CLANG_ANALYZER_NONNULL = YES;
diff --git a/apps/e2e/package-lock.json b/apps/e2e/package-lock.json
index 94cd9704..9b15de0d 100644
--- a/apps/e2e/package-lock.json
+++ b/apps/e2e/package-lock.json
@@ -17,7 +17,7 @@
"react-native-device-info": "^10.14.0",
"react-native-status-bar-height": "^2.6.0",
"react-native-svg": "^15.8.0",
- "react-native-theoplayer": "^9.3.0",
+ "react-native-theoplayer": "^9.9.1",
"react-native-web": "^0.19.13",
"react-native-web-image-loader": "^0.1.1"
},
@@ -11916,9 +11916,9 @@
}
},
"node_modules/react-native-theoplayer": {
- "version": "9.3.0",
- "resolved": "https://registry.npmjs.org/react-native-theoplayer/-/react-native-theoplayer-9.3.0.tgz",
- "integrity": "sha512-K8Lvaxpwq8lhSKTy49BcRWEzO2OsR7KMdINJiFmOEOdCuSASSAcXL9s0bqB5MF777q/dr+d3LQQc5ss1mNGpWQ==",
+ "version": "9.9.1",
+ "resolved": "https://registry.npmjs.org/react-native-theoplayer/-/react-native-theoplayer-9.9.1.tgz",
+ "integrity": "sha512-yJjbaIR4Vor9UlfXH11kT9csedKKlQBe+LDM0Urg4lVX2PY526qQA9JWpILJ9zFruAWpt/1ym7OP9Gguuksg0A==",
"license": "SEE LICENSE AT https://www.theoplayer.com/terms",
"dependencies": {
"@theoplayer/cmcd-connector-web": "^1.3.0",
diff --git a/apps/e2e/package.json b/apps/e2e/package.json
index 4eb492f6..ad6be81a 100644
--- a/apps/e2e/package.json
+++ b/apps/e2e/package.json
@@ -22,7 +22,7 @@
"react-native-device-info": "^10.14.0",
"react-native-status-bar-height": "^2.6.0",
"react-native-svg": "^15.8.0",
- "react-native-theoplayer": "^9.3.0",
+ "react-native-theoplayer": "^9.9.1",
"react-native-web": "^0.19.13",
"react-native-web-image-loader": "^0.1.1"
},
diff --git a/apps/e2e/tsconfig.json b/apps/e2e/tsconfig.json
index 8c0856b0..14e5d466 100644
--- a/apps/e2e/tsconfig.json
+++ b/apps/e2e/tsconfig.json
@@ -17,6 +17,12 @@
],
"@theoplayer/react-native-yospace": [
"../../yospace/src/index"
+ ],
+ "@theoplayer/react-native-adscript": [
+ "../../adscript/src/index"
+ ],
+ "@theoplayer/react-native-gemius": [
+ "../../gemius/src/index"
]
}
}
diff --git a/gemius/.gitignore b/gemius/.gitignore
new file mode 100644
index 00000000..028d7364
--- /dev/null
+++ b/gemius/.gitignore
@@ -0,0 +1,72 @@
+# OSX
+#
+.DS_Store
+
+# XDE
+.expo/
+
+# VSCode
+.vscode/
+jsconfig.json
+
+# Xcode
+#
+build/
+*.pbxuser
+!default.pbxuser
+*.mode1v3
+!default.mode1v3
+*.mode2v3
+!default.mode2v3
+*.perspectivev3
+!default.perspectivev3
+xcuserdata
+*.xccheckout
+*.moved-aside
+DerivedData
+*.hmap
+*.ipa
+*.xcuserstate
+project.xcworkspace
+
+# Android/IJ
+#
+.classpath
+.cxx
+.gradle
+.idea
+.project
+.settings
+local.properties
+android.iml
+
+# Cocoapods
+#
+example/ios/Pods
+
+# Ruby
+example/vendor/
+
+# node.js
+#
+node_modules/
+npm-debug.log
+yarn-debug.log
+yarn-error.log
+
+# BUCK
+buck-out/
+\.buckd/
+android/app/libs
+android/keystores/debug.keystore
+
+# Expo
+.expo/
+
+# Turborepo
+.turbo/
+
+# generated by bob
+lib/
+
+src/manifest.json
diff --git a/gemius/CHANGELOG.md b/gemius/CHANGELOG.md
new file mode 100644
index 00000000..47637602
--- /dev/null
+++ b/gemius/CHANGELOG.md
@@ -0,0 +1,7 @@
+# @theoplayer/react-native-analytics-gemius
+
+## 1.0.0
+
+### ✨ Features
+
+- Initial release
diff --git a/gemius/README.md b/gemius/README.md
new file mode 100644
index 00000000..527df05f
--- /dev/null
+++ b/gemius/README.md
@@ -0,0 +1,101 @@
+# THEOplayer React-Native Gemius Connector
+
+A Gemius analytics connector for `@theoplayer/react-native`.
+
+## Installation
+
+```sh
+npm install @theoplayer/react-native-analytics-gemius
+```
+
+[//]: # (npm install @theoplayer/react-native-analytics-gemius)
+
+## Prerequisites
+
+### Android
+
+The Gemius Android SDK is not publicly available as a Maven module, so additional work is needed to include it as
+connector dependency.
+It requires downloading the private `GemiusSDK_2.0.8.aar` module into the app's `libs/` folder.
+The SDK location needs to be passed to the connector by setting the `gemiusSdkDir` in your app's `gradle.properties` file:
+
+```bash
+# Location of the Gemius SDK
+gemiusSdkDir=./app/libs/
+```
+
+### iOS & tvOS
+
+On Apple platforms, the connector requires downloading the private `GemiusSDK_iOS` archive, which contains
+a multiplatform binary platform module for both iOS and tvOS.
+
+Create a `Frameworks` folder in your app's `ios` folder, copy the Gemius SDK XCFrameworks in it
+and add this `GemiusSDK.podspec` file inside, which describes the structure and metadata of Gemius's CocoaPod:
+
+```ruby
+Pod::Spec.new do |spec|
+ spec.name = "GemiusSDK"
+ spec.version = "2.0.6"
+ spec.summary = "The Gemius SDK for iOS"
+
+ spec.homepage = 'https://github.com/THEOplayer/iOS-Connector'
+ spec.license = { :type => 'MIT', :file => 'LICENSE' }
+ spec.author = "THEO technologies"
+ spec.source = { :git => 'https://github.com/THEOplayer/iOS-Connector.git', :tag => spec.version.to_s }
+
+ spec.source_files = "Classes", "Classes/**/*.{h,m}"
+ spec.ios.vendored_frameworks = "GemiusSDK.xcframework"
+ spec.tvos.vendored_frameworks = "GemiusSDKtvOS.xcframework"
+end
+```
+
+Finally, include the Gemius SDK as dependency in your app's `Podfile`:
+
+```ruby
+ pod 'GemiusSDK', :path => 'Frameworks/'
+```
+
+## Usage
+
+### Configuring the connector
+
+Create the connector by providing the `THEOplayer` instance and a `GemiusConfiguration` object.
+
+```tsx
+import { useGemius, GemiusConfiguration, ProgramType } from '@theoplayer/react-native-analytics-gemius';
+
+const gemiusConfig: GemiusConfiguration = {
+ applicationName: "Demo",
+ applicationVersion: "1.0",
+ hitCollectorHost: "your_hit_collector_host",
+ gemiusId: "your_gemius_id",
+ debug: true
+}
+
+const App = () => {
+ const [gemius, initGemius] = useGemius(gemiusConfig);
+
+ const onPlayerReady = (player: THEOplayer) => {
+ // Initialize Gemius connector
+ initGemius(player);
+ };
+
+ return ;
+};
+```
+
+### Passing metadata dynamically
+
+The connector allows passing or updating the current asset's metadata at any time:
+
+```typescript
+const onUpdateMetadata = () => {
+ gemius.current?.update('programId', {
+ name: 'Demo asset',
+ duration: 1200,
+ programType: ProgramType.VIDEO,
+ customKey: 'customValue',
+ // ...
+ });
+}
+```
diff --git a/gemius/android/build.gradle b/gemius/android/build.gradle
new file mode 100644
index 00000000..2b709091
--- /dev/null
+++ b/gemius/android/build.gradle
@@ -0,0 +1,117 @@
+import java.util.zip.GZIPInputStream
+
+buildscript {
+ // Buildscript is evaluated before everything else so we can't use getExtOrDefault
+ def kotlin_version = rootProject.ext.has("kotlinVersion") ? rootProject.ext.get("kotlinVersion") : '1.9.10'
+
+ repositories {
+ google()
+ mavenCentral()
+ }
+
+ dependencies {
+ classpath "com.android.tools.build:gradle:7.2.2"
+ // noinspection DifferentKotlinGradleVersion
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+ }
+}
+
+def isNewArchitectureEnabled() {
+ return rootProject.hasProperty("newArchEnabled") && rootProject.getProperty("newArchEnabled") == "true"
+}
+
+apply plugin: 'com.android.library'
+apply plugin: 'kotlin-android'
+
+if (isNewArchitectureEnabled()) {
+ apply plugin: "com.facebook.react"
+}
+
+def safeExtGet(prop, fallback) {
+ rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
+}
+
+android {
+ namespace = "com.theoplayer.reactnative.gemius"
+ compileSdkVersion safeExtGet("THEOplayerGemius_compileSdkVersion", 35)
+
+ defaultConfig {
+ minSdkVersion safeExtGet("THEOplayerGemius_minSdkVersion", 21)
+ targetSdkVersion safeExtGet("THEOplayerGemius_targetSdkVersion", 35)
+ buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
+ versionCode 1
+ versionName "1.0"
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ }
+ }
+
+ lintOptions {
+ disable "GradleCompatible"
+ }
+
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+}
+
+repositories {
+ mavenLocal()
+ google()
+ mavenCentral()
+ // Local Maven repo
+ maven { url("local") }
+ maven { url "https://maven.theoplayer.com/releases" }
+}
+
+rootProject.allprojects {
+ repositories {
+ maven { url("$rootDir/../node_modules/@theoplayer/react-native-analytics-gemius/android/local") }
+ }
+}
+
+// The Gemius connector requires at least THEOplayer SDK v9.0.0.
+def theoplayer_sdk_version = safeExtGet('THEOplayer_sdk', '[9.0.0, 10.0.0)')
+def kotlin_version = safeExtGet("THEOplayerGemius_kotlinVersion", "1.9.10")
+def gemius_version = safeExtGet("THEOplayerGemius_gemiusVersion", "2.0.8")
+
+// ACRA 5.8+ uses Kotlin; GemiusSDK is pure java (for now)
+def acra_version = safeExtGet("THEOplayerGemius_acraVersion", '5.7.0')
+
+dependencies {
+ // For < 0.71, this will be from the local maven repo
+ // For > 0.71, this will be replaced by `com.facebook.react:react-android:$version` by react gradle plugin
+ //noinspection GradleDynamicVersion
+ implementation "com.facebook.react:react-native"
+ implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
+ implementation 'androidx.lifecycle:lifecycle-process:2.5.1'
+
+ // THEOplayer dependencies
+ compileOnly "com.theoplayer.theoplayer-sdk-android:core:$theoplayer_sdk_version"
+ compileOnly "com.theoplayer.theoplayer-sdk-android:integration-ads-ima:$theoplayer_sdk_version"
+ implementation project(':react-native-theoplayer')
+
+ // TEMP: replace this once the native connector has been published
+ // implementation "com.theoplayer.android-connector:gemius:$gemius_version"
+ implementation files("./libs/gemius.aar")
+ def aarFileName = "GemiusSDK_${gemius_version}.aar"
+ def gemiusSdkDir = rootProject.properties['gemiusSdkDir']
+ if (!gemiusSdkDir) {
+ logger.warn("⚠️ WARNING: gemiusSdkDir not set.")
+ } else if (!rootProject.file(gemiusSdkDir).exists()) {
+ logger.warn("⚠️ WARNING: gemiusSdkDir does not exist at: ${gemiusSdkDir}")
+ } else {
+ dependencies {
+ implementation fileTree(dir: "${rootProject.file(gemiusSdkDir)}/$aarFileName", include: ['*.aar', '*.jar'], exclude: [])
+ }
+ }
+
+ implementation "ch.acra:acra-http:$acra_version"
+
+ // Align the Kotlin SDK libraries with the same version.
+ implementation(platform("org.jetbrains.kotlin:kotlin-bom:$kotlin_version"))
+}
diff --git a/gemius/android/gradle/wrapper/gradle-wrapper.jar b/gemius/android/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 00000000..41d9927a
Binary files /dev/null and b/gemius/android/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gemius/android/gradle/wrapper/gradle-wrapper.properties b/gemius/android/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 00000000..2733ed5d
--- /dev/null
+++ b/gemius/android/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/gemius/android/gradlew b/gemius/android/gradlew
new file mode 100755
index 00000000..1b6c7873
--- /dev/null
+++ b/gemius/android/gradlew
@@ -0,0 +1,234 @@
+#!/bin/sh
+
+#
+# Copyright © 2015-2021 the original authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+#
+# Gradle start up script for POSIX generated by Gradle.
+#
+# Important for running:
+#
+# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
+# noncompliant, but you have some other compliant shell such as ksh or
+# bash, then to run this script, type that shell name before the whole
+# command line, like:
+#
+# ksh Gradle
+#
+# Busybox and similar reduced shells will NOT work, because this script
+# requires all of these POSIX shell features:
+# * functions;
+# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
+# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
+# * compound commands having a testable exit status, especially «case»;
+# * various built-in commands including «command», «set», and «ulimit».
+#
+# Important for patching:
+#
+# (2) This script targets any POSIX shell, so it avoids extensions provided
+# by Bash, Ksh, etc; in particular arrays are avoided.
+#
+# The "traditional" practice of packing multiple parameters into a
+# space-separated string is a well documented source of bugs and security
+# problems, so this is (mostly) avoided, by progressively accumulating
+# options in "$@", and eventually passing that to Java.
+#
+# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
+# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
+# see the in-line comments for details.
+#
+# There are tweaks for specific operating systems such as AIX, CygWin,
+# Darwin, MinGW, and NonStop.
+#
+# (3) This script is generated from the Groovy template
+# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+# within the Gradle project.
+#
+# You can find Gradle at https://github.com/gradle/gradle/.
+#
+##############################################################################
+
+# Attempt to set APP_HOME
+
+# Resolve links: $0 may be a link
+app_path=$0
+
+# Need this for daisy-chained symlinks.
+while
+ APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
+ [ -h "$app_path" ]
+do
+ ls=$( ls -ld "$app_path" )
+ link=${ls#*' -> '}
+ case $link in #(
+ /*) app_path=$link ;; #(
+ *) app_path=$APP_HOME$link ;;
+ esac
+done
+
+APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
+
+APP_NAME="Gradle"
+APP_BASE_NAME=${0##*/}
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD=maximum
+
+warn () {
+ echo "$*"
+} >&2
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+} >&2
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "$( uname )" in #(
+ CYGWIN* ) cygwin=true ;; #(
+ Darwin* ) darwin=true ;; #(
+ MSYS* | MINGW* ) msys=true ;; #(
+ NONSTOP* ) nonstop=true ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD=$JAVA_HOME/jre/sh/java
+ else
+ JAVACMD=$JAVA_HOME/bin/java
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD=java
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
+ case $MAX_FD in #(
+ max*)
+ MAX_FD=$( ulimit -H -n ) ||
+ warn "Could not query maximum file descriptor limit"
+ esac
+ case $MAX_FD in #(
+ '' | soft) :;; #(
+ *)
+ ulimit -n "$MAX_FD" ||
+ warn "Could not set maximum file descriptor limit to $MAX_FD"
+ esac
+fi
+
+# Collect all arguments for the java command, stacking in reverse order:
+# * args from the command line
+# * the main class name
+# * -classpath
+# * -D...appname settings
+# * --module-path (only if needed)
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if "$cygwin" || "$msys" ; then
+ APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
+ CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
+
+ JAVACMD=$( cygpath --unix "$JAVACMD" )
+
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ for arg do
+ if
+ case $arg in #(
+ -*) false ;; # don't mess with options #(
+ /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
+ [ -e "$t" ] ;; #(
+ *) false ;;
+ esac
+ then
+ arg=$( cygpath --path --ignore --mixed "$arg" )
+ fi
+ # Roll the args list around exactly as many times as the number of
+ # args, so each arg winds up back in the position where it started, but
+ # possibly modified.
+ #
+ # NB: a `for` loop captures its iteration list before it begins, so
+ # changing the positional parameters here affects neither the number of
+ # iterations, nor the values presented in `arg`.
+ shift # remove old arg
+ set -- "$@" "$arg" # push replacement arg
+ done
+fi
+
+# Collect all arguments for the java command;
+# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
+# shell script including quotes and variable substitutions, so put them in
+# double quotes to make sure that they get re-expanded; and
+# * put everything else in single quotes, so that it's not re-expanded.
+
+set -- \
+ "-Dorg.gradle.appname=$APP_BASE_NAME" \
+ -classpath "$CLASSPATH" \
+ org.gradle.wrapper.GradleWrapperMain \
+ "$@"
+
+# Use "xargs" to parse quoted args.
+#
+# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
+#
+# In Bash we could simply go:
+#
+# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
+# set -- "${ARGS[@]}" "$@"
+#
+# but POSIX shell has neither arrays nor command substitution, so instead we
+# post-process each arg (as a line of input to sed) to backslash-escape any
+# character that might be a shell metacharacter, then use eval to reverse
+# that process (while maintaining the separation between arguments), and wrap
+# the whole thing up as a single "set" statement.
+#
+# This will of course break if any of these variables contains a newline or
+# an unmatched quote.
+#
+
+eval "set -- $(
+ printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
+ xargs -n1 |
+ sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
+ tr '\n' ' '
+ )" '"$@"'
+
+exec "$JAVACMD" "$@"
diff --git a/gemius/android/gradlew.bat b/gemius/android/gradlew.bat
new file mode 100644
index 00000000..107acd32
--- /dev/null
+++ b/gemius/android/gradlew.bat
@@ -0,0 +1,89 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/gemius/android/libs/gemius.aar b/gemius/android/libs/gemius.aar
new file mode 100644
index 00000000..8d9c06d6
Binary files /dev/null and b/gemius/android/libs/gemius.aar differ
diff --git a/gemius/android/src/main/AndroidManifest.xml b/gemius/android/src/main/AndroidManifest.xml
new file mode 100644
index 00000000..cc947c56
--- /dev/null
+++ b/gemius/android/src/main/AndroidManifest.xml
@@ -0,0 +1 @@
+
diff --git a/gemius/android/src/main/java/com/theoplayer/reactnative/gemius/ReactTHEOplayerGemiusModule.kt b/gemius/android/src/main/java/com/theoplayer/reactnative/gemius/ReactTHEOplayerGemiusModule.kt
new file mode 100644
index 00000000..99aef23c
--- /dev/null
+++ b/gemius/android/src/main/java/com/theoplayer/reactnative/gemius/ReactTHEOplayerGemiusModule.kt
@@ -0,0 +1,126 @@
+package com.theoplayer.reactnative.gemius
+
+import com.facebook.react.bridge.*
+import com.gemius.sdk.stream.ProgramData
+import com.theoplayer.ReactTHEOplayerView
+import com.theoplayer.android.api.THEOplayerView
+import com.theoplayer.android.connector.analytics.gemius.GemiusConfiguration
+import com.theoplayer.android.connector.analytics.gemius.GemiusConnector
+import com.theoplayer.util.ViewResolver
+
+private const val TAG = "GemiusModule"
+
+private const val PROP_APP_NAME = "applicationName"
+private const val PROP_APP_VERSION = "applicationVersion"
+private const val PROP_HIT_COLLECTOR_HOST = "hitCollectorHost"
+private const val PROP_GEMIUS_ID = "gemiusId"
+private const val PROP_DEBUG = "debug"
+
+private const val PROP_NAME = "name"
+private const val PROP_DURATION = "duration"
+private const val PROP_TRANSMISSION = "transmission"
+private const val PROP_QUALITY = "quality"
+private const val PROP_RESOLUTION = "resolution"
+private const val PROP_VOLUME = "volume"
+private const val PROP_EXTERNAL_PREMIERE_DATE = "externalPremiereDate"
+private const val PROP_PREMIERE_DATE = "premiereDate"
+private const val PROP_SERIES = "series"
+private const val PROP_PROGRAM_TYPE = "programType"
+private const val PROP_TYPOLOGY = "typology"
+private const val PROP_PROGRAM_GENRE = "programGenre"
+private const val PROP_PROGRAM_PARTIAL_NAME = "programPartialName"
+private const val PROP_PROGRAM_PRODUCER = "programProducer"
+private const val PROP_PROGRAM_THEMATIC_CATEGORY = "programThematicCategory"
+private const val PROP_PROGRAM_SEASON = "programSeason"
+private const val PROP_TRANSMISSION_CHANNEL = "transmissionChannel"
+private const val PROP_TRANSMISSION_START_TIME = "transmissionStartTime"
+private const val PROP_TRANSMISSION_TYPE = "transmissionType"
+
+class ReactTHEOplayerGemiusModule(context: ReactApplicationContext) :
+ ReactContextBaseJavaModule(context) {
+
+ private val viewResolver: ViewResolver = ViewResolver(context)
+
+ private var gemiusConnectors: HashMap = HashMap()
+
+ override fun getName(): String {
+ return TAG
+ }
+
+ @ReactMethod
+ fun initialize(tag: Int, configuration: ReadableMap) {
+ viewResolver.resolveViewByTag(tag) { view: ReactTHEOplayerView? ->
+ view?.playerContext?.playerView?.let { playerView ->
+ gemiusConnectors[tag] =
+ initializeGemius(playerView, configuration)
+ }
+ }
+ }
+
+ private fun initializeGemius(
+ view: THEOplayerView,
+ configuration: ReadableMap,
+ ): GemiusConnector {
+ return GemiusConnector(
+ context = reactApplicationContext,
+ playerView = view,
+ configuration = buildConfiguration(configuration))
+ }
+
+ private fun buildConfiguration(contentMetadata: ReadableMap): GemiusConfiguration {
+ return GemiusConfiguration(
+ applicationName = contentMetadata.getString(PROP_APP_NAME) ?: "NA",
+ applicationVersion = contentMetadata.getString(PROP_APP_VERSION) ?: "NA",
+ hitCollectorHost = contentMetadata.getString(PROP_HIT_COLLECTOR_HOST) ?: "NA",
+ gemiusId = contentMetadata.getString(PROP_GEMIUS_ID) ?: "NA",
+ debug = if (contentMetadata.hasKey(PROP_DEBUG)) contentMetadata.getBoolean(PROP_DEBUG) else false,
+ adProcessor = null
+ )
+ }
+
+ private fun buildProgramData(data: ReadableMap): ProgramData {
+ return ProgramData().apply {
+ data.toHashMap().entries.forEach { entry ->
+ when (entry.key) {
+ PROP_NAME -> name = data.getString(entry.key)
+ PROP_DURATION -> duration = data.takeIf { data.hasKey(entry.key) }?.getInt(entry.key)
+ PROP_TRANSMISSION -> transmission = data.getString(entry.key)
+ PROP_QUALITY -> quality = data.getString(entry.key)
+ PROP_RESOLUTION -> resolution = data.getString(entry.key)
+ PROP_VOLUME -> volume = data.takeIf { data.hasKey(entry.key) }?.getInt(entry.key)
+ PROP_EXTERNAL_PREMIERE_DATE -> externalPremiereDate = data.getString(entry.key)
+ PROP_PREMIERE_DATE -> premiereDate = data.getString(entry.key)
+ PROP_SERIES -> series = data.getString(entry.key)
+ PROP_PROGRAM_TYPE -> programType = data.takeIf { data.hasKey(entry.key) }?.getInt(entry.key)?.let {
+ when (it) {
+ 0 -> ProgramData.ProgramType.AUDIO
+ else -> ProgramData.ProgramType.VIDEO
+ }
+ }
+ PROP_TYPOLOGY -> typology = data.getString(entry.key)
+ PROP_PROGRAM_GENRE -> programGenre = data.takeIf { data.hasKey(entry.key) }?.getInt(entry.key)
+ PROP_PROGRAM_PARTIAL_NAME -> programPartialName = data.getString(entry.key)
+ PROP_PROGRAM_PRODUCER -> programProducer = data.getString(entry.key)
+ PROP_PROGRAM_THEMATIC_CATEGORY -> programThematicCategory = data.getString(entry.key)
+ PROP_PROGRAM_SEASON -> programSeason = data.getString(entry.key)
+ PROP_TRANSMISSION_CHANNEL -> transmissionChannel = data.getString(entry.key)
+ PROP_TRANSMISSION_START_TIME -> transmissionStartTime = data.getString(entry.key)
+ PROP_TRANSMISSION_TYPE -> transmissionType = data.takeIf { data.hasKey(entry.key) }?.getInt(entry.key)
+
+ // Custom parameter, just add
+ else -> addCustomParameter(entry.key, entry.value as? String)
+ }
+ }
+ }
+ }
+
+ @ReactMethod
+ fun update(tag: Int, programId: String, programData: ReadableMap) {
+ gemiusConnectors[tag]?.update(programId, buildProgramData(programData))
+ }
+
+ @ReactMethod
+ fun destroy(tag: Int) {
+// gemiusConnectors[tag]?.destroy()
+ }
+}
diff --git a/gemius/android/src/main/java/com/theoplayer/reactnative/gemius/ReactTHEOplayerGemiusPackage.kt b/gemius/android/src/main/java/com/theoplayer/reactnative/gemius/ReactTHEOplayerGemiusPackage.kt
new file mode 100644
index 00000000..9ac6f5c6
--- /dev/null
+++ b/gemius/android/src/main/java/com/theoplayer/reactnative/gemius/ReactTHEOplayerGemiusPackage.kt
@@ -0,0 +1,16 @@
+package com.theoplayer.reactnative.gemius
+
+import com.facebook.react.ReactPackage
+import com.facebook.react.bridge.NativeModule
+import com.facebook.react.bridge.ReactApplicationContext
+import com.facebook.react.uimanager.ViewManager
+
+class ReactTHEOplayerGemiusPackage : ReactPackage {
+ override fun createNativeModules(reactContext: ReactApplicationContext): List {
+ return listOf(ReactTHEOplayerGemiusModule(reactContext))
+ }
+
+ override fun createViewManagers(reactContext: ReactApplicationContext): List> {
+ return emptyList()
+ }
+}
diff --git a/gemius/babel.config.js b/gemius/babel.config.js
new file mode 100644
index 00000000..f842b77f
--- /dev/null
+++ b/gemius/babel.config.js
@@ -0,0 +1,3 @@
+module.exports = {
+ presets: ['module:metro-react-native-babel-preset'],
+};
diff --git a/gemius/ios/Source/GemiusAdapter.swift b/gemius/ios/Source/GemiusAdapter.swift
new file mode 100644
index 00000000..be61f109
--- /dev/null
+++ b/gemius/ios/Source/GemiusAdapter.swift
@@ -0,0 +1,398 @@
+import THEOplayerSDK
+#if canImport(GemiusSDK)
+import GemiusSDK
+#endif
+
+let LOG_PLAYER_EVENTS = false
+let LOG_GEMIUS_EVENTS = false
+
+public class GemiusAdapter {
+ private let player: THEOplayer
+ private let configuration: GemiusConfiguration
+ private var gsmPlayer: GSMPlayer
+ private let adProcessor: ((THEOplayerSDK.Ad) -> GemiusSDK.GSMAdData)?
+
+ private var programId: String?
+ private var programData: GemiusSDK.GSMProgramData?
+
+ private var partCount = 1
+ private var adCount = 1
+ private var currentAd: Ad? = nil
+
+ private var sourceChangeEventListener: EventListener?
+ private var playingEventListener: EventListener?
+ private var playEventListener: EventListener?
+ private var pauseEventListener: EventListener?
+ private var waitingEventListener: EventListener?
+ private var seekingEventListener: EventListener?
+ private var errorEventListener: EventListener?
+ private var endedEventListener: EventListener?
+ private var volumeChangeEventListener: EventListener?
+
+ private var addVideoTrackEventListener: EventListener?
+ private var removeVideoTrackEventListener: EventListener?
+ private var videoQualityChangedEventListener: EventListener?
+
+ private var adBreakBeginListener: EventListener?
+ private var adBeginListener: EventListener?
+ private var adEndListener: EventListener?
+ private var adSkipListener: EventListener?
+ private var adBreakEndedListener: EventListener?
+
+ public init(configuration: GemiusConfiguration, player: THEOplayer, adProcessor: ((THEOplayerSDK.Ad) -> GemiusSDK.GSMAdData)? = nil) {
+ self.player = player
+ self.configuration = configuration
+ self.adProcessor = adProcessor
+ let playerData = GemiusSDK.GSMPlayerData()
+ playerData.resolution = "\(player.frame.width)x\(player.frame.height)"
+ if (player.muted) {
+ playerData.volume = -1
+ } else {
+ playerData.volume = NSNumber(value: player.volume * 100)
+ }
+ GemiusSDK.GEMConfig.sharedInstance().loggingEnabled = configuration.debug
+ GemiusSDK.GEMConfig.sharedInstance().setAppInfo(configuration.applicationName, version: configuration.applicationVersion)
+ self.gsmPlayer = GemiusSDK.GSMPlayer(id: "THEOplayer", withHost: configuration.hitCollectorHost, withGemiusID: configuration.gemiusId, with: playerData)
+
+ addEventListeners()
+ }
+
+ deinit {
+ destroy()
+ }
+
+ public func destroy() {
+ removeEventListeners()
+ }
+
+ public func update(programId: String, programData: GemiusSDK.GSMProgramData) {
+ self.programId = programId
+ self.programData = programData
+ }
+
+ private func addEventListeners() {
+ self.sourceChangeEventListener = player.addEventListener(type: THEOplayerSDK.PlayerEventTypes.SOURCE_CHANGE, listener: { [weak self] event in
+ guard let welf: GemiusAdapter = self else { return }
+ if (welf.configuration.debug && LOG_PLAYER_EVENTS) {
+ print("[GemiusConnector] Player Event: \(event.type) : source = \(event.source.debugDescription)")
+ }
+ welf.partCount = 1
+ welf.currentAd = nil
+ if let programData = welf.programData, let programId = welf.programId {
+ welf.gsmPlayer.newProgram(programId, with: programData)
+ } else {
+ print("[GemiusConnector] No program parameters were provided")
+ }
+
+ if let playingEventListener: THEOplayerSDK.EventListener = welf.playingEventListener {
+ welf.player.removeEventListener(type: THEOplayerSDK.PlayerEventTypes.PLAYING, listener: playingEventListener)
+ }
+ welf.playingEventListener = welf.player.addEventListener(type: THEOplayerSDK.PlayerEventTypes.PLAYING, listener: { [weak self] event in self?.handleFirstPlaying(event: event) })
+ })
+ self.playingEventListener = player.addEventListener(type: THEOplayerSDK.PlayerEventTypes.PLAYING, listener: { [weak self] event in self?.handleFirstPlaying(event: event) })
+ self.playEventListener = player.addEventListener(type: THEOplayerSDK.PlayerEventTypes.PLAY, listener: { [weak self] event in
+ guard let welf: GemiusAdapter = self else { return }
+ if (welf.configuration.debug && LOG_PLAYER_EVENTS) {
+ print("[GemiusConnector] Player Event: \(event.type) : currentTime = \(event.currentTime)")
+ }
+ let computedVolume = welf.player.muted ? -1 : Int(welf.player.volume * 100)
+ if let currentAd = welf.currentAd, let id = currentAd.id {
+ let adBreak = currentAd.adBreak
+ let offset = adBreak.timeOffset
+ let adEventData = GSMEventAdData()
+ adEventData.adDuration = NSNumber(value: currentAd.duration ?? 0)
+ adEventData.autoPlay = welf.player.autoplay ? 1 : 0
+ adEventData.adPosition = NSNumber(value: welf.adCount)
+ adEventData.breakSize = NSNumber(value: adBreak.ads.count)
+ adEventData.volume = NSNumber(value: computedVolume)
+ welf.gsmPlayer.adEvent(.PLAY, forProgram: welf.programId, forAd: id, atOffset: NSNumber(value: offset), with: adEventData)
+ } else {
+ if (welf.hasPrerollScheduled()) { return }
+ let programEventData = GSMEventProgramData()
+ programEventData.autoPlay = welf.player.autoplay ? 1 : 0
+ programEventData.volume = NSNumber(value: computedVolume)
+ programEventData.partID = NSNumber(value: welf.partCount)
+ programEventData.programDuration = NSNumber(value: welf.player.duration ?? 0)
+ welf.gsmPlayer.program(.PLAY, forProgram: welf.programId, atOffset: NSNumber(value: welf.player.currentTime), with: programEventData)
+ }
+ })
+ self.pauseEventListener = player.addEventListener(type: THEOplayerSDK.PlayerEventTypes.PAUSE, listener: { [weak self] event in
+ guard let welf: GemiusAdapter = self else { return }
+ if (welf.configuration.debug && LOG_PLAYER_EVENTS) {
+ print("[GemiusConnector] Player Event: \(event.type) : currentTime = \(event.currentTime)")
+ }
+ welf.reportBasicEvent(event: .PAUSE)
+ })
+ self.waitingEventListener = player.addEventListener(type: THEOplayerSDK.PlayerEventTypes.WAITING, listener: { [weak self] event in
+ guard let welf: GemiusAdapter = self else { return }
+ if (welf.configuration.debug && LOG_PLAYER_EVENTS) {
+ print("[GemiusConnector] Player Event: \(event.type) : currentTime = \(event.currentTime)")
+ }
+ welf.reportBasicEvent(event: .BUFFER)
+ })
+ self.seekingEventListener = player.addEventListener(type: THEOplayerSDK.PlayerEventTypes.SEEKING, listener: { [weak self] event in
+ guard let welf: GemiusAdapter = self else { return }
+ if (welf.configuration.debug && LOG_PLAYER_EVENTS) {
+ print("[GemiusConnector] Player Event: \(event.type) : currentTime = \(event.currentTime)")
+ }
+ welf.reportBasicEvent(event: .SEEK)
+ })
+ self.errorEventListener = player.addEventListener(type: THEOplayerSDK.PlayerEventTypes.ERROR, listener: { [weak self] event in
+ guard let welf: GemiusAdapter = self else { return }
+ if let code = event.errorObject?.code, let cause = event.errorObject?.cause, welf.configuration.debug && LOG_PLAYER_EVENTS {
+ print("[GemiusConnector] Player Event: \(event.type) : code = \(code) ; cause = \(cause)")
+ }
+ welf.reportBasicEvent(event: .COMPLETE)
+ })
+ self.endedEventListener = player.addEventListener(type: THEOplayerSDK.PlayerEventTypes.ENDED, listener: { [weak self] event in
+ guard let welf: GemiusAdapter = self else { return }
+ if (welf.configuration.debug && LOG_PLAYER_EVENTS) {
+ print("[GemiusConnector] Player Event: \(event.type) : currentTime = \(event.currentTime)")
+ }
+ welf.reportBasicEvent(event: .COMPLETE)
+ })
+ self.volumeChangeEventListener = player.addEventListener(type: THEOplayerSDK.PlayerEventTypes.VOLUME_CHANGE, listener: { [weak self] event in
+ guard let welf: GemiusAdapter = self else { return }
+ if (welf.configuration.debug && LOG_PLAYER_EVENTS) {
+ print("[GemiusConnector] Player Event: \(event.type) : volume = \(event.volume)")
+ }
+ let computedVolume = welf.player.muted ? -1 : Int(welf.player.volume * 100)
+ let programId = welf.programId
+ if let currentAd = welf.currentAd, let id = currentAd.id {
+ let adBreak = currentAd.adBreak
+ let adEventData = GSMEventAdData()
+ adEventData.volume = NSNumber(value: computedVolume)
+ welf.gsmPlayer.adEvent(.CHANGE_VOL, forProgram: programId, forAd: id, atOffset: NSNumber(value: adBreak.timeOffset), with: adEventData)
+ } else {
+ let programEventData = GSMEventProgramData()
+ programEventData.volume = NSNumber(value: computedVolume)
+ welf.gsmPlayer.program(.CHANGE_VOL, forProgram: programId, atOffset: NSNumber( value: welf.player.currentTime), with: programEventData)
+ }
+ })
+
+ self.addVideoTrackEventListener = player.videoTracks.addEventListener(type: VideoTrackListEventTypes.ADD_TRACK, listener: { [weak self] event in
+ guard let welf: GemiusAdapter = self else { return }
+ let videoTrack = event.track
+ welf.videoQualityChangedEventListener = videoTrack.addEventListener(type: MediaTrackEventTypes.ACTIVE_QUALITY_CHANGED) { [weak self] event in
+ let programId = welf.programId
+ let height = welf.player.videoHeight
+ let width = welf.player.videoWidth
+ if let currentAd = welf.currentAd, let id = currentAd.id {
+ let adBreak = currentAd.adBreak
+ let adEventData = GSMEventAdData()
+ adEventData.quality = "\(width)x\(height)"
+ welf.gsmPlayer.adEvent(.CHANGE_QUAL, forProgram: programId, forAd: id, atOffset: NSNumber(value: adBreak.timeOffset), with: adEventData)
+ } else {
+ let programEventData = GSMEventProgramData()
+ programEventData.quality = "\(width)x\(height)"
+ welf.gsmPlayer.program(.CHANGE_QUAL, forProgram: programId, atOffset: NSNumber(value: welf.player.currentTime), with: programEventData)
+ }
+ }
+ })
+ self.removeVideoTrackEventListener = player.videoTracks.addEventListener(type: VideoTrackListEventTypes.REMOVE_TRACK, listener: { [weak self] event in
+ guard let welf: GemiusAdapter = self else { return }
+ let videoTrack = event.track
+ if let videoQualityChangedEventListener: THEOplayerSDK.EventListener = welf.videoQualityChangedEventListener {
+ videoTrack.removeEventListener(type: THEOplayerSDK.MediaTrackEventTypes.ACTIVE_QUALITY_CHANGED, listener: videoQualityChangedEventListener)
+ }
+ })
+
+ if (hasAdIntegration()) {
+ self.adBreakBeginListener = player.ads.addEventListener(type: THEOplayerSDK.AdsEventTypes.AD_BREAK_BEGIN, listener: { [weak self] event in
+ guard let welf: GemiusAdapter = self else { return }
+ if let offset = event.ad?.timeOffset, welf.configuration.debug && LOG_PLAYER_EVENTS {
+ print("[GemiusConnector] Player Event: \(event.type) : offset = \(offset)")
+ }
+ welf.reportBasicEvent(event: .BREAK)
+ if let playingEventListener: THEOplayerSDK.EventListener = welf.playingEventListener {
+ welf.player.removeEventListener(type: THEOplayerSDK.PlayerEventTypes.PLAYING, listener: playingEventListener)
+ }
+ welf.playingEventListener = welf.player.addEventListener(type: THEOplayerSDK.PlayerEventTypes.PLAYING, listener: { [weak self] event in self?.handleFirstPlaying(event: event) })
+ })
+ self.adBeginListener = player.ads.addEventListener(type: THEOplayerSDK.AdsEventTypes.AD_BEGIN, listener: { [weak self] event in
+ guard let welf: GemiusAdapter = self else { return }
+ if let id = event.ad?.id, welf.configuration.debug && LOG_PLAYER_EVENTS {
+ print("[GemiusConnector] Player Event: \(event.type) : id = \(id)")
+ }
+ guard let ad = event.ad, let id = ad.id else { return }
+ welf.currentAd = ad
+ let adData = welf.buildAdData(ad: ad)
+ welf.gsmPlayer.newAd(id, with: adData)
+ })
+ self.adEndListener = player.ads.addEventListener(type: THEOplayerSDK.AdsEventTypes.AD_END, listener: { [weak self] event in
+ guard let welf: GemiusAdapter = self else { return }
+ if let id = event.ad?.id, welf.configuration.debug && LOG_PLAYER_EVENTS {
+ print("[GemiusConnector] Player Event: \(event.type) : id = \(id)")
+ }
+ guard let ad = event.ad, let id = ad.id else { return }
+ welf.reportBasicEvent(event: .COMPLETE)
+ welf.reportBasicEvent(event: .CLOSE)
+ welf.adCount += 1
+ welf.currentAd = nil
+ if let playingEventListener: THEOplayerSDK.EventListener = welf.playingEventListener {
+ welf.player.removeEventListener(type: THEOplayerSDK.PlayerEventTypes.PLAYING, listener: playingEventListener)
+ }
+ welf.playingEventListener = welf.player.addEventListener(type: THEOplayerSDK.PlayerEventTypes.PLAYING, listener: { [weak self] event in self?.handleFirstPlaying(event: event) })
+
+ })
+ self.adSkipListener = player.ads.addEventListener(type: THEOplayerSDK.AdsEventTypes.AD_SKIP, listener: { [weak self] event in
+ guard let welf: GemiusAdapter = self else { return }
+ if let id = event.ad?.id, welf.configuration.debug && LOG_PLAYER_EVENTS {
+ print("[GemiusConnector] Player Event: \(event.type) : id = \(id)")
+ }
+ welf.reportBasicEvent(event: .SKIP)
+ })
+ self.adBreakEndedListener = player.ads.addEventListener(type: THEOplayerSDK.AdsEventTypes.AD_BREAK_END, listener: { [weak self] event in
+
+ guard let welf: GemiusAdapter = self else { return }
+ welf.adCount = 1
+ guard let offset = event.ad?.timeOffset else { return }
+ if welf.configuration.debug && LOG_PLAYER_EVENTS {
+ print("[GemiusConnector] Player Event: \(event.type) : offset = \(offset)")
+ }
+ if (offset > 0) {
+ welf.partCount += 1
+ }
+ welf.gsmPlayer.newProgram(welf.programId, with: welf.programData)
+ if let playingEventListener: THEOplayerSDK.EventListener = welf.playingEventListener {
+ welf.player.removeEventListener(type: THEOplayerSDK.PlayerEventTypes.PLAYING, listener: playingEventListener)
+ }
+ if (event.ad?.timeOffset == 0) {
+ welf.playingEventListener = welf.player.addEventListener(type: THEOplayerSDK.PlayerEventTypes.PLAYING, listener: { [weak self] event in self?.handleFirstPlaying(event: event) })
+ }
+ })
+ }
+ }
+
+ private func removeEventListeners() {
+ if let sourceChangeEventListener: THEOplayerSDK.EventListener = self.sourceChangeEventListener {
+ self.player.removeEventListener(type: THEOplayerSDK.PlayerEventTypes.SOURCE_CHANGE, listener: sourceChangeEventListener)
+ }
+ if let playingEventListener: THEOplayerSDK.EventListener = self.playingEventListener {
+ self.player.removeEventListener(type: THEOplayerSDK.PlayerEventTypes.PLAYING, listener: playingEventListener)
+ }
+ if let playEventListener: THEOplayerSDK.EventListener = self.playEventListener {
+ self.player.removeEventListener(type: THEOplayerSDK.PlayerEventTypes.PLAY, listener: playEventListener)
+ }
+ if let pauseEventListener: THEOplayerSDK.EventListener = self.pauseEventListener {
+ self.player.removeEventListener(type: THEOplayerSDK.PlayerEventTypes.PAUSE, listener: pauseEventListener)
+ }
+ if let waitingEventListener: THEOplayerSDK.EventListener = self.waitingEventListener {
+ self.player.removeEventListener(type: THEOplayerSDK.PlayerEventTypes.WAITING, listener: waitingEventListener)
+ }
+ if let seekingEventListener: THEOplayerSDK.EventListener = self.seekingEventListener {
+ self.player.removeEventListener(type: THEOplayerSDK.PlayerEventTypes.SEEKING, listener: seekingEventListener)
+ }
+ if let errorEventListener: THEOplayerSDK.EventListener = self.errorEventListener {
+ self.player.removeEventListener(type: THEOplayerSDK.PlayerEventTypes.ERROR, listener: errorEventListener)
+ }
+ if let endedEventListener: THEOplayerSDK.EventListener = self.endedEventListener {
+ self.player.removeEventListener(type: THEOplayerSDK.PlayerEventTypes.ENDED, listener: endedEventListener)
+ }
+ if let volumeChangeEventListener: THEOplayerSDK.EventListener = self.volumeChangeEventListener {
+ self.player.removeEventListener(type: THEOplayerSDK.PlayerEventTypes.VOLUME_CHANGE, listener: volumeChangeEventListener)
+ }
+ if let adBreakBeginListener: THEOplayerSDK.EventListener = self.adBreakBeginListener {
+ self.player.removeEventListener(type: THEOplayerSDK.AdsEventTypes.AD_BREAK_BEGIN, listener: adBreakBeginListener)
+ }
+ if let adBeginListener: THEOplayerSDK.EventListener = self.adBeginListener {
+ self.player.removeEventListener(type: THEOplayerSDK.AdsEventTypes.AD_BEGIN, listener: adBeginListener)
+ }
+ if let adEndListener: THEOplayerSDK.EventListener = self.adEndListener {
+ self.player.removeEventListener(type: THEOplayerSDK.AdsEventTypes.AD_END, listener: adEndListener)
+ }
+ if let adSkipListener: THEOplayerSDK.EventListener = self.adSkipListener {
+ self.player.removeEventListener(type: THEOplayerSDK.AdsEventTypes.AD_SKIP, listener: adSkipListener)
+ }
+ if let adBreakEndedListener: THEOplayerSDK.EventListener = self.adBreakEndedListener {
+ self.player.removeEventListener(type: THEOplayerSDK.AdsEventTypes.AD_BREAK_END, listener: adBreakEndedListener)
+ }
+ if let addVideoTrackEventListener: THEOplayerSDK.EventListener = self.addVideoTrackEventListener {
+ self.player.videoTracks.removeEventListener(type: THEOplayerSDK.VideoTrackListEventTypes.ADD_TRACK, listener: addVideoTrackEventListener)
+ }
+ if let removeVideoTrackEventListener: THEOplayerSDK.EventListener = self.removeVideoTrackEventListener {
+ self.player.videoTracks.removeEventListener(type: THEOplayerSDK.VideoTrackListEventTypes.REMOVE_TRACK, listener: removeVideoTrackEventListener)
+ }
+ }
+
+ private func handleFirstPlaying(event: PlayingEvent) {
+ if (self.configuration.debug && LOG_PLAYER_EVENTS) {
+ print("[GemiusConnector] Player Event: \(event.type) : currentTime = \(event.currentTime)")
+ }
+ let computedVolume = player.muted ? -1 : Int(player.volume * 100)
+ if let currentAd = self.currentAd, let id = currentAd.id {
+ let adBreak = currentAd.adBreak
+ let offset = adBreak.timeOffset
+ let adEventData = GSMEventAdData()
+ adEventData.adDuration = NSNumber(value: currentAd.duration ?? 0)
+ adEventData.autoPlay = self.player.autoplay ? 1 : 0
+ adEventData.adPosition = NSNumber(value: self.adCount)
+ adEventData.breakSize = NSNumber(value: adBreak.ads.count)
+ adEventData.volume = NSNumber(value: computedVolume)
+ self.gsmPlayer.adEvent(.PLAY, forProgram: self.programId, forAd: id, atOffset: NSNumber(value: offset), with: adEventData)
+ } else {
+ if (hasPrerollScheduled()) { return }
+ let programEventData = GSMEventProgramData()
+ programEventData.autoPlay = self.player.autoplay ? 1 : 0
+ programEventData.volume = NSNumber(value: computedVolume)
+ programEventData.partID = NSNumber(value: self.partCount)
+ programEventData.programDuration = NSNumber(value: self.player.duration ?? 0)
+ self.gsmPlayer.program(.PLAY, forProgram: self.programId, atOffset: NSNumber(value: self.player.currentTime), with: programEventData)
+ }
+
+ if let playingEventListener: THEOplayerSDK.EventListener = self.playingEventListener {
+ self.player.removeEventListener(type: THEOplayerSDK.PlayerEventTypes.PLAYING, listener: playingEventListener)
+ }
+ }
+
+ private func hasAdIntegration() -> Bool {
+ let hasAdIntegration = player.getAllIntegrations().contains { integration in
+ switch integration.kind {
+ case IntegrationKind.GOOGLE_DAI:
+ return true
+ case IntegrationKind.GOOGLE_IMA:
+ return true
+ default:
+ print("[GemiusConnector] no supported ad integration was found")
+ return false
+ }
+ }
+ return hasAdIntegration
+ }
+
+ private func buildAdData(ad: THEOplayerSDK.Ad) -> GemiusSDK.GSMAdData {
+ if let adProcessor = self.adProcessor {
+ return adProcessor(ad)
+ }
+ let adData = GemiusSDK.GSMAdData()
+ if [AdIntegrationKind.google_ima, AdIntegrationKind.google_dai].contains(ad.integration),
+ let imaAd = ad as? GoogleImaAd {
+ adData.name = imaAd.creativeId
+ }
+
+ adData.adFormat = .video
+ adData.adType = .AD_BREAK
+ if let duration = ad.duration {
+ adData.duration = NSNumber(value: duration)
+ }
+ adData.name = ad.id
+ adData.quality = "\(ad.width)x\(ad.height)"
+ adData.resolution = "\(player.frame.width)x\(player.frame.height)"
+ return adData
+ }
+
+ private func reportBasicEvent(event: GemiusSDK.GSMEventType) {
+ guard let programId = self.programId else { return }
+ if let currentAd = self.currentAd {
+ self.gsmPlayer.adEvent(event, forProgram: programId, forAd: currentAd.id, atOffset: NSNumber(value: currentAd.adBreak.timeOffset), with: nil)
+
+ } else {
+ self.gsmPlayer.program(event, forProgram: programId, atOffset: NSNumber(value: player.currentTime), with: nil)
+
+ }
+ }
+
+ private func hasPrerollScheduled() -> Bool {
+ player.ads.scheduledAdBreaks.contains(where: {adBreak in adBreak.timeOffset == 0})
+ }
+}
diff --git a/gemius/ios/Source/GemiusConnector.swift b/gemius/ios/Source/GemiusConnector.swift
new file mode 100644
index 00000000..0fdc501d
--- /dev/null
+++ b/gemius/ios/Source/GemiusConnector.swift
@@ -0,0 +1,41 @@
+import THEOplayerSDK
+#if canImport(GemiusSDK)
+import GemiusSDK
+#endif
+
+public struct GemiusConfiguration {
+ let applicationName: String
+ let applicationVersion: String
+ let hitCollectorHost: String
+ let gemiusId: String
+ let debug: Bool
+ let adProcessor: ((THEOplayerSDK.Ad) -> GemiusSDK.GSMAdData)?
+
+ public init(applicationName: String, applicationVersion: String, hitCollectorHost: String, gemiusId: String, debug: Bool, adProcessor: ((THEOplayerSDK.Ad) -> GemiusSDK.GSMAdData)? = nil) {
+ self.applicationName = applicationName
+ self.applicationVersion = applicationVersion
+ self.hitCollectorHost = hitCollectorHost
+ self.gemiusId = gemiusId
+ self.debug = debug
+ self.adProcessor = adProcessor
+ }
+}
+
+public struct GemiusConnector {
+ private let adapter: GemiusAdapter
+ private let player: THEOplayer
+
+
+ public init(configuration: GemiusConfiguration, player: THEOplayer) {
+ self.player = player
+ self.adapter = GemiusAdapter(configuration: configuration, player: player, adProcessor: configuration.adProcessor)
+ }
+
+ public func update(programId: String, programData: GemiusSDK.GSMProgramData) {
+ self.adapter.update(programId: programId, programData: programData)
+ }
+
+ public func destroy() {
+ self.adapter.destroy()
+ }
+}
diff --git a/gemius/ios/THEOplayerGemiusRCTBridge.m b/gemius/ios/THEOplayerGemiusRCTBridge.m
new file mode 100644
index 00000000..6a1e49cf
--- /dev/null
+++ b/gemius/ios/THEOplayerGemiusRCTBridge.m
@@ -0,0 +1,19 @@
+#import
+#import
+#import
+
+// ----------------------------------------------------------------------------
+// Gemius Module
+// ----------------------------------------------------------------------------
+@interface RCT_EXTERN_REMAP_MODULE(GemiusModule, THEOplayerGemiusRCTGemiusAPI, NSObject)
+
+RCT_EXTERN_METHOD(initialize:(nonnull NSNumber *)node
+ gemiusConfig:(NSDictionary)gemiusConfig)
+
+RCT_EXTERN_METHOD(update:(nonnull NSNumber *)node
+ programId:(nonnull NSString *)programId
+ metadata:(NSDictionary)metadata)
+
+RCT_EXTERN_METHOD(destroy:(nonnull NSNumber *)node)
+
+@end
diff --git a/gemius/ios/THEOplayerGemiusRCTGemiusAPI.swift b/gemius/ios/THEOplayerGemiusRCTGemiusAPI.swift
new file mode 100644
index 00000000..08d43fde
--- /dev/null
+++ b/gemius/ios/THEOplayerGemiusRCTGemiusAPI.swift
@@ -0,0 +1,158 @@
+import Foundation
+import THEOplayerSDK
+import UIKit
+import react_native_theoplayer
+import GemiusSDK
+
+@objc(THEOplayerGemiusRCTGemiusAPI)
+class THEOplayerGemiusRCTGemiusAPI: NSObject, RCTBridgeModule {
+ @objc var bridge: RCTBridge!
+
+ var connectors = [NSNumber: GemiusConnector]()
+
+ static func moduleName() -> String! {
+ return "GemiusModule"
+ }
+
+ static func requiresMainQueueSetup() -> Bool {
+ return false
+ }
+
+ @objc(initialize:gemiusConfig:)
+ func initialize(
+ _ node: NSNumber, gemiusConfig: NSDictionary
+ ) {
+ log("initialize triggered.")
+
+ DispatchQueue.main.async {
+ if let view = self.view(for: node), let player = view.player {
+ let configuration = GemiusConfiguration(
+ applicationName: gemiusConfig["applicationName"] as! String,
+ applicationVersion: gemiusConfig["applicationVersion"] as! String,
+ hitCollectorHost: gemiusConfig["hitCollectorHost"] as! String,
+ gemiusId: gemiusConfig["gemiusId"] as! String,
+ debug: gemiusConfig["debug"] as? Bool ?? false
+ )
+ self.connectors[node] = GemiusConnector(
+ configuration: configuration,
+ player: player
+ )
+ log("Added connector to view \(node)")
+ } else {
+ log("Cannot find THEOPlayer for node \(node)")
+ }
+ }
+ }
+
+ @objc(update:programId:metadata:)
+ func update(_ node: NSNumber, programId: NSString, metadata: NSDictionary) {
+ log("update triggered.")
+ DispatchQueue.main.async {
+ if let connector = self.connectors[node] {
+ connector
+ .update(
+ programId: programId as String,
+ programData: self.buildProgramData(metadata)
+ )
+ }
+ }
+ }
+
+ private func buildProgramData(_ metadata: NSDictionary) -> GemiusSDK.GSMProgramData {
+ let data = GemiusSDK.GSMProgramData()
+
+ metadata.forEach { key, value in
+ guard let key = key as? String else { return }
+
+ switch key {
+ case "name":
+ data.name = value as? String
+ case "duration":
+ data.duration = value as? NSNumber
+ case "transmission":
+ data.transmission = value as? String
+ case "quality":
+ data.quality = value as? String
+ case "resolution":
+ data.resolution = value as? String
+ case "volume":
+ data.volume = value as? NSNumber
+ case "externalPremiereDate":
+ data.externalPremiereDate = value as? String
+ case "premiereDate":
+ data.premiereDate = value as? String
+ case "series":
+ data.series = value as? String
+ case "programType":
+ if let num = value as? NSNumber {
+ data.programType = buildProgramType(num)
+ }
+ case "typology":
+ data.typology = value as? String
+ case "programGenre":
+ if let num = value as? NSNumber {
+ data.programGenre = buildProgramGenre(num)
+ }
+ case "programPartialName":
+ data.programPartialName = value as? String
+ case "programProducer":
+ data.programProducer = value as? String
+ case "programThematicCategory":
+ data.programThematicCategory = value as? String
+ case "programSeason":
+ data.programSeason = value as? String
+ case "transmissionChannel":
+ data.transmissionChannel = value as? String
+ case "transmissionStartTime":
+ data.transmissionStartTime = value as? String
+ case "transmissionType":
+ if let num = value as? NSNumber {
+ data.transmissionType = buildTransmissionType(num)
+ }
+ default:
+ // Assume any other field is a custom parameter
+ if let strVal = value as? String {
+ data.addCustomParameter(key, value: strVal)
+ }
+ }
+ }
+
+ return data
+ }
+
+
+ private func buildProgramType(_ type: NSNumber) -> GemiusSDK.GSMProgramType {
+ return GemiusSDK.GSMProgramType(rawValue: type.intValue) ?? .VIDEO
+ }
+
+ private func buildProgramGenre(_ genre: NSNumber) -> GemiusSDK.GSMProgramGenre {
+ return GemiusSDK.GSMProgramGenre(rawValue: genre.intValue) ?? .undefined
+ }
+
+ private func buildTransmissionType(_ type: NSNumber) -> GemiusSDK.GSMTransmissionType {
+ return GemiusSDK.GSMTransmissionType(rawValue: type.intValue) ?? .undefined
+ }
+
+ @objc(destroy:)
+ func destroy(_ node: NSNumber) {
+ log("destroy triggered.")
+ DispatchQueue.main.async {
+ // self.connectors[node]?.destroy()
+ self.connectors.removeValue(forKey: node)
+ }
+ }
+
+ func view(for node: NSNumber) -> THEOplayerRCTView? {
+ self.bridge.uiManager.view(forReactTag: node) as? THEOplayerRCTView
+ }
+
+ func player(for node: NSNumber) -> THEOplayer? {
+ view(for: node)?.player
+ }
+}
+
+func log(_ text: String) {
+#if DEBUG
+ print("[react-native-theoplayer-gemius bridge]", text)
+#endif
+}
diff --git a/gemius/ios/TheoplayerGemius-Bridging-Header.h b/gemius/ios/TheoplayerGemius-Bridging-Header.h
new file mode 100644
index 00000000..7ecf415d
--- /dev/null
+++ b/gemius/ios/TheoplayerGemius-Bridging-Header.h
@@ -0,0 +1,4 @@
+#import
+#import
+#import
+#import
diff --git a/gemius/ios/TheoplayerGemius.xcodeproj/project.pbxproj b/gemius/ios/TheoplayerGemius.xcodeproj/project.pbxproj
new file mode 100644
index 00000000..0ab9f5b8
--- /dev/null
+++ b/gemius/ios/TheoplayerGemius.xcodeproj/project.pbxproj
@@ -0,0 +1,283 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 46;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 5E555C0D2413F4C50049A1A2 /* TheoplayerGemius.m in Sources */ = {isa = PBXBuildFile; fileRef = B3E7B5891CC2AC0600A0062D /* TheoplayerGemius.m */; };
+ F4FF95D7245B92E800C19C63 /* TheoplayerGemius.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4FF95D6245B92E800C19C63 /* TheoplayerGemius.swift */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+ 58B511D91A9E6C8500147676 /* CopyFiles */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = "include/$(PRODUCT_NAME)";
+ dstSubfolderSpec = 16;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+ 134814201AA4EA6300B7C361 /* libTheoplayerGemius.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libTheoplayerGemius.a; sourceTree = BUILT_PRODUCTS_DIR; };
+ B3E7B5891CC2AC0600A0062D /* TheoplayerGemius.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TheoplayerGemius.m; sourceTree = ""; };
+ F4FF95D5245B92E700C19C63 /* TheoplayerGemius-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "TheoplayerGemius-Bridging-Header.h"; sourceTree = ""; };
+ F4FF95D6245B92E800C19C63 /* TheoplayerGemius.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TheoplayerGemius.swift; sourceTree = ""; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 58B511D81A9E6C8500147676 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 134814211AA4EA7D00B7C361 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 134814201AA4EA6300B7C361 /* libTheoplayerGemius.a */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+ 58B511D21A9E6C8500147676 = {
+ isa = PBXGroup;
+ children = (
+ F4FF95D6245B92E800C19C63 /* TheoplayerGemius.swift */,
+ B3E7B5891CC2AC0600A0062D /* TheoplayerGemius.m */,
+ F4FF95D5245B92E700C19C63 /* TheoplayerGemius-Bridging-Header.h */,
+ 134814211AA4EA7D00B7C361 /* Products */,
+ );
+ sourceTree = "";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 58B511DA1A9E6C8500147676 /* TheoplayerGemius */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "TheoplayerGemius" */;
+ buildPhases = (
+ 58B511D71A9E6C8500147676 /* Sources */,
+ 58B511D81A9E6C8500147676 /* Frameworks */,
+ 58B511D91A9E6C8500147676 /* CopyFiles */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = TheoplayerGemius;
+ productName = RCTDataManager;
+ productReference = 134814201AA4EA6300B7C361 /* libTheoplayerGemius.a */;
+ productType = "com.apple.product-type.library.static";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 58B511D31A9E6C8500147676 /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastUpgradeCheck = 0920;
+ ORGANIZATIONNAME = Facebook;
+ TargetAttributes = {
+ 58B511DA1A9E6C8500147676 = {
+ CreatedOnToolsVersion = 6.1.1;
+ };
+ };
+ };
+ buildConfigurationList = 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "TheoplayerGemius" */;
+ compatibilityVersion = "Xcode 3.2";
+ developmentRegion = English;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ English,
+ en,
+ );
+ mainGroup = 58B511D21A9E6C8500147676;
+ productRefGroup = 58B511D21A9E6C8500147676;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 58B511DA1A9E6C8500147676 /* TheoplayerGemius */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 58B511D71A9E6C8500147676 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ F4FF95D7245B92E800C19C63 /* TheoplayerGemius.swift in Sources */,
+ B3E7B58A1CC2AC0600A0062D /* TheoplayerGemius.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+ 58B511ED1A9E6C8500147676 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ "EXCLUDED_ARCHS[sdk=*]" = arm64;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 8.0;
+ MTL_ENABLE_DEBUG_INFO = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = iphoneos;
+ };
+ name = Debug;
+ };
+ 58B511EE1A9E6C8500147676 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = YES;
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ "EXCLUDED_ARCHS[sdk=*]" = arm64;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 8.0;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ SDKROOT = iphoneos;
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
+ 58B511F01A9E6C8500147676 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ HEADER_SEARCH_PATHS = (
+ "$(inherited)",
+ /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
+ "$(SRCROOT)/../../../React/**",
+ "$(SRCROOT)/../../react-native/React/**",
+ );
+ LIBRARY_SEARCH_PATHS = "$(inherited)";
+ OTHER_LDFLAGS = "-ObjC";
+ PRODUCT_NAME = TheoplayerGemius;
+ SKIP_INSTALL = YES;
+ SWIFT_OBJC_BRIDGING_HEADER = "TheoplayerGemius-Bridging-Header.h";
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ SWIFT_VERSION = 5.0;
+ };
+ name = Debug;
+ };
+ 58B511F11A9E6C8500147676 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ HEADER_SEARCH_PATHS = (
+ "$(inherited)",
+ /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
+ "$(SRCROOT)/../../../React/**",
+ "$(SRCROOT)/../../react-native/React/**",
+ );
+ LIBRARY_SEARCH_PATHS = "$(inherited)";
+ OTHER_LDFLAGS = "-ObjC";
+ PRODUCT_NAME = TheoplayerGemius;
+ SKIP_INSTALL = YES;
+ SWIFT_OBJC_BRIDGING_HEADER = "TheoplayerGemius-Bridging-Header.h";
+ SWIFT_VERSION = 5.0;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "TheoplayerGemius" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 58B511ED1A9E6C8500147676 /* Debug */,
+ 58B511EE1A9E6C8500147676 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "TheoplayerGemius" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 58B511F01A9E6C8500147676 /* Debug */,
+ 58B511F11A9E6C8500147676 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 58B511D31A9E6C8500147676 /* Project object */;
+}
diff --git a/gemius/manifest.js b/gemius/manifest.js
new file mode 100755
index 00000000..e7629f28
--- /dev/null
+++ b/gemius/manifest.js
@@ -0,0 +1,6 @@
+const manifest = {
+ version: process.env.npm_package_version,
+ buildDate: new Date().toISOString(),
+};
+
+console.log(JSON.stringify(manifest));
diff --git a/gemius/package.json b/gemius/package.json
new file mode 100644
index 00000000..2e5bd986
--- /dev/null
+++ b/gemius/package.json
@@ -0,0 +1,85 @@
+{
+ "name": "@theoplayer/react-native-analytics-gemius",
+ "version": "1.0.0",
+ "description": "Nielsen Gemius analytics connector for @theoplayer/react-native",
+ "main": "lib/commonjs/index",
+ "module": "lib/module/index",
+ "types": "lib/typescript/src/index.d.ts",
+ "react-native": "src/index",
+ "source": "src/index",
+ "files": [
+ "src",
+ "lib",
+ "android",
+ "ios",
+ "cpp",
+ "*.podspec",
+ "*.tgz",
+ "CHANGELOG.md",
+ "manifest.json",
+ "!lib/typescript/example",
+ "!ios/build",
+ "!android/build",
+ "!android/gradle",
+ "!android/gradlew",
+ "!android/gradlew.bat",
+ "!android/local.properties",
+ "!**/__tests__",
+ "!**/__fixtures__",
+ "!**/__mocks__",
+ "!**/.*"
+ ],
+ "scripts": {
+ "typescript": "tsc --noEmit",
+ "build": "npm run manifest && bob build",
+ "manifest": "node manifest.js > src/manifest.json",
+ "prepare": "npm run manifest && npm run build",
+ "clean": "rimraf lib android/build example/android/build example/android/app/build example/ios/build"
+ },
+ "keywords": [
+ "react-native",
+ "THEOplayer",
+ "ios",
+ "android",
+ "gemius"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git@github.com:THEOplayer/react-native-connectors.git"
+ },
+ "author": "THEO Technologies",
+ "license": "SEE LICENSE AT https://www.theoplayer.com/terms",
+ "homepage": "https://github.com/THEOplayer/react-native-connectors/tree/main/gemius#readme",
+ "publishConfig": {
+ "registry": "https://registry.npmjs.org/"
+ },
+ "peerDependencies": {
+ "react": "*",
+ "react-native": "*",
+ "react-native-theoplayer": "^3 || ^7 || ^8 || ^9",
+ "theoplayer": "^5 || ^6 || ^7 || ^8 || ^9"
+ },
+ "peerDependenciesMeta": {
+ "theoplayer": {
+ "optional": true
+ }
+ },
+ "eslintIgnore": [
+ "node_modules/",
+ "lib/"
+ ],
+ "react-native-builder-bob": {
+ "source": "src",
+ "output": "lib",
+ "targets": [
+ "commonjs",
+ "module",
+ [
+ "typescript",
+ {
+ "project": "tsconfig.build.json"
+ }
+ ]
+ ]
+ }
+}
diff --git a/gemius/react-native-theoplayer-gemius.podspec b/gemius/react-native-theoplayer-gemius.podspec
new file mode 100644
index 00000000..3c0c8f18
--- /dev/null
+++ b/gemius/react-native-theoplayer-gemius.podspec
@@ -0,0 +1,45 @@
+require "json"
+
+package = JSON.parse(File.read(File.join(__dir__, "package.json")))
+folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32'
+
+Pod::Spec.new do |s|
+ s.name = "react-native-theoplayer-gemius"
+ s.version = package["version"]
+ s.summary = package["description"]
+ s.homepage = package["homepage"]
+ s.license = package["license"]
+ s.authors = package["author"]
+
+ s.platforms = { :ios => "13.4", :tvos => "13.4" }
+ s.source = { :git => "https://github.com/THEOplayer/react-native-connectors.git", :tag => "gemius_v#{s.version}" }
+
+ s.source_files = "ios/**/*.{h,m,mm,swift}"
+
+ s.dependency "react-native-theoplayer"
+ s.dependency 'GemiusSDK'
+
+ # Use install_modules_dependencies helper to install the dependencies if React Native version >=0.71.0.
+ # See https://github.com/facebook/react-native/blob/febf6b7f33fdb4904669f99d795eba4c0f95d7bf/scripts/cocoapods/new_architecture.rb#L79.
+ if respond_to?(:install_modules_dependencies, true)
+ install_modules_dependencies(s)
+ else
+ s.dependency "React-Core"
+
+ # Don't install the dependencies when we run `pod install` in the old architecture.
+ if ENV['RCT_NEW_ARCH_ENABLED'] == '1' then
+ s.compiler_flags = folly_compiler_flags + " -DRCT_NEW_ARCH_ENABLED=1"
+ s.pod_target_xcconfig = {
+ "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\"",
+ "OTHER_CPLUSPLUSFLAGS" => "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1",
+ "CLANG_CXX_LANGUAGE_STANDARD" => "c++17"
+ }
+ s.dependency "React-Codegen"
+ s.dependency "RCT-Folly"
+ s.dependency "RCTRequired"
+ s.dependency "RCTTypeSafety"
+ s.dependency "ReactCommon/turbomodule/core"
+ end
+ end
+end
+
diff --git a/gemius/src/__tests__/index.test.tsx b/gemius/src/__tests__/index.test.tsx
new file mode 100644
index 00000000..cb0ff5c3
--- /dev/null
+++ b/gemius/src/__tests__/index.test.tsx
@@ -0,0 +1 @@
+export {};
diff --git a/gemius/src/api/GemiusConfiguration.ts b/gemius/src/api/GemiusConfiguration.ts
new file mode 100644
index 00000000..aeda8fcd
--- /dev/null
+++ b/gemius/src/api/GemiusConfiguration.ts
@@ -0,0 +1,7 @@
+export type GemiusConfiguration = {
+ applicationName: string;
+ applicationVersion: string;
+ hitCollectorHost: string;
+ gemiusId: string;
+ debug?: boolean;
+};
diff --git a/gemius/src/api/GemiusConnector.ts b/gemius/src/api/GemiusConnector.ts
new file mode 100644
index 00000000..87a47477
--- /dev/null
+++ b/gemius/src/api/GemiusConnector.ts
@@ -0,0 +1,36 @@
+import type { THEOplayer } from 'react-native-theoplayer';
+import { GemiusConfiguration } from './GemiusConfiguration';
+import { GemiusConnectorAdapter } from '../internal/GemiusConnectorAdapter';
+import { ProgramData } from './ProgramData';
+
+export class GemiusConnector {
+ private connectorAdapter: GemiusConnectorAdapter;
+
+ /**
+ * Create GemiusConnector
+ *
+ * @param player A React Native THEOplayer instance.
+ * @param configuration The connector configuration
+ *
+ * @public
+ */
+ constructor(player: THEOplayer, configuration: GemiusConfiguration) {
+ this.connectorAdapter = new GemiusConnectorAdapter(player, configuration);
+ }
+
+ /**
+ * Update the current program data.
+ */
+ update(programId: string, programData: ProgramData) {
+ this.connectorAdapter.update(programId, programData);
+ }
+
+ /**
+ * Stops video and ad analytics and closes all sessions.
+ *
+ * @public
+ */
+ destroy(): void {
+ this.connectorAdapter.destroy();
+ }
+}
diff --git a/gemius/src/api/ProgramData.ts b/gemius/src/api/ProgramData.ts
new file mode 100644
index 00000000..dd097f69
--- /dev/null
+++ b/gemius/src/api/ProgramData.ts
@@ -0,0 +1,27 @@
+export enum ProgramType {
+ AUDIO = 0,
+ VIDEO = 1,
+}
+
+export class ProgramData {
+ name?: string;
+ duration?: number;
+ transmission?: string;
+ quality?: string;
+ resolution?: string;
+ volume?: number;
+ externalPremiereDate?: string;
+ premiereDate?: string;
+ series?: string;
+ programType?: ProgramType;
+ typology?: string;
+ programGenre?: number;
+ programPartialName?: string;
+ programProducer?: string;
+ programThematicCategory?: string;
+ programSeason?: string;
+ transmissionChannel?: string;
+ transmissionStartTime?: string;
+ transmissionType?: number;
+ [key: string | number | ProgramType]: string | number;
+}
diff --git a/gemius/src/api/hooks/useGemius.ts b/gemius/src/api/hooks/useGemius.ts
new file mode 100644
index 00000000..89c823bf
--- /dev/null
+++ b/gemius/src/api/hooks/useGemius.ts
@@ -0,0 +1,39 @@
+import { PlayerEventType, THEOplayer } from 'react-native-theoplayer';
+import { RefObject, useEffect, useRef } from 'react';
+import { GemiusConnector } from '../GemiusConnector';
+import { GemiusConfiguration } from '../GemiusConfiguration';
+
+export function useGemius(configuration: GemiusConfiguration): [RefObject, (player: THEOplayer | undefined) => void] {
+ const connector = useRef();
+ const theoPlayer = useRef();
+
+ const initialize = (player: THEOplayer | undefined) => {
+ // Optionally destroy existent connector
+ onDestroy();
+
+ theoPlayer.current = player;
+ if (player) {
+ connector.current = new GemiusConnector(player, configuration);
+ player.addEventListener(PlayerEventType.DESTROY, onDestroy);
+ } else {
+ throw new Error('Invalid THEOplayer instance');
+ }
+ };
+
+ const onDestroy = () => {
+ if (connector.current) {
+ if (!theoPlayer.current) {
+ throw new Error('Invalid THEOplayer instance');
+ }
+ theoPlayer.current.removeEventListener(PlayerEventType.DESTROY, onDestroy);
+ connector.current.destroy();
+ connector.current = undefined;
+ }
+ };
+
+ useEffect(() => {
+ return onDestroy;
+ }, []);
+
+ return [connector, initialize];
+}
diff --git a/gemius/src/index.ts b/gemius/src/index.ts
new file mode 100644
index 00000000..e624b5dc
--- /dev/null
+++ b/gemius/src/index.ts
@@ -0,0 +1,4 @@
+export * from './api/GemiusConnector';
+export * from './api/GemiusConfiguration';
+export * from './api/ProgramData';
+export { useGemius } from './api/hooks/useGemius';
diff --git a/gemius/src/internal/GemiusConnectorAdapter.ts b/gemius/src/internal/GemiusConnectorAdapter.ts
new file mode 100644
index 00000000..ccf3857f
--- /dev/null
+++ b/gemius/src/internal/GemiusConnectorAdapter.ts
@@ -0,0 +1,36 @@
+import type { THEOplayer } from 'react-native-theoplayer';
+import { NativeModules } from 'react-native';
+import { GemiusConfiguration } from '../api/GemiusConfiguration';
+import { ProgramData } from '../api/ProgramData';
+
+const TAG = 'GemiusConnector';
+const ERROR_MSG = 'GemiusConnectorAdapter Error';
+
+export class GemiusConnectorAdapter {
+ constructor(
+ private player: THEOplayer,
+ configuration: GemiusConfiguration,
+ ) {
+ try {
+ NativeModules.GemiusModule.initialize(this.player.nativeHandle || -1, configuration);
+ } catch (error: unknown) {
+ console.error(TAG, `${ERROR_MSG}: ${error}`);
+ }
+ }
+
+ update(programId: string, programData: ProgramData) {
+ try {
+ NativeModules.GemiusModule.update(this.player.nativeHandle || -1, programId, programData);
+ } catch (error: unknown) {
+ console.error(TAG, `${ERROR_MSG}: ${error}`);
+ }
+ }
+
+ destroy(): void {
+ try {
+ NativeModules.GemiusModule.destroy(this.player.nativeHandle || -1);
+ } catch (error: unknown) {
+ console.error(TAG, `${ERROR_MSG}: ${error}`);
+ }
+ }
+}
diff --git a/gemius/src/internal/GemiusConnectorAdapter.web.ts b/gemius/src/internal/GemiusConnectorAdapter.web.ts
new file mode 100644
index 00000000..e375c23e
--- /dev/null
+++ b/gemius/src/internal/GemiusConnectorAdapter.web.ts
@@ -0,0 +1,16 @@
+import type { THEOplayer } from 'react-native-theoplayer';
+import { GemiusConfiguration } from '../api/GemiusConfiguration';
+import { ProgramData } from '../api/ProgramData';
+
+export class GemiusConnectorAdapter {
+ constructor(
+ private player: THEOplayer,
+ configuration: GemiusConfiguration,
+ ) {
+ throw new Error('Gemius connector is not supported for Web.');
+ }
+
+ update(programId: string, programData: ProgramData) {}
+
+ destroy() {}
+}
diff --git a/gemius/tsconfig.build.json b/gemius/tsconfig.build.json
new file mode 100644
index 00000000..f929194b
--- /dev/null
+++ b/gemius/tsconfig.build.json
@@ -0,0 +1,5 @@
+
+{
+ "extends": "./tsconfig",
+ "exclude": ["example", "ios", "android"]
+}
diff --git a/gemius/tsconfig.json b/gemius/tsconfig.json
new file mode 100644
index 00000000..61ad2c8e
--- /dev/null
+++ b/gemius/tsconfig.json
@@ -0,0 +1,11 @@
+{
+ "extends": "../tsconfig.base.json",
+ "compilerOptions": {
+ "baseUrl": "./",
+ "paths": {
+ "@theoplayer/react-native-analytics-gemius": [
+ "./src/index"
+ ]
+ }
+ }
+}
diff --git a/gemius/typedoc.json b/gemius/typedoc.json
new file mode 100644
index 00000000..7cafc8ff
--- /dev/null
+++ b/gemius/typedoc.json
@@ -0,0 +1,12 @@
+{
+ "$schema": "https://typedoc.org/schema.json",
+ "extends": [
+ "../typedoc.base.json"
+ ],
+ "entryPoints": [
+ "src/index.ts"
+ ],
+ "tsconfig": "tsconfig.json",
+ "readme": "README.md",
+ "name": "Gemius Connector"
+}
diff --git a/package-lock.json b/package-lock.json
index b515fb9b..ba4d4f84 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,17 +9,19 @@
"version": "0.0.0",
"license": "MIT",
"workspaces": [
+ "agama",
"adobe",
"adobe-edge",
- "agama",
+ "adscript",
"comscore",
"conviva",
+ "drm",
"engage",
"mux",
"nielsen",
"yospace",
"youbora",
- "drm"
+ "gemius"
],
"devDependencies": {
"@changesets/cli": "^2.27.10",
@@ -40,7 +42,7 @@
"react-native": "^0.74.5",
"react-native-builder-bob": "^0.23.2",
"react-native-device-info": "^14.0.4",
- "react-native-theoplayer": "^9.0.0",
+ "react-native-theoplayer": "^9.9.1",
"rimraf": "^5.0.10",
"theoplayer": "^9.0.0",
"typedoc": "^0.25.13",
@@ -51,7 +53,7 @@
},
"adobe": {
"name": "@theoplayer/react-native-analytics-adobe",
- "version": "1.9.0",
+ "version": "1.10.0",
"license": "SEE LICENSE AT https://www.theoplayer.com/terms",
"peerDependencies": {
"react": "*",
@@ -68,7 +70,7 @@
},
"adobe-edge": {
"name": "@theoplayer/react-native-analytics-adobe-edge",
- "version": "0.4.0",
+ "version": "0.5.0",
"license": "SEE LICENSE AT https://www.theoplayer.com/terms",
"dependencies": {
"openapi-fetch": "^0.9.8"
@@ -86,9 +88,25 @@
}
}
},
+ "adscript": {
+ "name": "@theoplayer/react-native-analytics-adscript",
+ "version": "1.0.0",
+ "license": "SEE LICENSE AT https://www.theoplayer.com/terms",
+ "peerDependencies": {
+ "react": "*",
+ "react-native": "*",
+ "react-native-theoplayer": "^3 || ^7 || ^8 || ^9",
+ "theoplayer": "^5 || ^6 || ^7 || ^8 || ^9"
+ },
+ "peerDependenciesMeta": {
+ "theoplayer": {
+ "optional": true
+ }
+ }
+ },
"agama": {
"name": "@theoplayer/react-native-analytics-agama",
- "version": "1.7.0",
+ "version": "1.8.0",
"license": "SEE LICENSE AT https://www.theoplayer.com/terms",
"dependencies": {
"react-native-uuid": "^2.0.2",
@@ -166,6 +184,22 @@
"react-native-mmkv": "^2.12.2"
}
},
+ "gemius": {
+ "name": "@theoplayer/react-native-analytics-gemius",
+ "version": "1.0.0",
+ "license": "SEE LICENSE AT https://www.theoplayer.com/terms",
+ "peerDependencies": {
+ "react": "*",
+ "react-native": "*",
+ "react-native-theoplayer": "^3 || ^7 || ^8 || ^9",
+ "theoplayer": "^5 || ^6 || ^7 || ^8 || ^9"
+ },
+ "peerDependenciesMeta": {
+ "theoplayer": {
+ "optional": true
+ }
+ }
+ },
"mux": {
"name": "@theoplayer/react-native-analytics-mux",
"version": "1.7.0",
@@ -4470,6 +4504,10 @@
"resolved": "adobe-edge",
"link": true
},
+ "node_modules/@theoplayer/react-native-analytics-adscript": {
+ "resolved": "adscript",
+ "link": true
+ },
"node_modules/@theoplayer/react-native-analytics-agama": {
"resolved": "agama",
"link": true
@@ -4482,6 +4520,10 @@
"resolved": "conviva",
"link": true
},
+ "node_modules/@theoplayer/react-native-analytics-gemius": {
+ "resolved": "gemius",
+ "link": true
+ },
"node_modules/@theoplayer/react-native-analytics-mux": {
"resolved": "mux",
"link": true
@@ -12042,9 +12084,10 @@
}
},
"node_modules/react-native-theoplayer": {
- "version": "9.0.0",
- "resolved": "https://registry.npmjs.org/react-native-theoplayer/-/react-native-theoplayer-9.0.0.tgz",
- "integrity": "sha512-4rzr7445/AxKBTKdkNF6MKH5+w/EfH0FMNijL30DkY1lnhs5VIMr4IYeD+vU4YP73YU0y436kPceFRhEOBRt+g==",
+ "version": "9.9.1",
+ "resolved": "https://registry.npmjs.org/react-native-theoplayer/-/react-native-theoplayer-9.9.1.tgz",
+ "integrity": "sha512-yJjbaIR4Vor9UlfXH11kT9csedKKlQBe+LDM0Urg4lVX2PY526qQA9JWpILJ9zFruAWpt/1ym7OP9Gguuksg0A==",
+ "license": "SEE LICENSE AT https://www.theoplayer.com/terms",
"dependencies": {
"@theoplayer/cmcd-connector-web": "^1.3.0",
"buffer": "^6.0.3"
@@ -14030,7 +14073,7 @@
},
"yospace": {
"name": "@theoplayer/react-native-yospace",
- "version": "1.3.0",
+ "version": "1.3.1",
"license": "SEE LICENSE AT https://www.theoplayer.com/terms",
"dependencies": {
"@theoplayer/yospace-connector-web": "^2.6.0"
diff --git a/package.json b/package.json
index 73971d0f..c07a1125 100644
--- a/package.json
+++ b/package.json
@@ -7,17 +7,19 @@
"author": "THEO Technologies NV",
"license": "MIT",
"workspaces": [
+ "agama",
"adobe",
"adobe-edge",
- "agama",
+ "adscript",
"comscore",
"conviva",
+ "drm",
"engage",
"mux",
"nielsen",
"yospace",
"youbora",
- "drm"
+ "gemius"
],
"scripts": {
"changeset:version": "changeset version && node .changeset/post-process.js",
@@ -56,7 +58,7 @@
"react-native": "^0.74.5",
"react-native-builder-bob": "^0.23.2",
"react-native-device-info": "^14.0.4",
- "react-native-theoplayer": "^9.0.0",
+ "react-native-theoplayer": "^9.9.1",
"rimraf": "^5.0.10",
"theoplayer": "^9.0.0",
"typedoc": "^0.25.13",