<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://engineeringportal.nielsen.com/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=AnkitAgrawal</id>
	<title>Engineering Client Portal - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://engineeringportal.nielsen.com/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=AnkitAgrawal"/>
	<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/wiki/Special:Contributions/AnkitAgrawal"/>
	<updated>2026-04-13T09:23:52Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.39.5</generator>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=DCR_%26_DTVR_Flutter_Integration&amp;diff=7415</id>
		<title>DCR &amp; DTVR Flutter Integration</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=DCR_%26_DTVR_Flutter_Integration&amp;diff=7415"/>
		<updated>2025-10-17T15:04:25Z</updated>

		<summary type="html">&lt;p&gt;AnkitAgrawal: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}}  {{Breadcrumb|DCR &amp;amp; DTVR}} {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
= Integrate Nielsen SDK Api in Flutter App =&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
The Nielsen Flutter Plugin provides a Dart API that bridges into the native Nielsen App SDKs (iOS and Android) using Flutter’s platform channels.&lt;br /&gt;
&lt;br /&gt;
Flow: Dart → Platform Channel → iOS/Android Plugin → Nielsen App SDK&lt;br /&gt;
&lt;br /&gt;
Supports SDK flavors: Global, GlobalAd, GlobalNoAd, AGF, AGFNoAd, AGFNoId&lt;br /&gt;
&lt;br /&gt;
Each flavor corresponds to a different Nielsen SDK package. You select the one required by your business case in the pubspec.yaml.&lt;br /&gt;
&amp;lt;p style=&amp;quot;color:#C70039;&amp;quot;&amp;gt;Note : Support for Flutter in Nielsen SDK is available from version 10.1.0.0&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
To start using the App SDK, the following details are required:&lt;br /&gt;
* '''App ID (appid):''' Unique ID assigned to the player/site and configured by product.&lt;br /&gt;
* '''sfcode:''' Unique identifier for the environment that the SDK should point to.&lt;br /&gt;
* '''Nielsen SDK:''' The Nielsen SDK package contains a variety of sample players for your reference.&lt;br /&gt;
If you do not have any of these prerequisites or if you have any questions, please contact our SDK sales support team.&lt;br /&gt;
Refer to [[Digital Measurement Onboarding]] guide for information on how to get a Nielsen App SDK and appid.&lt;br /&gt;
&lt;br /&gt;
== Setting up your Environment  ==&lt;br /&gt;
*  '''Add dependency in pubspec.yaml'''&lt;br /&gt;
   &amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   dependencies:&lt;br /&gt;
    nielsen_flutter_plugin:&lt;br /&gt;
     git:&lt;br /&gt;
      url: https://github.com/NielsenDigitalSDK/flutter.git&lt;br /&gt;
      # The path below is for the 'Global' flavor.&lt;br /&gt;
      # See the table below to select the path for other flavors.&lt;br /&gt;
      path: Flutter/FlutterPlugin/Global/nielsen_flutter_plugin/nielsen_flutter_plugin&lt;br /&gt;
      ref: main // or lock to specific tag like 10.1.0&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*  '''Select Your SDK Flavor Path'''&lt;br /&gt;
&lt;br /&gt;
   Use the following path values to select the appropriate Nielsen SDK flavor:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Flavor !! Flavor path in pubspec.yaml&lt;br /&gt;
|-&lt;br /&gt;
|Global||Flutter/FlutterPlugin/Global/nielsen_flutter_plugin/nielsen_flutter_plugin&lt;br /&gt;
|-&lt;br /&gt;
|GlobalAd||Flutter/FlutterPlugin/GlobalAd/nielsen_flutter_plugin/nielsen_flutter_plugin&lt;br /&gt;
|-&lt;br /&gt;
|GlobalNoAd||Flutter/FlutterPlugin/GlobalNoAd/nielsen_flutter_plugin/nielsen_flutter_plugin&lt;br /&gt;
|-&lt;br /&gt;
|AGF||Flutter/FlutterPlugin/AGF/nielsen_flutter_plugin/nielsen_flutter_plugin&lt;br /&gt;
|-&lt;br /&gt;
|AGFNoAd||Flutter/FlutterPlugin/AGFNoAd/nielsen_flutter_plugin/nielsen_flutter_plugin&lt;br /&gt;
|-&lt;br /&gt;
|AGFNoId||Flutter/FlutterPlugin/AGFNoId/nielsen_flutter_plugin/nielsen_flutter_plugin&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* '''Import the plugin in your Dart code'''&lt;br /&gt;
  &amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  import 'package:nielsen_flutter_plugin/nielsen_flutter_plugin.dart';	&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Public API's ==&lt;br /&gt;
&lt;br /&gt;
All API methods are static and require the sdkId that is returned by createInstance.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
import 'dart:convert';&lt;br /&gt;
import 'package:flutter/foundation.dart';&lt;br /&gt;
import 'package:nielsen_flutter_plugin_platform_interface/nielsen_flutter_plugin_platform_interface.dart';&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/// Nielsen App SDK – Flutter Public APIs.&lt;br /&gt;
class NielsenFlutterPlugin {&lt;br /&gt;
 NielsenFlutterPlugin._();&lt;br /&gt;
 static final NielsenFlutterPlugin instance = NielsenFlutterPlugin._();&lt;br /&gt;
&lt;br /&gt;
 NielsenFlutterPluginPlatform get _p =&amp;gt; NielsenFlutterPluginPlatform.instance;&lt;br /&gt;
&lt;br /&gt;
 bool _debugLogging = false;&lt;br /&gt;
&lt;br /&gt;
 /// Enable/disable debug logging of raw native responses.&lt;br /&gt;
 void enableDebugLogs(bool enable) {&lt;br /&gt;
 _debugLogging = enable;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 void _logDebug(String api, String? res) {&lt;br /&gt;
 if (_debugLogging) {&lt;br /&gt;
 debugPrint('[NielsenFlutterPlugin] $api → $res');&lt;br /&gt;
 }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 // ----------------------------------------------------------------------&lt;br /&gt;
 // Instance lifecycle&lt;br /&gt;
 // ----------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
 /// Creates a Nielsen SDK instance with the provided app info.&lt;br /&gt;
 /// Returns the generated sdkId string.&lt;br /&gt;
 Future&amp;lt;String?&amp;gt; createInstance(Map&amp;lt;String, dynamic&amp;gt; appInfo) async {&lt;br /&gt;
 final res = await _p.createInstance(jsonEncode(appInfo));&lt;br /&gt;
 _logDebug('createInstance', res);&lt;br /&gt;
 return res;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 /// Releases a previously created Nielsen SDK instance.&lt;br /&gt;
 Future&amp;lt;void&amp;gt; free(String sdkId) async {&lt;br /&gt;
 final res = await _p.free(jsonEncode({'sdkId': sdkId}));&lt;br /&gt;
 _logDebug('free', res);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 // ----------------------------------------------------------------------&lt;br /&gt;
 // Playback lifecycle and metadata&lt;br /&gt;
 // ----------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
 /// Signals playback start and passes play metadata.&lt;br /&gt;
 Future&amp;lt;void&amp;gt; play(String sdkId, Map&amp;lt;String, dynamic&amp;gt; playData) async {&lt;br /&gt;
 final res =&lt;br /&gt;
 await _p.play(jsonEncode({'sdkId': sdkId, 'playdata': playData}));&lt;br /&gt;
 _logDebug('play', res);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 /// Loads content/ad/static metadata into the active measurement session.&lt;br /&gt;
 Future&amp;lt;void&amp;gt; loadMetadata(String sdkId, Map&amp;lt;String, dynamic&amp;gt; metadata) async {&lt;br /&gt;
 final res = await _p&lt;br /&gt;
 .loadMetadata(jsonEncode({'sdkId': sdkId, 'metadata': metadata}));&lt;br /&gt;
 _logDebug('loadMetadata', res);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 /// Notifies a temporary stop/pause/interruption in playback.&lt;br /&gt;
 Future&amp;lt;void&amp;gt; stop(String sdkId) async {&lt;br /&gt;
 final res = await _p.stop(jsonEncode({'sdkId': sdkId}));&lt;br /&gt;
 _logDebug('stop', res);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 /// Ends the playback measurement session.&lt;br /&gt;
 Future&amp;lt;void&amp;gt; end(String sdkId) async {&lt;br /&gt;
 final res = await _p.end(jsonEncode({'sdkId': sdkId}));&lt;br /&gt;
 _logDebug('end', res);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 /// Ends a static content session (if used in your workflow).&lt;br /&gt;
 Future&amp;lt;void&amp;gt; staticEnd(String sdkId) async {&lt;br /&gt;
 final res = await _p.staticEnd(jsonEncode({'sdkId': sdkId}));&lt;br /&gt;
 _logDebug('staticEnd', res);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 /// Updates the playhead position (in seconds).&lt;br /&gt;
 Future&amp;lt;void&amp;gt; setPlayheadPosition(String sdkId, int positionSeconds) async {&lt;br /&gt;
 final res = await _p.setPlayheadPosition(&lt;br /&gt;
 jsonEncode({'sdkId': sdkId, 'position': '$positionSeconds'}),&lt;br /&gt;
 );&lt;br /&gt;
 _logDebug('setPlayheadPosition', res);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 /// Reporting OTT update event to the SDK.&lt;br /&gt;
 Future&amp;lt;void&amp;gt; updateOTT(String sdkId, Map&amp;lt;String, dynamic&amp;gt; ottData) async {&lt;br /&gt;
 final res =&lt;br /&gt;
 await _p.updateOTT(jsonEncode({'sdkId': sdkId, 'ottData': ottData}));&lt;br /&gt;
 _logDebug('updateOTT', res);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 // ----------------------------------------------------------------------&lt;br /&gt;
 // Timed metadata (ID3)&lt;br /&gt;
 // ----------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
 /// Sends ID3 timed metadata to the SDK.&lt;br /&gt;
 Future&amp;lt;void&amp;gt; sendID3(String sdkId, String id3) async {&lt;br /&gt;
 final res = await _p.sendID3(jsonEncode({'sdkId': sdkId, 'sendID3': id3}));&lt;br /&gt;
 _logDebug('sendID3', res);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 // ----------------------------------------------------------------------&lt;br /&gt;
 // Information / getters&lt;br /&gt;
 // ----------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
 /// Returns opt-out status as a string (&amp;quot;true&amp;quot;/&amp;quot;false&amp;quot;).&lt;br /&gt;
 Future&amp;lt;String?&amp;gt; getOptOutStatus(String sdkId) async {&lt;br /&gt;
 final res = await _p.getOptOutStatus(jsonEncode({'sdkId': sdkId}));&lt;br /&gt;
 _logDebug('getOptOutStatus', res);&lt;br /&gt;
 return res;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 /// Returns the user opt-out URL string.&lt;br /&gt;
 Future&amp;lt;String?&amp;gt; userOptOutURLString(String sdkId) async {&lt;br /&gt;
 final res = await _p.userOptOutURLString(jsonEncode({'sdkId': sdkId}));&lt;br /&gt;
 _logDebug('userOptOutURLString', res);&lt;br /&gt;
 return res;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
/// Returns Disable metering for the app due to user opt out.&lt;br /&gt;
 Future&amp;lt;String?&amp;gt; userOptOut(String sdkId, String url) async {&lt;br /&gt;
 final res = await _p.userOptOut(jsonEncode({'sdkId': sdkId, 'url': url}));&lt;br /&gt;
 _logDebug('userOptOut', res);&lt;br /&gt;
 return res;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 /// Returns the meter version string.&lt;br /&gt;
 Future&amp;lt;String?&amp;gt; getMeterVersion(String sdkId) async {&lt;br /&gt;
 final res = await _p.getMeterVersion(jsonEncode({'sdkId': sdkId}));&lt;br /&gt;
 _logDebug('getMeterVersion', res);&lt;br /&gt;
 return res;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 /// Returns the demographicId string.&lt;br /&gt;
 Future&amp;lt;String?&amp;gt; getDemographicId(String sdkId) async {&lt;br /&gt;
 final res = await _p.getDemographicId(jsonEncode({'sdkId': sdkId}));&lt;br /&gt;
 _logDebug('getDemographicId', res);&lt;br /&gt;
 return res;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 /// Returns the deviceId string.&lt;br /&gt;
 Future&amp;lt;String?&amp;gt; getDeviceId(String sdkId) async {&lt;br /&gt;
 final res = await _p.getDeviceId(jsonEncode({'sdkId': sdkId}));&lt;br /&gt;
 _logDebug('getDeviceId', res);&lt;br /&gt;
 return res;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 /// Returns the vendorId string (if implemented natively).&lt;br /&gt;
 Future&amp;lt;String?&amp;gt; getVendorId(String sdkId) async {&lt;br /&gt;
 final res = await _p.getVendorId(jsonEncode({'sdkId': sdkId}));&lt;br /&gt;
 _logDebug('getVendorId', res);&lt;br /&gt;
 return res;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 /// Returns the FPID string (if implemented natively).&lt;br /&gt;
 Future&amp;lt;String?&amp;gt; getFpId(String sdkId) async {&lt;br /&gt;
 final res = await _p.getFpId(jsonEncode({'sdkId': sdkId}));&lt;br /&gt;
 _logDebug('getFpid', res);&lt;br /&gt;
 return res;&lt;br /&gt;
 }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== API Reference &amp;amp; Examples ==&lt;br /&gt;
&lt;br /&gt;
* '''createInstance'''&lt;br /&gt;
&lt;br /&gt;
Creates a new Nielsen SDK instance and returns a unique sdkId string for future calls.&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
final sdkId = await NielsenFlutterPlugin.instance.createInstance({&lt;br /&gt;
  &amp;quot;appid&amp;quot;: &amp;quot;PXXXX-XXXX-XXXX&amp;quot;,&lt;br /&gt;
  &amp;quot;sfcode&amp;quot;: &amp;quot;us&amp;quot;,&lt;br /&gt;
  &amp;quot;nol_devDebug&amp;quot;: &amp;quot;DEBUG&amp;quot;,&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''free'''&lt;br /&gt;
&lt;br /&gt;
Releases the Nielsen SDK instance associated with the sdkId. Should be called when the session ends.&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
await NielsenFlutterPlugin.instance.free(sdkId);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''loadMetadata'''&lt;br /&gt;
&lt;br /&gt;
Loads content metadata for the current session.&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
await NielsenFlutterPlugin.instance.loadMetadata(sdkId, {&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;,&lt;br /&gt;
  &amp;quot;assetid&amp;quot;: &amp;quot;video123&amp;quot;,&lt;br /&gt;
  &amp;quot;program&amp;quot;: &amp;quot;Example Show&amp;quot;,&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''play'''&lt;br /&gt;
&lt;br /&gt;
Signals the start of content playback.&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
await NielsenFlutterPlugin.instance.play(sdkId);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''stop'''&lt;br /&gt;
&lt;br /&gt;
Signals that playback has been paused or stopped.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
await NielsenFlutterPlugin.instance.stop(sdkId);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''end'''&lt;br /&gt;
&lt;br /&gt;
Signals the end of content playback.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
await NielsenFlutterPlugin.instance.end(sdkId);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''staticEnd'''&lt;br /&gt;
&lt;br /&gt;
Signals the end of a static (non-video) content view.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
await NielsenFlutterPlugin.instance.staticEnd(sdkId);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''setPlayheadPosition'''&lt;br /&gt;
&lt;br /&gt;
Updates the SDK with the current playhead position in seconds.&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
await NielsenFlutterPlugin.instance.setPlayheadPosition(sdkId, 120);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Identifiers &amp;amp; Info'''&lt;br /&gt;
&lt;br /&gt;
Retrieve various IDs and version information from the SDK.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
final versionNumber = await NielsenFlutterPlugin.instance.getMeterVersion(sdkId);&lt;br /&gt;
final fpid = await NielsenFlutterPlugin.instance.getFpid(sdkId);&lt;br /&gt;
final vendorId = await NielsenFlutterPlugin.instance.getVendorId(sdkId);&lt;br /&gt;
final deviceId = await NielsenFlutterPlugin.instance.getDeviceId(sdkId);&lt;br /&gt;
final version = await NielsenFlutterPlugin.instance.getMeterVersion(sdkId);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Opt-Out'''&lt;br /&gt;
&lt;br /&gt;
Check the user's opt-out status and get the URL for the opt-out web page.&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
final status = await NielsenFlutterPlugin.instance.getOptOutStatus(sdkId);&lt;br /&gt;
final url = await NielsenFlutterPlugin.instance.userOptOutURLString(sdkId);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''UserOptOut'''&lt;br /&gt;
&lt;br /&gt;
Disable metering for the app due to user opt out.&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
final userOptOut = await NielsenFlutterPlugin.instance.userOptOut(sdkId, url);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''sendID3'''&lt;br /&gt;
&lt;br /&gt;
Passes raw ID3 tags to the SDK for live/linear content measurement.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
await NielsenFlutterPlugin.instance.sendID3(sdkId, rawId3Tag);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''enableDebugLogs'''&lt;br /&gt;
&lt;br /&gt;
Call this one before you create any Nielsen instance. It enables debug logs from the Nielsen Flutter plugin. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
await NielsenFlutterPlugin.instance.enableDebugLogs(true);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Error Handling (iOS Specific) ==&lt;br /&gt;
&lt;br /&gt;
The plugin surfaces descriptive error codes if an API is called incorrectly or in an invalid state. Errors are logged to the console but are designed not to crash the application.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Error Code !! Error Description&lt;br /&gt;
|-&lt;br /&gt;
|NLS_JSON_INVALID||The JSON passed to the API is invalid or cannot be parsed&lt;br /&gt;
|-&lt;br /&gt;
|NLS_ARGS_MISSING||One or more required arguments are missing&lt;br /&gt;
|-&lt;br /&gt;
|NLS_SDK_NOT_FOUND||No active SDK instance was found for the given sdkId&lt;br /&gt;
|-&lt;br /&gt;
|NLS_INIT_FAILED||Nielsen SDK initialization failed&lt;br /&gt;
|-&lt;br /&gt;
|NLS_METHOD_UNSUPPORTED||The requested API method is not supported in this context&lt;br /&gt;
|-&lt;br /&gt;
|NLS_PLAYHEAD_INVALID||Playhead position is missing or not valid (expected seconds)&lt;br /&gt;
|}&lt;br /&gt;
Example Log:&lt;br /&gt;
[NielsenFlutterPlugin][ERROR] NLS_SDK_NOT_FOUND: No active SDK instance was found for the given sdkId - Unknown sdkId: 12345&lt;/div&gt;</summary>
		<author><name>AnkitAgrawal</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=Android_SDK_Release_Notes&amp;diff=7414</id>
		<title>Android SDK Release Notes</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=Android_SDK_Release_Notes&amp;diff=7414"/>
		<updated>2025-10-17T11:17:34Z</updated>

		<summary type="html">&lt;p&gt;AnkitAgrawal: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Digital]]&lt;br /&gt;
 __NOTOC__&lt;br /&gt;
&lt;br /&gt;
{{Breadcrumb|}} {{Breadcrumb|Digital Downloads}} {{CurrentBreadcrumb}}&lt;br /&gt;
== Release 10.1.0.0 (10-17-2025) ==&lt;br /&gt;
*Support for FPID multi-instance integrations.&lt;br /&gt;
*Support for Flutter cross-platform plugin.&lt;br /&gt;
*Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 10.0.0.0 (04-04-2025) ==&lt;br /&gt;
*Support for DTVR Subminute product.&lt;br /&gt;
*Support for DCR video playhead bridging.&lt;br /&gt;
*Support for Ethernet network connection for TV platforms.&lt;br /&gt;
*Change in DemographicID behavior for Chromecast.&lt;br /&gt;
*Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 9.4.0.0 (07-09-2024) ==&lt;br /&gt;
*Support for content tracking and no-tracking domains across sdk flavors and products.&lt;br /&gt;
*Upgraded SDK to use Java 11 and Kotlin 1.8.0.                                  &lt;br /&gt;
*Other bug fixes and enhancements.&lt;br /&gt;
== Release 9.3.0.0 (05-10-2024) ==&lt;br /&gt;
*Support for capturing user opt-out during initialization.&lt;br /&gt;
== Release 9.2.0.0 (9-27-2023) ==&lt;br /&gt;
*DCR Static recognizing metadata with changed assetID for new impressions. &lt;br /&gt;
*Limiting ping retries during https failures. &lt;br /&gt;
*Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 9.1.0.0 (3-31-2023) ==&lt;br /&gt;
*DCR Static duration measurement for AppSDK (currently only AGF)&lt;br /&gt;
*Viewability: allow enabling by product (DCR, DTVR)&lt;br /&gt;
*Other bug fixes and enhancements&lt;br /&gt;
&lt;br /&gt;
== Release 9.0.0.0 (10-07-2022) ==&lt;br /&gt;
* Viewability measurement for DTVR, DCR Content and DCR Ad products. &lt;br /&gt;
* Audibility measurement for DTVR, DCR Content and DCR Ad products.&lt;br /&gt;
* Kotlin-Java interoperability implementation in SDK.&lt;br /&gt;
* Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 8.2.0.0 (03-21-2022) ==&lt;br /&gt;
* Support for EMM AGF AdID-less solution.&lt;br /&gt;
* Enabled SDK to capture network availability changes.&lt;br /&gt;
* Removed the usage of deprecated network classes.&lt;br /&gt;
* Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 8.1.0.0 (06-28-2021) ==&lt;br /&gt;
* Support for SDK build variants - AD/NoAD/NoID.&lt;br /&gt;
* Support to indicate ID used for AD build variant - AD ID vs Android ID.&lt;br /&gt;
* Support to capture Hashed email and UID.&lt;br /&gt;
* Support to collect SDK diagnostic data.&lt;br /&gt;
* Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 8.0.0.0 (10-05-2020) ==&lt;br /&gt;
* FPID and VendorID support.&lt;br /&gt;
* Support for Android apps running on ChromeOS.&lt;br /&gt;
* Support for Xamarin cross platform framework.&lt;br /&gt;
* Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 7.2.0.0 (05-18-2020) ==&lt;br /&gt;
* DTVR AQH and IVD requirements for End and pause timeout.&lt;br /&gt;
* Support for Hybrid app webview measurement. &lt;br /&gt;
* Support for Hybrid app react native webview measurement. &lt;br /&gt;
* Support for React Native measurement.&lt;br /&gt;
* Other bug fixes and enhancements&lt;br /&gt;
&lt;br /&gt;
== Release 7.1.0.0 (12-09-2019) ==&lt;br /&gt;
&lt;br /&gt;
* Application background/foreground state auto-detection (AndroidX)&lt;br /&gt;
* Fixed forward rewind evdata containing negative values&lt;br /&gt;
* Offline viewing measurement enhancements&lt;br /&gt;
* Revisited precedence logic for sfcode parameter&lt;br /&gt;
* Using default value for incorrect adModel parameter&lt;br /&gt;
* Defaulting isLive parameter value on channel change&lt;br /&gt;
* Other fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 7.0.0.0 (09-06-2019) ==&lt;br /&gt;
&lt;br /&gt;
* Support for CDN based config.&lt;br /&gt;
* Support for Market based EMM UAID pings.&lt;br /&gt;
* Changes required for proper DCR Static measurement in multi-instance/multiple appid's case.&lt;br /&gt;
* Fixes for OTT synchronization issues between iOS and Android platforms.&lt;br /&gt;
* Fixes for EV data parameters in few scenarios.&lt;br /&gt;
* Fixes for DCR Static product behaviour in background app refresh and background fetch scenarios.&lt;br /&gt;
* DCR Ad reporting improvements.&lt;br /&gt;
* Fixes and improvements for the SDK console log messages.&lt;br /&gt;
* Other enhancements and fixes.&lt;br /&gt;
&lt;br /&gt;
== Release 6.2.0.0  (02-04-2019) ==&lt;br /&gt;
* Removal of Location Module from SDK Code.&lt;br /&gt;
* Fixed the getOptoutStatus() api, so that client can call it in main thread.&lt;br /&gt;
* Fixed the parsing error happening when clientid/vcid provided as empty in metadata.&lt;br /&gt;
* Align AppSDK for FW detection with BSDK for DCR measurement.&lt;br /&gt;
* Other enhancements and fixes.&lt;br /&gt;
&lt;br /&gt;
== Release 6.1.0.1 (9-13-2018) ==&lt;br /&gt;
*Support added for Video On Demand in TV Ratings&lt;br /&gt;
*Bug fixes and improvements&lt;br /&gt;
&lt;br /&gt;
== Release 6.0.0.4 (5-24-2018) ==&lt;br /&gt;
*If the SDK build target is set to AGF then SDK will send the hello ping to “eu” and “eu-uat” for debug builds. No changes to the non AGF build the default sfcode will continue to be &amp;quot;sdk&amp;quot; and &amp;quot;cert&amp;quot; for debug build.&lt;br /&gt;
*The C1 parameter (NUID) will now be sent as encrypted DeviceID.&lt;br /&gt;
*New SessionID changes. The sessionID will contain 29 length random characters appended by timestamp.&lt;br /&gt;
*Support for multiple SDK instance without any limit.&lt;br /&gt;
*New log feature for CAT tool to retrieve the API level information from client apps. This ping will contain the eventType, parameters, SDK version, appid etc.&lt;br /&gt;
*Removed Viewability for this release.&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.26 (7-31-2017) ==&lt;br /&gt;
*Genre parameter will be a part of DCR pings and the value is reflected as part of c44 parameter.&lt;br /&gt;
*Merged adModel and adLoadType flags&lt;br /&gt;
*Fix for stop event data carried to next session’s duration ping&lt;br /&gt;
*Fix for last playhead call that is not processed (when there is no time-gap between the last playhead and end call)&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.24 (6-2-2017) ==&lt;br /&gt;
*Enhanced support for Digital Audio&lt;br /&gt;
*Ability to pass adloadtype as “linear” or “dynamic”&lt;br /&gt;
*Ability to detect end of content and static material through duration pings&lt;br /&gt;
*Acceptance of empty parameters with a warning message triggered, if a required parameter is missing&lt;br /&gt;
*Acceptance of case-insensitive JSON key values&lt;br /&gt;
*Configurable feature to show Ad view counts in the duration pings&lt;br /&gt;
*Automatic Pause Detection and Debug build detection&lt;br /&gt;
*Change of default ‘type’ from “ad” to “content”&lt;br /&gt;
*Removal of “Static” Launch Ping for Non-Static product implementations&lt;br /&gt;
*Fix for metadata carry over between channels after a channel change&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.18 (1-24-2017) ==&lt;br /&gt;
*Ability to opt-out using “Limit Ad Tracking” feature&lt;br /&gt;
*Improved CPU Performance through encryption process change&lt;br /&gt;
*Opt-Out pages can be served based on user’s language and locale from device&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.14 (12-10-2016) ==&lt;br /&gt;
*Support for Nielsen TV Brand Effect&lt;br /&gt;
*Ability to set CMS parameters at a more global level&lt;br /&gt;
*Collection of additional device information&lt;br /&gt;
*Opt-out pages based on locale and country&lt;br /&gt;
*Opt-out based on the ‘Limit Ad Tracking’ flag&lt;br /&gt;
*Issue a warning in client developer’s console when an ad is being played for more than 5 minutes&lt;br /&gt;
*Reduced load time of Android SDK, caused due to encryption.&lt;br /&gt;
*Limit the duration reported for App launch&lt;br /&gt;
*Modification to accept non-JSON strings&lt;br /&gt;
*Fixed&lt;br /&gt;
**Incorrect DRM placement ID&lt;br /&gt;
**DRM pings sent in bursts in case of time change&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.10 (10-19-2016) ==&lt;br /&gt;
*Fixed an issue where SDK will send a burst of data pings in Android.&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.7 (9-1-2016) ==&lt;br /&gt;
*Support for Android N&lt;br /&gt;
*Usage of stop API call is made optional when switching between content or advertising occurs.&lt;br /&gt;
*General bug fix and performance improvements&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.4 (8-1-2016) ==&lt;br /&gt;
*Support for Pause timeout (from 30 minutes to 5 minutes)&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.3 (7-7-2016) ==&lt;br /&gt;
*Sending event level (button press data) data to census collections.&lt;br /&gt;
*Changes in OTT when switching from mobile to Chromecast&lt;br /&gt;
*General bug fix and performance improvements&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.0.4 (4-25-2016) ==&lt;br /&gt;
*Combined SDK for DCR US and International (Germany)&lt;br /&gt;
*API to signal end of content (end API)&lt;br /&gt;
*Changes to use of stop API&lt;br /&gt;
*Support for OTT measurement&lt;br /&gt;
*Support for Pause timeout&lt;br /&gt;
*Offline viewing&lt;br /&gt;
*Updated API to support JSON object instead of string.&lt;br /&gt;
*Reporting of media URL and bundle ID&lt;br /&gt;
*Updated ping retry logic&lt;br /&gt;
*Changes in OptOut process behavioral&lt;br /&gt;
*Enhanced Debugging and SDK logging&lt;br /&gt;
*Changes to API signature&lt;br /&gt;
*Introduced new API updateOTT to report current OTT status.&lt;br /&gt;
&lt;br /&gt;
== Release 4.0.0.8 (6-9-2015) ==&lt;br /&gt;
*Support for Nielsen DCR product (Digital Content Ratings)&lt;br /&gt;
*All the products should be migrated to the latest SDK.&lt;br /&gt;
*This SDK distribution does not have a native library component or shared object.&lt;br /&gt;
*Support for Nielsen App static measurement&lt;br /&gt;
*Support for Ad measurement&lt;br /&gt;
*Removal of Native C++ code&lt;br /&gt;
*Removed singleton restriction&lt;br /&gt;
*Support for Android 6.0 Marshmallow&lt;br /&gt;
*General bug fix and performance improvements&lt;br /&gt;
&lt;br /&gt;
== Release 1.2.3.8 (1-10-2015) ==&lt;/div&gt;</summary>
		<author><name>AnkitAgrawal</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=TVOS_SDK_Release_Notes&amp;diff=7413</id>
		<title>TVOS SDK Release Notes</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=TVOS_SDK_Release_Notes&amp;diff=7413"/>
		<updated>2025-10-17T11:15:34Z</updated>

		<summary type="html">&lt;p&gt;AnkitAgrawal: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Digital]]&lt;br /&gt;
 __NOTOC__&lt;br /&gt;
&lt;br /&gt;
{{Breadcrumb|}} {{Breadcrumb|Digital}} {{CurrentBreadcrumb}}&lt;br /&gt;
== Release 10.1.0.0 (10-17-2025) ==&lt;br /&gt;
*Support for FPID multi-instance integrations.&lt;br /&gt;
*Support for Flutter cross-platform plugin.&lt;br /&gt;
*Support for Apple's iOS26/tvOS26 Log Visibility Changes.&lt;br /&gt;
*Other bug fixes and enhancements.&lt;br /&gt;
==Release 10.0.0.0 (04-04-2025)==&lt;br /&gt;
* Support for DTVR Subminute product.&lt;br /&gt;
*Support for DCR video playhead bridging.&lt;br /&gt;
*Support for VisionOS platform.&lt;br /&gt;
*Change in DemographicID behavior for Chromecast.&lt;br /&gt;
*Other bug fixes and enhancements.&lt;br /&gt;
== Release 9.4.0.0 (07-09-2024) ==&lt;br /&gt;
*Support for privacy manifest with content tracking domain for Ad flavors.&lt;br /&gt;
*Support for content tracking and no-tracking domains across sdk flavors and products.&lt;br /&gt;
*Other bug fixes and enhancements.&lt;br /&gt;
==Release 9.3.0.0 (05-10-2024)==&lt;br /&gt;
*Support for privacy manifest with tracking domain for Ad flavors.&lt;br /&gt;
*Support for capturing user opt-out during initialization.&lt;br /&gt;
*Other bug fixes and enhancements.&lt;br /&gt;
== Release 9.2.0.0 (9-27-2023) ==&lt;br /&gt;
*Support for privacy manifest and required reason API introduced in XCode 15.&lt;br /&gt;
*Digitally signed SDK framework per Apple recommendation&lt;br /&gt;
*DCR Static recognizing metadata with changed assetID for new impressions. &lt;br /&gt;
*Limiting ping retries during https failures. &lt;br /&gt;
*Other bug fixes and enhancements. &lt;br /&gt;
&lt;br /&gt;
== Release 9.1.0.0 (3-31-2023) ==&lt;br /&gt;
*DCR Static duration measurement for AppSDK (currently only AGF).&lt;br /&gt;
*Removed use of iOS keychains, started using NSUserDefaults for persistent storage.&lt;br /&gt;
*Viewability: allow enabling by product (DCR, DTVR).&lt;br /&gt;
*Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 9.0.0.0 (10-07-2022) ==&lt;br /&gt;
* Viewability measurement for DTVR, DCR Content and DCR Ad products.&lt;br /&gt;
* Audibility measurement for DTVR, DCR Content and DCR Ad products.&lt;br /&gt;
* SDK built with XCode 14.&lt;br /&gt;
* Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 8.2.0.0 (03-21-2022) ==&lt;br /&gt;
* Adopting Swift language internally, built on a mixed model (Swift+Objective C).&lt;br /&gt;
* Support for Swift markers to help Swift developers.&lt;br /&gt;
* Removed the usage of deprecated iOS network reachability class.&lt;br /&gt;
* Disabled iCloud backup/synchronization of SDK keychain items.&lt;br /&gt;
* Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 8.1.0.0 (06-28-2021) ==&lt;br /&gt;
* Support for XCFramework build distribution.&lt;br /&gt;
* Support for MacOS Catalyst platform framework.&lt;br /&gt;
* Fixed the device classification for MacOS M1 measurement.&lt;br /&gt;
* Support to capture Hashed email and UID.&lt;br /&gt;
* Support to collect SDK diagnostic data.&lt;br /&gt;
* Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 8.0.0.0 (10-05-2020) ==&lt;br /&gt;
* iOS 14 App Transparency Framework support.&lt;br /&gt;
* FPID and VendorID support.&lt;br /&gt;
* Fixed the device classification for iPADOS measurement.&lt;br /&gt;
* Support for Xamarin cross platform framework.&lt;br /&gt;
* Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 7.2.0.0 (05-18-2020) ==&lt;br /&gt;
* DTVR AQH and IVD requirements for End and pause timeout.&lt;br /&gt;
* Support for Hybrid app webview measurement. &lt;br /&gt;
* Support for Hybrid app react native webview measurement. &lt;br /&gt;
* Support for React Native measurement.&lt;br /&gt;
* Other bug fixes and enhancements&lt;br /&gt;
&lt;br /&gt;
== Release 7.1.0.0 (12-09-2019) ==&lt;br /&gt;
* Removed usage of deprecated class UIWebView&lt;br /&gt;
* Offline viewing measurement enhancements&lt;br /&gt;
* Fixed deadlock on SDK shutdown&lt;br /&gt;
* Revisited precedence logic for sfcode parameter&lt;br /&gt;
* Fix for DCR individual ad pings parameters after channel change&lt;br /&gt;
* Using default value for incorrect adModel parameter&lt;br /&gt;
* Defaulting isLive parameter value on channel change&lt;br /&gt;
* Other fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Release 7.0.0.0 (09-06-2019) ==&lt;br /&gt;
* Support for CDN based config.&lt;br /&gt;
* Support for Market based EMM UAID pings.&lt;br /&gt;
* Changes required for proper DCR Static measurement in multi-instance/multiple appid's case.&lt;br /&gt;
* Fixes for OTT synchronization issues between iOS and Android platforms.&lt;br /&gt;
* Fixes for EV data parameters in few scenarios.&lt;br /&gt;
* Fixes for DCR Static product behaviour in background app refresh and background fetch scenarios.&lt;br /&gt;
* DCR Ad reporting improvements.&lt;br /&gt;
* Fixes and improvements for the SDK console log messages.&lt;br /&gt;
* Other enhancements and fixes.&lt;br /&gt;
&lt;br /&gt;
== Release 6.2.0.0 (02-04-2019) == &lt;br /&gt;
* Introduced Dynamic framework for SDK.&lt;br /&gt;
* Removal of Location Module from SDK Code.&lt;br /&gt;
* Increased SDK log file size for Debug mode.&lt;br /&gt;
* Removed OTT Airplay/mirroring detection that caused crashes in AVAudioSession class.&lt;br /&gt;
* DCR performance improvements.&lt;br /&gt;
* Fixed the parsing error happening when clientid/vcid provided as empty in metadata.&lt;br /&gt;
* Align AppSDK for FW detection with BSDK for DCR measurement.&lt;br /&gt;
* Other Bug Fixes/Enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 6.1.0.1 (9-13-2018) ==&lt;br /&gt;
*Nielsen SDK support for Xcode 10 and tvOS 12&lt;br /&gt;
&lt;br /&gt;
== Release 6.0.0.4 (5-24-2018) ==&lt;br /&gt;
*If the SDK build target is set to AGF then SDK will send the hello ping to “eu” and “eu-uat” for debug builds. No changes to the non AGF build the default sfcode will continue to be &amp;quot;sdk&amp;quot; and &amp;quot;cert&amp;quot; for debug build.&lt;br /&gt;
*The C1 parameter (NUID) will now be sent as encrypted DeviceID.&lt;br /&gt;
*New SessionID changes. The sessionID will contain 29 length random characters appended by timestamp.&lt;br /&gt;
*Support for multiple SDK instance without any limit.&lt;br /&gt;
*New log feature for CAT tool to retrieve the API level information from client apps. This ping will contain the eventType, parameters, SDK version, appid etc.&lt;br /&gt;
*Removed Viewability for this release.&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.17 (1-23-2017) ==&lt;br /&gt;
*Added &amp;quot;seconds&amp;quot; place to the launch ping&lt;br /&gt;
*Ability to opt-out using &amp;quot;Limit Ad Tracking&amp;quot; feature&lt;br /&gt;
*Improved CPU Performance while apps are running in background&lt;br /&gt;
*Opt-Out pages can be served based on user’s language and locale from device&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.12 (12-14-2016) ==&lt;br /&gt;
*Support for Nielsen TV Brand Effect&lt;br /&gt;
*Ability to set CMS parameters at a more global level&lt;br /&gt;
*Opt-out pages based on locale and country&lt;br /&gt;
*Opt-out policy based on the &amp;quot;Limit Ad Tracking&amp;quot; flag&lt;br /&gt;
*Collection of additional device information&lt;br /&gt;
*Issue a warning in client developer’s console when ad is played for more than 5 minutes&lt;br /&gt;
*Removed the requirement for “type” parameter&lt;br /&gt;
*Limit the duration reported for App launch&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.7 (9-13-2016) ==&lt;br /&gt;
*General bug fix and performance improvements&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.5 (7-12-2016) ==&lt;br /&gt;
*Includes a sample TVOS application used to assist during integration.&lt;br /&gt;
*Support for TVML based optout pages&lt;br /&gt;
*General bug fix and performance improvements&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.0.7 (6-15-2016) ==&lt;br /&gt;
*Combined SDK for DCR US and International (Germany)&lt;br /&gt;
*API to signal end of content (end API)&lt;br /&gt;
*Support for Pause timeout&lt;br /&gt;
*Updated API to support JSON object instead of string.&lt;br /&gt;
*Reporting of media URL and bundle ID&lt;br /&gt;
*Updated ping retry logic&lt;br /&gt;
*Changes in OptOut process behavioral&lt;br /&gt;
*Enhanced Debugging and SDK logging&lt;br /&gt;
*Changes to API signature&lt;/div&gt;</summary>
		<author><name>AnkitAgrawal</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=iOS_SDK_Release_Notes&amp;diff=7412</id>
		<title>iOS SDK Release Notes</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=iOS_SDK_Release_Notes&amp;diff=7412"/>
		<updated>2025-10-17T11:14:31Z</updated>

		<summary type="html">&lt;p&gt;AnkitAgrawal: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Digital]]&lt;br /&gt;
 __NOTOC__&lt;br /&gt;
&lt;br /&gt;
{{Breadcrumb|}} {{Breadcrumb|Digital Downloads}} {{CurrentBreadcrumb}}&lt;br /&gt;
&lt;br /&gt;
== Release 10.1.0.0 (10-17-2025) ==&lt;br /&gt;
*Support for FPID multi-instance integrations.&lt;br /&gt;
*Support for Flutter cross-platform plugin.&lt;br /&gt;
*Support for Apple's iOS26/tvOS26 Log Visibility Changes.&lt;br /&gt;
*Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 10.0.0.0 (04-04-2025) ==&lt;br /&gt;
*Support for DTVR Subminute product.&lt;br /&gt;
*Support for DCR video playhead bridging.&lt;br /&gt;
*Support for VisionOS platform.&lt;br /&gt;
*Change in DemographicID behavior for Chromecast.&lt;br /&gt;
*Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== '''Release 9.4.0.0 (07-09-2024)''' ==&lt;br /&gt;
*Support for privacy manifest with content tracking domain for Ad flavors.&lt;br /&gt;
*Support for content tracking and no-tracking domains across sdk flavors and products.&lt;br /&gt;
*Other bug fixes and enhancements.&lt;br /&gt;
== Release 9.3.0.0 (05-10-2024) ==&lt;br /&gt;
*Support for privacy manifest with tracking domain for Ad flavors.&lt;br /&gt;
*Support for capturing user opt-out during initialization.&lt;br /&gt;
*Other bug fixes and enhancements.&lt;br /&gt;
== Release 9.2.0.0 (09-27-2023) ==&lt;br /&gt;
*Support for privacy manifest and required reason API introduced in XCode 15.&lt;br /&gt;
*Digitally signed SDK framework per Apple recommendation&lt;br /&gt;
*DCR Static recognizing metadata with changed assetID for new impressions. &lt;br /&gt;
*Limiting ping retries during https failures. &lt;br /&gt;
*Other bug fixes and enhancements. &lt;br /&gt;
&lt;br /&gt;
== Release 9.1.0.0 (03-31-2023) ==&lt;br /&gt;
*DCR Static duration measurement for AppSDK (currently only AGF).&lt;br /&gt;
*Removed use of iOS keychains, started using NSUserDefaults for persistent storage.&lt;br /&gt;
*Viewability: allow enabling by product (DCR, DTVR).&lt;br /&gt;
*Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 9.0.0.0 (10-07-2022) ==&lt;br /&gt;
* Viewability measurement for DTVR, DCR Content and DCR Ad products.&lt;br /&gt;
* Audibility measurement for DTVR, DCR Content and DCR Ad products.&lt;br /&gt;
* SDK built with XCode 14.&lt;br /&gt;
* Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 8.2.0.0 (03-21-2022) ==&lt;br /&gt;
* Adopting Swift language internally, built on a mixed model (Swift+Objective C).&lt;br /&gt;
* Support for Swift markers to help Swift developers.&lt;br /&gt;
* Removed the usage of deprecated iOS network reachability class.&lt;br /&gt;
* Disabled iCloud backup/synchronization of SDK keychain items.&lt;br /&gt;
* Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 8.1.0.0 (06-28-2021) ==&lt;br /&gt;
* Support for XCFramework build distribution.&lt;br /&gt;
* Support for MacOS Catalyst platform framework.&lt;br /&gt;
* Fixed the device classification for MacOS M1 measurement.&lt;br /&gt;
* Support to capture Hashed email and UID.&lt;br /&gt;
* Support to collect SDK diagnostic data.&lt;br /&gt;
* Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 8.0.0.0 (10-05-2020) ==&lt;br /&gt;
* iOS 14 App Transparency Framework support.&lt;br /&gt;
* FPID and VendorID support.&lt;br /&gt;
* Fixed the device classification for iPADOS measurement.&lt;br /&gt;
* Support for Xamarin cross platform framework.&lt;br /&gt;
* Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 7.2.0.0 (05-18-2020) ==&lt;br /&gt;
* DTVR AQH and IVD requirements for End and pause timeout.&lt;br /&gt;
* Support for Hybrid app webview measurement. &lt;br /&gt;
* Support for Hybrid app react native webview measurement. &lt;br /&gt;
* Support for React Native measurement.&lt;br /&gt;
* Other bug fixes and enhancements&lt;br /&gt;
&lt;br /&gt;
== Release 7.1.0.0 (12-09-2019) ==&lt;br /&gt;
* Removed usage of deprecated class UIWebView&lt;br /&gt;
* Offline viewing measurement enhancements&lt;br /&gt;
* Fixed deadlock on SDK shutdown&lt;br /&gt;
* Revisited precedence logic for sfcode parameter&lt;br /&gt;
* Fix for DCR individual ad pings parameters after channel change&lt;br /&gt;
* Using default value for incorrect adModel parameter&lt;br /&gt;
* Defaulting isLive parameter value on channel change&lt;br /&gt;
* Other fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 7.0.0.0 (09-06-2019) ==&lt;br /&gt;
* Support for CDN based config.&lt;br /&gt;
* Support for Market based EMM UAID pings.&lt;br /&gt;
* Changes required for proper DCR Static measurement in multi-instance/multiple appid's case.&lt;br /&gt;
* Fixes for OTT synchronization issues between iOS and Android platforms.&lt;br /&gt;
* Fixes for EV data parameters in few scenarios.&lt;br /&gt;
* Fixes for DCR Static product behaviour in background app refresh and background fetch scenarios.&lt;br /&gt;
* DCR Ad reporting improvements.&lt;br /&gt;
* Fixes and improvements for the SDK console log messages.&lt;br /&gt;
* Other enhancements and fixes.&lt;br /&gt;
&lt;br /&gt;
== Release 6.2.0.0 (02-04-2019) == &lt;br /&gt;
* Introduced Dynamic framework for SDK.&lt;br /&gt;
* Removal of Location Module from SDK Code.&lt;br /&gt;
* Increased SDK log file size for Debug mode.&lt;br /&gt;
* Removed OTT Airplay/mirroring detection that caused crashes in AVAudioSession class.&lt;br /&gt;
* DCR performance improvements.&lt;br /&gt;
* Fixed the parsing error happening when clientid/vcid provided as empty in metadata.&lt;br /&gt;
* Align AppSDK for FW detection with BSDK for DCR measurement.&lt;br /&gt;
* Other Bug Fixes/Enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 6.1.0.1 (9-13-2018) ==&lt;br /&gt;
*Support added for Video On Demand in TV Ratings&lt;br /&gt;
*Support for Xcode 10 and iOS 12&lt;br /&gt;
&lt;br /&gt;
== Release 6.0.0.4 (5-24-2018) ==&lt;br /&gt;
*If the SDK build target is set to AGF then SDK will send the hello ping to “eu” and “eu-uat” for debug builds. No changes to the non AGF build the default sfcode will continue to be &amp;quot;sdk&amp;quot; and &amp;quot;cert&amp;quot; for debug build.&lt;br /&gt;
*The C1 parameter (NUID) will now be sent as encrypted DeviceID.&lt;br /&gt;
*New SessionID changes. The sessionID will contain 29 length random characters appended by timestamp.&lt;br /&gt;
*Support for multiple SDK instance without any limit.&lt;br /&gt;
*New log feature for CAT tool to retrieve the API level information from client apps. This ping will contain the eventType, parameters, SDK version, appid etc.&lt;br /&gt;
*Removed Viewability for this release.&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.29 (7-31-2017) ==&lt;br /&gt;
*Genre parameter will be a part of DCR pings and the value will be reflected as part of c44 parameter.&lt;br /&gt;
*Merged adModel and adLoadType flags&lt;br /&gt;
*Fix for stop event data carried to next session’s duration ping&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.25 (5-31-2017) ==&lt;br /&gt;
*Enhanced support for Digital Audio&lt;br /&gt;
*Ability to pass adloadtype as “linear” or “dynamic”&lt;br /&gt;
*Ability to detect end of content and static material through duration pings&lt;br /&gt;
*Acceptance of empty parameters with a warning message triggered, if a required parameter is missing&lt;br /&gt;
*Acceptance of case-insensitive JSON key values&lt;br /&gt;
*Configurable feature to show Ad view counts in the duration pings&lt;br /&gt;
*Automatic Pause Detection and Debug build detection&lt;br /&gt;
*Change of default ‘type’ from “ad” to “content”&lt;br /&gt;
*Removal of “Static” Launch Ping for Non-Static product implementations&lt;br /&gt;
*Fix for App crash when multiple threads are accessing the SQLite&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.23 (5-5-2017) ==&lt;br /&gt;
*Ability to pass adloadtype as “linear” or “dynamic”&lt;br /&gt;
*Ability to detect end of content and static material through duration pings&lt;br /&gt;
*Acceptance of empty parameters with a warning message triggered, if a required parameter is missing&lt;br /&gt;
*Acceptance of case-insensitive JSON key values&lt;br /&gt;
*Configurable feature to show Ad view counts in the duration pings&lt;br /&gt;
*Automatic Pause Detection and Debug build detection&lt;br /&gt;
*Change of default ‘type’ from “ad” to “content”&lt;br /&gt;
*Removal of “Static” Launch Ping for Non-Static product implementations&lt;br /&gt;
*Fix for App crash when multiple threads are accessing the SQLite&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.19 (4-3-2017) ==&lt;br /&gt;
*Fix for muting background music apps&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.18 (2-3-2017) ==&lt;br /&gt;
*Minor bug fixes and performance improvement&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.17 (1-23-2017) ==&lt;br /&gt;
*Added “seconds” place to the launch ping&lt;br /&gt;
*Ability to opt-out using “Limit Ad Tracking” feature&lt;br /&gt;
*Improved CPU Performance while apps are running in background&lt;br /&gt;
*Opt-Out pages can be served based on user’s language and locale from device&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.12 (12-14-2016) ==&lt;br /&gt;
*Support for Nielsen TV Brand Effect&lt;br /&gt;
*Ability to set CMS parameters at a more global level&lt;br /&gt;
*Opt-out pages based on locale and country&lt;br /&gt;
*Opt-out policy based on the ‘Limit Ad Tracking’ flag&lt;br /&gt;
*Collection of additional device information&lt;br /&gt;
*Issue a warning in client developer’s console when ad is played for more than 5 minutes&lt;br /&gt;
*Removed the requirement for “type” parameter&lt;br /&gt;
*Limit the duration reported for App launch&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.9 (10-18-2016) ==&lt;br /&gt;
*Fixed Linker error duplicate symbols for Reachability notification in iOS.&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.7 (9-13-2016) ==&lt;br /&gt;
*Support for iOS 10&lt;br /&gt;
*Usage of stop API call is made optional when switching between content or advertising occurs.&lt;br /&gt;
*General bug fix and performance improvements&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.5 (7-12-2016) ==&lt;br /&gt;
*Sending event level (button press data) data to census collections.&lt;br /&gt;
*Support for Pause timeout (from 30 minutes to 5 minutes)&lt;br /&gt;
*Changes in OTT when switching from mobile to Chromecast&lt;br /&gt;
*Self-error Reporting for iOS SDK&lt;br /&gt;
*General bug fix and performance improvements&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.0.5 (4-25-2016) ==&lt;br /&gt;
*Combined SDK for DCR US and International (Germany)&lt;br /&gt;
*API to signal end of content (end API)&lt;br /&gt;
*Changes to use of stop API&lt;br /&gt;
*Support for OTT measurement&lt;br /&gt;
*Support for Pause timeout&lt;br /&gt;
*Offline viewing&lt;br /&gt;
*Updated API to support JSON object instead of string.&lt;br /&gt;
*Reporting of media URL and bundle ID&lt;br /&gt;
*Updated ping retry logic&lt;br /&gt;
*Changes in OptOut process behavioral&lt;br /&gt;
*Enhanced Debugging and SDK logging&lt;br /&gt;
*Changes to API signature&lt;br /&gt;
*Introduced new API updateOTT to report current OTT status.&lt;br /&gt;
&lt;br /&gt;
== Release 4.0.0.8 (6-9-2015) ==&lt;br /&gt;
*Support for Nielsen DCR product (Digital Content Ratings)&lt;br /&gt;
**All the products should be migrated to the latest SDK.&lt;br /&gt;
**This SDK distribution does not have a native library component or shared object.&lt;br /&gt;
*Support for Nielsen App static measurement&lt;br /&gt;
*Support for Ad measurement&lt;br /&gt;
*Removal of Native C++ code&lt;br /&gt;
*Removed singleton restriction&lt;br /&gt;
*Support for iOS 9 and iOS 9 PIP mode&lt;br /&gt;
*General bug fix and performance improvements&lt;br /&gt;
&lt;br /&gt;
== Release 3.2.1.26 (1-10-2015) ==&lt;/div&gt;</summary>
		<author><name>AnkitAgrawal</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=Digital_Measurement_Android_Suffix_Guide&amp;diff=7411</id>
		<title>Digital Measurement Android Suffix Guide</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=Digital_Measurement_Android_Suffix_Guide&amp;diff=7411"/>
		<updated>2025-10-17T11:02:01Z</updated>

		<summary type="html">&lt;p&gt;AnkitAgrawal: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|DCR &amp;amp; DTVR}} {{Breadcrumb|Digital_Measurement_Android_Artifactory_Guide}} {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
= Android app sdk version suffix=&lt;br /&gt;
We have added an extra third character in the build version of appsdk to represent the android-x support in appsdk. &lt;br /&gt;
&lt;br /&gt;
From onwards now you will see meter version of app sdk ending with 5 characters suffix  as &amp;lt;code&amp;gt;aa.8.2.0.0_{suffix}&amp;lt;/code&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
Below are details of possible suffix characters with description&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Character Index in suffix !! Possible Values!! Description&lt;br /&gt;
|-&lt;br /&gt;
|0 (first character in suffix)||g,a and v||&amp;lt;code&amp;gt;g&amp;lt;/code&amp;gt; means it's the GLOBAL flavored sdk (Default).&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt; means the build was designed for AGF.&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;v&amp;lt;/code&amp;gt; identifies the VRI flavoured sdk.&lt;br /&gt;
|-&lt;br /&gt;
|1 (second character in suffix)||a,s and l ||&amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt; means the sdk is coming from github as a gradle dependency.&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt; sdk is integrated as jar.&amp;lt;br&amp;gt; &amp;lt;code&amp;gt;l&amp;lt;/code&amp;gt; sdk is coming from adobe launch.&lt;br /&gt;
|-&lt;br /&gt;
|2 (third character in suffix)||a and x	||&amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt; means the sdk is built for non androidx apps.&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; means the sdk is built for '''androidx''' apps.&amp;lt;br&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|3 (fourth character in suffix)||a, n and k||&amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt; means AdSupport included. (Default)&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; no AdSupport included.&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt; No IDFA or IDFV (kids framework).&amp;lt;br&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|4 (fifth character in suffix)||o and t||&amp;lt;code&amp;gt;o&amp;lt;/code&amp;gt; means the sdk is getting instantiated using the AppSdk class. (Default)&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;t&amp;lt;/code&amp;gt; means sdk is  using NielsenEventTracker class.&amp;lt;br&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|5 (sixth character in suffix)||h,w,r,f and n||&amp;lt;code&amp;gt;h&amp;lt;/code&amp;gt; then sdk supports Hybrid Webviews.&amp;lt;br&amp;gt; &amp;lt;code&amp;gt;w&amp;lt;/code&amp;gt; identifies React Native Webview support.&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;r&amp;lt;/code&amp;gt; sdk supports React Native standard bridge.&lt;br /&gt;
&amp;lt;code&amp;gt;f&amp;lt;/code&amp;gt; sdk supports Flutter plugin.&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; means sdk supports Native apps.&lt;br /&gt;
|-&lt;br /&gt;
|6 (seventh character in suffix)||g,s and n||&amp;lt;code&amp;gt;g&amp;lt;/code&amp;gt; the sdk will request the Google Advertising ID.&amp;lt;br&amp;gt; &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt; the sdk will request the Secure Android ID.&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; the sdk will not request any ID. (EG: Not Applicable)&lt;br /&gt;
|}&lt;br /&gt;
Below are few examples of possible suffix in app sdk meter version &lt;br /&gt;
&lt;br /&gt;
* '''aa.8.2.0.0_gaxaohg''' &lt;br /&gt;
** Sdk version 8.2.0.0 &lt;br /&gt;
** '''GLOBAL flavour'''&lt;br /&gt;
** integrated as '''gradle dependency'''&lt;br /&gt;
** '''android x'''&lt;br /&gt;
** AdSupport&lt;br /&gt;
** using AppSdk class to instantiate&lt;br /&gt;
** Hybrid Webview support&lt;br /&gt;
** Google Ad ID&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
* '''aa.8.2.0.0_vaxkons'''&lt;br /&gt;
**Sdk version 8.2.0.0&lt;br /&gt;
** '''VRI flavour'''&lt;br /&gt;
** integrated as '''gradle dependency''' &lt;br /&gt;
** supporting '''android x''' &lt;br /&gt;
** Kids framework&lt;br /&gt;
** using AppSdk class to instantiate&lt;br /&gt;
** native app.&lt;br /&gt;
** Secure Android ID&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>AnkitAgrawal</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=DCR_%26_DTVR_Flutter_Integration&amp;diff=7407</id>
		<title>DCR &amp; DTVR Flutter Integration</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=DCR_%26_DTVR_Flutter_Integration&amp;diff=7407"/>
		<updated>2025-10-15T19:35:42Z</updated>

		<summary type="html">&lt;p&gt;AnkitAgrawal: Created page with &amp;quot;{{Breadcrumb|}} {{Breadcrumb|Digital}}  {{Breadcrumb|DCR &amp;amp; DTVR}} {{CurrentBreadcrumb}} Category:Digital = Integrate Nielsen SDK Api in Flutter App =  == Overview ==  The Nielsen Flutter Plugin provides a Dart API that bridges into the native Nielsen App SDKs (iOS and Android) using Flutter’s platform channels.  Flow: Dart → Platform Channel → iOS/Android Plugin → Nielsen App SDK  Supports SDK flavors: Global, GlobalAd, GlobalNoAd, AGF, AGFNoAd, AGFNoId  Each...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}}  {{Breadcrumb|DCR &amp;amp; DTVR}} {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
= Integrate Nielsen SDK Api in Flutter App =&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
The Nielsen Flutter Plugin provides a Dart API that bridges into the native Nielsen App SDKs (iOS and Android) using Flutter’s platform channels.&lt;br /&gt;
&lt;br /&gt;
Flow: Dart → Platform Channel → iOS/Android Plugin → Nielsen App SDK&lt;br /&gt;
&lt;br /&gt;
Supports SDK flavors: Global, GlobalAd, GlobalNoAd, AGF, AGFNoAd, AGFNoId&lt;br /&gt;
&lt;br /&gt;
Each flavor corresponds to a different Nielsen SDK package. You select the one required by your business case in the pubspec.yaml.&lt;br /&gt;
&amp;lt;p style=&amp;quot;color:#C70039;&amp;quot;&amp;gt;Note : Support for Flutter in Nielsen SDK is available from version 10.1.0.0&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
To start using the App SDK, the following details are required:&lt;br /&gt;
* '''App ID (appid):''' Unique ID assigned to the player/site and configured by product.&lt;br /&gt;
* '''sfcode:''' Unique identifier for the environment that the SDK should point to.&lt;br /&gt;
* '''Nielsen SDK:''' The Nielsen SDK package contains a variety of sample players for your reference.&lt;br /&gt;
If you do not have any of these prerequisites or if you have any questions, please contact our SDK sales support team.&lt;br /&gt;
Refer to [[Digital Measurement Onboarding]] guide for information on how to get a Nielsen App SDK and appid.&lt;br /&gt;
&lt;br /&gt;
== Setting up your Environment  ==&lt;br /&gt;
*  '''Add dependency in pubspec.yaml'''&lt;br /&gt;
   &amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   dependencies:&lt;br /&gt;
    nielsen_flutter_plugin:&lt;br /&gt;
     git:&lt;br /&gt;
      url: https://github.com/NielsenDigitalSDK/flutter.git&lt;br /&gt;
      # The path below is for the 'Global' flavor.&lt;br /&gt;
      # See the table below to select the path for other flavors.&lt;br /&gt;
      path: Flutter/FlutterPlugin/Global/nielsen_flutter_plugin/nielsen_flutter_plugin&lt;br /&gt;
      ref: main&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*  '''Select Your SDK Flavor Path'''&lt;br /&gt;
&lt;br /&gt;
   Use the following path values to select the appropriate Nielsen SDK flavor:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Flavor !! Flavor path in pubspec.yaml&lt;br /&gt;
|-&lt;br /&gt;
|Global||Flutter/FlutterPlugin/Global/nielsen_flutter_plugin/nielsen_flutter_plugin&lt;br /&gt;
|-&lt;br /&gt;
|GlobalAd||Flutter/FlutterPlugin/GlobalAd/nielsen_flutter_plugin/nielsen_flutter_plugin&lt;br /&gt;
|-&lt;br /&gt;
|GlobalNoAd||Flutter/FlutterPlugin/GlobalNoAd/nielsen_flutter_plugin/nielsen_flutter_plugin&lt;br /&gt;
|-&lt;br /&gt;
|AGF||Flutter/FlutterPlugin/AGF/nielsen_flutter_plugin/nielsen_flutter_plugin&lt;br /&gt;
|-&lt;br /&gt;
|AGFNoAd||Flutter/FlutterPlugin/AGFNoAd/nielsen_flutter_plugin/nielsen_flutter_plugin&lt;br /&gt;
|-&lt;br /&gt;
|AGFNoId||Flutter/FlutterPlugin/AGFNoId/nielsen_flutter_plugin/nielsen_flutter_plugin&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* '''Import the plugin in your Dart code'''&lt;br /&gt;
  &amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  import 'package:nielsen_flutter_plugin/nielsen_flutter_plugin.dart';	&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Public API's ==&lt;br /&gt;
&lt;br /&gt;
All API methods are static and require the sdkId that is returned by createInstance.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
import 'dart:convert';&lt;br /&gt;
import 'package:flutter/foundation.dart';&lt;br /&gt;
import 'package:nielsen_flutter_plugin_platform_interface/nielsen_flutter_plugin_platform_interface.dart';&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/// Nielsen App SDK – Flutter Public APIs.&lt;br /&gt;
class NielsenFlutterPlugin {&lt;br /&gt;
 NielsenFlutterPlugin._();&lt;br /&gt;
 static final NielsenFlutterPlugin instance = NielsenFlutterPlugin._();&lt;br /&gt;
&lt;br /&gt;
 NielsenFlutterPluginPlatform get _p =&amp;gt; NielsenFlutterPluginPlatform.instance;&lt;br /&gt;
&lt;br /&gt;
 bool _debugLogging = false;&lt;br /&gt;
&lt;br /&gt;
 /// Enable/disable debug logging of raw native responses.&lt;br /&gt;
 void enableDebugLogs(bool enable) {&lt;br /&gt;
 _debugLogging = enable;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 void _logDebug(String api, String? res) {&lt;br /&gt;
 if (_debugLogging) {&lt;br /&gt;
 debugPrint('[NielsenFlutterPlugin] $api → $res');&lt;br /&gt;
 }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 // ----------------------------------------------------------------------&lt;br /&gt;
 // Instance lifecycle&lt;br /&gt;
 // ----------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
 /// Creates a Nielsen SDK instance with the provided app info.&lt;br /&gt;
 /// Returns the generated sdkId string.&lt;br /&gt;
 Future&amp;lt;String?&amp;gt; createInstance(Map&amp;lt;String, dynamic&amp;gt; appInfo) async {&lt;br /&gt;
 final res = await _p.createInstance(jsonEncode(appInfo));&lt;br /&gt;
 _logDebug('createInstance', res);&lt;br /&gt;
 return res;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 /// Releases a previously created Nielsen SDK instance.&lt;br /&gt;
 Future&amp;lt;void&amp;gt; free(String sdkId) async {&lt;br /&gt;
 final res = await _p.free(jsonEncode({'sdkId': sdkId}));&lt;br /&gt;
 _logDebug('free', res);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 // ----------------------------------------------------------------------&lt;br /&gt;
 // Playback lifecycle and metadata&lt;br /&gt;
 // ----------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
 /// Signals playback start and passes play metadata.&lt;br /&gt;
 Future&amp;lt;void&amp;gt; play(String sdkId, Map&amp;lt;String, dynamic&amp;gt; playData) async {&lt;br /&gt;
 final res =&lt;br /&gt;
 await _p.play(jsonEncode({'sdkId': sdkId, 'playdata': playData}));&lt;br /&gt;
 _logDebug('play', res);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 /// Loads content/ad/static metadata into the active measurement session.&lt;br /&gt;
 Future&amp;lt;void&amp;gt; loadMetadata(String sdkId, Map&amp;lt;String, dynamic&amp;gt; metadata) async {&lt;br /&gt;
 final res = await _p&lt;br /&gt;
 .loadMetadata(jsonEncode({'sdkId': sdkId, 'metadata': metadata}));&lt;br /&gt;
 _logDebug('loadMetadata', res);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 /// Notifies a temporary stop/pause/interruption in playback.&lt;br /&gt;
 Future&amp;lt;void&amp;gt; stop(String sdkId) async {&lt;br /&gt;
 final res = await _p.stop(jsonEncode({'sdkId': sdkId}));&lt;br /&gt;
 _logDebug('stop', res);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 /// Ends the playback measurement session.&lt;br /&gt;
 Future&amp;lt;void&amp;gt; end(String sdkId) async {&lt;br /&gt;
 final res = await _p.end(jsonEncode({'sdkId': sdkId}));&lt;br /&gt;
 _logDebug('end', res);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 /// Ends a static content session (if used in your workflow).&lt;br /&gt;
 Future&amp;lt;void&amp;gt; staticEnd(String sdkId) async {&lt;br /&gt;
 final res = await _p.staticEnd(jsonEncode({'sdkId': sdkId}));&lt;br /&gt;
 _logDebug('staticEnd', res);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 /// Updates the playhead position (in seconds).&lt;br /&gt;
 Future&amp;lt;void&amp;gt; setPlayheadPosition(String sdkId, int positionSeconds) async {&lt;br /&gt;
 final res = await _p.setPlayheadPosition(&lt;br /&gt;
 jsonEncode({'sdkId': sdkId, 'position': '$positionSeconds'}),&lt;br /&gt;
 );&lt;br /&gt;
 _logDebug('setPlayheadPosition', res);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 /// Reporting OTT update event to the SDK.&lt;br /&gt;
 Future&amp;lt;void&amp;gt; updateOTT(String sdkId, Map&amp;lt;String, dynamic&amp;gt; ottData) async {&lt;br /&gt;
 final res =&lt;br /&gt;
 await _p.updateOTT(jsonEncode({'sdkId': sdkId, 'ottData': ottData}));&lt;br /&gt;
 _logDebug('updateOTT', res);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 // ----------------------------------------------------------------------&lt;br /&gt;
 // Timed metadata (ID3)&lt;br /&gt;
 // ----------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
 /// Sends ID3 timed metadata to the SDK.&lt;br /&gt;
 Future&amp;lt;void&amp;gt; sendID3(String sdkId, String id3) async {&lt;br /&gt;
 final res = await _p.sendID3(jsonEncode({'sdkId': sdkId, 'sendID3': id3}));&lt;br /&gt;
 _logDebug('sendID3', res);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 // ----------------------------------------------------------------------&lt;br /&gt;
 // Information / getters&lt;br /&gt;
 // ----------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
 /// Returns opt-out status as a string (&amp;quot;true&amp;quot;/&amp;quot;false&amp;quot;).&lt;br /&gt;
 Future&amp;lt;String?&amp;gt; getOptOutStatus(String sdkId) async {&lt;br /&gt;
 final res = await _p.getOptOutStatus(jsonEncode({'sdkId': sdkId}));&lt;br /&gt;
 _logDebug('getOptOutStatus', res);&lt;br /&gt;
 return res;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 /// Returns the user opt-out URL string.&lt;br /&gt;
 Future&amp;lt;String?&amp;gt; userOptOutURLString(String sdkId) async {&lt;br /&gt;
 final res = await _p.userOptOutURLString(jsonEncode({'sdkId': sdkId}));&lt;br /&gt;
 _logDebug('userOptOutURLString', res);&lt;br /&gt;
 return res;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
/// Returns Disable metering for the app due to user opt out.&lt;br /&gt;
 Future&amp;lt;String?&amp;gt; userOptOut(String sdkId, String url) async {&lt;br /&gt;
 final res = await _p.userOptOut(jsonEncode({'sdkId': sdkId, 'url': url}));&lt;br /&gt;
 _logDebug('userOptOut', res);&lt;br /&gt;
 return res;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 /// Returns the meter version string.&lt;br /&gt;
 Future&amp;lt;String?&amp;gt; getMeterVersion(String sdkId) async {&lt;br /&gt;
 final res = await _p.getMeterVersion(jsonEncode({'sdkId': sdkId}));&lt;br /&gt;
 _logDebug('getMeterVersion', res);&lt;br /&gt;
 return res;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 /// Returns the demographicId string.&lt;br /&gt;
 Future&amp;lt;String?&amp;gt; getDemographicId(String sdkId) async {&lt;br /&gt;
 final res = await _p.getDemographicId(jsonEncode({'sdkId': sdkId}));&lt;br /&gt;
 _logDebug('getDemographicId', res);&lt;br /&gt;
 return res;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 /// Returns the deviceId string.&lt;br /&gt;
 Future&amp;lt;String?&amp;gt; getDeviceId(String sdkId) async {&lt;br /&gt;
 final res = await _p.getDeviceId(jsonEncode({'sdkId': sdkId}));&lt;br /&gt;
 _logDebug('getDeviceId', res);&lt;br /&gt;
 return res;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 /// Returns the vendorId string (if implemented natively).&lt;br /&gt;
 Future&amp;lt;String?&amp;gt; getVendorId(String sdkId) async {&lt;br /&gt;
 final res = await _p.getVendorId(jsonEncode({'sdkId': sdkId}));&lt;br /&gt;
 _logDebug('getVendorId', res);&lt;br /&gt;
 return res;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 /// Returns the FPID string (if implemented natively).&lt;br /&gt;
 Future&amp;lt;String?&amp;gt; getFpId(String sdkId) async {&lt;br /&gt;
 final res = await _p.getFpId(jsonEncode({'sdkId': sdkId}));&lt;br /&gt;
 _logDebug('getFpid', res);&lt;br /&gt;
 return res;&lt;br /&gt;
 }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== API Reference &amp;amp; Examples ==&lt;br /&gt;
&lt;br /&gt;
* '''createInstance'''&lt;br /&gt;
&lt;br /&gt;
Creates a new Nielsen SDK instance and returns a unique sdkId string for future calls.&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
final sdkId = await NielsenFlutterPlugin.instance.createInstance({&lt;br /&gt;
  &amp;quot;appid&amp;quot;: &amp;quot;PXXXX-XXXX-XXXX&amp;quot;,&lt;br /&gt;
  &amp;quot;sfcode&amp;quot;: &amp;quot;us&amp;quot;,&lt;br /&gt;
  &amp;quot;nol_devDebug&amp;quot;: &amp;quot;DEBUG&amp;quot;,&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''free'''&lt;br /&gt;
&lt;br /&gt;
Releases the Nielsen SDK instance associated with the sdkId. Should be called when the session ends.&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
await NielsenFlutterPlugin.instance.free(sdkId);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''loadMetadata'''&lt;br /&gt;
&lt;br /&gt;
Loads content metadata for the current session.&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
await NielsenFlutterPlugin.instance.loadMetadata(sdkId, {&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;,&lt;br /&gt;
  &amp;quot;assetid&amp;quot;: &amp;quot;video123&amp;quot;,&lt;br /&gt;
  &amp;quot;program&amp;quot;: &amp;quot;Example Show&amp;quot;,&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''play'''&lt;br /&gt;
&lt;br /&gt;
Signals the start of content playback.&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
await NielsenFlutterPlugin.instance.play(sdkId);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''stop'''&lt;br /&gt;
&lt;br /&gt;
Signals that playback has been paused or stopped.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
await NielsenFlutterPlugin.instance.stop(sdkId);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''end'''&lt;br /&gt;
&lt;br /&gt;
Signals the end of content playback.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
await NielsenFlutterPlugin.instance.end(sdkId);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''staticEnd'''&lt;br /&gt;
&lt;br /&gt;
Signals the end of a static (non-video) content view.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
await NielsenFlutterPlugin.instance.staticEnd(sdkId);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''setPlayheadPosition'''&lt;br /&gt;
&lt;br /&gt;
Updates the SDK with the current playhead position in seconds.&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
await NielsenFlutterPlugin.instance.setPlayheadPosition(sdkId, 120);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Identifiers &amp;amp; Info'''&lt;br /&gt;
&lt;br /&gt;
Retrieve various IDs and version information from the SDK.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
final versionNumber = await NielsenFlutterPlugin.instance.getMeterVersion(sdkId);&lt;br /&gt;
final fpid = await NielsenFlutterPlugin.instance.getFpid(sdkId);&lt;br /&gt;
final vendorId = await NielsenFlutterPlugin.instance.getVendorId(sdkId);&lt;br /&gt;
final deviceId = await NielsenFlutterPlugin.instance.getDeviceId(sdkId);&lt;br /&gt;
final version = await NielsenFlutterPlugin.instance.getMeterVersion(sdkId);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Opt-Out'''&lt;br /&gt;
&lt;br /&gt;
Check the user's opt-out status and get the URL for the opt-out web page.&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
final status = await NielsenFlutterPlugin.instance.getOptOutStatus(sdkId);&lt;br /&gt;
final url = await NielsenFlutterPlugin.instance.userOptOutURLString(sdkId);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''UserOptOut'''&lt;br /&gt;
&lt;br /&gt;
Disable metering for the app due to user opt out.&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
final userOptOut = await NielsenFlutterPlugin.instance.userOptOut(sdkId, url);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''sendID3'''&lt;br /&gt;
&lt;br /&gt;
Passes raw ID3 tags to the SDK for live/linear content measurement.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
await NielsenFlutterPlugin.instance.sendID3(sdkId, rawId3Tag);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''enableDebugLogs'''&lt;br /&gt;
&lt;br /&gt;
Call this one before you create any Nielsen instance. It enables debug logs from the Nielsen Flutter plugin. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
await NielsenFlutterPlugin.instance.enableDebugLogs(true);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Error Handling (iOS Specific) ==&lt;br /&gt;
&lt;br /&gt;
The plugin surfaces descriptive error codes if an API is called incorrectly or in an invalid state. Errors are logged to the console but are designed not to crash the application.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Error Code !! Error Description&lt;br /&gt;
|-&lt;br /&gt;
|NLS_JSON_INVALID||The JSON passed to the API is invalid or cannot be parsed&lt;br /&gt;
|-&lt;br /&gt;
|NLS_ARGS_MISSING||One or more required arguments are missing&lt;br /&gt;
|-&lt;br /&gt;
|NLS_SDK_NOT_FOUND||No active SDK instance was found for the given sdkId&lt;br /&gt;
|-&lt;br /&gt;
|NLS_INIT_FAILED||Nielsen SDK initialization failed&lt;br /&gt;
|-&lt;br /&gt;
|NLS_METHOD_UNSUPPORTED||The requested API method is not supported in this context&lt;br /&gt;
|-&lt;br /&gt;
|NLS_PLAYHEAD_INVALID||Playhead position is missing or not valid (expected seconds)&lt;br /&gt;
|}&lt;br /&gt;
Example Log:&lt;br /&gt;
[NielsenFlutterPlugin][ERROR] NLS_SDK_NOT_FOUND: No active SDK instance was found for the given sdkId - Unknown sdkId: 12345&lt;/div&gt;</summary>
		<author><name>AnkitAgrawal</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=US_DCR_%26_DTVR&amp;diff=7406</id>
		<title>US DCR &amp; DTVR</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=US_DCR_%26_DTVR&amp;diff=7406"/>
		<updated>2025-10-15T15:47:32Z</updated>

		<summary type="html">&lt;p&gt;AnkitAgrawal: /* AppSDK Flutter Plugin */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
{{CategoryIcon|DCR.png|US Digital Content Ratings (DCR) &amp;amp; Digital in TV Ratings (DTVR)}}&lt;br /&gt;
&lt;br /&gt;
__NOTOC__&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot;| Start Here&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;7&amp;quot; |&lt;br /&gt;
| '''Step-By-Step SDK Integration Guides ([[BSDK Step By Step|Browser]], [[Android Step By Step|Android]], [[iOS Step By Step|iOS]])'''&lt;br /&gt;
| '''API Reference Tables ([[Browser_SDK_API_Table|Browser]], [[Android_SDK_API_Table|Android]], [[iOS_SDK_API_Table|iOS]])'''&lt;br /&gt;
|-&lt;br /&gt;
| '''[[DCR_vs_DTVR|DCR vs. DTVR Implementation - Key Differences]]'''&lt;br /&gt;
| '''Product Information - [https://markets.nielsen.com/us/en/solutions/capabilities/digital-content-ratings/ DCR], [https://www.nielsen.com/solutions/audience-measurement/national-tv/ DTVR]'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot;| General Reference&lt;br /&gt;
|-&lt;br /&gt;
| '''[[Digital Measurement Onboarding]]'''&lt;br /&gt;
| '''[[Digital Measurement Metadata]]'''&lt;br /&gt;
| '''[[Digital Measurement Testing]]'''&lt;br /&gt;
|-&lt;br /&gt;
| '''[[Digital Measurement Interruption Scenarios]]'''&lt;br /&gt;
| '''[[Digital Measurement FAQ]]'''&lt;br /&gt;
| '''SDK Release Notes - [[Browser_SDK_Release_Notes|Browser]], [[Android_SDK_Release_Notes|Android]], [[iOS_SDK_Release_Notes|iOS]], [[TVOS_SDK_Release_Notes|TVOS]], [[DOMless SDK Release Notes|DOMless]]'''&lt;br /&gt;
|-&lt;br /&gt;
| '''[[Digital Pre-Certification Checklist App SDK]]'''&lt;br /&gt;
| '''[[Digital Pre-Certification Checklist Browser SDK]]'''&lt;br /&gt;
| '''[[Digital Measurement Persistent Identifiers]]'''&lt;br /&gt;
|-&lt;br /&gt;
|[[Dual Instances of SDK|'''Dual Instances of SDK''']]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SDK - Video ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| colspan=&amp;quot;6&amp;quot; | Maintaining an existing ''DCR'' or ''DTVR'' App integration? Continue to reference the API you're already using with the guides below.&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 90px;&amp;quot; | Type&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; |&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; | OS&lt;br /&gt;
! style=&amp;quot;width: 30%;&amp;quot; | DCR Implementation Guide&lt;br /&gt;
! style=&amp;quot;width: 25%;&amp;quot; | DTVR Implementation Guide&lt;br /&gt;
!| SDK Documentation&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;8&amp;quot; | {{SmallIcon|SDKIcon.png|alt=SDK}}&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; | {{OSIcon|VideoIcon.png|alt=Video}}&lt;br /&gt;
| {{OSIcon|macOSIcon.png|alt=iOS}}&lt;br /&gt;
| '''[[DCR Video iOS SDK]]'''&lt;br /&gt;
| '''[[DTVR iOS SDK]]'''&lt;br /&gt;
| [[iOS SDK API Reference]]&lt;br /&gt;
|-&lt;br /&gt;
| {{OSIcon|AndroidIcon.png|alt=Android}}&lt;br /&gt;
| '''[[DCR Video Android SDK]]'''&lt;br /&gt;
| '''[[DTVR Android SDK]]'''&lt;br /&gt;
| [[Android SDK API Reference]]&lt;br /&gt;
|-&lt;br /&gt;
| {{OSIcon|BrowserIcon.png|alt=Browser}}&lt;br /&gt;
| '''[[DCR Video Browser SDK]]'''&lt;br /&gt;
| '''[[DTVR Browser SDK]]'''&lt;br /&gt;
| [[Browser SDK API Reference]]&lt;br /&gt;
|-&lt;br /&gt;
|{{OSIcon|BrowserIcon.png|alt=Browser}}&lt;br /&gt;
|'''[[DCR Video Domless SDK]]'''&lt;br /&gt;
|'''[[DTVR Domless SDK]]'''&lt;br /&gt;
|[[Domless SDK API Reference]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SDK - Static ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;width: 90px;&amp;quot; | Type&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; |&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; | OS&lt;br /&gt;
! style=&amp;quot;width: 55%;&amp;quot; | DCR Implementation Guide&lt;br /&gt;
!| SDK Documentation&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;9&amp;quot; | {{SmallIcon|SDKIcon.png|alt=SDK}}&lt;br /&gt;
| rowspan=&amp;quot;9&amp;quot; | {{OSIcon|StaticIcon.png|alt=Static Content}}&lt;br /&gt;
| {{OSIcon|macOSIcon.png|alt=iOS}}&lt;br /&gt;
| '''[[DCR Static iOS SDK]]'''&lt;br /&gt;
| [[iOS SDK API Reference]]&lt;br /&gt;
|-&lt;br /&gt;
| {{OSIcon|AndroidIcon.png|alt=Android}}&lt;br /&gt;
| '''[[DCR Static Android SDK]]'''&lt;br /&gt;
| [[Android SDK API Reference]]&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | {{OSIcon|BrowserIcon.png|alt=Browser}}&lt;br /&gt;
| '''[[DCR Static Browser SDK]]'''&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; | [[Browser SDK API Reference]]&lt;br /&gt;
|-&lt;br /&gt;
| '''[[DCR Static Lite Browser SDK]]'''&lt;br /&gt;
|-&lt;br /&gt;
|  {{OSIcon|GoogleTagManagerIcon.png|alt=Google Tag Manager}}&lt;br /&gt;
| '''[[DCR Static Google Tag Manager]]'''&lt;br /&gt;
|-&lt;br /&gt;
|  {{OSIcon|FacebookIcon.png|alt=Facebook Instant Articles}}&lt;br /&gt;
| '''[[DCR Static Facebook Instant Articles Browser SDK]]'''&lt;br /&gt;
|-&lt;br /&gt;
|  {{OSIcon|Tealium_Icon.png|alt=Tealium}}&lt;br /&gt;
| '''[[DCR Static Tealium]]'''&lt;br /&gt;
|-&lt;br /&gt;
|  {{OSIcon|AMPIcon.png|alt=Google AMP}}&lt;br /&gt;
| '''[[DCR Static Google AMP Cloud API]]'''&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
|{{OSIcon|BrowserIcon.png|alt=Browser}}&lt;br /&gt;
|'''[[DCR Static Domless SDK]]'''&lt;br /&gt;
|[[Domless SDK API Reference]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Xamarin ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| colspan=&amp;quot;6&amp;quot; | Xamarin Integration Guides (Xamarin support is part of [[Special:Downloads|Nielsen's AppSDK V8]] and above.)&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 90px;&amp;quot; | Type&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; |&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; | OS&lt;br /&gt;
!| Implementation Guide&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;8&amp;quot; | {{SmallIcon|SDKIcon.png|alt=SDK}}&lt;br /&gt;
|-&lt;br /&gt;
|  {{OSIcon|VideoIcon.png|alt=Video}}&lt;br /&gt;
| {{OSIcon|APIIcon.png|alt=Xamarin}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | '''[[DCR_%26_DTVR_Xamarin_Integration|DCR &amp;amp; DTVR Xamarin Integration]]'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== AppSDK Flutter Plugin ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| colspan=&amp;quot;6&amp;quot; | Flutter Integration Guides (Flutter support is part of [[Special:Downloads|Nielsen's AppSDK V10.1.0]] and above.)&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 90px;&amp;quot; | Type&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; |&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; | OS&lt;br /&gt;
!| Implementation Guide&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;8&amp;quot; | {{SmallIcon|SDKIcon.png|alt=SDK}}&lt;br /&gt;
|-&lt;br /&gt;
|  {{OSIcon|VideoIcon.png|alt=Video}}&lt;br /&gt;
| {{OSIcon|APIIcon.png|alt=Xamarin}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | '''[[DCR_%26_DTVR_Flutter_Integration|DCR &amp;amp; DTVR Flutter Integration]]'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Cloud API ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;width: 90px;&amp;quot; | Type&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; |&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; | OS&lt;br /&gt;
!| DCR Implementation Guide&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | {{SmallIcon|CloudAPIIcon.png|alt=Cloud API}} &lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; |&lt;br /&gt;
{{OSIcon|VideoIcon.png|alt=Video}}&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
{{OSIcon|StaticIcon.png|alt=Static Content}}&lt;br /&gt;
| {{OSIcon|APIIcon.png|alt=Cloud API}}&lt;br /&gt;
| '''[[DCR Video &amp;amp; Static Cloud API ]]''' &lt;br /&gt;
|-&lt;br /&gt;
| {{OSIcon|APIIcon.png|alt=Cloud API}}&lt;br /&gt;
| '''[[DCR Video &amp;amp; Static Mobile Cloud API ]]'''&lt;br /&gt;
|-&lt;br /&gt;
| {{OSIcon|RokuIcon.png|alt=Roku}}&lt;br /&gt;
| '''[[DCR Video &amp;amp; Static Roku Cloud API]]'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Adobe Launch Extensions ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| colspan=&amp;quot;6&amp;quot; | Leverage Launch by Adobe? The guides below describe how to integrate DCR and DTVR with Nielsen's Adobe Launch extension&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 90px;&amp;quot; | Type&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; |&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; | OS&lt;br /&gt;
!| Implementation Guide&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;8&amp;quot; | {{SmallIcon|SDKIcon.png|alt=SDK}}&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | '''[[Digital Measurement Onboarding Adobe ]]'''&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | {{OSIcon|VideoIcon.png|alt=Video}}&lt;br /&gt;
| {{OSIcon|macOSIcon.png|alt=iOS}}&lt;br /&gt;
| '''[[DCR &amp;amp; DTVR iOS Adobe Launch Extension]]'''&lt;br /&gt;
|-&lt;br /&gt;
| {{OSIcon|AndroidIcon.png|alt=Android}}&lt;br /&gt;
| '''[[DCR &amp;amp; DTVR Android Adobe Launch Extension]]'''&lt;br /&gt;
|-&lt;br /&gt;
| {{OSIcon|BrowserIcon.png|alt=Browser}}&lt;br /&gt;
| '''[[DCR &amp;amp; DTVR Browser Adobe Launch Extension]]'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SDK - Connected TV ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| colspan=&amp;quot;6&amp;quot; | The guides below describe how to integrate DCR and DTVR with Smart tv's&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 90px;&amp;quot; | Type&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; |&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; | OS&lt;br /&gt;
! | Implementation Guide&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;8&amp;quot; | {{SmallIcon|SDKIcon.png|alt=SDK}}&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | {{OSIcon|VideoIcon.png|alt=Video}}&lt;br /&gt;
| {{OSIcon|BrowserIcon.png|alt=Browser}}&lt;br /&gt;
| '''[[Digital Measurement Video TizenTv]]'''&lt;br /&gt;
|-&lt;br /&gt;
| {{OSIcon|BrowserIcon.png|alt=Browser}}&lt;br /&gt;
| '''[[Digital Measurement Video webOS]]'''&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>AnkitAgrawal</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=US_DCR_%26_DTVR&amp;diff=7405</id>
		<title>US DCR &amp; DTVR</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=US_DCR_%26_DTVR&amp;diff=7405"/>
		<updated>2025-10-15T15:39:34Z</updated>

		<summary type="html">&lt;p&gt;AnkitAgrawal: /* AppSDK Flutter Plugin */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
{{CategoryIcon|DCR.png|US Digital Content Ratings (DCR) &amp;amp; Digital in TV Ratings (DTVR)}}&lt;br /&gt;
&lt;br /&gt;
__NOTOC__&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot;| Start Here&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;7&amp;quot; |&lt;br /&gt;
| '''Step-By-Step SDK Integration Guides ([[BSDK Step By Step|Browser]], [[Android Step By Step|Android]], [[iOS Step By Step|iOS]])'''&lt;br /&gt;
| '''API Reference Tables ([[Browser_SDK_API_Table|Browser]], [[Android_SDK_API_Table|Android]], [[iOS_SDK_API_Table|iOS]])'''&lt;br /&gt;
|-&lt;br /&gt;
| '''[[DCR_vs_DTVR|DCR vs. DTVR Implementation - Key Differences]]'''&lt;br /&gt;
| '''Product Information - [https://markets.nielsen.com/us/en/solutions/capabilities/digital-content-ratings/ DCR], [https://www.nielsen.com/solutions/audience-measurement/national-tv/ DTVR]'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot;| General Reference&lt;br /&gt;
|-&lt;br /&gt;
| '''[[Digital Measurement Onboarding]]'''&lt;br /&gt;
| '''[[Digital Measurement Metadata]]'''&lt;br /&gt;
| '''[[Digital Measurement Testing]]'''&lt;br /&gt;
|-&lt;br /&gt;
| '''[[Digital Measurement Interruption Scenarios]]'''&lt;br /&gt;
| '''[[Digital Measurement FAQ]]'''&lt;br /&gt;
| '''SDK Release Notes - [[Browser_SDK_Release_Notes|Browser]], [[Android_SDK_Release_Notes|Android]], [[iOS_SDK_Release_Notes|iOS]], [[TVOS_SDK_Release_Notes|TVOS]], [[DOMless SDK Release Notes|DOMless]]'''&lt;br /&gt;
|-&lt;br /&gt;
| '''[[Digital Pre-Certification Checklist App SDK]]'''&lt;br /&gt;
| '''[[Digital Pre-Certification Checklist Browser SDK]]'''&lt;br /&gt;
| '''[[Digital Measurement Persistent Identifiers]]'''&lt;br /&gt;
|-&lt;br /&gt;
|[[Dual Instances of SDK|'''Dual Instances of SDK''']]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SDK - Video ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| colspan=&amp;quot;6&amp;quot; | Maintaining an existing ''DCR'' or ''DTVR'' App integration? Continue to reference the API you're already using with the guides below.&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 90px;&amp;quot; | Type&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; |&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; | OS&lt;br /&gt;
! style=&amp;quot;width: 30%;&amp;quot; | DCR Implementation Guide&lt;br /&gt;
! style=&amp;quot;width: 25%;&amp;quot; | DTVR Implementation Guide&lt;br /&gt;
!| SDK Documentation&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;8&amp;quot; | {{SmallIcon|SDKIcon.png|alt=SDK}}&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; | {{OSIcon|VideoIcon.png|alt=Video}}&lt;br /&gt;
| {{OSIcon|macOSIcon.png|alt=iOS}}&lt;br /&gt;
| '''[[DCR Video iOS SDK]]'''&lt;br /&gt;
| '''[[DTVR iOS SDK]]'''&lt;br /&gt;
| [[iOS SDK API Reference]]&lt;br /&gt;
|-&lt;br /&gt;
| {{OSIcon|AndroidIcon.png|alt=Android}}&lt;br /&gt;
| '''[[DCR Video Android SDK]]'''&lt;br /&gt;
| '''[[DTVR Android SDK]]'''&lt;br /&gt;
| [[Android SDK API Reference]]&lt;br /&gt;
|-&lt;br /&gt;
| {{OSIcon|BrowserIcon.png|alt=Browser}}&lt;br /&gt;
| '''[[DCR Video Browser SDK]]'''&lt;br /&gt;
| '''[[DTVR Browser SDK]]'''&lt;br /&gt;
| [[Browser SDK API Reference]]&lt;br /&gt;
|-&lt;br /&gt;
|{{OSIcon|BrowserIcon.png|alt=Browser}}&lt;br /&gt;
|'''[[DCR Video Domless SDK]]'''&lt;br /&gt;
|'''[[DTVR Domless SDK]]'''&lt;br /&gt;
|[[Domless SDK API Reference]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SDK - Static ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;width: 90px;&amp;quot; | Type&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; |&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; | OS&lt;br /&gt;
! style=&amp;quot;width: 55%;&amp;quot; | DCR Implementation Guide&lt;br /&gt;
!| SDK Documentation&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;9&amp;quot; | {{SmallIcon|SDKIcon.png|alt=SDK}}&lt;br /&gt;
| rowspan=&amp;quot;9&amp;quot; | {{OSIcon|StaticIcon.png|alt=Static Content}}&lt;br /&gt;
| {{OSIcon|macOSIcon.png|alt=iOS}}&lt;br /&gt;
| '''[[DCR Static iOS SDK]]'''&lt;br /&gt;
| [[iOS SDK API Reference]]&lt;br /&gt;
|-&lt;br /&gt;
| {{OSIcon|AndroidIcon.png|alt=Android}}&lt;br /&gt;
| '''[[DCR Static Android SDK]]'''&lt;br /&gt;
| [[Android SDK API Reference]]&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | {{OSIcon|BrowserIcon.png|alt=Browser}}&lt;br /&gt;
| '''[[DCR Static Browser SDK]]'''&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; | [[Browser SDK API Reference]]&lt;br /&gt;
|-&lt;br /&gt;
| '''[[DCR Static Lite Browser SDK]]'''&lt;br /&gt;
|-&lt;br /&gt;
|  {{OSIcon|GoogleTagManagerIcon.png|alt=Google Tag Manager}}&lt;br /&gt;
| '''[[DCR Static Google Tag Manager]]'''&lt;br /&gt;
|-&lt;br /&gt;
|  {{OSIcon|FacebookIcon.png|alt=Facebook Instant Articles}}&lt;br /&gt;
| '''[[DCR Static Facebook Instant Articles Browser SDK]]'''&lt;br /&gt;
|-&lt;br /&gt;
|  {{OSIcon|Tealium_Icon.png|alt=Tealium}}&lt;br /&gt;
| '''[[DCR Static Tealium]]'''&lt;br /&gt;
|-&lt;br /&gt;
|  {{OSIcon|AMPIcon.png|alt=Google AMP}}&lt;br /&gt;
| '''[[DCR Static Google AMP Cloud API]]'''&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
|{{OSIcon|BrowserIcon.png|alt=Browser}}&lt;br /&gt;
|'''[[DCR Static Domless SDK]]'''&lt;br /&gt;
|[[Domless SDK API Reference]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Xamarin ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| colspan=&amp;quot;6&amp;quot; | Xamarin Integration Guides (Xamarin support is part of [[Special:Downloads|Nielsen's AppSDK V8]] and above.)&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 90px;&amp;quot; | Type&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; |&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; | OS&lt;br /&gt;
!| Implementation Guide&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;8&amp;quot; | {{SmallIcon|SDKIcon.png|alt=SDK}}&lt;br /&gt;
|-&lt;br /&gt;
|  {{OSIcon|VideoIcon.png|alt=Video}}&lt;br /&gt;
| {{OSIcon|APIIcon.png|alt=Xamarin}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | '''[[DCR_%26_DTVR_Xamarin_Integration|DCR &amp;amp; DTVR Xamarin Integration]]'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== AppSDK Flutter Plugin ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| colspan=&amp;quot;6&amp;quot; | Flutter Integration Guides (flutter support is part of [[Special:Downloads|Nielsen's AppSDK V10.1.0]] and above.)&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 90px;&amp;quot; | Type&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; |&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; | OS&lt;br /&gt;
!| Implementation Guide&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;8&amp;quot; | {{SmallIcon|SDKIcon.png|alt=SDK}}&lt;br /&gt;
|-&lt;br /&gt;
|  {{OSIcon|VideoIcon.png|alt=Video}}&lt;br /&gt;
| {{OSIcon|APIIcon.png|alt=Xamarin}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | '''[[DCR_%26_DTVR_Flutter_Integration|DCR &amp;amp; DTVR Flutter Integration]]'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Cloud API ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;width: 90px;&amp;quot; | Type&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; |&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; | OS&lt;br /&gt;
!| DCR Implementation Guide&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | {{SmallIcon|CloudAPIIcon.png|alt=Cloud API}} &lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; |&lt;br /&gt;
{{OSIcon|VideoIcon.png|alt=Video}}&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
{{OSIcon|StaticIcon.png|alt=Static Content}}&lt;br /&gt;
| {{OSIcon|APIIcon.png|alt=Cloud API}}&lt;br /&gt;
| '''[[DCR Video &amp;amp; Static Cloud API ]]''' &lt;br /&gt;
|-&lt;br /&gt;
| {{OSIcon|APIIcon.png|alt=Cloud API}}&lt;br /&gt;
| '''[[DCR Video &amp;amp; Static Mobile Cloud API ]]'''&lt;br /&gt;
|-&lt;br /&gt;
| {{OSIcon|RokuIcon.png|alt=Roku}}&lt;br /&gt;
| '''[[DCR Video &amp;amp; Static Roku Cloud API]]'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Adobe Launch Extensions ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| colspan=&amp;quot;6&amp;quot; | Leverage Launch by Adobe? The guides below describe how to integrate DCR and DTVR with Nielsen's Adobe Launch extension&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 90px;&amp;quot; | Type&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; |&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; | OS&lt;br /&gt;
!| Implementation Guide&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;8&amp;quot; | {{SmallIcon|SDKIcon.png|alt=SDK}}&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | '''[[Digital Measurement Onboarding Adobe ]]'''&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | {{OSIcon|VideoIcon.png|alt=Video}}&lt;br /&gt;
| {{OSIcon|macOSIcon.png|alt=iOS}}&lt;br /&gt;
| '''[[DCR &amp;amp; DTVR iOS Adobe Launch Extension]]'''&lt;br /&gt;
|-&lt;br /&gt;
| {{OSIcon|AndroidIcon.png|alt=Android}}&lt;br /&gt;
| '''[[DCR &amp;amp; DTVR Android Adobe Launch Extension]]'''&lt;br /&gt;
|-&lt;br /&gt;
| {{OSIcon|BrowserIcon.png|alt=Browser}}&lt;br /&gt;
| '''[[DCR &amp;amp; DTVR Browser Adobe Launch Extension]]'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SDK - Connected TV ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| colspan=&amp;quot;6&amp;quot; | The guides below describe how to integrate DCR and DTVR with Smart tv's&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 90px;&amp;quot; | Type&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; |&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; | OS&lt;br /&gt;
! | Implementation Guide&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;8&amp;quot; | {{SmallIcon|SDKIcon.png|alt=SDK}}&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | {{OSIcon|VideoIcon.png|alt=Video}}&lt;br /&gt;
| {{OSIcon|BrowserIcon.png|alt=Browser}}&lt;br /&gt;
| '''[[Digital Measurement Video TizenTv]]'''&lt;br /&gt;
|-&lt;br /&gt;
| {{OSIcon|BrowserIcon.png|alt=Browser}}&lt;br /&gt;
| '''[[Digital Measurement Video webOS]]'''&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>AnkitAgrawal</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=US_DCR_%26_DTVR&amp;diff=7404</id>
		<title>US DCR &amp; DTVR</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=US_DCR_%26_DTVR&amp;diff=7404"/>
		<updated>2025-10-15T15:28:37Z</updated>

		<summary type="html">&lt;p&gt;AnkitAgrawal: /* AppSDK f Plugin */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
{{CategoryIcon|DCR.png|US Digital Content Ratings (DCR) &amp;amp; Digital in TV Ratings (DTVR)}}&lt;br /&gt;
&lt;br /&gt;
__NOTOC__&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot;| Start Here&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;7&amp;quot; |&lt;br /&gt;
| '''Step-By-Step SDK Integration Guides ([[BSDK Step By Step|Browser]], [[Android Step By Step|Android]], [[iOS Step By Step|iOS]])'''&lt;br /&gt;
| '''API Reference Tables ([[Browser_SDK_API_Table|Browser]], [[Android_SDK_API_Table|Android]], [[iOS_SDK_API_Table|iOS]])'''&lt;br /&gt;
|-&lt;br /&gt;
| '''[[DCR_vs_DTVR|DCR vs. DTVR Implementation - Key Differences]]'''&lt;br /&gt;
| '''Product Information - [https://markets.nielsen.com/us/en/solutions/capabilities/digital-content-ratings/ DCR], [https://www.nielsen.com/solutions/audience-measurement/national-tv/ DTVR]'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot;| General Reference&lt;br /&gt;
|-&lt;br /&gt;
| '''[[Digital Measurement Onboarding]]'''&lt;br /&gt;
| '''[[Digital Measurement Metadata]]'''&lt;br /&gt;
| '''[[Digital Measurement Testing]]'''&lt;br /&gt;
|-&lt;br /&gt;
| '''[[Digital Measurement Interruption Scenarios]]'''&lt;br /&gt;
| '''[[Digital Measurement FAQ]]'''&lt;br /&gt;
| '''SDK Release Notes - [[Browser_SDK_Release_Notes|Browser]], [[Android_SDK_Release_Notes|Android]], [[iOS_SDK_Release_Notes|iOS]], [[TVOS_SDK_Release_Notes|TVOS]], [[DOMless SDK Release Notes|DOMless]]'''&lt;br /&gt;
|-&lt;br /&gt;
| '''[[Digital Pre-Certification Checklist App SDK]]'''&lt;br /&gt;
| '''[[Digital Pre-Certification Checklist Browser SDK]]'''&lt;br /&gt;
| '''[[Digital Measurement Persistent Identifiers]]'''&lt;br /&gt;
|-&lt;br /&gt;
|[[Dual Instances of SDK|'''Dual Instances of SDK''']]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SDK - Video ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| colspan=&amp;quot;6&amp;quot; | Maintaining an existing ''DCR'' or ''DTVR'' App integration? Continue to reference the API you're already using with the guides below.&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 90px;&amp;quot; | Type&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; |&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; | OS&lt;br /&gt;
! style=&amp;quot;width: 30%;&amp;quot; | DCR Implementation Guide&lt;br /&gt;
! style=&amp;quot;width: 25%;&amp;quot; | DTVR Implementation Guide&lt;br /&gt;
!| SDK Documentation&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;8&amp;quot; | {{SmallIcon|SDKIcon.png|alt=SDK}}&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; | {{OSIcon|VideoIcon.png|alt=Video}}&lt;br /&gt;
| {{OSIcon|macOSIcon.png|alt=iOS}}&lt;br /&gt;
| '''[[DCR Video iOS SDK]]'''&lt;br /&gt;
| '''[[DTVR iOS SDK]]'''&lt;br /&gt;
| [[iOS SDK API Reference]]&lt;br /&gt;
|-&lt;br /&gt;
| {{OSIcon|AndroidIcon.png|alt=Android}}&lt;br /&gt;
| '''[[DCR Video Android SDK]]'''&lt;br /&gt;
| '''[[DTVR Android SDK]]'''&lt;br /&gt;
| [[Android SDK API Reference]]&lt;br /&gt;
|-&lt;br /&gt;
| {{OSIcon|BrowserIcon.png|alt=Browser}}&lt;br /&gt;
| '''[[DCR Video Browser SDK]]'''&lt;br /&gt;
| '''[[DTVR Browser SDK]]'''&lt;br /&gt;
| [[Browser SDK API Reference]]&lt;br /&gt;
|-&lt;br /&gt;
|{{OSIcon|BrowserIcon.png|alt=Browser}}&lt;br /&gt;
|'''[[DCR Video Domless SDK]]'''&lt;br /&gt;
|'''[[DTVR Domless SDK]]'''&lt;br /&gt;
|[[Domless SDK API Reference]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SDK - Static ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;width: 90px;&amp;quot; | Type&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; |&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; | OS&lt;br /&gt;
! style=&amp;quot;width: 55%;&amp;quot; | DCR Implementation Guide&lt;br /&gt;
!| SDK Documentation&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;9&amp;quot; | {{SmallIcon|SDKIcon.png|alt=SDK}}&lt;br /&gt;
| rowspan=&amp;quot;9&amp;quot; | {{OSIcon|StaticIcon.png|alt=Static Content}}&lt;br /&gt;
| {{OSIcon|macOSIcon.png|alt=iOS}}&lt;br /&gt;
| '''[[DCR Static iOS SDK]]'''&lt;br /&gt;
| [[iOS SDK API Reference]]&lt;br /&gt;
|-&lt;br /&gt;
| {{OSIcon|AndroidIcon.png|alt=Android}}&lt;br /&gt;
| '''[[DCR Static Android SDK]]'''&lt;br /&gt;
| [[Android SDK API Reference]]&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | {{OSIcon|BrowserIcon.png|alt=Browser}}&lt;br /&gt;
| '''[[DCR Static Browser SDK]]'''&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; | [[Browser SDK API Reference]]&lt;br /&gt;
|-&lt;br /&gt;
| '''[[DCR Static Lite Browser SDK]]'''&lt;br /&gt;
|-&lt;br /&gt;
|  {{OSIcon|GoogleTagManagerIcon.png|alt=Google Tag Manager}}&lt;br /&gt;
| '''[[DCR Static Google Tag Manager]]'''&lt;br /&gt;
|-&lt;br /&gt;
|  {{OSIcon|FacebookIcon.png|alt=Facebook Instant Articles}}&lt;br /&gt;
| '''[[DCR Static Facebook Instant Articles Browser SDK]]'''&lt;br /&gt;
|-&lt;br /&gt;
|  {{OSIcon|Tealium_Icon.png|alt=Tealium}}&lt;br /&gt;
| '''[[DCR Static Tealium]]'''&lt;br /&gt;
|-&lt;br /&gt;
|  {{OSIcon|AMPIcon.png|alt=Google AMP}}&lt;br /&gt;
| '''[[DCR Static Google AMP Cloud API]]'''&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
|{{OSIcon|BrowserIcon.png|alt=Browser}}&lt;br /&gt;
|'''[[DCR Static Domless SDK]]'''&lt;br /&gt;
|[[Domless SDK API Reference]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Xamarin ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| colspan=&amp;quot;6&amp;quot; | Xamarin Integration Guides (Xamarin support is part of [[Special:Downloads|Nielsen's AppSDK V8]] and above.)&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 90px;&amp;quot; | Type&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; |&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; | OS&lt;br /&gt;
!| Implementation Guide&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;8&amp;quot; | {{SmallIcon|SDKIcon.png|alt=SDK}}&lt;br /&gt;
|-&lt;br /&gt;
|  {{OSIcon|VideoIcon.png|alt=Video}}&lt;br /&gt;
| {{OSIcon|APIIcon.png|alt=Xamarin}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | '''[[DCR_%26_DTVR_Xamarin_Integration|DCR &amp;amp; DTVR Xamarin Integration]]'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== AppSDK f Plugin ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| colspan=&amp;quot;6&amp;quot; | F Integration Guides (f support is part of [[Special:Downloads|Nielsen's AppSDK V10.1.0]] and above.)&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 90px;&amp;quot; | Type&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; |&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; | OS&lt;br /&gt;
!| Implementation Guide&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;8&amp;quot; | {{SmallIcon|SDKIcon.png|alt=SDK}}&lt;br /&gt;
|-&lt;br /&gt;
|  {{OSIcon|VideoIcon.png|alt=Video}}&lt;br /&gt;
| {{OSIcon|APIIcon.png|alt=Xamarin}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | '''[[DCR_%26_DTVR_Xamarin_Integration|DCR &amp;amp; DTVR F Integration]]'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Cloud API ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;width: 90px;&amp;quot; | Type&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; |&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; | OS&lt;br /&gt;
!| DCR Implementation Guide&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | {{SmallIcon|CloudAPIIcon.png|alt=Cloud API}} &lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; |&lt;br /&gt;
{{OSIcon|VideoIcon.png|alt=Video}}&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
{{OSIcon|StaticIcon.png|alt=Static Content}}&lt;br /&gt;
| {{OSIcon|APIIcon.png|alt=Cloud API}}&lt;br /&gt;
| '''[[DCR Video &amp;amp; Static Cloud API ]]''' &lt;br /&gt;
|-&lt;br /&gt;
| {{OSIcon|APIIcon.png|alt=Cloud API}}&lt;br /&gt;
| '''[[DCR Video &amp;amp; Static Mobile Cloud API ]]'''&lt;br /&gt;
|-&lt;br /&gt;
| {{OSIcon|RokuIcon.png|alt=Roku}}&lt;br /&gt;
| '''[[DCR Video &amp;amp; Static Roku Cloud API]]'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Adobe Launch Extensions ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| colspan=&amp;quot;6&amp;quot; | Leverage Launch by Adobe? The guides below describe how to integrate DCR and DTVR with Nielsen's Adobe Launch extension&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 90px;&amp;quot; | Type&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; |&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; | OS&lt;br /&gt;
!| Implementation Guide&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;8&amp;quot; | {{SmallIcon|SDKIcon.png|alt=SDK}}&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | '''[[Digital Measurement Onboarding Adobe ]]'''&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | {{OSIcon|VideoIcon.png|alt=Video}}&lt;br /&gt;
| {{OSIcon|macOSIcon.png|alt=iOS}}&lt;br /&gt;
| '''[[DCR &amp;amp; DTVR iOS Adobe Launch Extension]]'''&lt;br /&gt;
|-&lt;br /&gt;
| {{OSIcon|AndroidIcon.png|alt=Android}}&lt;br /&gt;
| '''[[DCR &amp;amp; DTVR Android Adobe Launch Extension]]'''&lt;br /&gt;
|-&lt;br /&gt;
| {{OSIcon|BrowserIcon.png|alt=Browser}}&lt;br /&gt;
| '''[[DCR &amp;amp; DTVR Browser Adobe Launch Extension]]'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SDK - Connected TV ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| colspan=&amp;quot;6&amp;quot; | The guides below describe how to integrate DCR and DTVR with Smart tv's&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 90px;&amp;quot; | Type&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; |&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; | OS&lt;br /&gt;
! | Implementation Guide&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;8&amp;quot; | {{SmallIcon|SDKIcon.png|alt=SDK}}&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | {{OSIcon|VideoIcon.png|alt=Video}}&lt;br /&gt;
| {{OSIcon|BrowserIcon.png|alt=Browser}}&lt;br /&gt;
| '''[[Digital Measurement Video TizenTv]]'''&lt;br /&gt;
|-&lt;br /&gt;
| {{OSIcon|BrowserIcon.png|alt=Browser}}&lt;br /&gt;
| '''[[Digital Measurement Video webOS]]'''&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>AnkitAgrawal</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=US_DCR_%26_DTVR&amp;diff=7403</id>
		<title>US DCR &amp; DTVR</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=US_DCR_%26_DTVR&amp;diff=7403"/>
		<updated>2025-10-15T15:27:50Z</updated>

		<summary type="html">&lt;p&gt;AnkitAgrawal: /* AppSDK Flutter Plugin */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
{{CategoryIcon|DCR.png|US Digital Content Ratings (DCR) &amp;amp; Digital in TV Ratings (DTVR)}}&lt;br /&gt;
&lt;br /&gt;
__NOTOC__&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot;| Start Here&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;7&amp;quot; |&lt;br /&gt;
| '''Step-By-Step SDK Integration Guides ([[BSDK Step By Step|Browser]], [[Android Step By Step|Android]], [[iOS Step By Step|iOS]])'''&lt;br /&gt;
| '''API Reference Tables ([[Browser_SDK_API_Table|Browser]], [[Android_SDK_API_Table|Android]], [[iOS_SDK_API_Table|iOS]])'''&lt;br /&gt;
|-&lt;br /&gt;
| '''[[DCR_vs_DTVR|DCR vs. DTVR Implementation - Key Differences]]'''&lt;br /&gt;
| '''Product Information - [https://markets.nielsen.com/us/en/solutions/capabilities/digital-content-ratings/ DCR], [https://www.nielsen.com/solutions/audience-measurement/national-tv/ DTVR]'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot;| General Reference&lt;br /&gt;
|-&lt;br /&gt;
| '''[[Digital Measurement Onboarding]]'''&lt;br /&gt;
| '''[[Digital Measurement Metadata]]'''&lt;br /&gt;
| '''[[Digital Measurement Testing]]'''&lt;br /&gt;
|-&lt;br /&gt;
| '''[[Digital Measurement Interruption Scenarios]]'''&lt;br /&gt;
| '''[[Digital Measurement FAQ]]'''&lt;br /&gt;
| '''SDK Release Notes - [[Browser_SDK_Release_Notes|Browser]], [[Android_SDK_Release_Notes|Android]], [[iOS_SDK_Release_Notes|iOS]], [[TVOS_SDK_Release_Notes|TVOS]], [[DOMless SDK Release Notes|DOMless]]'''&lt;br /&gt;
|-&lt;br /&gt;
| '''[[Digital Pre-Certification Checklist App SDK]]'''&lt;br /&gt;
| '''[[Digital Pre-Certification Checklist Browser SDK]]'''&lt;br /&gt;
| '''[[Digital Measurement Persistent Identifiers]]'''&lt;br /&gt;
|-&lt;br /&gt;
|[[Dual Instances of SDK|'''Dual Instances of SDK''']]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SDK - Video ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| colspan=&amp;quot;6&amp;quot; | Maintaining an existing ''DCR'' or ''DTVR'' App integration? Continue to reference the API you're already using with the guides below.&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 90px;&amp;quot; | Type&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; |&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; | OS&lt;br /&gt;
! style=&amp;quot;width: 30%;&amp;quot; | DCR Implementation Guide&lt;br /&gt;
! style=&amp;quot;width: 25%;&amp;quot; | DTVR Implementation Guide&lt;br /&gt;
!| SDK Documentation&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;8&amp;quot; | {{SmallIcon|SDKIcon.png|alt=SDK}}&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; | {{OSIcon|VideoIcon.png|alt=Video}}&lt;br /&gt;
| {{OSIcon|macOSIcon.png|alt=iOS}}&lt;br /&gt;
| '''[[DCR Video iOS SDK]]'''&lt;br /&gt;
| '''[[DTVR iOS SDK]]'''&lt;br /&gt;
| [[iOS SDK API Reference]]&lt;br /&gt;
|-&lt;br /&gt;
| {{OSIcon|AndroidIcon.png|alt=Android}}&lt;br /&gt;
| '''[[DCR Video Android SDK]]'''&lt;br /&gt;
| '''[[DTVR Android SDK]]'''&lt;br /&gt;
| [[Android SDK API Reference]]&lt;br /&gt;
|-&lt;br /&gt;
| {{OSIcon|BrowserIcon.png|alt=Browser}}&lt;br /&gt;
| '''[[DCR Video Browser SDK]]'''&lt;br /&gt;
| '''[[DTVR Browser SDK]]'''&lt;br /&gt;
| [[Browser SDK API Reference]]&lt;br /&gt;
|-&lt;br /&gt;
|{{OSIcon|BrowserIcon.png|alt=Browser}}&lt;br /&gt;
|'''[[DCR Video Domless SDK]]'''&lt;br /&gt;
|'''[[DTVR Domless SDK]]'''&lt;br /&gt;
|[[Domless SDK API Reference]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SDK - Static ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;width: 90px;&amp;quot; | Type&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; |&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; | OS&lt;br /&gt;
! style=&amp;quot;width: 55%;&amp;quot; | DCR Implementation Guide&lt;br /&gt;
!| SDK Documentation&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;9&amp;quot; | {{SmallIcon|SDKIcon.png|alt=SDK}}&lt;br /&gt;
| rowspan=&amp;quot;9&amp;quot; | {{OSIcon|StaticIcon.png|alt=Static Content}}&lt;br /&gt;
| {{OSIcon|macOSIcon.png|alt=iOS}}&lt;br /&gt;
| '''[[DCR Static iOS SDK]]'''&lt;br /&gt;
| [[iOS SDK API Reference]]&lt;br /&gt;
|-&lt;br /&gt;
| {{OSIcon|AndroidIcon.png|alt=Android}}&lt;br /&gt;
| '''[[DCR Static Android SDK]]'''&lt;br /&gt;
| [[Android SDK API Reference]]&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | {{OSIcon|BrowserIcon.png|alt=Browser}}&lt;br /&gt;
| '''[[DCR Static Browser SDK]]'''&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; | [[Browser SDK API Reference]]&lt;br /&gt;
|-&lt;br /&gt;
| '''[[DCR Static Lite Browser SDK]]'''&lt;br /&gt;
|-&lt;br /&gt;
|  {{OSIcon|GoogleTagManagerIcon.png|alt=Google Tag Manager}}&lt;br /&gt;
| '''[[DCR Static Google Tag Manager]]'''&lt;br /&gt;
|-&lt;br /&gt;
|  {{OSIcon|FacebookIcon.png|alt=Facebook Instant Articles}}&lt;br /&gt;
| '''[[DCR Static Facebook Instant Articles Browser SDK]]'''&lt;br /&gt;
|-&lt;br /&gt;
|  {{OSIcon|Tealium_Icon.png|alt=Tealium}}&lt;br /&gt;
| '''[[DCR Static Tealium]]'''&lt;br /&gt;
|-&lt;br /&gt;
|  {{OSIcon|AMPIcon.png|alt=Google AMP}}&lt;br /&gt;
| '''[[DCR Static Google AMP Cloud API]]'''&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
|{{OSIcon|BrowserIcon.png|alt=Browser}}&lt;br /&gt;
|'''[[DCR Static Domless SDK]]'''&lt;br /&gt;
|[[Domless SDK API Reference]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Xamarin ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| colspan=&amp;quot;6&amp;quot; | Xamarin Integration Guides (Xamarin support is part of [[Special:Downloads|Nielsen's AppSDK V8]] and above.)&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 90px;&amp;quot; | Type&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; |&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; | OS&lt;br /&gt;
!| Implementation Guide&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;8&amp;quot; | {{SmallIcon|SDKIcon.png|alt=SDK}}&lt;br /&gt;
|-&lt;br /&gt;
|  {{OSIcon|VideoIcon.png|alt=Video}}&lt;br /&gt;
| {{OSIcon|APIIcon.png|alt=Xamarin}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | '''[[DCR_%26_DTVR_Xamarin_Integration|DCR &amp;amp; DTVR Xamarin Integration]]'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== AppSDK f Plugin ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| colspan=&amp;quot;6&amp;quot; | F Integration Guides (Flutter support is part of [[Special:Downloads|Nielsen's AppSDK V10.1.0]] and above.)&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 90px;&amp;quot; | Type&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; |&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; | OS&lt;br /&gt;
!| Implementation Guide&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;8&amp;quot; | {{SmallIcon|SDKIcon.png|alt=SDK}}&lt;br /&gt;
|-&lt;br /&gt;
|  {{OSIcon|VideoIcon.png|alt=Video}}&lt;br /&gt;
| {{OSIcon|APIIcon.png|alt=Xamarin}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | '''[[DCR_%26_DTVR_Xamarin_Integration|DCR &amp;amp; DTVR F Integration]]'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Cloud API ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;width: 90px;&amp;quot; | Type&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; |&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; | OS&lt;br /&gt;
!| DCR Implementation Guide&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | {{SmallIcon|CloudAPIIcon.png|alt=Cloud API}} &lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; |&lt;br /&gt;
{{OSIcon|VideoIcon.png|alt=Video}}&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
{{OSIcon|StaticIcon.png|alt=Static Content}}&lt;br /&gt;
| {{OSIcon|APIIcon.png|alt=Cloud API}}&lt;br /&gt;
| '''[[DCR Video &amp;amp; Static Cloud API ]]''' &lt;br /&gt;
|-&lt;br /&gt;
| {{OSIcon|APIIcon.png|alt=Cloud API}}&lt;br /&gt;
| '''[[DCR Video &amp;amp; Static Mobile Cloud API ]]'''&lt;br /&gt;
|-&lt;br /&gt;
| {{OSIcon|RokuIcon.png|alt=Roku}}&lt;br /&gt;
| '''[[DCR Video &amp;amp; Static Roku Cloud API]]'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Adobe Launch Extensions ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| colspan=&amp;quot;6&amp;quot; | Leverage Launch by Adobe? The guides below describe how to integrate DCR and DTVR with Nielsen's Adobe Launch extension&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 90px;&amp;quot; | Type&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; |&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; | OS&lt;br /&gt;
!| Implementation Guide&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;8&amp;quot; | {{SmallIcon|SDKIcon.png|alt=SDK}}&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | '''[[Digital Measurement Onboarding Adobe ]]'''&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | {{OSIcon|VideoIcon.png|alt=Video}}&lt;br /&gt;
| {{OSIcon|macOSIcon.png|alt=iOS}}&lt;br /&gt;
| '''[[DCR &amp;amp; DTVR iOS Adobe Launch Extension]]'''&lt;br /&gt;
|-&lt;br /&gt;
| {{OSIcon|AndroidIcon.png|alt=Android}}&lt;br /&gt;
| '''[[DCR &amp;amp; DTVR Android Adobe Launch Extension]]'''&lt;br /&gt;
|-&lt;br /&gt;
| {{OSIcon|BrowserIcon.png|alt=Browser}}&lt;br /&gt;
| '''[[DCR &amp;amp; DTVR Browser Adobe Launch Extension]]'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SDK - Connected TV ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| colspan=&amp;quot;6&amp;quot; | The guides below describe how to integrate DCR and DTVR with Smart tv's&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 90px;&amp;quot; | Type&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; |&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; | OS&lt;br /&gt;
! | Implementation Guide&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;8&amp;quot; | {{SmallIcon|SDKIcon.png|alt=SDK}}&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | {{OSIcon|VideoIcon.png|alt=Video}}&lt;br /&gt;
| {{OSIcon|BrowserIcon.png|alt=Browser}}&lt;br /&gt;
| '''[[Digital Measurement Video TizenTv]]'''&lt;br /&gt;
|-&lt;br /&gt;
| {{OSIcon|BrowserIcon.png|alt=Browser}}&lt;br /&gt;
| '''[[Digital Measurement Video webOS]]'''&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>AnkitAgrawal</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=US_DCR_%26_DTVR&amp;diff=7402</id>
		<title>US DCR &amp; DTVR</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=US_DCR_%26_DTVR&amp;diff=7402"/>
		<updated>2025-10-15T15:10:03Z</updated>

		<summary type="html">&lt;p&gt;AnkitAgrawal: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
{{CategoryIcon|DCR.png|US Digital Content Ratings (DCR) &amp;amp; Digital in TV Ratings (DTVR)}}&lt;br /&gt;
&lt;br /&gt;
__NOTOC__&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot;| Start Here&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;7&amp;quot; |&lt;br /&gt;
| '''Step-By-Step SDK Integration Guides ([[BSDK Step By Step|Browser]], [[Android Step By Step|Android]], [[iOS Step By Step|iOS]])'''&lt;br /&gt;
| '''API Reference Tables ([[Browser_SDK_API_Table|Browser]], [[Android_SDK_API_Table|Android]], [[iOS_SDK_API_Table|iOS]])'''&lt;br /&gt;
|-&lt;br /&gt;
| '''[[DCR_vs_DTVR|DCR vs. DTVR Implementation - Key Differences]]'''&lt;br /&gt;
| '''Product Information - [https://markets.nielsen.com/us/en/solutions/capabilities/digital-content-ratings/ DCR], [https://www.nielsen.com/solutions/audience-measurement/national-tv/ DTVR]'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot;| General Reference&lt;br /&gt;
|-&lt;br /&gt;
| '''[[Digital Measurement Onboarding]]'''&lt;br /&gt;
| '''[[Digital Measurement Metadata]]'''&lt;br /&gt;
| '''[[Digital Measurement Testing]]'''&lt;br /&gt;
|-&lt;br /&gt;
| '''[[Digital Measurement Interruption Scenarios]]'''&lt;br /&gt;
| '''[[Digital Measurement FAQ]]'''&lt;br /&gt;
| '''SDK Release Notes - [[Browser_SDK_Release_Notes|Browser]], [[Android_SDK_Release_Notes|Android]], [[iOS_SDK_Release_Notes|iOS]], [[TVOS_SDK_Release_Notes|TVOS]], [[DOMless SDK Release Notes|DOMless]]'''&lt;br /&gt;
|-&lt;br /&gt;
| '''[[Digital Pre-Certification Checklist App SDK]]'''&lt;br /&gt;
| '''[[Digital Pre-Certification Checklist Browser SDK]]'''&lt;br /&gt;
| '''[[Digital Measurement Persistent Identifiers]]'''&lt;br /&gt;
|-&lt;br /&gt;
|[[Dual Instances of SDK|'''Dual Instances of SDK''']]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SDK - Video ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| colspan=&amp;quot;6&amp;quot; | Maintaining an existing ''DCR'' or ''DTVR'' App integration? Continue to reference the API you're already using with the guides below.&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 90px;&amp;quot; | Type&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; |&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; | OS&lt;br /&gt;
! style=&amp;quot;width: 30%;&amp;quot; | DCR Implementation Guide&lt;br /&gt;
! style=&amp;quot;width: 25%;&amp;quot; | DTVR Implementation Guide&lt;br /&gt;
!| SDK Documentation&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;8&amp;quot; | {{SmallIcon|SDKIcon.png|alt=SDK}}&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; | {{OSIcon|VideoIcon.png|alt=Video}}&lt;br /&gt;
| {{OSIcon|macOSIcon.png|alt=iOS}}&lt;br /&gt;
| '''[[DCR Video iOS SDK]]'''&lt;br /&gt;
| '''[[DTVR iOS SDK]]'''&lt;br /&gt;
| [[iOS SDK API Reference]]&lt;br /&gt;
|-&lt;br /&gt;
| {{OSIcon|AndroidIcon.png|alt=Android}}&lt;br /&gt;
| '''[[DCR Video Android SDK]]'''&lt;br /&gt;
| '''[[DTVR Android SDK]]'''&lt;br /&gt;
| [[Android SDK API Reference]]&lt;br /&gt;
|-&lt;br /&gt;
| {{OSIcon|BrowserIcon.png|alt=Browser}}&lt;br /&gt;
| '''[[DCR Video Browser SDK]]'''&lt;br /&gt;
| '''[[DTVR Browser SDK]]'''&lt;br /&gt;
| [[Browser SDK API Reference]]&lt;br /&gt;
|-&lt;br /&gt;
|{{OSIcon|BrowserIcon.png|alt=Browser}}&lt;br /&gt;
|'''[[DCR Video Domless SDK]]'''&lt;br /&gt;
|'''[[DTVR Domless SDK]]'''&lt;br /&gt;
|[[Domless SDK API Reference]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SDK - Static ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;width: 90px;&amp;quot; | Type&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; |&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; | OS&lt;br /&gt;
! style=&amp;quot;width: 55%;&amp;quot; | DCR Implementation Guide&lt;br /&gt;
!| SDK Documentation&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;9&amp;quot; | {{SmallIcon|SDKIcon.png|alt=SDK}}&lt;br /&gt;
| rowspan=&amp;quot;9&amp;quot; | {{OSIcon|StaticIcon.png|alt=Static Content}}&lt;br /&gt;
| {{OSIcon|macOSIcon.png|alt=iOS}}&lt;br /&gt;
| '''[[DCR Static iOS SDK]]'''&lt;br /&gt;
| [[iOS SDK API Reference]]&lt;br /&gt;
|-&lt;br /&gt;
| {{OSIcon|AndroidIcon.png|alt=Android}}&lt;br /&gt;
| '''[[DCR Static Android SDK]]'''&lt;br /&gt;
| [[Android SDK API Reference]]&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | {{OSIcon|BrowserIcon.png|alt=Browser}}&lt;br /&gt;
| '''[[DCR Static Browser SDK]]'''&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; | [[Browser SDK API Reference]]&lt;br /&gt;
|-&lt;br /&gt;
| '''[[DCR Static Lite Browser SDK]]'''&lt;br /&gt;
|-&lt;br /&gt;
|  {{OSIcon|GoogleTagManagerIcon.png|alt=Google Tag Manager}}&lt;br /&gt;
| '''[[DCR Static Google Tag Manager]]'''&lt;br /&gt;
|-&lt;br /&gt;
|  {{OSIcon|FacebookIcon.png|alt=Facebook Instant Articles}}&lt;br /&gt;
| '''[[DCR Static Facebook Instant Articles Browser SDK]]'''&lt;br /&gt;
|-&lt;br /&gt;
|  {{OSIcon|Tealium_Icon.png|alt=Tealium}}&lt;br /&gt;
| '''[[DCR Static Tealium]]'''&lt;br /&gt;
|-&lt;br /&gt;
|  {{OSIcon|AMPIcon.png|alt=Google AMP}}&lt;br /&gt;
| '''[[DCR Static Google AMP Cloud API]]'''&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
|{{OSIcon|BrowserIcon.png|alt=Browser}}&lt;br /&gt;
|'''[[DCR Static Domless SDK]]'''&lt;br /&gt;
|[[Domless SDK API Reference]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Xamarin ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| colspan=&amp;quot;6&amp;quot; | Xamarin Integration Guides (Xamarin support is part of [[Special:Downloads|Nielsen's AppSDK V8]] and above.)&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 90px;&amp;quot; | Type&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; |&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; | OS&lt;br /&gt;
!| Implementation Guide&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;8&amp;quot; | {{SmallIcon|SDKIcon.png|alt=SDK}}&lt;br /&gt;
|-&lt;br /&gt;
|  {{OSIcon|VideoIcon.png|alt=Video}}&lt;br /&gt;
| {{OSIcon|APIIcon.png|alt=Xamarin}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | '''[[DCR_%26_DTVR_Xamarin_Integration|DCR &amp;amp; DTVR Xamarin Integration]]'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== AppSDK Flutter Plugin ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| colspan=&amp;quot;6&amp;quot; | Flutter Integration Guides (Flutter support is part of [[Special:Downloads|Nielsen's AppSDK V10.1.0]] and above.)&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 90px;&amp;quot; | Type&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; |&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; | OS&lt;br /&gt;
!| Implementation Guide&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;8&amp;quot; | {{SmallIcon|SDKIcon.png|alt=SDK}}&lt;br /&gt;
|-&lt;br /&gt;
|  {{OSIcon|VideoIcon.png|alt=Video}}&lt;br /&gt;
| {{OSIcon|APIIcon.png|alt=Xamarin}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | '''[[DCR_%26_DTVR_Xamarin_Integration|DCR &amp;amp; DTVR Flutter Integration]]'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Cloud API ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;width: 90px;&amp;quot; | Type&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; |&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; | OS&lt;br /&gt;
!| DCR Implementation Guide&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | {{SmallIcon|CloudAPIIcon.png|alt=Cloud API}} &lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; |&lt;br /&gt;
{{OSIcon|VideoIcon.png|alt=Video}}&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
{{OSIcon|StaticIcon.png|alt=Static Content}}&lt;br /&gt;
| {{OSIcon|APIIcon.png|alt=Cloud API}}&lt;br /&gt;
| '''[[DCR Video &amp;amp; Static Cloud API ]]''' &lt;br /&gt;
|-&lt;br /&gt;
| {{OSIcon|APIIcon.png|alt=Cloud API}}&lt;br /&gt;
| '''[[DCR Video &amp;amp; Static Mobile Cloud API ]]'''&lt;br /&gt;
|-&lt;br /&gt;
| {{OSIcon|RokuIcon.png|alt=Roku}}&lt;br /&gt;
| '''[[DCR Video &amp;amp; Static Roku Cloud API]]'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Adobe Launch Extensions ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| colspan=&amp;quot;6&amp;quot; | Leverage Launch by Adobe? The guides below describe how to integrate DCR and DTVR with Nielsen's Adobe Launch extension&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 90px;&amp;quot; | Type&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; |&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; | OS&lt;br /&gt;
!| Implementation Guide&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;8&amp;quot; | {{SmallIcon|SDKIcon.png|alt=SDK}}&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | '''[[Digital Measurement Onboarding Adobe ]]'''&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | {{OSIcon|VideoIcon.png|alt=Video}}&lt;br /&gt;
| {{OSIcon|macOSIcon.png|alt=iOS}}&lt;br /&gt;
| '''[[DCR &amp;amp; DTVR iOS Adobe Launch Extension]]'''&lt;br /&gt;
|-&lt;br /&gt;
| {{OSIcon|AndroidIcon.png|alt=Android}}&lt;br /&gt;
| '''[[DCR &amp;amp; DTVR Android Adobe Launch Extension]]'''&lt;br /&gt;
|-&lt;br /&gt;
| {{OSIcon|BrowserIcon.png|alt=Browser}}&lt;br /&gt;
| '''[[DCR &amp;amp; DTVR Browser Adobe Launch Extension]]'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SDK - Connected TV ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| colspan=&amp;quot;6&amp;quot; | The guides below describe how to integrate DCR and DTVR with Smart tv's&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 90px;&amp;quot; | Type&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; |&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; | OS&lt;br /&gt;
! | Implementation Guide&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;8&amp;quot; | {{SmallIcon|SDKIcon.png|alt=SDK}}&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | {{OSIcon|VideoIcon.png|alt=Video}}&lt;br /&gt;
| {{OSIcon|BrowserIcon.png|alt=Browser}}&lt;br /&gt;
| '''[[Digital Measurement Video TizenTv]]'''&lt;br /&gt;
|-&lt;br /&gt;
| {{OSIcon|BrowserIcon.png|alt=Browser}}&lt;br /&gt;
| '''[[Digital Measurement Video webOS]]'''&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>AnkitAgrawal</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=TVOS_SDK_Release_Notes&amp;diff=7309</id>
		<title>TVOS SDK Release Notes</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=TVOS_SDK_Release_Notes&amp;diff=7309"/>
		<updated>2025-05-08T02:53:40Z</updated>

		<summary type="html">&lt;p&gt;AnkitAgrawal: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Digital]]&lt;br /&gt;
 __NOTOC__&lt;br /&gt;
&lt;br /&gt;
{{Breadcrumb|}} {{Breadcrumb|Digital}} {{CurrentBreadcrumb}}&lt;br /&gt;
==Release 10.0.0.0 (04-04-2025)==&lt;br /&gt;
* Support for DTVR Subminute product.&lt;br /&gt;
*Support for DCR video playhead bridging.&lt;br /&gt;
*Support for VisionOS platform.&lt;br /&gt;
*Change in DemographicID behavior for Chromecast.&lt;br /&gt;
*Other bug fixes and enhancements.&lt;br /&gt;
== Release 9.4.0.0 (07-09-2024) ==&lt;br /&gt;
*Support for privacy manifest with content tracking domain for Ad flavors.&lt;br /&gt;
*Support for content tracking and no-tracking domains across sdk flavors and products.&lt;br /&gt;
*Other bug fixes and enhancements.&lt;br /&gt;
==Release 9.3.0.0 (05-10-2024)==&lt;br /&gt;
*Support for privacy manifest with tracking domain for Ad flavors.&lt;br /&gt;
*Support for capturing user opt-out during initialization.&lt;br /&gt;
*Other bug fixes and enhancements.&lt;br /&gt;
== Release 9.2.0.0 (9-27-2023) ==&lt;br /&gt;
*Support for privacy manifest and required reason API introduced in XCode 15.&lt;br /&gt;
*Digitally signed SDK framework per Apple recommendation&lt;br /&gt;
*DCR Static recognizing metadata with changed assetID for new impressions. &lt;br /&gt;
*Limiting ping retries during https failures. &lt;br /&gt;
*Other bug fixes and enhancements. &lt;br /&gt;
&lt;br /&gt;
== Release 9.1.0.0 (3-31-2023) ==&lt;br /&gt;
*DCR Static duration measurement for AppSDK (currently only AGF).&lt;br /&gt;
*Removed use of iOS keychains, started using NSUserDefaults for persistent storage.&lt;br /&gt;
*Viewability: allow enabling by product (DCR, DTVR).&lt;br /&gt;
*Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 9.0.0.0 (10-07-2022) ==&lt;br /&gt;
* Viewability measurement for DTVR, DCR Content and DCR Ad products.&lt;br /&gt;
* Audibility measurement for DTVR, DCR Content and DCR Ad products.&lt;br /&gt;
* SDK built with XCode 14.&lt;br /&gt;
* Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 8.2.0.0 (03-21-2022) ==&lt;br /&gt;
* Adopting Swift language internally, built on a mixed model (Swift+Objective C).&lt;br /&gt;
* Support for Swift markers to help Swift developers.&lt;br /&gt;
* Removed the usage of deprecated iOS network reachability class.&lt;br /&gt;
* Disabled iCloud backup/synchronization of SDK keychain items.&lt;br /&gt;
* Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 8.1.0.0 (06-28-2021) ==&lt;br /&gt;
* Support for XCFramework build distribution.&lt;br /&gt;
* Support for MacOS Catalyst platform framework.&lt;br /&gt;
* Fixed the device classification for MacOS M1 measurement.&lt;br /&gt;
* Support to capture Hashed email and UID.&lt;br /&gt;
* Support to collect SDK diagnostic data.&lt;br /&gt;
* Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 8.0.0.0 (10-05-2020) ==&lt;br /&gt;
* iOS 14 App Transparency Framework support.&lt;br /&gt;
* FPID and VendorID support.&lt;br /&gt;
* Fixed the device classification for iPADOS measurement.&lt;br /&gt;
* Support for Xamarin cross platform framework.&lt;br /&gt;
* Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 7.2.0.0 (05-18-2020) ==&lt;br /&gt;
* DTVR AQH and IVD requirements for End and pause timeout.&lt;br /&gt;
* Support for Hybrid app webview measurement. &lt;br /&gt;
* Support for Hybrid app react native webview measurement. &lt;br /&gt;
* Support for React Native measurement.&lt;br /&gt;
* Other bug fixes and enhancements&lt;br /&gt;
&lt;br /&gt;
== Release 7.1.0.0 (12-09-2019) ==&lt;br /&gt;
* Removed usage of deprecated class UIWebView&lt;br /&gt;
* Offline viewing measurement enhancements&lt;br /&gt;
* Fixed deadlock on SDK shutdown&lt;br /&gt;
* Revisited precedence logic for sfcode parameter&lt;br /&gt;
* Fix for DCR individual ad pings parameters after channel change&lt;br /&gt;
* Using default value for incorrect adModel parameter&lt;br /&gt;
* Defaulting isLive parameter value on channel change&lt;br /&gt;
* Other fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Release 7.0.0.0 (09-06-2019) ==&lt;br /&gt;
* Support for CDN based config.&lt;br /&gt;
* Support for Market based EMM UAID pings.&lt;br /&gt;
* Changes required for proper DCR Static measurement in multi-instance/multiple appid's case.&lt;br /&gt;
* Fixes for OTT synchronization issues between iOS and Android platforms.&lt;br /&gt;
* Fixes for EV data parameters in few scenarios.&lt;br /&gt;
* Fixes for DCR Static product behaviour in background app refresh and background fetch scenarios.&lt;br /&gt;
* DCR Ad reporting improvements.&lt;br /&gt;
* Fixes and improvements for the SDK console log messages.&lt;br /&gt;
* Other enhancements and fixes.&lt;br /&gt;
&lt;br /&gt;
== Release 6.2.0.0 (02-04-2019) == &lt;br /&gt;
* Introduced Dynamic framework for SDK.&lt;br /&gt;
* Removal of Location Module from SDK Code.&lt;br /&gt;
* Increased SDK log file size for Debug mode.&lt;br /&gt;
* Removed OTT Airplay/mirroring detection that caused crashes in AVAudioSession class.&lt;br /&gt;
* DCR performance improvements.&lt;br /&gt;
* Fixed the parsing error happening when clientid/vcid provided as empty in metadata.&lt;br /&gt;
* Align AppSDK for FW detection with BSDK for DCR measurement.&lt;br /&gt;
* Other Bug Fixes/Enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 6.1.0.1 (9-13-2018) ==&lt;br /&gt;
*Nielsen SDK support for Xcode 10 and tvOS 12&lt;br /&gt;
&lt;br /&gt;
== Release 6.0.0.4 (5-24-2018) ==&lt;br /&gt;
*If the SDK build target is set to AGF then SDK will send the hello ping to “eu” and “eu-uat” for debug builds. No changes to the non AGF build the default sfcode will continue to be &amp;quot;sdk&amp;quot; and &amp;quot;cert&amp;quot; for debug build.&lt;br /&gt;
*The C1 parameter (NUID) will now be sent as encrypted DeviceID.&lt;br /&gt;
*New SessionID changes. The sessionID will contain 29 length random characters appended by timestamp.&lt;br /&gt;
*Support for multiple SDK instance without any limit.&lt;br /&gt;
*New log feature for CAT tool to retrieve the API level information from client apps. This ping will contain the eventType, parameters, SDK version, appid etc.&lt;br /&gt;
*Removed Viewability for this release.&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.17 (1-23-2017) ==&lt;br /&gt;
*Added &amp;quot;seconds&amp;quot; place to the launch ping&lt;br /&gt;
*Ability to opt-out using &amp;quot;Limit Ad Tracking&amp;quot; feature&lt;br /&gt;
*Improved CPU Performance while apps are running in background&lt;br /&gt;
*Opt-Out pages can be served based on user’s language and locale from device&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.12 (12-14-2016) ==&lt;br /&gt;
*Support for Nielsen TV Brand Effect&lt;br /&gt;
*Ability to set CMS parameters at a more global level&lt;br /&gt;
*Opt-out pages based on locale and country&lt;br /&gt;
*Opt-out policy based on the &amp;quot;Limit Ad Tracking&amp;quot; flag&lt;br /&gt;
*Collection of additional device information&lt;br /&gt;
*Issue a warning in client developer’s console when ad is played for more than 5 minutes&lt;br /&gt;
*Removed the requirement for “type” parameter&lt;br /&gt;
*Limit the duration reported for App launch&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.7 (9-13-2016) ==&lt;br /&gt;
*General bug fix and performance improvements&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.5 (7-12-2016) ==&lt;br /&gt;
*Includes a sample TVOS application used to assist during integration.&lt;br /&gt;
*Support for TVML based optout pages&lt;br /&gt;
*General bug fix and performance improvements&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.0.7 (6-15-2016) ==&lt;br /&gt;
*Combined SDK for DCR US and International (Germany)&lt;br /&gt;
*API to signal end of content (end API)&lt;br /&gt;
*Support for Pause timeout&lt;br /&gt;
*Updated API to support JSON object instead of string.&lt;br /&gt;
*Reporting of media URL and bundle ID&lt;br /&gt;
*Updated ping retry logic&lt;br /&gt;
*Changes in OptOut process behavioral&lt;br /&gt;
*Enhanced Debugging and SDK logging&lt;br /&gt;
*Changes to API signature&lt;/div&gt;</summary>
		<author><name>AnkitAgrawal</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=DCR_Video_Android_SDK&amp;diff=7261</id>
		<title>DCR Video Android SDK</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=DCR_Video_Android_SDK&amp;diff=7261"/>
		<updated>2025-04-04T21:58:35Z</updated>

		<summary type="html">&lt;p&gt;AnkitAgrawal: /* Interruptions during playback */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|US DCR &amp;amp; DTVR}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The Nielsen SDK is one of multiple framework SDKs that Nielsen provides to enable measuring linear (live) and on-demand TV viewing using TVs, mobile devices, etc.&lt;br /&gt;
The App SDK is the framework for mobile application developers to integrate Nielsen Measurement into their media player applications. It supports a variety of Nielsen Measurement Products like Digital in TV Ratings, Digital Content Ratings ([[DCR &amp;amp; DTVR]]), and [[Digital Ad Ratings]] (DAR). Nielsen SDKs are also equipped to measure static content and can track key life cycle events of an application like:&lt;br /&gt;
*Application launch events and how long app was running&lt;br /&gt;
*Time of viewing a sub section / page in the application.&lt;br /&gt;
&lt;br /&gt;
{{Android_Prerequisites_and_Implementation_Overview}}&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
{{Android_Setting_Up_Development_Environment}}&lt;br /&gt;
&lt;br /&gt;
{{Android_SDK_Initialization}}&lt;br /&gt;
&lt;br /&gt;
== APP SDK Error &amp;amp; Event Codes ==&lt;br /&gt;
To view the Error and Event codes for iOS and Android, please review the [[APP SDK Event Codes|App SDK Event Code]] Reference page.&lt;br /&gt;
&lt;br /&gt;
== Configure Payload ==&lt;br /&gt;
=== Handling JSON Metadata ===&lt;br /&gt;
All the SDK methods handles only two types of objects: NSString, NSDictionary. The parameters passed must be either a JSON formatted string or a NSDictionary object. The JSON passed in the SDK must be well-formed.&lt;br /&gt;
* NSDictionary object&lt;br /&gt;
** If an object of unexpected type is passed to the method, the error message will be logged.&lt;br /&gt;
** If string has invalid JSON format, the error message will be logged.&lt;br /&gt;
* JSON value must be string value.&lt;br /&gt;
** This includes boolean and numeric values. For example, a value of true should be represented with &amp;quot;true&amp;quot;, number value 123 should be &amp;quot;123&amp;quot;.&lt;br /&gt;
** All the Variable Names like appid, appname, sfcode, dataSrc, title, type etc. are case-sensitive. Use the correct variable name as specified in the documentation.&lt;br /&gt;
* JSON string can be prepared using either raw NSString or serialized NSDictionary.&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
JSONObject contentMetadata = new JSONObject()&lt;br /&gt;
//SDK Metadata&lt;br /&gt;
    .put(&amp;quot;type&amp;quot;, &amp;quot;content&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;assetid&amp;quot;, &amp;quot;vid345-67483&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;program&amp;quot;, &amp;quot;The Big Bang Theory&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;title&amp;quot;, &amp;quot;The Pants Alternative S03E18&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;crossId1&amp;quot;, &amp;quot;EP009311820061&amp;quot;)  //optional  &lt;br /&gt;
    .put(&amp;quot;crossId2&amp;quot;, &amp;quot;Content Originator&amp;quot;)  //optional  &lt;br /&gt;
    .put(&amp;quot;length&amp;quot;, &amp;quot;3600&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;isfullepisode&amp;quot;, &amp;quot;yes&amp;quot;) &lt;br /&gt;
    .put(&amp;quot;airdate&amp;quot;, &amp;quot;2022-03-21T10:05:00&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;adloadtype&amp;quot;, &amp;quot;2&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;segB&amp;quot;, &amp;quot;CustomSegmentValueB&amp;quot;) //optional&lt;br /&gt;
    .put(&amp;quot;segC&amp;quot;, &amp;quot;CustomSegmentValueC&amp;quot;) //optional&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Content metadata ===&lt;br /&gt;
Content metadata should remain constant throughout the entirety of an episode/clip including when ads play.&lt;br /&gt;
{{DCR Content Metadata}}&lt;br /&gt;
&lt;br /&gt;
=== Ad Metadata ===&lt;br /&gt;
The Ad Metadata (if applicable) should be passed for each individual ad.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys	!! Description	!! Values	!! Required&lt;br /&gt;
|-&lt;br /&gt;
| type 	|| type of Ad	||  &amp;lt;code&amp;gt;'preroll'&amp;lt;/code&amp;gt;,  &amp;lt;code&amp;gt;'midroll'&amp;lt;/code&amp;gt;,  &amp;lt;code&amp;gt;'postroll'&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; &amp;lt;code&amp;gt;'ad'&amp;lt;/code&amp;gt;  - If specific type can not be identified.||	✓&lt;br /&gt;
|-&lt;br /&gt;
| assetid ||	unique ID assigned to Ad	|| custom &amp;lt;br&amp;gt;(no [[Special Characters]])	|| ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Example Ad Object ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// create ad object&lt;br /&gt;
&amp;quot;ad&amp;quot;: {&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;preroll&amp;quot;,&lt;br /&gt;
  &amp;quot;assetid&amp;quot;: &amp;quot;AD-ID123&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sequence of Calls ==&lt;br /&gt;
=== play ===&lt;br /&gt;
Use [[DCR_Video_APP_SDK#play|play]] to pass the channel descriptor information through channelName parameter when the user taps the '''Play''' button on the player.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;    public void play(JSONObject channelInfo);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== loadMetadata ===&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;public void loadMetadata(JSONObject contentMetadata);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== playheadPosition ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public void setPlayheadPosition(long position)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== stop ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;public void stop()&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== end ===&lt;br /&gt;
When content stop is initiated and content cannot be resumed from the same position (it can only be restarted from the beginning of stream).&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;public void end()&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Configure API Calls ==&lt;br /&gt;
&lt;br /&gt;
=== Sample API Sequence ===&lt;br /&gt;
A Sample API sequence could follow this flow:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type !! Sample code !! Description&lt;br /&gt;
|-&lt;br /&gt;
|On App Start||&amp;lt;code&amp;gt;[nielsenMeter loadMetadata: contentMetadata];&amp;lt;/code&amp;gt; || // contentMetadata Object contains the JSON metadata for the impression&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Start of stream || &amp;lt;code&amp;gt;[nielsenMeter play];&amp;lt;/code&amp;gt; || // call at start of each new stream&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;[nielsenMeter loadMetadata: contentMetadataObject];&amp;lt;/code&amp;gt; || // contentMetadataObject contains the JSON metadata for the content being played&lt;br /&gt;
|-&lt;br /&gt;
| Content || &amp;lt;code&amp;gt;[nielsenMeter setplayheadPosition: position];&amp;lt;/code&amp;gt; || // playheadPosition is position of the playhead while the content is being played&lt;br /&gt;
|-&lt;br /&gt;
| End of Stream || &amp;lt;code&amp;gt;[nielsenMeter end];&amp;lt;/code&amp;gt; || // Content playback is completed.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== SDK Events ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Event !!	Parameter	!! Description&lt;br /&gt;
|-&lt;br /&gt;
| 'play'	|| 	|| Call at start of each new stream&lt;br /&gt;
|-&lt;br /&gt;
| 'loadMetadata'	|| content/ad metadata object	|| Needs to be called at the beginning of each asset&lt;br /&gt;
|-&lt;br /&gt;
| 'setPlayheadPosition'	|| playhead position as integer&amp;lt;br/&amp;gt;&lt;br /&gt;
VOD: || current position in seconds &amp;lt;br/&amp;gt;&lt;br /&gt;
Live: current Unix timestamp (seconds since Jan-1-1970 UTC) &amp;lt;br/&amp;gt;&lt;br /&gt;
Note: 'setPlayheadPosition' has to be called every second&lt;br /&gt;
||&lt;br /&gt;
Pass playhead position every second during playback&lt;br /&gt;
|-&lt;br /&gt;
| 'stop' ||	playhead position	|| Call during any interruption to content or Ad playback and at the end of each Ad.&lt;br /&gt;
|-&lt;br /&gt;
| 'end'	|| playhead position in seconds	|| Call when the current video asset completes playback and pass the playhead position. &amp;lt;br/&amp;gt;&lt;br /&gt;
Example: At the end of the content stream, if the user switches to another piece of content, when the browser is refreshed or closed.&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Note: For livestream, send the Unix timestamp; for VOD send the time in seconds as integer. The final playhead position must be sent for the current asset being played before calling &amp;lt;code&amp;gt;'''stop'''&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;'''end'''&amp;lt;/code&amp;gt; or&amp;lt;code&amp;gt; '''loadmetadata'''&amp;lt;/code&amp;gt;,.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Life cycle of SDK instance ===&lt;br /&gt;
Life cycle of SDK instance includes four general states:&lt;br /&gt;
# '''Initial state''' – The SDK is not initialized and hence, not ready to process playing information. Once the SDK is moved out of this state, it needs instantiation of the new SDK instance in order to get the instance in the '''Initial state'''.&lt;br /&gt;
# '''Idle state''' – The SDK is initialized and is ready to process playing information. Once Initialized, the SDK instance is not processing any data, but is listening for the play event to occur.&lt;br /&gt;
# '''Processing state''' – The SDK instance is processing playing information. The &amp;lt;code&amp;gt;'''play'''&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;'''loadMetadata''' &amp;lt;/code&amp;gt; calls move the SDK instance into this state. In this state, the SDK instance will be able to process the following calls.&lt;br /&gt;
## &amp;lt;code&amp;gt;'''setplayheadPosition'''&amp;lt;/code&amp;gt; – Call this API every one second when playhead position timer is fired.  If a LIVE event, use the current Unix timestamp (seconds since Jan-1-1970 UTC).&lt;br /&gt;
## &amp;lt;code&amp;gt;'''stop'''&amp;lt;/code&amp;gt; – Call this API when the playback is paused, switches between content and ad (within the same content playback) or encounters interruptions.&lt;br /&gt;
## &amp;lt;code&amp;gt;'''end'''&amp;lt;/code&amp;gt; – Call when content completes. When called, the SDK instance exits from Processing state.&lt;br /&gt;
# '''Disabled state''' – The SDK instance is disabled and is not processing playing information. SDK instance moves into this state in one of the following scenarios.&lt;br /&gt;
## Initialization fails&lt;br /&gt;
## &amp;lt;code&amp;gt;'''appDisableApi'''&amp;lt;/code&amp;gt; is set to &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note:''' For API Version 5.1 and above, App SDK will fire data pings and continue measurement even after the user has opted out from Nielsen measurement on a device. The data ping will be marked as opted-out ping.&lt;br /&gt;
&lt;br /&gt;
'''Note''': In case of any interruptions during playback due to alarm, calendar, call, flight mode, Wi-Fi toggle, channel change, etc., call [[stop]] to stop the measurement.&lt;br /&gt;
* As soon as the playback resumes, &amp;lt;code&amp;gt;'''loadMetadata''' &amp;lt;/code&amp;gt; and   &amp;lt;code&amp;gt;'''playheadPosition'''&amp;lt;/code&amp;gt; &amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== API Call Sequence ===&lt;br /&gt;
==== Use Case 1: Content has no Advertisements ====&lt;br /&gt;
Call [[play()]] at start of stream&lt;br /&gt;
&lt;br /&gt;
Call [[loadMetadata()]] with JSON metadata for content as below.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;{&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;,&lt;br /&gt;
  &amp;quot;assetid&amp;quot;: &amp;quot;vid345-67483&amp;quot;,&lt;br /&gt;
  &amp;quot;program&amp;quot;: &amp;quot;ProgramName&amp;quot;,&lt;br /&gt;
  &amp;quot;title&amp;quot;: &amp;quot;Program S3, EP1&amp;quot;,&lt;br /&gt;
  &amp;quot;length&amp;quot;: &amp;quot;3600&amp;quot;,&lt;br /&gt;
  ...&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Call [[setPlayheadPosition()]] every one second until a pause / stop.&lt;br /&gt;
Use the sample API sequence below as a reference to identify the specific events that need to be called during content playback without ads.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type !! Sample code !! Description&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Start of stream || &amp;lt;code&amp;gt;mAppSdk.play(); &amp;lt;/code&amp;gt; || // Call at start of each new stream&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.loadMetadata(contentMetaDataObject);&amp;lt;/code&amp;gt; || // contentMetadataObject contains the JSON metadata for the content being played&lt;br /&gt;
|-&lt;br /&gt;
| Content || &amp;lt;code&amp;gt;mAppSdk.setPlayheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // position is position of the playhead while the content is being played&lt;br /&gt;
|-&lt;br /&gt;
| Interruption || &amp;lt;code&amp;gt;mAppSdk.stop();&amp;lt;/code&amp;gt; || // call stop when content playback is interrupted&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Resume Content || &amp;lt;code&amp;gt;mAppSdk.loadMetadata(contentMetaDataObject);&amp;lt;/code&amp;gt;  || // Call loadMetadata and pass content metadata object when content resumes&lt;br /&gt;
|- &lt;br /&gt;
|&amp;lt;code&amp;gt;mAppSdk.setPlayheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // continue pasing playhead position every second starting from position where content is resumed&lt;br /&gt;
|- &lt;br /&gt;
| End of Stream || &amp;lt;code&amp;gt;mAppSdk.end();&amp;lt;/code&amp;gt; || // Content playback is completed.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Use Case 2: Content has Advertisements ====&lt;br /&gt;
Call [[play()]] &lt;br /&gt;
&lt;br /&gt;
Call [[loadMetadata()]] with JSON metadata for ad as below.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;{&lt;br /&gt;
   &amp;quot;type&amp;quot;: &amp;quot;preroll&amp;quot;,&lt;br /&gt;
   &amp;quot;assetid&amp;quot;: &amp;quot;ad-123&amp;quot;&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Note: In case the individual ad details are not available, send ad pod (presence) details through the [[loadMetadata]] and playhead position through [[playheadPosition]].&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Call [[setPlayheadPosition()]] every one second until a pause / stop / another [[loadMetadata()]] is called. Playhead should be passed for the entire duration of ad pod, if the ad pod details are passed as part of [[loadMetadata()]].&lt;br /&gt;
&lt;br /&gt;
'''Ad Content'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;    long pos = mAdPlayer.videoPosition() / 1000;&lt;br /&gt;
   if (mAppSdk != null)&lt;br /&gt;
   {&lt;br /&gt;
     mAppSdk.setPlayheadPosition(pos);&lt;br /&gt;
   }&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Note: The playhead positions for ad and content should be maintained separately.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The sample API sequence can be used as a reference to identify the specific events that need to be called during content and ad playback.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type !! Sample code !! Description&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Start of stream || &amp;lt;code&amp;gt;mAppSdk.play(); &amp;lt;/code&amp;gt; || // stream starts&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.loadMetadata(contentMetaDataObject);&amp;lt;/code&amp;gt; || // contentMetadataObject contains the JSON metadata for the content being played&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | Preroll || &amp;lt;code&amp;gt;mAppSdk.loadMetadata(prerollMetadataObject);&amp;lt;/code&amp;gt; || // prerollMetadataObject contains the JSON metadata for the preroll ad&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.setPlayheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // position is position of the playhead while the preroll ad is being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.stop();&amp;lt;/code&amp;gt; || // Call stop after preroll occurs&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Content || &amp;lt;code&amp;gt;mAppSdk.loadMetadata(contentMetaDataObject);&amp;lt;/code&amp;gt; || // contentMetadataObject contains the JSON metadata for the content being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.setPlayheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // position is position of the playhead while the content is being played&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | Midroll || &amp;lt;code&amp;gt;mAppSdk.loadMetadata(midrollMetaDataObject);&amp;lt;/code&amp;gt; || // midrollMetadataObject contains the JSON metadata for the midroll ad&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.setPlayheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // position is position of the playhead while the midroll ad is being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.stop();&amp;lt;/code&amp;gt; || // Call stop after midroll occurs&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Content Resumes || &amp;lt;code&amp;gt;mAppSdk.loadMetadata(contentMetaDataObject);&amp;lt;/code&amp;gt; || // contentMetadataObject contains the JSON metadata for the content being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.setPlayheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // position is position of the playhead while the content is being played&lt;br /&gt;
|-&lt;br /&gt;
|  rowspan=&amp;quot;1&amp;quot; | End of Stream || &amp;lt;code&amp;gt;mAppSdk.end();&amp;lt;/code&amp;gt; || // Call end() at the end of content&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | Postroll || &amp;lt;code&amp;gt;mAppSdk.loadMetadata(postrollMetaDataObject);&amp;lt;/code&amp;gt; || // postrollMetadataObject contains the JSON metadata for the postroll ad&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.setPlayheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // position is position of the playhead while the postroll ad is being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.stop();&amp;lt;/code&amp;gt; || // Call stop after postroll occurs&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Note: Each Ad playhead should reset or begin from 0 at ad start. When content has resumed following an ad break, playhead position must continue from where previous content segment was left off.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Handling Foreground and Background states ==&lt;br /&gt;
There are a few approaches to managing the Foreground and Background states of an app available to use for state measurement.&lt;br /&gt;
* Utilizing the Androidx LifeCycleObserver (The recommended approach starting sdk version 7.1.0.0+)&lt;br /&gt;
* Utilizing the [[DCR_Video_Android_SDK#The_SdkBgFgDetectionUtility_class|SdkBgFgDetectionUtility]] class&lt;br /&gt;
* Adding a tag to the Manifest XML&lt;br /&gt;
* Manual Management&lt;br /&gt;
=== The LifeCycleObserver ===&lt;br /&gt;
AndroidX replaces the original support library APIs with packages in the androidx namespace, and Android Studio 3.2 and higher provides an automated migration tool. (Select '''Refactor&amp;gt; Migrate to AndroidX''' from the menu bar.)&lt;br /&gt;
&lt;br /&gt;
Starting with version 7.1.0, with AndroidX support, an additional utility is provided in the AppSDK - application background/foreground state detection by the AppSdk leveraging the Android Architecture component &amp;quot;LifeCycleObserver&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The AppSdk is now capable of detecting the application UI visibility state transitions between background and foreground, without forcing the applications to register for AppSdk's AppSdkApplication class, which is responsible for handling the detection of application background/foreground state transitions at present.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Please note, that if you already have an app designed that utilizes the depreciated SdkBgFgDetectionUtility Class, the AppSDK will ignore any calls to these methods if it can utilize the LifeCycleObserver.  LifeCycleObserver based auto detection will take precedence. &amp;lt;/blockquote&amp;gt;&lt;br /&gt;
==== Adding the AndroidX dependency ====&lt;br /&gt;
In order to make use of the app background/foreground state transition auto detection feature of AndroidX AppSdk, the app gradle file needs the androidx dependency. The AppSdk API calls - &amp;lt;code&amp;gt;appInForeground()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;appInBackground()&amp;lt;/code&amp;gt;  will still be respected by AppSdk by executing the old AppSdk flow of handling &amp;quot;app in foreground&amp;quot; and &amp;quot;app in background&amp;quot; states as is.&lt;br /&gt;
&lt;br /&gt;
==== Using the LifeCycle Extension ====&lt;br /&gt;
The following androidx dependency is required in the app gradle file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
implementation &amp;quot;androidx.lifecycle:lifecycle-extensions:2.1.0&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
If you would like to take advantage of this auto detection feature of AppSdk at the very initial stage (e.g. splash screen or at of app launch time), before the AppSdk is initialized, can do so by calling the following newly introduced AppSdk public api, passing the application context :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public static void registerLifeCycleObserver(Context applicationContext)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Log messages for the new auto detection ====&lt;br /&gt;
&lt;br /&gt;
When the AppSdk app successfully registers for the LifeCycleObserver : &amp;lt;code&amp;gt;Registered LifeCycleObserver for App Background/Foreground auto-detection&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* When the app enters the foreground state :&amp;lt;code&amp;gt;App is in foreground, auto detected by AppSDK&amp;lt;/code&amp;gt;&lt;br /&gt;
* When the app enters the background state :&amp;lt;code&amp;gt;App is in background, auto detected by AppSDK&amp;lt;/code&amp;gt;&lt;br /&gt;
* If the client app doesn't have the &amp;quot;androidx&amp;quot; gradle dependency and AppSdk fails to register LifeCycleObserver :&amp;lt;code&amp;gt;AndroidX LifecycleObserver can not be observed. Please use androidx dependency to activate SDK auto-detection of app background/foreground state.&amp;lt;/code&amp;gt;&lt;br /&gt;
* When the appInForeground() is explicitly called while LifeCycleObserver auto detection is active :&amp;lt;code&amp;gt;Ignoring the appInBackground() call, as the App Background/Foreground auto-detection is active. The current state is - foreground&amp;lt;/code&amp;gt;&lt;br /&gt;
* When the appInBackground() is explicitly called while LifeCycleObserver auto detection is active :&amp;lt;code&amp;gt;Ignoring the appInBackground() call, as the App Background/Foreground auto-detection is active. The current state is - background&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The SdkBgFgDetectionUtility class ===&lt;br /&gt;
Foreground/Background state measurement is a requirement of Nielsen AppSDK implementation which is especially crucial for static measurement. It may be implemented in multiple ways for Android. This includes&lt;br /&gt;
* Enable the Nielsen SDK to measure background/foreground state by makingthe relevant update to the AndroidManifest.&lt;br /&gt;
* Integrate Nielsen’s SdkBgFgDetectionUtility class within your Custom Application Class.&lt;br /&gt;
* Custom implementation of the required methods within your application.&lt;br /&gt;
&lt;br /&gt;
==== ForeGround/Background Measurement via AndroidManifest ====&lt;br /&gt;
The simplest way to measure the app background/foreground state is to add the following application tag to the Manifest XML. Integrating this into the Manifest XML will enable the SDK to measure app state directly. This approach is supported for Android 4.0 and up only; it requires that the application class is not in use for some other purpose.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;application android:name=&amp;quot;com.nielsen.app.sdk.AppSdkApplication&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using the Android SdkBgFbDetectionUtility Class ====&lt;br /&gt;
For developers who are already using the application class, it is recommended that background/foreground state is implemented using the  [https://engineeringportal.nielsen.com/docs/Android_Background_Foreground SdkBgFgDetectionUtility class].  The  [https://engineeringportal.nielsen.com/docs/Android_Background_Foreground SdkBgFgDetectionUtility class] is compatible with Android 4+ and has been made available to Nielsen clients. (You will need to copy/paste the code provided into a file).&lt;br /&gt;
&lt;br /&gt;
==== Manual Background/ForeGround State Management ====&lt;br /&gt;
In cases where the developer is not able to use the AndroidManifest.xml solution nor the Nielsen provided   [https://engineeringportal.nielsen.com/docs/Android_Background_Foreground SdkBgFgDetectionUtility class] the developer will need to manually identify the change of state through the application and call the respective API (appInForeground() or appInBackground()) to inform the SDK regarding the change of state from background to foreground or foreground to background.&lt;br /&gt;
&lt;br /&gt;
The SDK is informed about app state using the below methods.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
AppLaunchMeasurementManager.appInForeground(getApplicationContext());&lt;br /&gt;
AppLaunchMeasurementManager.appInBackground(getApplicationContext());&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Within the lifecycle of individual activities, onResume() and onPause() are best suited to providing indication of the app state.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Correct measurement of the foreground/background state is crucial to Static App measurement within Nielsen Digital Content Ratings (DCR).&lt;br /&gt;
== Using the NielsenAppSDKJSHandler ==&lt;br /&gt;
There could be a scenario in which a browser page, that is already tagged with the Nielsen BSDK, needs to be loaded via a webview.  In this situation it is recommended to use the '''NielsenAppSDKJSHandler''' which will allow communication between the AppSDK and the BSDK. &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''This feature is supported in versions 7.2 and above.'''&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Implementation ===&lt;br /&gt;
* Make sure you have the latest AppSdk.jar from Nielsen&lt;br /&gt;
* Enable the javascript on webview using below lines&lt;br /&gt;
&amp;lt;br&amp;gt; &lt;br /&gt;
 &amp;lt;syntaxhighlight lang=java&amp;gt;&lt;br /&gt;
WebSettings webSetting = webView.getSettings();&lt;br /&gt;
webSetting.setJavaScriptEnabled(true);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
* Add  NielsenAppSDKJSHandler instance as javascript interface to webview with name “NielsenAppSDK” like below snippet&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=java&amp;gt;&lt;br /&gt;
webView.addJavascriptInterface(new NielsenAppSDKJSHandler(getApplicationContext()), &amp;quot;NielsenAppSDK&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
This will enable listening to BSDK api calls within the APPSDK.  Please make sure your Technical Account Manager is aware that you wish to implement this method so a configuration file can be modified on the Nielsen servers; however, there are '''no changes required to the Browser page'''.&lt;br /&gt;
&lt;br /&gt;
==== Example:====&lt;br /&gt;
The below is an example of opening a webview with the NielsenAppSDKJSHandler&lt;br /&gt;
&amp;lt;syntaxhighlight lang=java&amp;gt;&lt;br /&gt;
      WebSettings webSetting = webView.getSettings();&lt;br /&gt;
      webView.getSettings().setDomStorageEnabled(true); &lt;br /&gt;
      webSetting.setJavaScriptEnabled(true);&lt;br /&gt;
      webView.addJavascriptInterface(new NielsenAppSDKJSHandler(getApplicationContext(), &amp;quot;&amp;quot;), &amp;quot;NielsenAppSDK&amp;quot;);&lt;br /&gt;
      String url = &amp;quot;https://nielsen.com.index.htm&amp;quot;;&lt;br /&gt;
      webView.loadUrl(url);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;AndroidManifest.xml&amp;lt;/code&amp;gt; may need the following permissions set:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=java&amp;gt;&lt;br /&gt;
    &amp;lt;uses-permission android:name=&amp;quot;android.permission.INTERNET&amp;quot;/&amp;gt;&lt;br /&gt;
    &amp;lt;uses-permission android:name=&amp;quot;android.permission.ACCESS_NETWORK_STATE&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Closing NielsenAppSDKJSHandler ===&lt;br /&gt;
NielsenAppSDKJSHandler should be closed or cleaned up in below scenarios&lt;br /&gt;
* Before WebView is getting destructed&lt;br /&gt;
* Before loading new page&lt;br /&gt;
* Before closing application&lt;br /&gt;
NielsenAppSDKJSHandler provides a public interface with name &amp;quot;close()&amp;quot; and this function should be called on NielsenAppSDKJSHandler's instance in all above scenarios.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=java&amp;gt;&lt;br /&gt;
// get your webview&lt;br /&gt;
WebView webView = findViewById(R.id.webView);&lt;br /&gt;
 &lt;br /&gt;
//Added JS Handler instance as java script interface for ggpm api type&lt;br /&gt;
NielsenAppSDKJSHandler jshandler = new NielsenAppSDKJSHandler(getApplicationContext(), &amp;quot;&amp;quot;);&lt;br /&gt;
webView.addJavascriptInterface(jshandler, &amp;quot;NielsenAppSDK&amp;quot;);&lt;br /&gt;
 &lt;br /&gt;
//Close JS Handler before making webview as null&lt;br /&gt;
jshandler.close();&lt;br /&gt;
webView = null;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Interruptions during playback ==&lt;br /&gt;
As part of integrating Nielsen App SDK with the player application, the Video app developer needs to handle the following possible interruption scenarios:&lt;br /&gt;
* Pause / Play&lt;br /&gt;
* Network Loss (Wi-Fi / Airplane / Cellular)&lt;br /&gt;
* Call Interrupt (SIM or Third party Skype / Hangout call)&lt;br /&gt;
* Alarm Interrupt&lt;br /&gt;
* Content Buffering&lt;br /&gt;
* Device Lock / Unlock &lt;br /&gt;
* App going in the Background/Foreground&lt;br /&gt;
* Channel / Station Change Scenario&lt;br /&gt;
* Unplugging of headphone&lt;br /&gt;
In case of encountering one of the above interruptions, the player application needs to&lt;br /&gt;
* Call [[stop]] immediately (except when content is buffering) and withhold sending playhead position.&lt;br /&gt;
* Start sending API calls – &amp;lt;code&amp;gt;'loadMetadata'&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;'playheadPosition'&amp;lt;/code&amp;gt; to resume the viewing session, once the playback resumes.&lt;br /&gt;
Please see the [https://engineeringportal.nielsen.com/docs/Digital_Measurement_Interruption_Scenarios Interruption Scenarios Page] for more details&lt;br /&gt;
&lt;br /&gt;
== Pre-Certification Checklists ==&lt;br /&gt;
After the application is ready to be sent for Nielsen Certification, please go through the [[Digital Pre-Certification Checklist App SDK]] and ensure the app behaves as expected, before submitting to Nielsen.&lt;br /&gt;
&lt;br /&gt;
{{Template:Android_Privacy_and_Opt-Out}}&lt;br /&gt;
== Required Privacy Links ==&lt;br /&gt;
Users must either have access to the &amp;quot;About Nielsen Measurement&amp;quot; page, or have similar text available within the native app. Include &amp;quot;About Nielsen Measurement&amp;quot; and &amp;quot;Your Choices&amp;quot; link in the Privacy Policy / EULA or as a button near the link to the app's Privacy Policy.&lt;br /&gt;
&lt;br /&gt;
== Sample Applications ==&lt;br /&gt;
The below sample applications have been designed to show the API's functionality and are broken into two distinct categories:&lt;br /&gt;
* '''Basic''' - To show the functionality of the Nielsen  API using a standard no-frills player.&lt;br /&gt;
** [[Android Basic example|Android Studio Example]]&lt;br /&gt;
&lt;br /&gt;
* '''Advanced''' - Nielsen API integrated into a custom video player is bundled with the SDK.&lt;/div&gt;</summary>
		<author><name>AnkitAgrawal</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=Template:iOS_Interuptions_during_Playback&amp;diff=7260</id>
		<title>Template:iOS Interuptions during Playback</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=Template:iOS_Interuptions_during_Playback&amp;diff=7260"/>
		<updated>2025-04-04T21:50:23Z</updated>

		<summary type="html">&lt;p&gt;AnkitAgrawal: /* Interruptions during playback */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Interruptions during playback ==&lt;br /&gt;
As part of integrating Nielsen App SDK with the player application, the Audio / Video app developer needs to handle the following possible interruption scenarios:&lt;br /&gt;
* Pause / Play&lt;br /&gt;
* Network Loss (Wi-Fi / Airplane / Cellular)&lt;br /&gt;
* Call Interrupt (SIM or Third party Skype / Hangout call)&lt;br /&gt;
* Alarm Interrupt&lt;br /&gt;
* Content Buffering&lt;br /&gt;
* Device Lock / Unlock &lt;br /&gt;
* App going in the Background/Foreground &lt;br /&gt;
* Channel / Station Change Scenario&lt;br /&gt;
* Unplugging of headphone&lt;br /&gt;
In case of encountering one of the above interruptions, the player application needs to&lt;br /&gt;
* Call [[stop]] immediately (except when content is buffering) and withhold sending playhead position.&lt;br /&gt;
* Start sending API calls – &amp;lt;code&amp;gt;'loadMetadata'&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;'playheadPosition'&amp;lt;/code&amp;gt; to resume the viewing session, once the playback resumes.&lt;br /&gt;
Please see the [https://engineeringportal.nielsen.com/docs/Digital_Measurement_Interruption_Scenarios Interruption Scenarios Page] for more details&lt;/div&gt;</summary>
		<author><name>AnkitAgrawal</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=DCR_Video_Android_SDK&amp;diff=7259</id>
		<title>DCR Video Android SDK</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=DCR_Video_Android_SDK&amp;diff=7259"/>
		<updated>2025-04-04T21:47:56Z</updated>

		<summary type="html">&lt;p&gt;AnkitAgrawal: /* Interruptions during playback */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|US DCR &amp;amp; DTVR}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The Nielsen SDK is one of multiple framework SDKs that Nielsen provides to enable measuring linear (live) and on-demand TV viewing using TVs, mobile devices, etc.&lt;br /&gt;
The App SDK is the framework for mobile application developers to integrate Nielsen Measurement into their media player applications. It supports a variety of Nielsen Measurement Products like Digital in TV Ratings, Digital Content Ratings ([[DCR &amp;amp; DTVR]]), and [[Digital Ad Ratings]] (DAR). Nielsen SDKs are also equipped to measure static content and can track key life cycle events of an application like:&lt;br /&gt;
*Application launch events and how long app was running&lt;br /&gt;
*Time of viewing a sub section / page in the application.&lt;br /&gt;
&lt;br /&gt;
{{Android_Prerequisites_and_Implementation_Overview}}&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
{{Android_Setting_Up_Development_Environment}}&lt;br /&gt;
&lt;br /&gt;
{{Android_SDK_Initialization}}&lt;br /&gt;
&lt;br /&gt;
== APP SDK Error &amp;amp; Event Codes ==&lt;br /&gt;
To view the Error and Event codes for iOS and Android, please review the [[APP SDK Event Codes|App SDK Event Code]] Reference page.&lt;br /&gt;
&lt;br /&gt;
== Configure Payload ==&lt;br /&gt;
=== Handling JSON Metadata ===&lt;br /&gt;
All the SDK methods handles only two types of objects: NSString, NSDictionary. The parameters passed must be either a JSON formatted string or a NSDictionary object. The JSON passed in the SDK must be well-formed.&lt;br /&gt;
* NSDictionary object&lt;br /&gt;
** If an object of unexpected type is passed to the method, the error message will be logged.&lt;br /&gt;
** If string has invalid JSON format, the error message will be logged.&lt;br /&gt;
* JSON value must be string value.&lt;br /&gt;
** This includes boolean and numeric values. For example, a value of true should be represented with &amp;quot;true&amp;quot;, number value 123 should be &amp;quot;123&amp;quot;.&lt;br /&gt;
** All the Variable Names like appid, appname, sfcode, dataSrc, title, type etc. are case-sensitive. Use the correct variable name as specified in the documentation.&lt;br /&gt;
* JSON string can be prepared using either raw NSString or serialized NSDictionary.&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
JSONObject contentMetadata = new JSONObject()&lt;br /&gt;
//SDK Metadata&lt;br /&gt;
    .put(&amp;quot;type&amp;quot;, &amp;quot;content&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;assetid&amp;quot;, &amp;quot;vid345-67483&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;program&amp;quot;, &amp;quot;The Big Bang Theory&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;title&amp;quot;, &amp;quot;The Pants Alternative S03E18&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;crossId1&amp;quot;, &amp;quot;EP009311820061&amp;quot;)  //optional  &lt;br /&gt;
    .put(&amp;quot;crossId2&amp;quot;, &amp;quot;Content Originator&amp;quot;)  //optional  &lt;br /&gt;
    .put(&amp;quot;length&amp;quot;, &amp;quot;3600&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;isfullepisode&amp;quot;, &amp;quot;yes&amp;quot;) &lt;br /&gt;
    .put(&amp;quot;airdate&amp;quot;, &amp;quot;2022-03-21T10:05:00&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;adloadtype&amp;quot;, &amp;quot;2&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;segB&amp;quot;, &amp;quot;CustomSegmentValueB&amp;quot;) //optional&lt;br /&gt;
    .put(&amp;quot;segC&amp;quot;, &amp;quot;CustomSegmentValueC&amp;quot;) //optional&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Content metadata ===&lt;br /&gt;
Content metadata should remain constant throughout the entirety of an episode/clip including when ads play.&lt;br /&gt;
{{DCR Content Metadata}}&lt;br /&gt;
&lt;br /&gt;
=== Ad Metadata ===&lt;br /&gt;
The Ad Metadata (if applicable) should be passed for each individual ad.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys	!! Description	!! Values	!! Required&lt;br /&gt;
|-&lt;br /&gt;
| type 	|| type of Ad	||  &amp;lt;code&amp;gt;'preroll'&amp;lt;/code&amp;gt;,  &amp;lt;code&amp;gt;'midroll'&amp;lt;/code&amp;gt;,  &amp;lt;code&amp;gt;'postroll'&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; &amp;lt;code&amp;gt;'ad'&amp;lt;/code&amp;gt;  - If specific type can not be identified.||	✓&lt;br /&gt;
|-&lt;br /&gt;
| assetid ||	unique ID assigned to Ad	|| custom &amp;lt;br&amp;gt;(no [[Special Characters]])	|| ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Example Ad Object ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// create ad object&lt;br /&gt;
&amp;quot;ad&amp;quot;: {&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;preroll&amp;quot;,&lt;br /&gt;
  &amp;quot;assetid&amp;quot;: &amp;quot;AD-ID123&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sequence of Calls ==&lt;br /&gt;
=== play ===&lt;br /&gt;
Use [[DCR_Video_APP_SDK#play|play]] to pass the channel descriptor information through channelName parameter when the user taps the '''Play''' button on the player.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;    public void play(JSONObject channelInfo);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== loadMetadata ===&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;public void loadMetadata(JSONObject contentMetadata);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== playheadPosition ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public void setPlayheadPosition(long position)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== stop ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;public void stop()&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== end ===&lt;br /&gt;
When content stop is initiated and content cannot be resumed from the same position (it can only be restarted from the beginning of stream).&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;public void end()&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Configure API Calls ==&lt;br /&gt;
&lt;br /&gt;
=== Sample API Sequence ===&lt;br /&gt;
A Sample API sequence could follow this flow:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type !! Sample code !! Description&lt;br /&gt;
|-&lt;br /&gt;
|On App Start||&amp;lt;code&amp;gt;[nielsenMeter loadMetadata: contentMetadata];&amp;lt;/code&amp;gt; || // contentMetadata Object contains the JSON metadata for the impression&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Start of stream || &amp;lt;code&amp;gt;[nielsenMeter play];&amp;lt;/code&amp;gt; || // call at start of each new stream&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;[nielsenMeter loadMetadata: contentMetadataObject];&amp;lt;/code&amp;gt; || // contentMetadataObject contains the JSON metadata for the content being played&lt;br /&gt;
|-&lt;br /&gt;
| Content || &amp;lt;code&amp;gt;[nielsenMeter setplayheadPosition: position];&amp;lt;/code&amp;gt; || // playheadPosition is position of the playhead while the content is being played&lt;br /&gt;
|-&lt;br /&gt;
| End of Stream || &amp;lt;code&amp;gt;[nielsenMeter end];&amp;lt;/code&amp;gt; || // Content playback is completed.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== SDK Events ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Event !!	Parameter	!! Description&lt;br /&gt;
|-&lt;br /&gt;
| 'play'	|| 	|| Call at start of each new stream&lt;br /&gt;
|-&lt;br /&gt;
| 'loadMetadata'	|| content/ad metadata object	|| Needs to be called at the beginning of each asset&lt;br /&gt;
|-&lt;br /&gt;
| 'setPlayheadPosition'	|| playhead position as integer&amp;lt;br/&amp;gt;&lt;br /&gt;
VOD: || current position in seconds &amp;lt;br/&amp;gt;&lt;br /&gt;
Live: current Unix timestamp (seconds since Jan-1-1970 UTC) &amp;lt;br/&amp;gt;&lt;br /&gt;
Note: 'setPlayheadPosition' has to be called every second&lt;br /&gt;
||&lt;br /&gt;
Pass playhead position every second during playback&lt;br /&gt;
|-&lt;br /&gt;
| 'stop' ||	playhead position	|| Call during any interruption to content or Ad playback and at the end of each Ad.&lt;br /&gt;
|-&lt;br /&gt;
| 'end'	|| playhead position in seconds	|| Call when the current video asset completes playback and pass the playhead position. &amp;lt;br/&amp;gt;&lt;br /&gt;
Example: At the end of the content stream, if the user switches to another piece of content, when the browser is refreshed or closed.&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Note: For livestream, send the Unix timestamp; for VOD send the time in seconds as integer. The final playhead position must be sent for the current asset being played before calling &amp;lt;code&amp;gt;'''stop'''&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;'''end'''&amp;lt;/code&amp;gt; or&amp;lt;code&amp;gt; '''loadmetadata'''&amp;lt;/code&amp;gt;,.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Life cycle of SDK instance ===&lt;br /&gt;
Life cycle of SDK instance includes four general states:&lt;br /&gt;
# '''Initial state''' – The SDK is not initialized and hence, not ready to process playing information. Once the SDK is moved out of this state, it needs instantiation of the new SDK instance in order to get the instance in the '''Initial state'''.&lt;br /&gt;
# '''Idle state''' – The SDK is initialized and is ready to process playing information. Once Initialized, the SDK instance is not processing any data, but is listening for the play event to occur.&lt;br /&gt;
# '''Processing state''' – The SDK instance is processing playing information. The &amp;lt;code&amp;gt;'''play'''&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;'''loadMetadata''' &amp;lt;/code&amp;gt; calls move the SDK instance into this state. In this state, the SDK instance will be able to process the following calls.&lt;br /&gt;
## &amp;lt;code&amp;gt;'''setplayheadPosition'''&amp;lt;/code&amp;gt; – Call this API every one second when playhead position timer is fired.  If a LIVE event, use the current Unix timestamp (seconds since Jan-1-1970 UTC).&lt;br /&gt;
## &amp;lt;code&amp;gt;'''stop'''&amp;lt;/code&amp;gt; – Call this API when the playback is paused, switches between content and ad (within the same content playback) or encounters interruptions.&lt;br /&gt;
## &amp;lt;code&amp;gt;'''end'''&amp;lt;/code&amp;gt; – Call when content completes. When called, the SDK instance exits from Processing state.&lt;br /&gt;
# '''Disabled state''' – The SDK instance is disabled and is not processing playing information. SDK instance moves into this state in one of the following scenarios.&lt;br /&gt;
## Initialization fails&lt;br /&gt;
## &amp;lt;code&amp;gt;'''appDisableApi'''&amp;lt;/code&amp;gt; is set to &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note:''' For API Version 5.1 and above, App SDK will fire data pings and continue measurement even after the user has opted out from Nielsen measurement on a device. The data ping will be marked as opted-out ping.&lt;br /&gt;
&lt;br /&gt;
'''Note''': In case of any interruptions during playback due to alarm, calendar, call, flight mode, Wi-Fi toggle, channel change, etc., call [[stop]] to stop the measurement.&lt;br /&gt;
* As soon as the playback resumes, &amp;lt;code&amp;gt;'''loadMetadata''' &amp;lt;/code&amp;gt; and   &amp;lt;code&amp;gt;'''playheadPosition'''&amp;lt;/code&amp;gt; &amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== API Call Sequence ===&lt;br /&gt;
==== Use Case 1: Content has no Advertisements ====&lt;br /&gt;
Call [[play()]] at start of stream&lt;br /&gt;
&lt;br /&gt;
Call [[loadMetadata()]] with JSON metadata for content as below.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;{&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;,&lt;br /&gt;
  &amp;quot;assetid&amp;quot;: &amp;quot;vid345-67483&amp;quot;,&lt;br /&gt;
  &amp;quot;program&amp;quot;: &amp;quot;ProgramName&amp;quot;,&lt;br /&gt;
  &amp;quot;title&amp;quot;: &amp;quot;Program S3, EP1&amp;quot;,&lt;br /&gt;
  &amp;quot;length&amp;quot;: &amp;quot;3600&amp;quot;,&lt;br /&gt;
  ...&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Call [[setPlayheadPosition()]] every one second until a pause / stop.&lt;br /&gt;
Use the sample API sequence below as a reference to identify the specific events that need to be called during content playback without ads.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type !! Sample code !! Description&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Start of stream || &amp;lt;code&amp;gt;mAppSdk.play(); &amp;lt;/code&amp;gt; || // Call at start of each new stream&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.loadMetadata(contentMetaDataObject);&amp;lt;/code&amp;gt; || // contentMetadataObject contains the JSON metadata for the content being played&lt;br /&gt;
|-&lt;br /&gt;
| Content || &amp;lt;code&amp;gt;mAppSdk.setPlayheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // position is position of the playhead while the content is being played&lt;br /&gt;
|-&lt;br /&gt;
| Interruption || &amp;lt;code&amp;gt;mAppSdk.stop();&amp;lt;/code&amp;gt; || // call stop when content playback is interrupted&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Resume Content || &amp;lt;code&amp;gt;mAppSdk.loadMetadata(contentMetaDataObject);&amp;lt;/code&amp;gt;  || // Call loadMetadata and pass content metadata object when content resumes&lt;br /&gt;
|- &lt;br /&gt;
|&amp;lt;code&amp;gt;mAppSdk.setPlayheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // continue pasing playhead position every second starting from position where content is resumed&lt;br /&gt;
|- &lt;br /&gt;
| End of Stream || &amp;lt;code&amp;gt;mAppSdk.end();&amp;lt;/code&amp;gt; || // Content playback is completed.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Use Case 2: Content has Advertisements ====&lt;br /&gt;
Call [[play()]] &lt;br /&gt;
&lt;br /&gt;
Call [[loadMetadata()]] with JSON metadata for ad as below.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;{&lt;br /&gt;
   &amp;quot;type&amp;quot;: &amp;quot;preroll&amp;quot;,&lt;br /&gt;
   &amp;quot;assetid&amp;quot;: &amp;quot;ad-123&amp;quot;&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Note: In case the individual ad details are not available, send ad pod (presence) details through the [[loadMetadata]] and playhead position through [[playheadPosition]].&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Call [[setPlayheadPosition()]] every one second until a pause / stop / another [[loadMetadata()]] is called. Playhead should be passed for the entire duration of ad pod, if the ad pod details are passed as part of [[loadMetadata()]].&lt;br /&gt;
&lt;br /&gt;
'''Ad Content'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;    long pos = mAdPlayer.videoPosition() / 1000;&lt;br /&gt;
   if (mAppSdk != null)&lt;br /&gt;
   {&lt;br /&gt;
     mAppSdk.setPlayheadPosition(pos);&lt;br /&gt;
   }&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Note: The playhead positions for ad and content should be maintained separately.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The sample API sequence can be used as a reference to identify the specific events that need to be called during content and ad playback.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type !! Sample code !! Description&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Start of stream || &amp;lt;code&amp;gt;mAppSdk.play(); &amp;lt;/code&amp;gt; || // stream starts&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.loadMetadata(contentMetaDataObject);&amp;lt;/code&amp;gt; || // contentMetadataObject contains the JSON metadata for the content being played&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | Preroll || &amp;lt;code&amp;gt;mAppSdk.loadMetadata(prerollMetadataObject);&amp;lt;/code&amp;gt; || // prerollMetadataObject contains the JSON metadata for the preroll ad&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.setPlayheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // position is position of the playhead while the preroll ad is being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.stop();&amp;lt;/code&amp;gt; || // Call stop after preroll occurs&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Content || &amp;lt;code&amp;gt;mAppSdk.loadMetadata(contentMetaDataObject);&amp;lt;/code&amp;gt; || // contentMetadataObject contains the JSON metadata for the content being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.setPlayheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // position is position of the playhead while the content is being played&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | Midroll || &amp;lt;code&amp;gt;mAppSdk.loadMetadata(midrollMetaDataObject);&amp;lt;/code&amp;gt; || // midrollMetadataObject contains the JSON metadata for the midroll ad&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.setPlayheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // position is position of the playhead while the midroll ad is being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.stop();&amp;lt;/code&amp;gt; || // Call stop after midroll occurs&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Content Resumes || &amp;lt;code&amp;gt;mAppSdk.loadMetadata(contentMetaDataObject);&amp;lt;/code&amp;gt; || // contentMetadataObject contains the JSON metadata for the content being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.setPlayheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // position is position of the playhead while the content is being played&lt;br /&gt;
|-&lt;br /&gt;
|  rowspan=&amp;quot;1&amp;quot; | End of Stream || &amp;lt;code&amp;gt;mAppSdk.end();&amp;lt;/code&amp;gt; || // Call end() at the end of content&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | Postroll || &amp;lt;code&amp;gt;mAppSdk.loadMetadata(postrollMetaDataObject);&amp;lt;/code&amp;gt; || // postrollMetadataObject contains the JSON metadata for the postroll ad&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.setPlayheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // position is position of the playhead while the postroll ad is being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.stop();&amp;lt;/code&amp;gt; || // Call stop after postroll occurs&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Note: Each Ad playhead should reset or begin from 0 at ad start. When content has resumed following an ad break, playhead position must continue from where previous content segment was left off.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Handling Foreground and Background states ==&lt;br /&gt;
There are a few approaches to managing the Foreground and Background states of an app available to use for state measurement.&lt;br /&gt;
* Utilizing the Androidx LifeCycleObserver (The recommended approach starting sdk version 7.1.0.0+)&lt;br /&gt;
* Utilizing the [[DCR_Video_Android_SDK#The_SdkBgFgDetectionUtility_class|SdkBgFgDetectionUtility]] class&lt;br /&gt;
* Adding a tag to the Manifest XML&lt;br /&gt;
* Manual Management&lt;br /&gt;
=== The LifeCycleObserver ===&lt;br /&gt;
AndroidX replaces the original support library APIs with packages in the androidx namespace, and Android Studio 3.2 and higher provides an automated migration tool. (Select '''Refactor&amp;gt; Migrate to AndroidX''' from the menu bar.)&lt;br /&gt;
&lt;br /&gt;
Starting with version 7.1.0, with AndroidX support, an additional utility is provided in the AppSDK - application background/foreground state detection by the AppSdk leveraging the Android Architecture component &amp;quot;LifeCycleObserver&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The AppSdk is now capable of detecting the application UI visibility state transitions between background and foreground, without forcing the applications to register for AppSdk's AppSdkApplication class, which is responsible for handling the detection of application background/foreground state transitions at present.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Please note, that if you already have an app designed that utilizes the depreciated SdkBgFgDetectionUtility Class, the AppSDK will ignore any calls to these methods if it can utilize the LifeCycleObserver.  LifeCycleObserver based auto detection will take precedence. &amp;lt;/blockquote&amp;gt;&lt;br /&gt;
==== Adding the AndroidX dependency ====&lt;br /&gt;
In order to make use of the app background/foreground state transition auto detection feature of AndroidX AppSdk, the app gradle file needs the androidx dependency. The AppSdk API calls - &amp;lt;code&amp;gt;appInForeground()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;appInBackground()&amp;lt;/code&amp;gt;  will still be respected by AppSdk by executing the old AppSdk flow of handling &amp;quot;app in foreground&amp;quot; and &amp;quot;app in background&amp;quot; states as is.&lt;br /&gt;
&lt;br /&gt;
==== Using the LifeCycle Extension ====&lt;br /&gt;
The following androidx dependency is required in the app gradle file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
implementation &amp;quot;androidx.lifecycle:lifecycle-extensions:2.1.0&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
If you would like to take advantage of this auto detection feature of AppSdk at the very initial stage (e.g. splash screen or at of app launch time), before the AppSdk is initialized, can do so by calling the following newly introduced AppSdk public api, passing the application context :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public static void registerLifeCycleObserver(Context applicationContext)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Log messages for the new auto detection ====&lt;br /&gt;
&lt;br /&gt;
When the AppSdk app successfully registers for the LifeCycleObserver : &amp;lt;code&amp;gt;Registered LifeCycleObserver for App Background/Foreground auto-detection&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* When the app enters the foreground state :&amp;lt;code&amp;gt;App is in foreground, auto detected by AppSDK&amp;lt;/code&amp;gt;&lt;br /&gt;
* When the app enters the background state :&amp;lt;code&amp;gt;App is in background, auto detected by AppSDK&amp;lt;/code&amp;gt;&lt;br /&gt;
* If the client app doesn't have the &amp;quot;androidx&amp;quot; gradle dependency and AppSdk fails to register LifeCycleObserver :&amp;lt;code&amp;gt;AndroidX LifecycleObserver can not be observed. Please use androidx dependency to activate SDK auto-detection of app background/foreground state.&amp;lt;/code&amp;gt;&lt;br /&gt;
* When the appInForeground() is explicitly called while LifeCycleObserver auto detection is active :&amp;lt;code&amp;gt;Ignoring the appInBackground() call, as the App Background/Foreground auto-detection is active. The current state is - foreground&amp;lt;/code&amp;gt;&lt;br /&gt;
* When the appInBackground() is explicitly called while LifeCycleObserver auto detection is active :&amp;lt;code&amp;gt;Ignoring the appInBackground() call, as the App Background/Foreground auto-detection is active. The current state is - background&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The SdkBgFgDetectionUtility class ===&lt;br /&gt;
Foreground/Background state measurement is a requirement of Nielsen AppSDK implementation which is especially crucial for static measurement. It may be implemented in multiple ways for Android. This includes&lt;br /&gt;
* Enable the Nielsen SDK to measure background/foreground state by makingthe relevant update to the AndroidManifest.&lt;br /&gt;
* Integrate Nielsen’s SdkBgFgDetectionUtility class within your Custom Application Class.&lt;br /&gt;
* Custom implementation of the required methods within your application.&lt;br /&gt;
&lt;br /&gt;
==== ForeGround/Background Measurement via AndroidManifest ====&lt;br /&gt;
The simplest way to measure the app background/foreground state is to add the following application tag to the Manifest XML. Integrating this into the Manifest XML will enable the SDK to measure app state directly. This approach is supported for Android 4.0 and up only; it requires that the application class is not in use for some other purpose.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;application android:name=&amp;quot;com.nielsen.app.sdk.AppSdkApplication&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using the Android SdkBgFbDetectionUtility Class ====&lt;br /&gt;
For developers who are already using the application class, it is recommended that background/foreground state is implemented using the  [https://engineeringportal.nielsen.com/docs/Android_Background_Foreground SdkBgFgDetectionUtility class].  The  [https://engineeringportal.nielsen.com/docs/Android_Background_Foreground SdkBgFgDetectionUtility class] is compatible with Android 4+ and has been made available to Nielsen clients. (You will need to copy/paste the code provided into a file).&lt;br /&gt;
&lt;br /&gt;
==== Manual Background/ForeGround State Management ====&lt;br /&gt;
In cases where the developer is not able to use the AndroidManifest.xml solution nor the Nielsen provided   [https://engineeringportal.nielsen.com/docs/Android_Background_Foreground SdkBgFgDetectionUtility class] the developer will need to manually identify the change of state through the application and call the respective API (appInForeground() or appInBackground()) to inform the SDK regarding the change of state from background to foreground or foreground to background.&lt;br /&gt;
&lt;br /&gt;
The SDK is informed about app state using the below methods.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
AppLaunchMeasurementManager.appInForeground(getApplicationContext());&lt;br /&gt;
AppLaunchMeasurementManager.appInBackground(getApplicationContext());&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Within the lifecycle of individual activities, onResume() and onPause() are best suited to providing indication of the app state.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Correct measurement of the foreground/background state is crucial to Static App measurement within Nielsen Digital Content Ratings (DCR).&lt;br /&gt;
== Using the NielsenAppSDKJSHandler ==&lt;br /&gt;
There could be a scenario in which a browser page, that is already tagged with the Nielsen BSDK, needs to be loaded via a webview.  In this situation it is recommended to use the '''NielsenAppSDKJSHandler''' which will allow communication between the AppSDK and the BSDK. &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''This feature is supported in versions 7.2 and above.'''&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Implementation ===&lt;br /&gt;
* Make sure you have the latest AppSdk.jar from Nielsen&lt;br /&gt;
* Enable the javascript on webview using below lines&lt;br /&gt;
&amp;lt;br&amp;gt; &lt;br /&gt;
 &amp;lt;syntaxhighlight lang=java&amp;gt;&lt;br /&gt;
WebSettings webSetting = webView.getSettings();&lt;br /&gt;
webSetting.setJavaScriptEnabled(true);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
* Add  NielsenAppSDKJSHandler instance as javascript interface to webview with name “NielsenAppSDK” like below snippet&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=java&amp;gt;&lt;br /&gt;
webView.addJavascriptInterface(new NielsenAppSDKJSHandler(getApplicationContext()), &amp;quot;NielsenAppSDK&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
This will enable listening to BSDK api calls within the APPSDK.  Please make sure your Technical Account Manager is aware that you wish to implement this method so a configuration file can be modified on the Nielsen servers; however, there are '''no changes required to the Browser page'''.&lt;br /&gt;
&lt;br /&gt;
==== Example:====&lt;br /&gt;
The below is an example of opening a webview with the NielsenAppSDKJSHandler&lt;br /&gt;
&amp;lt;syntaxhighlight lang=java&amp;gt;&lt;br /&gt;
      WebSettings webSetting = webView.getSettings();&lt;br /&gt;
      webView.getSettings().setDomStorageEnabled(true); &lt;br /&gt;
      webSetting.setJavaScriptEnabled(true);&lt;br /&gt;
      webView.addJavascriptInterface(new NielsenAppSDKJSHandler(getApplicationContext(), &amp;quot;&amp;quot;), &amp;quot;NielsenAppSDK&amp;quot;);&lt;br /&gt;
      String url = &amp;quot;https://nielsen.com.index.htm&amp;quot;;&lt;br /&gt;
      webView.loadUrl(url);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;AndroidManifest.xml&amp;lt;/code&amp;gt; may need the following permissions set:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=java&amp;gt;&lt;br /&gt;
    &amp;lt;uses-permission android:name=&amp;quot;android.permission.INTERNET&amp;quot;/&amp;gt;&lt;br /&gt;
    &amp;lt;uses-permission android:name=&amp;quot;android.permission.ACCESS_NETWORK_STATE&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Closing NielsenAppSDKJSHandler ===&lt;br /&gt;
NielsenAppSDKJSHandler should be closed or cleaned up in below scenarios&lt;br /&gt;
* Before WebView is getting destructed&lt;br /&gt;
* Before loading new page&lt;br /&gt;
* Before closing application&lt;br /&gt;
NielsenAppSDKJSHandler provides a public interface with name &amp;quot;close()&amp;quot; and this function should be called on NielsenAppSDKJSHandler's instance in all above scenarios.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=java&amp;gt;&lt;br /&gt;
// get your webview&lt;br /&gt;
WebView webView = findViewById(R.id.webView);&lt;br /&gt;
 &lt;br /&gt;
//Added JS Handler instance as java script interface for ggpm api type&lt;br /&gt;
NielsenAppSDKJSHandler jshandler = new NielsenAppSDKJSHandler(getApplicationContext(), &amp;quot;&amp;quot;);&lt;br /&gt;
webView.addJavascriptInterface(jshandler, &amp;quot;NielsenAppSDK&amp;quot;);&lt;br /&gt;
 &lt;br /&gt;
//Close JS Handler before making webview as null&lt;br /&gt;
jshandler.close();&lt;br /&gt;
webView = null;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Interruptions during playback ==&lt;br /&gt;
As part of integrating Nielsen App SDK with the player application, the Video app developer needs to handle the following possible interruption scenarios:&lt;br /&gt;
* Pause / Play&lt;br /&gt;
* Network Loss (Wi-Fi / Airplane / Cellular)&lt;br /&gt;
* Call Interrupt (SIM or Third party Skype / Hangout call)&lt;br /&gt;
* Alarm Interrupt&lt;br /&gt;
* Content Buffering&lt;br /&gt;
* Device Lock / Unlock &lt;br /&gt;
* App going in the Background/Foreground&lt;br /&gt;
* Channel / Station Change Scenario&lt;br /&gt;
* Unplugging of headphone&lt;br /&gt;
In case of encountering one of the above interruptions, the player application needs to&lt;br /&gt;
* Call [[stop]] immediately (except when content is buffering) and withhold sending playhead position.&lt;br /&gt;
* Start sending pings – &amp;lt;code&amp;gt;'loadMetadata'&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;'playheadPosition'&amp;lt;/code&amp;gt; to resume the viewing session, once the playback resumes.&lt;br /&gt;
Please see the [https://engineeringportal.nielsen.com/docs/Digital_Measurement_Interruption_Scenarios Interruption Scenarios Page] for more details&lt;br /&gt;
&lt;br /&gt;
== Pre-Certification Checklists ==&lt;br /&gt;
After the application is ready to be sent for Nielsen Certification, please go through the [[Digital Pre-Certification Checklist App SDK]] and ensure the app behaves as expected, before submitting to Nielsen.&lt;br /&gt;
&lt;br /&gt;
{{Template:Android_Privacy_and_Opt-Out}}&lt;br /&gt;
== Required Privacy Links ==&lt;br /&gt;
Users must either have access to the &amp;quot;About Nielsen Measurement&amp;quot; page, or have similar text available within the native app. Include &amp;quot;About Nielsen Measurement&amp;quot; and &amp;quot;Your Choices&amp;quot; link in the Privacy Policy / EULA or as a button near the link to the app's Privacy Policy.&lt;br /&gt;
&lt;br /&gt;
== Sample Applications ==&lt;br /&gt;
The below sample applications have been designed to show the API's functionality and are broken into two distinct categories:&lt;br /&gt;
* '''Basic''' - To show the functionality of the Nielsen  API using a standard no-frills player.&lt;br /&gt;
** [[Android Basic example|Android Studio Example]]&lt;br /&gt;
&lt;br /&gt;
* '''Advanced''' - Nielsen API integrated into a custom video player is bundled with the SDK.&lt;/div&gt;</summary>
		<author><name>AnkitAgrawal</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=demographicId&amp;diff=7258</id>
		<title>demographicId</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=demographicId&amp;diff=7258"/>
		<updated>2025-04-04T11:22:04Z</updated>

		<summary type="html">&lt;p&gt;AnkitAgrawal: v10.0.0.0 Changes&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|iOS SDK API Reference}}  {{CurrentBreadcrumb}}&lt;br /&gt;
&lt;br /&gt;
Retrieves SDK generated UAID(v10.0.0.0+) or Demographic ID (Device ID) of the current device for legacy versions.&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
[[Category:iOS SDK API Reference]]&lt;br /&gt;
== Syntax ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
@property (readonly) NSString *demographicId;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Input Parameters ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
| None ||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Output Parameters ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Output Parameters (Return value) !! Description&lt;br /&gt;
|-&lt;br /&gt;
| demographicId || Returns a NSString object containing SDK generated UAID(v10.0.0.0+) or Demographic ID (Device ID) of the current device for legacy versions&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>AnkitAgrawal</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=iOS_SDK_API_Reference&amp;diff=7257</id>
		<title>iOS SDK API Reference</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=iOS_SDK_API_Reference&amp;diff=7257"/>
		<updated>2025-04-04T11:20:57Z</updated>

		<summary type="html">&lt;p&gt;AnkitAgrawal: v10.0.0.0 Changes&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
== Overview ==&lt;br /&gt;
The Nielsen SDK is one of multiple framework SDKs that Nielsen provides to enable measuring linear (live) and on-demand TV viewing using TVs, mobile devices, etc.&lt;br /&gt;
The App SDK is the framework for mobile application developers to integrate Nielsen Measurement into their media player applications. It supports a variety of Nielsen Measurement Products like Digital in TV Ratings, Digital Content Ratings ([[DCR &amp;amp; DTVR]]), and [[Digital Ad Ratings]] (DAR). Nielsen SDKs are also equipped to measure static content and can track key life cycle events of an application like:&lt;br /&gt;
*Application launch events and how long app was running&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
To start using the App SDK, the following items are required:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 30px;&amp;quot; |&lt;br /&gt;
! style=&amp;quot;width: 15%;&amp;quot; | Item&lt;br /&gt;
! Description&lt;br /&gt;
! Source&lt;br /&gt;
|-&lt;br /&gt;
|| ☑ || '''App ID (appid)''' || Unique ID assigned to the player/site and configured by product. || Contact Nielsen&lt;br /&gt;
|-&lt;br /&gt;
|| ☑ || '''sfcode''' || Environment that the SDK must point to || Contact Nielsen&lt;br /&gt;
|-&lt;br /&gt;
|| ☑ || '''Nielsen SDK''' || Includes SDK frameworks and '''sample implementation'''; ''See [[iOS SDK Release Notes]]'' || [[Special:Downloads|Download]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
If you do not have any of these pre-requisites or if you have any questions, please contact our SDK sales support team.&lt;br /&gt;
Refer to [[Digital Measurement Onboarding]] guide for information on how to get a Nielsen App SDK and appid.&lt;br /&gt;
==SDK Implementation==&lt;br /&gt;
Information on how to obtain, how to configure your development environment, and how to Initialize the Nielsen SDK is located in either the [[DCR Video iOS SDK|DCR Implementation Guide,]] or the [[DTVR iOS SDK|DTVR Implementation Guide]] depending on your requirements.&lt;br /&gt;
___TOC___&lt;br /&gt;
&lt;br /&gt;
== Nielsen iOS App SDK Application Life Cycle ==&lt;br /&gt;
&lt;br /&gt;
[[File:initialization_appcycle.png|center|link=]]&lt;br /&gt;
&lt;br /&gt;
Life cycle of SDK instance includes four general states:&lt;br /&gt;
# '''Initial state''' – The SDK is not initialized and hence, not ready to process playing information. Once the SDK is moved out of this state, it needs instantiation of the new SDK instance in order to get the instance in the '''Idle state'''.&lt;br /&gt;
# '''Idle state''' – The SDK is initialized and is ready to process playing information. Once Initialized, the SDK instance is not processing any data, but is listening for an event to occur.&lt;br /&gt;
# '''Processing state''' – The SDK instance is processing playing information. The &amp;lt;code&amp;gt;'''play'''&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;'''loadMetadata''' &amp;lt;/code&amp;gt; calls move the SDK instance into this state. In this state, the SDK instance will be able to process the following calls.&lt;br /&gt;
## &amp;lt;code&amp;gt;'''playheadPosition'''&amp;lt;/code&amp;gt; – Call this API every one second when playhead position is active.  If a LIVE event, use the current UNIX timestamp (seconds since Jan-1-1970 UTC).&lt;br /&gt;
## &amp;lt;code&amp;gt;'''stop'''&amp;lt;/code&amp;gt; – Call this API when the playback is paused, switches between content and ad (within the same content playback) or encounters interruptions.&lt;br /&gt;
## &amp;lt;code&amp;gt;'''end'''&amp;lt;/code&amp;gt; – SDK instance exits from Processing state when this API is called.&lt;br /&gt;
# '''Disabled state''' – The SDK instance is disabled and is not processing playing information. &lt;br /&gt;
## &amp;lt;code&amp;gt;'''appDisableApi'''&amp;lt;/code&amp;gt; is set to &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note:''' For API Version 5.1 and above, App SDK will fire data pings and continue measurement even after the user has opted out from Nielsen measurement on a device. The data ping will be marked as opted-out ping.&lt;br /&gt;
&lt;br /&gt;
'''Note''': In case of any interruptions during playback due to alarm, calendar, call, flight mode, Wi-Fi toggle, channel change, etc., call [[stop]] to stop the measurement.&lt;br /&gt;
* As soon as the playback resumes, call &amp;lt;code&amp;gt;'''play'''&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;'''loadMetadata''' &amp;lt;/code&amp;gt; and   &amp;lt;code&amp;gt;'''playheadPosition'''&amp;lt;/code&amp;gt; &amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:appsdkTimeline-DCR.png|icon|link=]]&lt;br /&gt;
=== Finite-state machine table ===&lt;br /&gt;
This table provides the possible changes of state for the SDK instance, when it is in a specific state and receives an API call.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! API call received !! Initial State !! Idle State !! Processing State !! Disabled State&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;[[initWithAppInfo:delegate:]]&amp;lt;/code&amp;gt; || IDLE STATE (OR)&lt;br /&gt;
&lt;br /&gt;
DISABLED STATE&lt;br /&gt;
|| IDLE STATE || - || -&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;[[play]]&amp;lt;/code&amp;gt; &amp;amp; &amp;lt;code&amp;gt;[[loadMetadata]]&amp;lt;/code&amp;gt;|| - || PROCESSING&lt;br /&gt;
&lt;br /&gt;
STATE&lt;br /&gt;
|| - || -&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;[[playheadPosition]]&amp;lt;/code&amp;gt; || - || - || PROCESSING&lt;br /&gt;
&lt;br /&gt;
STATE&lt;br /&gt;
|| -&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;[[sendID3]]&amp;lt;/code&amp;gt; || - || - || PROCESSING&lt;br /&gt;
&lt;br /&gt;
STATE&lt;br /&gt;
|| -&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;[[stop]]&amp;lt;/code&amp;gt; || - || - || IDLE STATE || -&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;[[end]]&amp;lt;/code&amp;gt; || - || - || IDLE STATE || -&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;[[appDisableApi]]&amp;lt;/code&amp;gt;: YES || - || DISABLED&lt;br /&gt;
&lt;br /&gt;
STATE&lt;br /&gt;
|| - || -&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;[[appDisableApi]]&amp;lt;/code&amp;gt;: NO || - || - || - || IDLE STATE (OR)&lt;br /&gt;
&lt;br /&gt;
DISABLED STATE&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;[[userOptOut]]&amp;lt;/code&amp;gt;: YES || - || - || IDLE STATE || -&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;[[userOptOut]]&amp;lt;/code&amp;gt;: NO || - || PROCESSING&lt;br /&gt;
&lt;br /&gt;
STATE&lt;br /&gt;
| - &lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
| colspan = 5 | '-' indicates that no API call is expected.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Handling JSON Metadata ===&lt;br /&gt;
All the SDK methods handles only two types of objects: NSString, NSDictionary. The parameters passed must be either a JSON formatted string or a NSDictionary object. The JSON passed in the SDK must be well-formed.&lt;br /&gt;
* NSDictionary object&lt;br /&gt;
** If an object of unexpected type is passed to the method, the error message will be logged.&lt;br /&gt;
** If string has invalid JSON format, the error message will be logged.&lt;br /&gt;
* JSON value must be string value.&lt;br /&gt;
** This includes boolean and numeric values. For example, a value of true should be represented with &amp;quot;true&amp;quot;, number value 123 should be &amp;quot;123&amp;quot;.&lt;br /&gt;
** All the Variable Names like appid, appname, sfcode, dataSrc, title, type etc. are case-sensitive. Use the correct variable name as specified in the documentation.&lt;br /&gt;
* JSON string can be prepared using either raw NSString or serialized NSDictionary.&lt;br /&gt;
The below is a sample - detailed information on the '''metadata requirements''' are located in either the [[DCR Video iOS SDK|DCR Implementation Guide,]] or the [[DTVR iOS SDK|DTVR Implementation Guide]] &lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Swift = &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
let contentMetadata = [&lt;br /&gt;
    &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;,&lt;br /&gt;
    &amp;quot;assetid&amp;quot;: &amp;quot;C77664&amp;quot;,&lt;br /&gt;
    &amp;quot;title&amp;quot;: &amp;quot;Program S2, E3&amp;quot;,&lt;br /&gt;
    &amp;quot;isfullepisode&amp;quot;: &amp;quot;Yes&amp;quot;,&lt;br /&gt;
    &amp;quot;program&amp;quot;: &amp;quot;Program Name&amp;quot;,&lt;br /&gt;
    &amp;quot;length&amp;quot;: &amp;quot;3600&amp;quot;,&lt;br /&gt;
    &amp;quot;airdate&amp;quot;: &amp;quot;20171020 10:05:00&amp;quot;,&lt;br /&gt;
    &amp;quot;adloadtype&amp;quot;: &amp;quot;2&amp;quot;,&lt;br /&gt;
    &amp;quot;segB&amp;quot;: &amp;quot;CustomSegmentValueB&amp;quot;, //optional&lt;br /&gt;
    &amp;quot;segC&amp;quot;: &amp;quot;CustomSegmentValueC&amp;quot;, //optional&lt;br /&gt;
];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;     &lt;br /&gt;
|Objective C = &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt; &lt;br /&gt;
NSDictionary * contentMetadata = @ {&lt;br /&gt;
    @ &amp;quot;type&amp;quot;: @ &amp;quot;content&amp;quot;,&lt;br /&gt;
        @ &amp;quot;assetid&amp;quot;: @ &amp;quot;C77664&amp;quot;,&lt;br /&gt;
        @ &amp;quot;title&amp;quot;: @ &amp;quot;S2,E3&amp;quot;,&lt;br /&gt;
        @ &amp;quot;isfullepisode&amp;quot;: @ &amp;quot;y&amp;quot;,  &lt;br /&gt;
        @ &amp;quot;program&amp;quot;: @ &amp;quot;Program Name&amp;quot;,&lt;br /&gt;
        @ &amp;quot;length&amp;quot;: @ &amp;quot;3600&amp;quot;,&lt;br /&gt;
        @ &amp;quot;airdate&amp;quot;: @ &amp;quot;20180120 10:00:00&amp;quot;,&lt;br /&gt;
        @ &amp;quot;adloadtype&amp;quot;: @ &amp;quot;2&amp;quot;,&lt;br /&gt;
        @ &amp;quot;segB&amp;quot;: @ &amp;quot;CustomSegmentValueB&amp;quot;, //optional&lt;br /&gt;
        @ &amp;quot;segC&amp;quot;: @ &amp;quot;CustomSegmentValueC&amp;quot;, //optional&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Retrieving ID3 Tags ==&lt;br /&gt;
'''Only required for DTVR clients'''&amp;lt;br&amp;gt;&lt;br /&gt;
'''Not applicable for German Clients'''&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ID3 tags have a payload of about 249 characters and start with &amp;quot;www.nielsen.com&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
ID3 tags are extracted by observing a property called timedMetadata on the iOS player item. Now this is done via a concept called KVO (Key Value Observing), where you register interest in a property, and the runtime will let you know when it has changed.&lt;br /&gt;
&lt;br /&gt;
Both the iOS native players have the ability to extract ID3 tags, If any other player apart from iOS native players (AVPlayer, MPMoviePlayer) is used, check and ensure that the player has the capability to extract ID3 tags.&lt;br /&gt;
&lt;br /&gt;
=== Examples of extracting ID3 tags from the iOS Native Player ===&lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Objective C = &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
    //Adding observer to player to track play,pause and reverse&lt;br /&gt;
    [player addObserver:self&lt;br /&gt;
             forKeyPath:@&amp;quot;rate&amp;quot;&lt;br /&gt;
                options:(NSKeyValueObservingOptionNew)&lt;br /&gt;
                context:nil];&lt;br /&gt;
  &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
------------------------------&lt;br /&gt;
  &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;       &lt;br /&gt;
        //Setting observer to track timedMetadata&lt;br /&gt;
        [player addObserver:self&lt;br /&gt;
                 forKeyPath: timedMetadataKey&lt;br /&gt;
                    options: (NSKeyValueObservingOptionNew)&lt;br /&gt;
                    context: &amp;amp;TimedMetadataObserverContext];&lt;br /&gt;
  &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
------------------------------&lt;br /&gt;
  &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;     &lt;br /&gt;
- (void)observeValueForKeyPath:(NSString *)keyPath&lt;br /&gt;
                      ofObject:(id)object&lt;br /&gt;
                        change:(NSDictionary *)change&lt;br /&gt;
                       context:(void *)context&lt;br /&gt;
{&lt;br /&gt;
    if(keyPath == timedMetadataKey){&lt;br /&gt;
        if(context == &amp;amp;TimedMetadataObserverContext){&lt;br /&gt;
            &lt;br /&gt;
            id newMetadataArray = [change objectForKey:NSKeyValueChangeNewKey];&lt;br /&gt;
            if (newMetadataArray != [NSNull null])&lt;br /&gt;
            {&lt;br /&gt;
                array = newMetadataArray;&lt;br /&gt;
                for (AVMetadataItem *metadataItem in array)&lt;br /&gt;
                {&lt;br /&gt;
                    //Handling TimedMetadata&lt;br /&gt;
                    [self handleTimedMetadata: metadataItem];&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
------------------------------&lt;br /&gt;
  &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;     &lt;br /&gt;
- (void)handleTimedMetadata:(AVMetadataItem *)timedMetadata&lt;br /&gt;
{&lt;br /&gt;
    // We expect the content to contain plists encoded as timed metadata&lt;br /&gt;
    // AVPlayer turns these into NSDictionaries&lt;br /&gt;
    &lt;br /&gt;
    id extraAttributeType = [timedMetadata extraAttributes];&lt;br /&gt;
    NSString *extraString = nil;&lt;br /&gt;
    if ([extraAttributeType isKindOfClass:[NSDictionary class]])&lt;br /&gt;
    {&lt;br /&gt;
        extraString = [extraAttributeType valueForKey:@&amp;quot;info&amp;quot;];&lt;br /&gt;
    }&lt;br /&gt;
    else if ([extraAttributeType isKindOfClass:[NSString class]])&lt;br /&gt;
    {&lt;br /&gt;
        extraString = extraAttributeType;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    NSString *key = [NSString stringWithFormat:@&amp;quot;%@&amp;quot;, [timedMetadata key]];&lt;br /&gt;
    &lt;br /&gt;
    //If tag starts with &amp;quot;www.nielsen.com&amp;quot;, then only sending to SDK&lt;br /&gt;
    if ([key isEqualToString:@&amp;quot;PRIV&amp;quot;] &amp;amp;&amp;amp; [extraString rangeOfString:@&amp;quot;www.nielsen.com&amp;quot;].length &amp;gt; 0)&lt;br /&gt;
    {&lt;br /&gt;
        &lt;br /&gt;
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{&lt;br /&gt;
            [nielsenApi sendID3:extraString];&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Swift = &amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt; &lt;br /&gt;
      //Setting observer to track timedMetadata&lt;br /&gt;
            player.addObserver(self, forKeyPath: timedMetadataKey, options: NSKeyValueObservingOptions.new, context: &amp;amp;TimedMetadataObserverContext)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
------------------------------------------------------&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt; &lt;br /&gt;
   override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {&lt;br /&gt;
        &lt;br /&gt;
        if keyPath == timedMetadataKey {&lt;br /&gt;
            if(context == &amp;amp;TimedMetadataObserverContext){&lt;br /&gt;
                if change != nil {&lt;br /&gt;
                    let timedMetadataArray = change![.newKey]&lt;br /&gt;
                    if timedMetadataArray != nil &amp;amp;&amp;amp; (timedMetadataArray! as AnyObject) is Array&amp;lt;Any&amp;gt; {&lt;br /&gt;
                        for item in timedMetadataArray as! [AVMetadataItem]  {&lt;br /&gt;
                            //Handling TimedMetadata&lt;br /&gt;
                            self.handleTimedMetadata(metadataItem: item)&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
------------------------------------------------------&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt; &lt;br /&gt;
 func handleTimedMetadata(metadataItem: AVMetadataItem) {&lt;br /&gt;
        guard let extraAttributeType = metadataItem.extraAttributes else {&lt;br /&gt;
            return&lt;br /&gt;
        }&lt;br /&gt;
        let info : AVMetadataExtraAttributeKey = AVMetadataExtraAttributeKey(rawValue: &amp;quot;info&amp;quot;)&lt;br /&gt;
        let extraString = extraAttributeType[info] as AnyObject&lt;br /&gt;
        let key = metadataItem.key as! String&lt;br /&gt;
        &lt;br /&gt;
        //If tag starts with &amp;quot;www.nielsen.com&amp;quot;, then only sending to SDK&lt;br /&gt;
        if key == &amp;quot;PRIV&amp;quot; &amp;amp;&amp;amp; extraString.range(of: &amp;quot;www.nielsen.com&amp;quot;).length &amp;gt; 0 {&lt;br /&gt;
            &lt;br /&gt;
            DispatchQueue.global(qos: .default).async { () -&amp;gt; Void in&lt;br /&gt;
                self.nielsenApi?.sendID3(extraString as! String)&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note:''' ID3 tags are not applicable for International (Germany)&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== IOS SDK API Methods &amp;amp; Properties ==&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Scenario !! Method / Property !! DTVR !! DAR !! DCR !! International (Germany) !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Initialize || [[initWithAppInfo:delegate:]] || ✔ || ✔ || ✔ || ✔ || Used to create a new instance of the SDK object&lt;br /&gt;
|-&lt;br /&gt;
| Measurement || [[play]] || ✔ || ✔ || ✔ || ✔ || Used when there is an ID3 fed product such as DTVR and the client does not want to send in all the CMS metadata that is sent in loadMetadata. This allows the client to send in at least the required “channel name” value associated to the ID3 feed. If this is not called then the “channel name” value populated will be the default value of “defaultChannelName”.&lt;br /&gt;
|-&lt;br /&gt;
| Measurement || [[loadMetadata]] || ✔ || ✔ || ✔ || ✔ || Used to send ad or content metadata to the SDK in the form of JSON string. Application constructs a JSON hashmap and calls this API.&lt;br /&gt;
|-&lt;br /&gt;
| Measurement || [[sendID3]] || ✔ ||   ||   ||   || Used to send the ID3 metadata.&lt;br /&gt;
|-&lt;br /&gt;
| Measurement || [[playheadPosition]] ||   ||   || ✔ || ✔ || Used to send the playhead position.&lt;br /&gt;
|-&lt;br /&gt;
| Measurement || [[stop]] || ✔ ||   || ✔ || ✔ || Used when playback is paused and when switching between ad and content or content and ad.&lt;br /&gt;
|-&lt;br /&gt;
| Measurement || [[end]] || ✔ || ✔ || ✔ || ✔ || Used when content playback is complete. This is triggered 1) at the end of the content stream, 2) if the user switches to another piece of content&lt;br /&gt;
|-&lt;br /&gt;
| Measurement || [[staticEnd]] ||   ||   || ✔ || ✔ || Used with DCR Static duration in between loadMetadata calls for static content when section name is the same but a new static view event and duration measurement restart is desired &lt;br /&gt;
|-&lt;br /&gt;
| Measurement || [[updateOTT]] ||   ||   ||   || ✔ || Used to notify App SDK that the remote OTT device (like Google ChromeCast, Roku, Amazon FireTV, etc.) is connected / disconnected (change of OTT status).&lt;br /&gt;
|-&lt;br /&gt;
| Opt-out || [[optOutURL]] || ✔ || ✔ || ✔ || ✔ || Used to fetch the Nielsen opt-out web page URL.&lt;br /&gt;
|-&lt;br /&gt;
| Opt-out || [[userOptOut]] || ✔ || ✔ || ✔ || ✔ || Used to supply the response message from opt-out webpage to the SDK.&lt;br /&gt;
|-&lt;br /&gt;
| Opt-out || [[optOutStatus]] || ✔ || ✔ || ✔ || ✔ || Call this API to retrieve the Opt-Out or Opt-In state.&lt;br /&gt;
|-&lt;br /&gt;
| Opt-out&lt;br /&gt;
| [[appDisableApi]]&lt;br /&gt;
(kill switch) &lt;br /&gt;
|| ✔ || ✔ || ✔ || ✔ || Used to disable the SDK.&lt;br /&gt;
|-&lt;br /&gt;
| Viewability&amp;lt;br/&amp;gt;Audibility&lt;br /&gt;
| [[trackViewability]]&lt;br /&gt;
|| ✔ ||   || ✔ || ✔ || Used to start the viewability measurement.&lt;br /&gt;
|-&lt;br /&gt;
| Log || [[lastErrorDict]] || ✔ || ✔ || ✔ || ✔ || Returns SDK error in the form of dictionary if any error has occurred.&lt;br /&gt;
|-&lt;br /&gt;
| Log || [[lastEventDict]] || ✔ || ✔ || ✔ || ✔ || Returns SDK event in the form of dictionary if any event has occurred.&lt;br /&gt;
|-&lt;br /&gt;
| Log || [[meterVersion]] || ✔ || ✔ || ✔ || ✔ || Returns the current SDK version.&lt;br /&gt;
|-&lt;br /&gt;
| Log || [[nielsenId]] || ✔ || ✔ || ✔ || ✔ || Used to get a string defining the Nielsen ID (NUID) number for the device.&lt;br /&gt;
|-&lt;br /&gt;
| Log || [[demographicId]] || ✔ || ✔ || ✔ || ✔ || Used to retrieve SDK generated UAID(v10.0.0.0+) or Demographic ID (Device ID) of the current device for legacy versions.&lt;br /&gt;
|-&lt;br /&gt;
| Log || [[deviceId]] || ✔ || ✔ || ✔ || ✔ || Used to get a Device ID of the current device(Introduced in v10.0.0.0).&lt;br /&gt;
|-&lt;br /&gt;
| Log || [[debug]] || ✔ || ✔ || ✔ || ✔ || Used to enable/disable debug flags. Newly introduced in SDK version 5.0.0 for International (Germany)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== NielsenAppApi Class Description ==&lt;br /&gt;
The NielsenAppApi class is the primary application interface to the Nielsen App SDK. For example, after an instance object of the NielsenAppApi class is created and initialized, it can be used by the calling application to collect HLS timed metadata using the SDK’s [[sendID3]]: method. These are the public methods and properties exposed by the NielsenAppApi class:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
@interface NielsenAppApi: NSObject&lt;br /&gt;
&lt;br /&gt;
  @property (readonly) BOOL optOutStatus;&lt;br /&gt;
  @property (assign) BOOL appDisableApi;&lt;br /&gt;
  @property (assign) BOOL debug;&lt;br /&gt;
  @property (readonly, nonnull) NSString *nielsenId;&lt;br /&gt;
  @property (readonly, nonnull) NSString *demographicId;&lt;br /&gt;
  @property (readonly, nonnull) NSString *deviceId;&lt;br /&gt;
  @property (readonly, nonnull) NSString *firstPartyId;&lt;br /&gt;
  @property (readonly, nonnull) NSString *vendorId;&lt;br /&gt;
  @property (readonly, nonnull) NSString *optOutURL;&lt;br /&gt;
  @property (readonly, nullable) NSString *meterVersion;&lt;br /&gt;
  @property (readonly, nullable) NSDictionary *lastEventDict;&lt;br /&gt;
  @property (readonly, nullable) NSDictionary *lastErrorDict;&lt;br /&gt;
&lt;br /&gt;
  - (nullable instancetype)initWithAppInfo:(nonnull id)appInfo delegate:(nullable id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate&lt;br /&gt;
&lt;br /&gt;
  - (void)play:(nullable id)channelInfo;&lt;br /&gt;
  - (void)loadMetadata:(nullable id)metadata;&lt;br /&gt;
  – (void)stop;&lt;br /&gt;
  – (void)end;&lt;br /&gt;
  - (void)playheadPosition:(long long)playheadPos;&lt;br /&gt;
  - (void)sendID3:(nonnull NSString *)data;&lt;br /&gt;
  - (void)updateOTT:(nonnull id)ottInfo;&lt;br /&gt;
  - (BOOL)userOptOut:(nonnull NSString *)optOut;&lt;br /&gt;
  - (void)trackViewability:(nonnull NSDictionary *)data;&lt;br /&gt;
&lt;br /&gt;
  - (nonnull NSString *)getNielsenId __attribute((deprecated((&amp;quot;nielsenId is not used by the SDK anymore&amp;quot;))));&lt;br /&gt;
  - (nonnull NSString *)optOutURLString __attribute((deprecated((&amp;quot;Please use optOutURL property instead.&amp;quot;))));&lt;br /&gt;
  - (nullable NSString *)getMeterVersion __attribute((deprecated((&amp;quot;Please use meterVersion property instead.&amp;quot;))));&lt;br /&gt;
  - (nullable NSDictionary *)getLastEventDict __attribute((deprecated((&amp;quot;Please use lastEventDict property instead.&amp;quot;))));&lt;br /&gt;
  - (nullable NSDictionary *)getLastErrorDict __attribute((deprecated((&amp;quot;Please use lastErrorDict property instead.&amp;quot;)))); &lt;br /&gt;
&lt;br /&gt;
  @protocol NielsenAppApiDelegate &amp;lt;NSObject&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  @optional&lt;br /&gt;
  - (void)nielsenAppApi:(nonnull NielsenAppApi *)appApi eventOccurred:(nonnull NSDictionary *)event;&lt;br /&gt;
  - (void)nielsenAppApi:(nonnull NielsenAppApi *)appApi errorOccurred:(nonnull NSDictionary *)error;&lt;br /&gt;
&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== AppApiEventCode ===&lt;br /&gt;
An enumeration with predefined App SDK event state transition codes.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
typedef NS_ENUM(unsigned int, AppApiEventCode)&lt;br /&gt;
{&lt;br /&gt;
     AppApiStartup = 2001,&lt;br /&gt;
     AppApiShutdown = 2002,&lt;br /&gt;
}AppApiEventCode;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== App SDK Event Codes ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Event Code !! Event Name !! Event Description&lt;br /&gt;
|-&lt;br /&gt;
| 2001 || AppApiStartup || App SDK has initialized successfully. It will happen only after App SDK has received a valid config file&lt;br /&gt;
|-&lt;br /&gt;
| 2002 || AppApiShutdown || App SDK is shutting down. It will happen just before App SDK is destroyed&lt;br /&gt;
|}&lt;br /&gt;
=== AppApiErrorCode ===&lt;br /&gt;
iOS contains two types of error codes, 1-15 and 1001-1009.&lt;br /&gt;
&lt;br /&gt;
For, 1-15, an enumeration with predefined error codes which the App SDK object can generate.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;typedef NS_ENUM(unsigned int, LogCode) {&lt;br /&gt;
    LogCodeFailedParseStartInfo, // 1.&lt;br /&gt;
    LogCodeFailedParseMetadata, // 2.&lt;br /&gt;
    LogCodeFailedProcessID3, // 3.&lt;br /&gt;
    LogCodeFailedReceiveConfig, // 4.&lt;br /&gt;
    LogCodeFailedParseConfig, // 5.&lt;br /&gt;
    LogCodeFailedStartProcessor, // 6.&lt;br /&gt;
    LogCodeFailedCreateUrl, // 7.&lt;br /&gt;
    LogCodeFailedCreateRequest, // 8.&lt;br /&gt;
    LogCodeFailedSendHttpRequest, // 9.&lt;br /&gt;
    LogCodeFailedSendPing, // 10.&lt;br /&gt;
    LogCodeFailedSendTSV, // 11.&lt;br /&gt;
    LogCodeFailedSendStationRequest, // 12.&lt;br /&gt;
    LogCodeFailedAccessDatabase, // 13.&lt;br /&gt;
    LogCodeException, // 14.&lt;br /&gt;
    LogCodeInvalidPlayheadPosition, // 15.&lt;br /&gt;
    LogCodeLongAd, // 16.&lt;br /&gt;
    LogCodeIncorrectSfcode, // 17.&lt;br /&gt;
    LogCodeHemUidExceedLimit, // 18.&lt;br /&gt;
    LogCodeViewabilityUnableFindView // 19.&lt;br /&gt;
};&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For, 1001-1009, an enumeration with predefined error codes which the App SDK object can generate.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
typedef NS_ENUM(unsigned int, AppApiErrorCode)&lt;br /&gt;
{&lt;br /&gt;
   AppApiNetworkConnectionFailure = 1001,&lt;br /&gt;
   AppApiFileWriteFailure = 1002,&lt;br /&gt;
   AppApiFileReadFailure = 1003,&lt;br /&gt;
   AppApiEmptyValue = 1004,&lt;br /&gt;
   AppApiEmptyAppName = 1005,&lt;br /&gt;
   AppApiEmptyAppVersion = 1006,&lt;br /&gt;
   AppApiEmptyAppId = 1007,&lt;br /&gt;
   AppApiAnExceptionOccured = 1008,&lt;br /&gt;
   AppApiUnknownExceptionOccured = 1009&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== App SDK Error Codes ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Error Code !! Error Name !! Error Description&lt;br /&gt;
|-&lt;br /&gt;
| 1 || LogCodeFailedParseStartInfo || Failed to parse the play() JSON string&lt;br /&gt;
|-&lt;br /&gt;
| 2 || LogCodeFailedParseMetadata || Failed to parse the loadMetadata() JSON string&lt;br /&gt;
|-&lt;br /&gt;
| 3 || LogCodeFailedProcessID3 || Failed to process ID3 data on a data processor&lt;br /&gt;
|-&lt;br /&gt;
| 4 || LogCodeFailedReceiveConfig || Failed to receive configuration file from Census&lt;br /&gt;
|-&lt;br /&gt;
| 5 || LogCodeFailedParseConfig || Failed to parse the config file JSON string&lt;br /&gt;
|-&lt;br /&gt;
| 6 || LogCodeFailedStartProcessor || Failed to create SDK processor&lt;br /&gt;
|-&lt;br /&gt;
| 7 || LogCodeFailedCreateUrl || Failed to generate URL due to missing mandatory parameter&lt;br /&gt;
|-&lt;br /&gt;
| 8 || LogCodeFailedCreateRequest || Failed to create request in HTTP client&lt;br /&gt;
|-&lt;br /&gt;
| 9 || LogCodeFailedSendHttpRequest || Failed sending HTTP or HTTPS request&lt;br /&gt;
|-&lt;br /&gt;
| 10 || LogCodeFailedSendPing || Failed to send ping&lt;br /&gt;
|-&lt;br /&gt;
| 11 || LogCodeFailedSendTSV || Failed to send TSV request&lt;br /&gt;
|-&lt;br /&gt;
| 12 || LogCodeFailedSendStationRequest || Failed to send StationId request&lt;br /&gt;
|-&lt;br /&gt;
| 13 || LogCodeFailedAccessDatabase || Failed to read/write from/to database table&lt;br /&gt;
|-&lt;br /&gt;
| 14 || LogCodeException || Any exception handled by SDK code&lt;br /&gt;
|-&lt;br /&gt;
| 15 || LogCodeInvalidPlayheadPosition || Invalid playhead position&lt;br /&gt;
|-&lt;br /&gt;
| 16 || LogCodeLongAd || Long ad&lt;br /&gt;
|-&lt;br /&gt;
| 17 || LogCodeIncorrectSfcode || Incorrect client supplied sfcode&lt;br /&gt;
|-&lt;br /&gt;
| 18 || LogCodeHemUidExceedLimit || Exceeded limit of chars for hem uid&lt;br /&gt;
|-&lt;br /&gt;
| 19 || LogCodeViewabilityUnableFindView || Viewability unable to find a view with the specificed tag&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Error Code !! Error Name !! Error Description&lt;br /&gt;
|-&lt;br /&gt;
| 1001 || AppApiNetworkConnectionFailure || App SDK Could not connect to server&lt;br /&gt;
|-&lt;br /&gt;
| 1002 || AppApiFileWriteFailure || App SDK Could not write to file&lt;br /&gt;
|-&lt;br /&gt;
| 1003 || AppApiFileReadFailure || App SDK Could not read data from file&lt;br /&gt;
|-&lt;br /&gt;
| 1004 || AppApiEmptyValue || Empty value Found.&lt;br /&gt;
|-&lt;br /&gt;
| 1005 || AppApiEmptyAppName || Cannot initialize SDK Object without an AppName(Player Name)&lt;br /&gt;
|-&lt;br /&gt;
| 1006 || AppApiEmptyAppVersion || Cannot initialize API Object without an AppVersion&lt;br /&gt;
|-&lt;br /&gt;
| 1007 || AppApiEmptyAppId || Cannot initialize API Object without an AppId&lt;br /&gt;
|-&lt;br /&gt;
| 1008 || AppApiAnExceptionOccured || Exception occurred&lt;br /&gt;
|-&lt;br /&gt;
| 1009 || AppApiUnknownExceptionOccured || Unknown exception occurred&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Nielsen Sample Applications ==&lt;br /&gt;
Nielsen SDK client package contains iOS sample player applications based on native Players integrated with SDK framework. The players demonstrate all the supported functions of the SDK and show the integration details for both legacy and trackEvent API. There are players developed on Objective C and Swift. Implementation of the sample apps is based on native iOS AVPlayer.&lt;br /&gt;
&lt;br /&gt;
The UI components of the iOS App SDK sample applications are common to both as shown below.&lt;br /&gt;
*From the Channel Selection buttons ⬇️ &amp;amp; ⬆️ , the user will be able select the channels to stream.&lt;br /&gt;
*The Info button ℹ️ displays information of the SDK version, current Nielsen ID used for the device, and the option for opt-out/opt-in.&lt;br /&gt;
*The Play ▶️ and Pause ⏸️ buttons will control the streaming of the selected channel.&lt;br /&gt;
*The area at the bottom of the window displays the current stream status.&lt;br /&gt;
*The Clear button 🔃 clears out the status window.&lt;br /&gt;
*The Email button 📧 can be used to email the tags and status in a text file to Nielsen.&lt;br /&gt;
If target device supports Picture-in-Picture playing, it could be activated by PIP button in the Video player window.&lt;br /&gt;
*Channel URLs and metadata are obtained from the JSON file named appConfig.json and stored in the application bundle.&lt;br /&gt;
=== Viewability testing ===&lt;br /&gt;
The sample applications shipped with the client package has support for viewability metrics verification. The player view can be moved using a finger-dragging gesture in the application window. This allows the tester to reduce the visible area of the player view and check the resulting data. There are additional UI buttons:&lt;br /&gt;
*Cover View button opens a popup with multiple UI controls which allow changing a player-view alpha and/or visibility as well to show a cover view in front of the player view.&lt;br /&gt;
*Alert button to open a native UI alert in the application.&amp;lt;br/&amp;gt;&lt;br /&gt;
[[File:PlayerView AlertView1.png|200px]]&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;[[File:PlayerViewDragging.png|200px]]&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;[[File:PlayerView CustomView.png|200px]]&lt;br /&gt;
&lt;br /&gt;
== Nielsen Privacy Requirements ==&lt;br /&gt;
There are three primary methods for implementing user Opt-out preferences:&lt;br /&gt;
# [[Template:iOS_Privacy_and_Opt-Out#OS-level_Opt-out|OS-level Opt-out]] - managed by ''Limit Ad Tracking'' setting on device ('''preferred approach''').&lt;br /&gt;
# [[Template:iOS_Privacy_and_Opt-Out#Legacy_Opt-out|Legacy Opt-out]] - Direct call to SDK; used only for older versions of Nielsen iOS SDK (&amp;lt; 5.1.1.18)&lt;br /&gt;
# [https://engineeringportal.nielsen.com/docs/iOS_SDK_App_Level_Opt_Out App Level Opt-Out] - Where [https://developer.apple.com/documentation/adsupport Ad Framework] cannot be leveraged&lt;br /&gt;
=== Privacy Protections ===&lt;br /&gt;
Privacy protections that Nielsen ensures to have with each App SDK integration are as follows.&lt;br /&gt;
*Disclosure of viewership data collection in EULA / Privacy Policy&lt;br /&gt;
*A link in the EULA/Privacy policy, or in another conspicuous location within the App, to a Nielsen-hosted web page outlining what Nielsen is collecting and how it is being used&lt;br /&gt;
*Method for users to opt-out of Nielsen measurement, any time while using the application&lt;br /&gt;
&lt;br /&gt;
=== Ratings Data Flow ===&lt;br /&gt;
Every view of creditable and watermarked content is measured by Nielsen.&lt;br /&gt;
[[File:RatingsDataFlow.png]]&lt;br /&gt;
&lt;br /&gt;
'''Information NOT Shared'''&lt;br /&gt;
* '''With Nielsen'''&lt;br /&gt;
** User's Identity&lt;br /&gt;
* '''With Data Provider'''&lt;br /&gt;
** Content information&lt;br /&gt;
** Whether user is viewing an ad or video content&lt;br /&gt;
** Player used to play the streaming (audio / video, etc.)&lt;br /&gt;
** Values being de-duped / aggregating for&lt;br /&gt;
&lt;br /&gt;
Nielsen collects only what it needs for audience measurement. Every view of creditable, watermarked content will be measured by Nielsen.&lt;br /&gt;
&lt;br /&gt;
=== Data Collected ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type of Information !! Parameter !! Transmitted to Nielsen? !! Sent to Provider?&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;8&amp;quot; | Nielsen ID3 Watermark&lt;br /&gt;
|-&lt;br /&gt;
| FinalDistributor Timestamp || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| Program Content Timestamp || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| Mobile Breakout Code || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| Commercial Credit Code – Linear or Dynamic || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| Time ShiftedViewing Code || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| Segment Number || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| Segment View Pattern || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;10&amp;quot; | Device/App Info&lt;br /&gt;
|-&lt;br /&gt;
| Device OSVersion || Yes || Yes &lt;br /&gt;
|-&lt;br /&gt;
| Device Model || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| Device Advertiser ID (Apple IDFA or Google AdID/Android ID) || Yes || Yes &lt;br /&gt;
|-&lt;br /&gt;
| Cache Buster || Yes || Yes &lt;br /&gt;
|-&lt;br /&gt;
| App Version || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| App Name || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| SDKDisabled Flag || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| ServerCode || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| Channel or URL || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;9&amp;quot; | Nielsen Identifiers&lt;br /&gt;
|-&lt;br /&gt;
| Client ID || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| Campaign ID || Yes || Yes &lt;br /&gt;
|-&lt;br /&gt;
| Nielsen Unique Device ID || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| Application ID || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| DeviceGroup (ex. Tablet, Smartphone, Desktop) || Yes || Yes &lt;br /&gt;
|-&lt;br /&gt;
| OS Group (ex. Android, iOS, Windows) || Yes || Yes &lt;br /&gt;
|-&lt;br /&gt;
| SDKVersion || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| IP Address for DMA, Country Code || Yes || Yes &lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': Data is hashed, and encrypted using AES 128 before transmission to data provider.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Example ping sent to provider ====&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;https://provider.com/cgi-bin/brandlift.php&amp;lt;/nowiki&amp;gt;?campaign_id=ff12725d724fac7934cf6003f096b4cd&amp;lt;wbr /&amp;gt;&amp;amp;placement_id=a4164b8fba9ee7c873a9c72c7091bb58&amp;lt;wbr /&amp;gt;&amp;amp;creative_id=25280139b61a947e127a52f56c8a2fdd&amp;lt;wbr /&amp;gt;&amp;amp;segment1=9000&amp;lt;wbr /&amp;gt;&amp;amp;segment2=41&amp;lt;wbr /&amp;gt;&amp;amp;segment3=iOS&amp;lt;wbr /&amp;gt;&amp;amp;OSVer=iOS6.1&amp;lt;wbr /&amp;gt;&amp;amp;c9=&amp;lt;wbr /&amp;gt;&amp;amp;devgrp=tablet&amp;lt;wbr /&amp;gt;&amp;amp;h=f5f243fe6d&amp;lt;wbr /&amp;gt;&amp;amp;rnd=1376971827360&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This ping passes the following parameters to the provider:&lt;br /&gt;
* Campaign ID – (campaign, placement, creative)&lt;br /&gt;
* Country Code&lt;br /&gt;
* DMA&lt;br /&gt;
* OS Group (ex. iOS, Android)&lt;br /&gt;
* DeviceOS Version&lt;br /&gt;
* Device Advertiser ID&lt;br /&gt;
* DeviceGroup (ex. Tablet, Smartphone, Desktop)&lt;br /&gt;
* Cache Buster&lt;br /&gt;
&lt;br /&gt;
=== TVOS Opt-out ===&lt;br /&gt;
To Opt-Out, users must have access to “About Nielsen Measurement” page.&lt;br /&gt;
&lt;br /&gt;
TVOS does not support creating instances of UIWebView and display web pages. Instead it makes use of a TVML page (built on TVML template) which displays information in a specific order.&lt;br /&gt;
&lt;br /&gt;
Opt-Out page is built on descriptiveAlertTemplate and appears as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:TVOs OptOut LimitAdTracking1.png|link=]]&lt;br /&gt;
&lt;br /&gt;
[[File:TVOs OptOut LimitAdTracking2.png|link=]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Opt-out wording ===&lt;br /&gt;
&amp;lt;blockquote&amp;gt;About Nielsen Measurement&lt;br /&gt;
&lt;br /&gt;
YOUR CHOICES &lt;br /&gt;
&lt;br /&gt;
Television and the way we watch it have come a long way since Nielsen began measuring TV audiences in 1950. Today, the ability to watch programs at any time and on multiple devices amplifies the need for exceptionally adept and flexible audience measurement capabilities. &lt;br /&gt;
	Consumers are changing with the times, and the same goes for Nielsen. As technology continues to evolve and media companies try new ways to attract viewers, understanding what consumers are watching — and what they're watching on — is more important than ever. Today, viewing video is a personal and mobile experience —anytime and anywhere. Our capabilities provide relevant metrics that are necessary to inform successful marketing and programming and drive continued growth.&lt;br /&gt;
	As a global information and measurement leader, we are committed to protecting the privacy and security of the data we collect, process and use. While our digital measurement products are not used to identify you in any way, they help us and our clients measure and analyze how consumers engage with media across online, mobile and emerging technologies, and offer insights into consumer behavior.&lt;br /&gt;
	Nielsen believes that you should have a choice about whether to contribute to our research and insights. To opt out of Nielsen measurement on this device, you need only to activate the “Limit Ad Tracking” option in your device's settings. If you have this app on more than one mobile device, you will need to change the settings on each device. &lt;br /&gt;
	If, after you have opted out, you change your mind and would like to opt back in, please deactivate the “Limit Ad Tracking” option in your device's settings. &lt;br /&gt;
	To learn more about our digital measurement products and your choices in regard to them, please visit https://www.nielsen.com/digitaIprivacy.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Users need to toggle the “Limit Ad Tracking” option in order to Opt-In / Opt-Out of Nielsen Measurement.&lt;br /&gt;
&lt;br /&gt;
To retrieve the current Opt-Out status of a device, use the [[optOutStatus]] method.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note:''' For API Version 5.1 and above, App SDK will fire data pings and continue measurement even after the user has opted out from Nielsen measurement on a device. The data ping will be marked as opted-out ping.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Viewability and Audibility Implementation ==&lt;br /&gt;
Viewability metrics allow AppSDK to track the visibility of the player and collect information about how much of the player container is visible to the end user during playback. &lt;br /&gt;
&lt;br /&gt;
The viewability pings will be fired following the same rules as measurement pings. Viewability pings will be POST requests, not GET requests like other data pings. POST body for viewability requests will contain the key-value pairs in JSON format. The key parameters in the URL schemes are '''invs, inau, inss, invp''' and '''ines''' which will contain the collected viewability data. This data will be formatted according to the specific rules so that downstream it will be possible to match measurement and viewability data for a session.&lt;br /&gt;
&lt;br /&gt;
Audibility metrics will capture the volume level as well as mute/unmute state of the device during playback.&lt;br /&gt;
&lt;br /&gt;
=== Data Collected ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Measured Value || Value is different for different request parameters:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''invs''' ||  Intersection ratio for the target view in percent (from 0 to 100). Default threshold for this value is 5. Example: ['''50''',1,1528457356,10]&lt;br /&gt;
|-&lt;br /&gt;
| '''inau''' || Volume level on the device in percent (from 0 to 100), where 0 - mute, 100 - max volume level. Default threshold for this value is 1. Example: ['''30''',1,1528457356,10]&lt;br /&gt;
|-&lt;br /&gt;
| '''inss''' || Device screen size as &amp;quot;WxH&amp;quot;, where W - is width in pixels, H - is height in pixels. Example: ['''&amp;quot;1024x768&amp;quot;''',1,1528457356,10]&lt;br /&gt;
|-&lt;br /&gt;
| '''invp''' || Current window size. This is different than the device screen size in a multiple scene mode or on a desktop. Format is &amp;quot;WxH&amp;quot;, where W - is width in pixels, H - is height in pixels. Example: ['''&amp;quot;800x600&amp;quot;''',1,1528457356,10]&lt;br /&gt;
|-&lt;br /&gt;
| '''ines''' || Player view size as &amp;quot;WxH&amp;quot;, where W - is width in pixels, H - is height in pixels. Example: ['''&amp;quot;300x200&amp;quot;''',1,1528457356,10]&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| Start offset || Value contains the first playhead or the first id3 offset with non-null CID after start, flush or resume. Example playhead: [50,'''1''',1528457356,10]. Example id3 offset: [50,'''70100''',1528457356,10]&lt;br /&gt;
|-&lt;br /&gt;
| Start timestamp || Timestamp value when the time period related to this time series item was started. Example: [50,1,'''1528457356''',10]&lt;br /&gt;
|-&lt;br /&gt;
| Duration || Duration value is calculated as a difference between the last playhead and the first playhead for the current time series item. Example: [50,1,1528457356,'''10''']&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Viewability support requires additional parameters to be provided from player applications to the SDK. In order to provide these parameters and to start the viewability measurement, the following method has been added to the public SDK API (please refer to the [[trackViewability|trackViewability public API reference]] for details and usage examples):&lt;br /&gt;
&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
'''Objective C'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
- (void)trackViewability:(nonnull NSDictionary *)data;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
'''Swift'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
func trackViewability(_ data: [String : Any])&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
For Audibility measurement SDK uses iOS system API in order to get the volume level for the device:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
AVAudioSession.sharedInstance().outputVolume&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>AnkitAgrawal</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=getDemographicId()&amp;diff=7256</id>
		<title>getDemographicId()</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=getDemographicId()&amp;diff=7256"/>
		<updated>2025-04-04T11:17:06Z</updated>

		<summary type="html">&lt;p&gt;AnkitAgrawal: v10.0.0.0 Changes&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|Android SDK API Reference}} {{CurrentBreadcrumb}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This API gets the current SDK generated UAID for SDK v10.0.0.0+. Previous versions, it gets Demographic ID of the device. &lt;br /&gt;
&lt;br /&gt;
'''Warning:''' calling getDemographicId() in main thread may cause deadlock, be sure to call in a background thread.&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
[[Category:Android SDK API Reference]]&lt;br /&gt;
== Syntax ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public String getDemographicId()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Input Parameters ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
| None || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Output Parameters ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Output Parameters (Return value) !! Description&lt;br /&gt;
|-&lt;br /&gt;
| String || Returns SDK generated UAID or Demographic ID of the device for legacy versions.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>AnkitAgrawal</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=Android_SDK_Release_Notes&amp;diff=7255</id>
		<title>Android SDK Release Notes</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=Android_SDK_Release_Notes&amp;diff=7255"/>
		<updated>2025-04-04T10:23:21Z</updated>

		<summary type="html">&lt;p&gt;AnkitAgrawal: v10.0.0.0 Changes&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Digital]]&lt;br /&gt;
 __NOTOC__&lt;br /&gt;
&lt;br /&gt;
{{Breadcrumb|}} {{Breadcrumb|Digital Downloads}} {{CurrentBreadcrumb}}&lt;br /&gt;
&lt;br /&gt;
== Release 10.0.0.0 (04-04-2025) ==&lt;br /&gt;
*Support for DTVR Subminute product.&lt;br /&gt;
*Support for DCR video playhead bridging.&lt;br /&gt;
*Support for Ethernet network connection for TV platforms.&lt;br /&gt;
*Change in DemographicID behavior for Chromecast.&lt;br /&gt;
*Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 9.4.0.0 (07-09-2024) ==&lt;br /&gt;
*Support for content tracking and no-tracking domains across sdk flavors and products.&lt;br /&gt;
*Upgraded SDK to use Java 11 and Kotlin 1.8.0.                                  &lt;br /&gt;
*Other bug fixes and enhancements.&lt;br /&gt;
== Release 9.3.0.0 (05-10-2024) ==&lt;br /&gt;
*Support for capturing user opt-out during initialization.&lt;br /&gt;
== Release 9.2.0.0 (9-27-2023) ==&lt;br /&gt;
*DCR Static recognizing metadata with changed assetID for new impressions. &lt;br /&gt;
*Limiting ping retries during https failures. &lt;br /&gt;
*Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 9.1.0.0 (3-31-2023) ==&lt;br /&gt;
*DCR Static duration measurement for AppSDK (currently only AGF)&lt;br /&gt;
*Viewability: allow enabling by product (DCR, DTVR)&lt;br /&gt;
*Other bug fixes and enhancements&lt;br /&gt;
&lt;br /&gt;
== Release 9.0.0.0 (10-07-2022) ==&lt;br /&gt;
* Viewability measurement for DTVR, DCR Content and DCR Ad products. &lt;br /&gt;
* Audibility measurement for DTVR, DCR Content and DCR Ad products.&lt;br /&gt;
* Kotlin-Java interoperability implementation in SDK.&lt;br /&gt;
* Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 8.2.0.0 (03-21-2022) ==&lt;br /&gt;
* Support for EMM AGF AdID-less solution.&lt;br /&gt;
* Enabled SDK to capture network availability changes.&lt;br /&gt;
* Removed the usage of deprecated network classes.&lt;br /&gt;
* Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 8.1.0.0 (06-28-2021) ==&lt;br /&gt;
* Support for SDK build variants - AD/NoAD/NoID.&lt;br /&gt;
* Support to indicate ID used for AD build variant - AD ID vs Android ID.&lt;br /&gt;
* Support to capture Hashed email and UID.&lt;br /&gt;
* Support to collect SDK diagnostic data.&lt;br /&gt;
* Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 8.0.0.0 (10-05-2020) ==&lt;br /&gt;
* FPID and VendorID support.&lt;br /&gt;
* Support for Android apps running on ChromeOS.&lt;br /&gt;
* Support for Xamarin cross platform framework.&lt;br /&gt;
* Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 7.2.0.0 (05-18-2020) ==&lt;br /&gt;
* DTVR AQH and IVD requirements for End and pause timeout.&lt;br /&gt;
* Support for Hybrid app webview measurement. &lt;br /&gt;
* Support for Hybrid app react native webview measurement. &lt;br /&gt;
* Support for React Native measurement.&lt;br /&gt;
* Other bug fixes and enhancements&lt;br /&gt;
&lt;br /&gt;
== Release 7.1.0.0 (12-09-2019) ==&lt;br /&gt;
&lt;br /&gt;
* Application background/foreground state auto-detection (AndroidX)&lt;br /&gt;
* Fixed forward rewind evdata containing negative values&lt;br /&gt;
* Offline viewing measurement enhancements&lt;br /&gt;
* Revisited precedence logic for sfcode parameter&lt;br /&gt;
* Using default value for incorrect adModel parameter&lt;br /&gt;
* Defaulting isLive parameter value on channel change&lt;br /&gt;
* Other fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 7.0.0.0 (09-06-2019) ==&lt;br /&gt;
&lt;br /&gt;
* Support for CDN based config.&lt;br /&gt;
* Support for Market based EMM UAID pings.&lt;br /&gt;
* Changes required for proper DCR Static measurement in multi-instance/multiple appid's case.&lt;br /&gt;
* Fixes for OTT synchronization issues between iOS and Android platforms.&lt;br /&gt;
* Fixes for EV data parameters in few scenarios.&lt;br /&gt;
* Fixes for DCR Static product behaviour in background app refresh and background fetch scenarios.&lt;br /&gt;
* DCR Ad reporting improvements.&lt;br /&gt;
* Fixes and improvements for the SDK console log messages.&lt;br /&gt;
* Other enhancements and fixes.&lt;br /&gt;
&lt;br /&gt;
== Release 6.2.0.0  (02-04-2019) ==&lt;br /&gt;
* Removal of Location Module from SDK Code.&lt;br /&gt;
* Fixed the getOptoutStatus() api, so that client can call it in main thread.&lt;br /&gt;
* Fixed the parsing error happening when clientid/vcid provided as empty in metadata.&lt;br /&gt;
* Align AppSDK for FW detection with BSDK for DCR measurement.&lt;br /&gt;
* Other enhancements and fixes.&lt;br /&gt;
&lt;br /&gt;
== Release 6.1.0.1 (9-13-2018) ==&lt;br /&gt;
*Support added for Video On Demand in TV Ratings&lt;br /&gt;
*Bug fixes and improvements&lt;br /&gt;
&lt;br /&gt;
== Release 6.0.0.4 (5-24-2018) ==&lt;br /&gt;
*If the SDK build target is set to AGF then SDK will send the hello ping to “eu” and “eu-uat” for debug builds. No changes to the non AGF build the default sfcode will continue to be &amp;quot;sdk&amp;quot; and &amp;quot;cert&amp;quot; for debug build.&lt;br /&gt;
*The C1 parameter (NUID) will now be sent as encrypted DeviceID.&lt;br /&gt;
*New SessionID changes. The sessionID will contain 29 length random characters appended by timestamp.&lt;br /&gt;
*Support for multiple SDK instance without any limit.&lt;br /&gt;
*New log feature for CAT tool to retrieve the API level information from client apps. This ping will contain the eventType, parameters, SDK version, appid etc.&lt;br /&gt;
*Removed Viewability for this release.&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.26 (7-31-2017) ==&lt;br /&gt;
*Genre parameter will be a part of DCR pings and the value is reflected as part of c44 parameter.&lt;br /&gt;
*Merged adModel and adLoadType flags&lt;br /&gt;
*Fix for stop event data carried to next session’s duration ping&lt;br /&gt;
*Fix for last playhead call that is not processed (when there is no time-gap between the last playhead and end call)&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.24 (6-2-2017) ==&lt;br /&gt;
*Enhanced support for Digital Audio&lt;br /&gt;
*Ability to pass adloadtype as “linear” or “dynamic”&lt;br /&gt;
*Ability to detect end of content and static material through duration pings&lt;br /&gt;
*Acceptance of empty parameters with a warning message triggered, if a required parameter is missing&lt;br /&gt;
*Acceptance of case-insensitive JSON key values&lt;br /&gt;
*Configurable feature to show Ad view counts in the duration pings&lt;br /&gt;
*Automatic Pause Detection and Debug build detection&lt;br /&gt;
*Change of default ‘type’ from “ad” to “content”&lt;br /&gt;
*Removal of “Static” Launch Ping for Non-Static product implementations&lt;br /&gt;
*Fix for metadata carry over between channels after a channel change&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.18 (1-24-2017) ==&lt;br /&gt;
*Ability to opt-out using “Limit Ad Tracking” feature&lt;br /&gt;
*Improved CPU Performance through encryption process change&lt;br /&gt;
*Opt-Out pages can be served based on user’s language and locale from device&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.14 (12-10-2016) ==&lt;br /&gt;
*Support for Nielsen TV Brand Effect&lt;br /&gt;
*Ability to set CMS parameters at a more global level&lt;br /&gt;
*Collection of additional device information&lt;br /&gt;
*Opt-out pages based on locale and country&lt;br /&gt;
*Opt-out based on the ‘Limit Ad Tracking’ flag&lt;br /&gt;
*Issue a warning in client developer’s console when an ad is being played for more than 5 minutes&lt;br /&gt;
*Reduced load time of Android SDK, caused due to encryption.&lt;br /&gt;
*Limit the duration reported for App launch&lt;br /&gt;
*Modification to accept non-JSON strings&lt;br /&gt;
*Fixed&lt;br /&gt;
**Incorrect DRM placement ID&lt;br /&gt;
**DRM pings sent in bursts in case of time change&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.10 (10-19-2016) ==&lt;br /&gt;
*Fixed an issue where SDK will send a burst of data pings in Android.&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.7 (9-1-2016) ==&lt;br /&gt;
*Support for Android N&lt;br /&gt;
*Usage of stop API call is made optional when switching between content or advertising occurs.&lt;br /&gt;
*General bug fix and performance improvements&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.4 (8-1-2016) ==&lt;br /&gt;
*Support for Pause timeout (from 30 minutes to 5 minutes)&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.3 (7-7-2016) ==&lt;br /&gt;
*Sending event level (button press data) data to census collections.&lt;br /&gt;
*Changes in OTT when switching from mobile to Chromecast&lt;br /&gt;
*General bug fix and performance improvements&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.0.4 (4-25-2016) ==&lt;br /&gt;
*Combined SDK for DCR US and International (Germany)&lt;br /&gt;
*API to signal end of content (end API)&lt;br /&gt;
*Changes to use of stop API&lt;br /&gt;
*Support for OTT measurement&lt;br /&gt;
*Support for Pause timeout&lt;br /&gt;
*Offline viewing&lt;br /&gt;
*Updated API to support JSON object instead of string.&lt;br /&gt;
*Reporting of media URL and bundle ID&lt;br /&gt;
*Updated ping retry logic&lt;br /&gt;
*Changes in OptOut process behavioral&lt;br /&gt;
*Enhanced Debugging and SDK logging&lt;br /&gt;
*Changes to API signature&lt;br /&gt;
*Introduced new API updateOTT to report current OTT status.&lt;br /&gt;
&lt;br /&gt;
== Release 4.0.0.8 (6-9-2015) ==&lt;br /&gt;
*Support for Nielsen DCR product (Digital Content Ratings)&lt;br /&gt;
*All the products should be migrated to the latest SDK.&lt;br /&gt;
*This SDK distribution does not have a native library component or shared object.&lt;br /&gt;
*Support for Nielsen App static measurement&lt;br /&gt;
*Support for Ad measurement&lt;br /&gt;
*Removal of Native C++ code&lt;br /&gt;
*Removed singleton restriction&lt;br /&gt;
*Support for Android 6.0 Marshmallow&lt;br /&gt;
*General bug fix and performance improvements&lt;br /&gt;
&lt;br /&gt;
== Release 1.2.3.8 (1-10-2015) ==&lt;/div&gt;</summary>
		<author><name>AnkitAgrawal</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=iOS_SDK_Release_Notes&amp;diff=7254</id>
		<title>iOS SDK Release Notes</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=iOS_SDK_Release_Notes&amp;diff=7254"/>
		<updated>2025-04-04T10:20:27Z</updated>

		<summary type="html">&lt;p&gt;AnkitAgrawal: /* Release 10.0.0.0 (04-04-2025) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Digital]]&lt;br /&gt;
 __NOTOC__&lt;br /&gt;
&lt;br /&gt;
{{Breadcrumb|}} {{Breadcrumb|Digital Downloads}} {{CurrentBreadcrumb}}&lt;br /&gt;
&lt;br /&gt;
== Release 10.0.0.0 (04-04-2025) ==&lt;br /&gt;
*Support for DTVR Subminute product.&lt;br /&gt;
*Support for DCR video playhead bridging.&lt;br /&gt;
*Support for VisionOS platform.&lt;br /&gt;
*Change in DemographicID behavior for Chromecast.&lt;br /&gt;
*Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== '''Release 9.4.0.0 (07-09-2024)''' ==&lt;br /&gt;
*Support for privacy manifest with content tracking domain for Ad flavors.&lt;br /&gt;
*Support for content tracking and no-tracking domains across sdk flavors and products.&lt;br /&gt;
*Other bug fixes and enhancements.&lt;br /&gt;
== Release 9.3.0.0 (05-10-2024) ==&lt;br /&gt;
*Support for privacy manifest with tracking domain for Ad flavors.&lt;br /&gt;
*Support for capturing user opt-out during initialization.&lt;br /&gt;
*Other bug fixes and enhancements.&lt;br /&gt;
== Release 9.2.0.0 (09-27-2023) ==&lt;br /&gt;
*Support for privacy manifest and required reason API introduced in XCode 15.&lt;br /&gt;
*Digitally signed SDK framework per Apple recommendation&lt;br /&gt;
*DCR Static recognizing metadata with changed assetID for new impressions. &lt;br /&gt;
*Limiting ping retries during https failures. &lt;br /&gt;
*Other bug fixes and enhancements. &lt;br /&gt;
&lt;br /&gt;
== Release 9.1.0.0 (03-31-2023) ==&lt;br /&gt;
*DCR Static duration measurement for AppSDK (currently only AGF).&lt;br /&gt;
*Removed use of iOS keychains, started using NSUserDefaults for persistent storage.&lt;br /&gt;
*Viewability: allow enabling by product (DCR, DTVR).&lt;br /&gt;
*Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 9.0.0.0 (10-07-2022) ==&lt;br /&gt;
* Viewability measurement for DTVR, DCR Content and DCR Ad products.&lt;br /&gt;
* Audibility measurement for DTVR, DCR Content and DCR Ad products.&lt;br /&gt;
* SDK built with XCode 14.&lt;br /&gt;
* Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 8.2.0.0 (03-21-2022) ==&lt;br /&gt;
* Adopting Swift language internally, built on a mixed model (Swift+Objective C).&lt;br /&gt;
* Support for Swift markers to help Swift developers.&lt;br /&gt;
* Removed the usage of deprecated iOS network reachability class.&lt;br /&gt;
* Disabled iCloud backup/synchronization of SDK keychain items.&lt;br /&gt;
* Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 8.1.0.0 (06-28-2021) ==&lt;br /&gt;
* Support for XCFramework build distribution.&lt;br /&gt;
* Support for MacOS Catalyst platform framework.&lt;br /&gt;
* Fixed the device classification for MacOS M1 measurement.&lt;br /&gt;
* Support to capture Hashed email and UID.&lt;br /&gt;
* Support to collect SDK diagnostic data.&lt;br /&gt;
* Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 8.0.0.0 (10-05-2020) ==&lt;br /&gt;
* iOS 14 App Transparency Framework support.&lt;br /&gt;
* FPID and VendorID support.&lt;br /&gt;
* Fixed the device classification for iPADOS measurement.&lt;br /&gt;
* Support for Xamarin cross platform framework.&lt;br /&gt;
* Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 7.2.0.0 (05-18-2020) ==&lt;br /&gt;
* DTVR AQH and IVD requirements for End and pause timeout.&lt;br /&gt;
* Support for Hybrid app webview measurement. &lt;br /&gt;
* Support for Hybrid app react native webview measurement. &lt;br /&gt;
* Support for React Native measurement.&lt;br /&gt;
* Other bug fixes and enhancements&lt;br /&gt;
&lt;br /&gt;
== Release 7.1.0.0 (12-09-2019) ==&lt;br /&gt;
* Removed usage of deprecated class UIWebView&lt;br /&gt;
* Offline viewing measurement enhancements&lt;br /&gt;
* Fixed deadlock on SDK shutdown&lt;br /&gt;
* Revisited precedence logic for sfcode parameter&lt;br /&gt;
* Fix for DCR individual ad pings parameters after channel change&lt;br /&gt;
* Using default value for incorrect adModel parameter&lt;br /&gt;
* Defaulting isLive parameter value on channel change&lt;br /&gt;
* Other fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 7.0.0.0 (09-06-2019) ==&lt;br /&gt;
* Support for CDN based config.&lt;br /&gt;
* Support for Market based EMM UAID pings.&lt;br /&gt;
* Changes required for proper DCR Static measurement in multi-instance/multiple appid's case.&lt;br /&gt;
* Fixes for OTT synchronization issues between iOS and Android platforms.&lt;br /&gt;
* Fixes for EV data parameters in few scenarios.&lt;br /&gt;
* Fixes for DCR Static product behaviour in background app refresh and background fetch scenarios.&lt;br /&gt;
* DCR Ad reporting improvements.&lt;br /&gt;
* Fixes and improvements for the SDK console log messages.&lt;br /&gt;
* Other enhancements and fixes.&lt;br /&gt;
&lt;br /&gt;
== Release 6.2.0.0 (02-04-2019) == &lt;br /&gt;
* Introduced Dynamic framework for SDK.&lt;br /&gt;
* Removal of Location Module from SDK Code.&lt;br /&gt;
* Increased SDK log file size for Debug mode.&lt;br /&gt;
* Removed OTT Airplay/mirroring detection that caused crashes in AVAudioSession class.&lt;br /&gt;
* DCR performance improvements.&lt;br /&gt;
* Fixed the parsing error happening when clientid/vcid provided as empty in metadata.&lt;br /&gt;
* Align AppSDK for FW detection with BSDK for DCR measurement.&lt;br /&gt;
* Other Bug Fixes/Enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 6.1.0.1 (9-13-2018) ==&lt;br /&gt;
*Support added for Video On Demand in TV Ratings&lt;br /&gt;
*Support for Xcode 10 and iOS 12&lt;br /&gt;
&lt;br /&gt;
== Release 6.0.0.4 (5-24-2018) ==&lt;br /&gt;
*If the SDK build target is set to AGF then SDK will send the hello ping to “eu” and “eu-uat” for debug builds. No changes to the non AGF build the default sfcode will continue to be &amp;quot;sdk&amp;quot; and &amp;quot;cert&amp;quot; for debug build.&lt;br /&gt;
*The C1 parameter (NUID) will now be sent as encrypted DeviceID.&lt;br /&gt;
*New SessionID changes. The sessionID will contain 29 length random characters appended by timestamp.&lt;br /&gt;
*Support for multiple SDK instance without any limit.&lt;br /&gt;
*New log feature for CAT tool to retrieve the API level information from client apps. This ping will contain the eventType, parameters, SDK version, appid etc.&lt;br /&gt;
*Removed Viewability for this release.&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.29 (7-31-2017) ==&lt;br /&gt;
*Genre parameter will be a part of DCR pings and the value will be reflected as part of c44 parameter.&lt;br /&gt;
*Merged adModel and adLoadType flags&lt;br /&gt;
*Fix for stop event data carried to next session’s duration ping&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.25 (5-31-2017) ==&lt;br /&gt;
*Enhanced support for Digital Audio&lt;br /&gt;
*Ability to pass adloadtype as “linear” or “dynamic”&lt;br /&gt;
*Ability to detect end of content and static material through duration pings&lt;br /&gt;
*Acceptance of empty parameters with a warning message triggered, if a required parameter is missing&lt;br /&gt;
*Acceptance of case-insensitive JSON key values&lt;br /&gt;
*Configurable feature to show Ad view counts in the duration pings&lt;br /&gt;
*Automatic Pause Detection and Debug build detection&lt;br /&gt;
*Change of default ‘type’ from “ad” to “content”&lt;br /&gt;
*Removal of “Static” Launch Ping for Non-Static product implementations&lt;br /&gt;
*Fix for App crash when multiple threads are accessing the SQLite&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.23 (5-5-2017) ==&lt;br /&gt;
*Ability to pass adloadtype as “linear” or “dynamic”&lt;br /&gt;
*Ability to detect end of content and static material through duration pings&lt;br /&gt;
*Acceptance of empty parameters with a warning message triggered, if a required parameter is missing&lt;br /&gt;
*Acceptance of case-insensitive JSON key values&lt;br /&gt;
*Configurable feature to show Ad view counts in the duration pings&lt;br /&gt;
*Automatic Pause Detection and Debug build detection&lt;br /&gt;
*Change of default ‘type’ from “ad” to “content”&lt;br /&gt;
*Removal of “Static” Launch Ping for Non-Static product implementations&lt;br /&gt;
*Fix for App crash when multiple threads are accessing the SQLite&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.19 (4-3-2017) ==&lt;br /&gt;
*Fix for muting background music apps&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.18 (2-3-2017) ==&lt;br /&gt;
*Minor bug fixes and performance improvement&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.17 (1-23-2017) ==&lt;br /&gt;
*Added “seconds” place to the launch ping&lt;br /&gt;
*Ability to opt-out using “Limit Ad Tracking” feature&lt;br /&gt;
*Improved CPU Performance while apps are running in background&lt;br /&gt;
*Opt-Out pages can be served based on user’s language and locale from device&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.12 (12-14-2016) ==&lt;br /&gt;
*Support for Nielsen TV Brand Effect&lt;br /&gt;
*Ability to set CMS parameters at a more global level&lt;br /&gt;
*Opt-out pages based on locale and country&lt;br /&gt;
*Opt-out policy based on the ‘Limit Ad Tracking’ flag&lt;br /&gt;
*Collection of additional device information&lt;br /&gt;
*Issue a warning in client developer’s console when ad is played for more than 5 minutes&lt;br /&gt;
*Removed the requirement for “type” parameter&lt;br /&gt;
*Limit the duration reported for App launch&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.9 (10-18-2016) ==&lt;br /&gt;
*Fixed Linker error duplicate symbols for Reachability notification in iOS.&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.7 (9-13-2016) ==&lt;br /&gt;
*Support for iOS 10&lt;br /&gt;
*Usage of stop API call is made optional when switching between content or advertising occurs.&lt;br /&gt;
*General bug fix and performance improvements&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.5 (7-12-2016) ==&lt;br /&gt;
*Sending event level (button press data) data to census collections.&lt;br /&gt;
*Support for Pause timeout (from 30 minutes to 5 minutes)&lt;br /&gt;
*Changes in OTT when switching from mobile to Chromecast&lt;br /&gt;
*Self-error Reporting for iOS SDK&lt;br /&gt;
*General bug fix and performance improvements&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.0.5 (4-25-2016) ==&lt;br /&gt;
*Combined SDK for DCR US and International (Germany)&lt;br /&gt;
*API to signal end of content (end API)&lt;br /&gt;
*Changes to use of stop API&lt;br /&gt;
*Support for OTT measurement&lt;br /&gt;
*Support for Pause timeout&lt;br /&gt;
*Offline viewing&lt;br /&gt;
*Updated API to support JSON object instead of string.&lt;br /&gt;
*Reporting of media URL and bundle ID&lt;br /&gt;
*Updated ping retry logic&lt;br /&gt;
*Changes in OptOut process behavioral&lt;br /&gt;
*Enhanced Debugging and SDK logging&lt;br /&gt;
*Changes to API signature&lt;br /&gt;
*Introduced new API updateOTT to report current OTT status.&lt;br /&gt;
&lt;br /&gt;
== Release 4.0.0.8 (6-9-2015) ==&lt;br /&gt;
*Support for Nielsen DCR product (Digital Content Ratings)&lt;br /&gt;
**All the products should be migrated to the latest SDK.&lt;br /&gt;
**This SDK distribution does not have a native library component or shared object.&lt;br /&gt;
*Support for Nielsen App static measurement&lt;br /&gt;
*Support for Ad measurement&lt;br /&gt;
*Removal of Native C++ code&lt;br /&gt;
*Removed singleton restriction&lt;br /&gt;
*Support for iOS 9 and iOS 9 PIP mode&lt;br /&gt;
*General bug fix and performance improvements&lt;br /&gt;
&lt;br /&gt;
== Release 3.2.1.26 (1-10-2015) ==&lt;/div&gt;</summary>
		<author><name>AnkitAgrawal</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=iOS_SDK_Release_Notes&amp;diff=7253</id>
		<title>iOS SDK Release Notes</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=iOS_SDK_Release_Notes&amp;diff=7253"/>
		<updated>2025-04-04T10:19:10Z</updated>

		<summary type="html">&lt;p&gt;AnkitAgrawal: v10.0.0.0 Changes&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Digital]]&lt;br /&gt;
 __NOTOC__&lt;br /&gt;
&lt;br /&gt;
{{Breadcrumb|}} {{Breadcrumb|Digital Downloads}} {{CurrentBreadcrumb}}&lt;br /&gt;
&lt;br /&gt;
== Release 10.0.0.0 (04-04-2025) ==&lt;br /&gt;
*Support for DTVR Subminute product.&lt;br /&gt;
*Support for DCR Video Playhead Bridging.&lt;br /&gt;
*Support for VisionOS platform.&lt;br /&gt;
*Change in DemographicID behavior for Chromecast.&lt;br /&gt;
*Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== '''Release 9.4.0.0 (07-09-2024)''' ==&lt;br /&gt;
*Support for privacy manifest with content tracking domain for Ad flavors.&lt;br /&gt;
*Support for content tracking and no-tracking domains across sdk flavors and products.&lt;br /&gt;
*Other bug fixes and enhancements.&lt;br /&gt;
== Release 9.3.0.0 (05-10-2024) ==&lt;br /&gt;
*Support for privacy manifest with tracking domain for Ad flavors.&lt;br /&gt;
*Support for capturing user opt-out during initialization.&lt;br /&gt;
*Other bug fixes and enhancements.&lt;br /&gt;
== Release 9.2.0.0 (09-27-2023) ==&lt;br /&gt;
*Support for privacy manifest and required reason API introduced in XCode 15.&lt;br /&gt;
*Digitally signed SDK framework per Apple recommendation&lt;br /&gt;
*DCR Static recognizing metadata with changed assetID for new impressions. &lt;br /&gt;
*Limiting ping retries during https failures. &lt;br /&gt;
*Other bug fixes and enhancements. &lt;br /&gt;
&lt;br /&gt;
== Release 9.1.0.0 (03-31-2023) ==&lt;br /&gt;
*DCR Static duration measurement for AppSDK (currently only AGF).&lt;br /&gt;
*Removed use of iOS keychains, started using NSUserDefaults for persistent storage.&lt;br /&gt;
*Viewability: allow enabling by product (DCR, DTVR).&lt;br /&gt;
*Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 9.0.0.0 (10-07-2022) ==&lt;br /&gt;
* Viewability measurement for DTVR, DCR Content and DCR Ad products.&lt;br /&gt;
* Audibility measurement for DTVR, DCR Content and DCR Ad products.&lt;br /&gt;
* SDK built with XCode 14.&lt;br /&gt;
* Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 8.2.0.0 (03-21-2022) ==&lt;br /&gt;
* Adopting Swift language internally, built on a mixed model (Swift+Objective C).&lt;br /&gt;
* Support for Swift markers to help Swift developers.&lt;br /&gt;
* Removed the usage of deprecated iOS network reachability class.&lt;br /&gt;
* Disabled iCloud backup/synchronization of SDK keychain items.&lt;br /&gt;
* Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 8.1.0.0 (06-28-2021) ==&lt;br /&gt;
* Support for XCFramework build distribution.&lt;br /&gt;
* Support for MacOS Catalyst platform framework.&lt;br /&gt;
* Fixed the device classification for MacOS M1 measurement.&lt;br /&gt;
* Support to capture Hashed email and UID.&lt;br /&gt;
* Support to collect SDK diagnostic data.&lt;br /&gt;
* Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 8.0.0.0 (10-05-2020) ==&lt;br /&gt;
* iOS 14 App Transparency Framework support.&lt;br /&gt;
* FPID and VendorID support.&lt;br /&gt;
* Fixed the device classification for iPADOS measurement.&lt;br /&gt;
* Support for Xamarin cross platform framework.&lt;br /&gt;
* Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 7.2.0.0 (05-18-2020) ==&lt;br /&gt;
* DTVR AQH and IVD requirements for End and pause timeout.&lt;br /&gt;
* Support for Hybrid app webview measurement. &lt;br /&gt;
* Support for Hybrid app react native webview measurement. &lt;br /&gt;
* Support for React Native measurement.&lt;br /&gt;
* Other bug fixes and enhancements&lt;br /&gt;
&lt;br /&gt;
== Release 7.1.0.0 (12-09-2019) ==&lt;br /&gt;
* Removed usage of deprecated class UIWebView&lt;br /&gt;
* Offline viewing measurement enhancements&lt;br /&gt;
* Fixed deadlock on SDK shutdown&lt;br /&gt;
* Revisited precedence logic for sfcode parameter&lt;br /&gt;
* Fix for DCR individual ad pings parameters after channel change&lt;br /&gt;
* Using default value for incorrect adModel parameter&lt;br /&gt;
* Defaulting isLive parameter value on channel change&lt;br /&gt;
* Other fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 7.0.0.0 (09-06-2019) ==&lt;br /&gt;
* Support for CDN based config.&lt;br /&gt;
* Support for Market based EMM UAID pings.&lt;br /&gt;
* Changes required for proper DCR Static measurement in multi-instance/multiple appid's case.&lt;br /&gt;
* Fixes for OTT synchronization issues between iOS and Android platforms.&lt;br /&gt;
* Fixes for EV data parameters in few scenarios.&lt;br /&gt;
* Fixes for DCR Static product behaviour in background app refresh and background fetch scenarios.&lt;br /&gt;
* DCR Ad reporting improvements.&lt;br /&gt;
* Fixes and improvements for the SDK console log messages.&lt;br /&gt;
* Other enhancements and fixes.&lt;br /&gt;
&lt;br /&gt;
== Release 6.2.0.0 (02-04-2019) == &lt;br /&gt;
* Introduced Dynamic framework for SDK.&lt;br /&gt;
* Removal of Location Module from SDK Code.&lt;br /&gt;
* Increased SDK log file size for Debug mode.&lt;br /&gt;
* Removed OTT Airplay/mirroring detection that caused crashes in AVAudioSession class.&lt;br /&gt;
* DCR performance improvements.&lt;br /&gt;
* Fixed the parsing error happening when clientid/vcid provided as empty in metadata.&lt;br /&gt;
* Align AppSDK for FW detection with BSDK for DCR measurement.&lt;br /&gt;
* Other Bug Fixes/Enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 6.1.0.1 (9-13-2018) ==&lt;br /&gt;
*Support added for Video On Demand in TV Ratings&lt;br /&gt;
*Support for Xcode 10 and iOS 12&lt;br /&gt;
&lt;br /&gt;
== Release 6.0.0.4 (5-24-2018) ==&lt;br /&gt;
*If the SDK build target is set to AGF then SDK will send the hello ping to “eu” and “eu-uat” for debug builds. No changes to the non AGF build the default sfcode will continue to be &amp;quot;sdk&amp;quot; and &amp;quot;cert&amp;quot; for debug build.&lt;br /&gt;
*The C1 parameter (NUID) will now be sent as encrypted DeviceID.&lt;br /&gt;
*New SessionID changes. The sessionID will contain 29 length random characters appended by timestamp.&lt;br /&gt;
*Support for multiple SDK instance without any limit.&lt;br /&gt;
*New log feature for CAT tool to retrieve the API level information from client apps. This ping will contain the eventType, parameters, SDK version, appid etc.&lt;br /&gt;
*Removed Viewability for this release.&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.29 (7-31-2017) ==&lt;br /&gt;
*Genre parameter will be a part of DCR pings and the value will be reflected as part of c44 parameter.&lt;br /&gt;
*Merged adModel and adLoadType flags&lt;br /&gt;
*Fix for stop event data carried to next session’s duration ping&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.25 (5-31-2017) ==&lt;br /&gt;
*Enhanced support for Digital Audio&lt;br /&gt;
*Ability to pass adloadtype as “linear” or “dynamic”&lt;br /&gt;
*Ability to detect end of content and static material through duration pings&lt;br /&gt;
*Acceptance of empty parameters with a warning message triggered, if a required parameter is missing&lt;br /&gt;
*Acceptance of case-insensitive JSON key values&lt;br /&gt;
*Configurable feature to show Ad view counts in the duration pings&lt;br /&gt;
*Automatic Pause Detection and Debug build detection&lt;br /&gt;
*Change of default ‘type’ from “ad” to “content”&lt;br /&gt;
*Removal of “Static” Launch Ping for Non-Static product implementations&lt;br /&gt;
*Fix for App crash when multiple threads are accessing the SQLite&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.23 (5-5-2017) ==&lt;br /&gt;
*Ability to pass adloadtype as “linear” or “dynamic”&lt;br /&gt;
*Ability to detect end of content and static material through duration pings&lt;br /&gt;
*Acceptance of empty parameters with a warning message triggered, if a required parameter is missing&lt;br /&gt;
*Acceptance of case-insensitive JSON key values&lt;br /&gt;
*Configurable feature to show Ad view counts in the duration pings&lt;br /&gt;
*Automatic Pause Detection and Debug build detection&lt;br /&gt;
*Change of default ‘type’ from “ad” to “content”&lt;br /&gt;
*Removal of “Static” Launch Ping for Non-Static product implementations&lt;br /&gt;
*Fix for App crash when multiple threads are accessing the SQLite&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.19 (4-3-2017) ==&lt;br /&gt;
*Fix for muting background music apps&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.18 (2-3-2017) ==&lt;br /&gt;
*Minor bug fixes and performance improvement&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.17 (1-23-2017) ==&lt;br /&gt;
*Added “seconds” place to the launch ping&lt;br /&gt;
*Ability to opt-out using “Limit Ad Tracking” feature&lt;br /&gt;
*Improved CPU Performance while apps are running in background&lt;br /&gt;
*Opt-Out pages can be served based on user’s language and locale from device&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.12 (12-14-2016) ==&lt;br /&gt;
*Support for Nielsen TV Brand Effect&lt;br /&gt;
*Ability to set CMS parameters at a more global level&lt;br /&gt;
*Opt-out pages based on locale and country&lt;br /&gt;
*Opt-out policy based on the ‘Limit Ad Tracking’ flag&lt;br /&gt;
*Collection of additional device information&lt;br /&gt;
*Issue a warning in client developer’s console when ad is played for more than 5 minutes&lt;br /&gt;
*Removed the requirement for “type” parameter&lt;br /&gt;
*Limit the duration reported for App launch&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.9 (10-18-2016) ==&lt;br /&gt;
*Fixed Linker error duplicate symbols for Reachability notification in iOS.&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.7 (9-13-2016) ==&lt;br /&gt;
*Support for iOS 10&lt;br /&gt;
*Usage of stop API call is made optional when switching between content or advertising occurs.&lt;br /&gt;
*General bug fix and performance improvements&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.5 (7-12-2016) ==&lt;br /&gt;
*Sending event level (button press data) data to census collections.&lt;br /&gt;
*Support for Pause timeout (from 30 minutes to 5 minutes)&lt;br /&gt;
*Changes in OTT when switching from mobile to Chromecast&lt;br /&gt;
*Self-error Reporting for iOS SDK&lt;br /&gt;
*General bug fix and performance improvements&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.0.5 (4-25-2016) ==&lt;br /&gt;
*Combined SDK for DCR US and International (Germany)&lt;br /&gt;
*API to signal end of content (end API)&lt;br /&gt;
*Changes to use of stop API&lt;br /&gt;
*Support for OTT measurement&lt;br /&gt;
*Support for Pause timeout&lt;br /&gt;
*Offline viewing&lt;br /&gt;
*Updated API to support JSON object instead of string.&lt;br /&gt;
*Reporting of media URL and bundle ID&lt;br /&gt;
*Updated ping retry logic&lt;br /&gt;
*Changes in OptOut process behavioral&lt;br /&gt;
*Enhanced Debugging and SDK logging&lt;br /&gt;
*Changes to API signature&lt;br /&gt;
*Introduced new API updateOTT to report current OTT status.&lt;br /&gt;
&lt;br /&gt;
== Release 4.0.0.8 (6-9-2015) ==&lt;br /&gt;
*Support for Nielsen DCR product (Digital Content Ratings)&lt;br /&gt;
**All the products should be migrated to the latest SDK.&lt;br /&gt;
**This SDK distribution does not have a native library component or shared object.&lt;br /&gt;
*Support for Nielsen App static measurement&lt;br /&gt;
*Support for Ad measurement&lt;br /&gt;
*Removal of Native C++ code&lt;br /&gt;
*Removed singleton restriction&lt;br /&gt;
*Support for iOS 9 and iOS 9 PIP mode&lt;br /&gt;
*General bug fix and performance improvements&lt;br /&gt;
&lt;br /&gt;
== Release 3.2.1.26 (1-10-2015) ==&lt;/div&gt;</summary>
		<author><name>AnkitAgrawal</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=Android_SDK_API_Reference&amp;diff=7252</id>
		<title>Android SDK API Reference</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=Android_SDK_API_Reference&amp;diff=7252"/>
		<updated>2025-04-03T15:34:20Z</updated>

		<summary type="html">&lt;p&gt;AnkitAgrawal: /* Android SDK API Methods &amp;amp; Properties */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
The Nielsen App SDK (located in the ''com.nielsen.app.sdk'' package) class is the primary application interface to the Nielsen App SDK on Android.&lt;br /&gt;
*Create and initialize an instance object of &amp;lt;code&amp;gt;AppSdk&amp;lt;/code&amp;gt; class.&lt;br /&gt;
*The player application can use this object to collect HLS timed metadata through a [[sendID3()]] call.&lt;br /&gt;
The Nielsen App SDK class is defined as the only public class belonging to the com.nielsen.app.sdk package. It inherits from the closeable interface and exposes the public APIs the client’s app will use. Below is the declaration of the &amp;lt;code&amp;gt;AppSdk&amp;lt;/code&amp;gt; class: &amp;lt;code&amp;gt;public class AppSdk implements Closeable&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Setting Up Development Environment ==&lt;br /&gt;
'''Nielsen App SDK is compatible with Android OS versions 2.3+. Clients can control / configure the protocol to be used – HTTPS or HTTP to suit their needs.'''&lt;br /&gt;
&lt;br /&gt;
The Nielsen App SDK 1.2 library is composed of two parts:&lt;br /&gt;
* The Java AppSdk.jar library that runs on the Android’s Dalvik Virtual Machine.&lt;br /&gt;
* The C/C++ libAppSdk.so native library that runs directly on the device’s hardware.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': App SDK 4.0.0 contains AppSDK.jar component only and does not support C/C++ libAppSdk.so components.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The requirement for the Java ''AppSdk.jar'' library and the ''libAppSdk.so'' native library will depend on the type of host application that will make use of them.&lt;br /&gt;
* '''For Video player applications'''&lt;br /&gt;
** The Android OS hosting the App SDK should use a media player supporting HLS streaming (Android 3.0 and later will support it natively).&lt;br /&gt;
** If the player application uses a 3rd party media player implementing its own HLS, then the minimum Android version will be limited to version 2.3, since the SDK depends on Google Play support to work properly.&lt;br /&gt;
* '''For Audio player applications'''&lt;br /&gt;
** The Android OS hosting the App SDK should be at version 2.3 and later since the SDK depends on the Google Play support to work properly.&lt;br /&gt;
&lt;br /&gt;
=== Setting up in Eclipse IDE ===&lt;br /&gt;
Be sure to unzip the Nielsen App SDK sample app and copy the ''AppSdk.jar'' into the libs/ folder on the App’s Eclipse project. Copy the ''libAppSdk.so'' file under ''libs/armeabi/'' folder into the same Eclipse project.&lt;br /&gt;
* App SDK 1.2 provides support for x86, mips, and armeabi-7a architecture; the respective ''libAppSdk.so'' can be found under the ''libs/x86/'', ''libs/mips/'', and ''libs/armeabi-7a/'' folders.&lt;br /&gt;
Add the following permissions on the project’s ''AndroidManifest.xml'' file.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&amp;lt;uses-permission android:name=&amp;quot;android.permission.ACCESS_COARSE_LOCATION&amp;quot; android:required=&amp;quot;false&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;uses-permission android:name=&amp;quot;android.permission.ACCESS_NETWORK_STATE&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;uses-permission android:name=&amp;quot;android.permission.INTERNET&amp;quot;/&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
For more details to handle run-time permissions in Android versions, please visit [https://developer.android.com/training/permissions/requesting.html].   Download the latest ''google-play-services_lib'' and include it in the App’s project in order to use the App SDK.&lt;br /&gt;
&lt;br /&gt;
* App SDK checks to see if there is a Google service available and updated.&lt;br /&gt;
* If not available or updated, App SDK will not use this service when executing its functions and will make reference to missing imports and the app will not be compiled.&lt;br /&gt;
To include the Google Play library in the media player project, copy the ''google-play-services_lib'' folder into the same location as the project&lt;br /&gt;
* Access '''File &amp;gt; Import'''.&lt;br /&gt;
* Select '''Existing Android Code into Workspace''' and click '''Next'''.&lt;br /&gt;
* Click '''Browse''' and navigate to the ''google-play-services_lib'' to include it into the projects.&lt;br /&gt;
* Select the exact '''Project Build Target''' for Eclipse to use from Android SDK.&lt;br /&gt;
** Android 4.4.2, etc. OR&lt;br /&gt;
** Edit ''project.properties'' file to point to Android target version e.g. target= android-19.&lt;br /&gt;
&lt;br /&gt;
[[File:andr-properties-drm.jpg|link=]]&lt;br /&gt;
&lt;br /&gt;
Once the google-play-services_lib is included into the App project, include the following code under the &amp;lt;code&amp;gt;&amp;lt;application&amp;gt;&amp;lt;/code&amp;gt; node in the &amp;lt;code&amp;gt;AndroidManifest.xml&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&amp;lt;meta-data android:name=&amp;quot;com.google.android.gms.version&amp;quot; android:value=&amp;quot;@integer/google_play_services_version&amp;quot;/&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Also, include the ''version.xml'' file that comes with the ''google-play-services_lib'' under the res/values directory of the media player project.&lt;br /&gt;
* Once the files are in place, import com.nielsen.app.sdk to the java source code and start accessing the public interface.&lt;br /&gt;
Nielsen App SDK uses the following packages/classes from the Google Play service.&lt;br /&gt;
&lt;br /&gt;
'''Library''':&lt;br /&gt;
* google-play-services_lib&lt;br /&gt;
'''Classes/package''':&lt;br /&gt;
* com.google.android.gms.ads.identifier.AdvertisingIdClient;&lt;br /&gt;
* com.google.android.gms.ads.identifier.AdvertisingIdClient.Info;&lt;br /&gt;
* com.google.android.gms.common.ConnectionResult;&lt;br /&gt;
* com.google.android.gms.common.GooglePlayServicesUtil;&lt;br /&gt;
* com.google.android.gms.common.GooglePlayServicesRepairableException;&lt;br /&gt;
* com.google.android.gms.common.GooglePlayServicesNotAvailableException;&lt;br /&gt;
 &lt;br /&gt;
=== Setting up in Android Studio IDE ===&lt;br /&gt;
Launch '''Android Studio''' and select '''Import project (Eclipse ADT)'''.&lt;br /&gt;
&lt;br /&gt;
[[File:andr-setup-launch.jpg|link=]]&lt;br /&gt;
&lt;br /&gt;
Browse for project destination directory and click '''Next'''.&lt;br /&gt;
&lt;br /&gt;
[[File:andr-import-project.jpg|link=]]&lt;br /&gt;
&lt;br /&gt;
Go to '''File &amp;gt; Project Structure &amp;gt; App &amp;gt; Dependencies'''.&lt;br /&gt;
&lt;br /&gt;
[[File:andr-pro-structure.jpg|link=]]&lt;br /&gt;
&lt;br /&gt;
Click '''+''' to add library dependency.&lt;br /&gt;
&lt;br /&gt;
Select '''play-services''' and click '''OK'''&lt;br /&gt;
&lt;br /&gt;
[[File:andr-choose-library.jpg|link=]]&lt;br /&gt;
&lt;br /&gt;
For more information, refer to https://developer.android.com/google/play-services/setup.html&lt;br /&gt;
&lt;br /&gt;
*For applications using ''Google Play Services 17.0.0'' and above, one of the following tags must be included within ''AndroidManifest.xml'', or the application will crash (more information https://developers.google.com/ad-manager/mobile-ads-sdk/android/quick-start#update_your_androidmanifestxml]):&lt;br /&gt;
**&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;com.google.android.gms.ads.APPLICATION_ID&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
**&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;com.google.android.gms.ads.AD_MANAGER_APP&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Initialization ==&lt;br /&gt;
=== Android Application Life Cycle with respect to Nielsen App SDK ===&lt;br /&gt;
[[File:andr-init-img1.jpg|link=]]&lt;br /&gt;
&lt;br /&gt;
=== Step 1: App SDK initialization ===&lt;br /&gt;
==== For API version 4.0.0 and above ====&lt;br /&gt;
&lt;br /&gt;
[[AppSDK()]] is no longer a singleton object and should be initialized as below.&lt;br /&gt;
&lt;br /&gt;
==== APPSDK Kotlin/Java Interpretability ====&lt;br /&gt;
&lt;br /&gt;
Starting Nielsen SDK version 9.0.0.0, all new feature/modules are written in Kotlin language, coexisting with legacy features written in Java. If you are having an app purely written in Java language, then you need to enable the Kotlin support dependency in your project as described below:&lt;br /&gt;
&lt;br /&gt;
Minimum version of kotlin plugin and org.jetbrains.kotlin:kotlin-stdlib dependency supported by AppSDK is 1.4.0.  &amp;lt;br/&amp;gt;&lt;br /&gt;
To enable kotlin support in your java based android project please add below gradle dependency in your app's build.gradle file&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;gradle&amp;quot;&amp;gt;&lt;br /&gt;
implementation &amp;quot;org.jetbrains.kotlin:kotlin-stdlib:1.4.0&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Initialization_of_App_SDK_object_through_a_JSON_object}}&lt;br /&gt;
&lt;br /&gt;
==== Android Application Life Cycle with respect to Nielsen App SDK ====&lt;br /&gt;
[[File:andr-radioandvideo-app.jpg|link=]]&lt;br /&gt;
&lt;br /&gt;
=== Step 2: App SDK libraries inclusion in project ===&lt;br /&gt;
The integration of Nielsen App SDK will depend on type of client app.&lt;br /&gt;
*Ensure that SDK files (AppSdk.jar and libAppSdk.so [App SDK 1.2 Only]) are included under the App’s project and the App SDK is linked to the App (the setting to link App SDK to the App can be found on property page of the App’s project).&lt;br /&gt;
&lt;br /&gt;
=== Step 3: Nielsen App SDK Streaming Sessions ===&lt;br /&gt;
After ensuring that the SDK object has been initialized, link the streaming session APIs. The next steps are:&lt;br /&gt;
*Call [[play()]] when starting or resuming a streaming session. Use the channelName parameter to pass channel descriptor information. The channel name field is a 32-character free-form text field containing the name of the program or feed being sent (such as ESPN2, Food Network, etc.) which must be inserted on a JSON string.&lt;br /&gt;
*Load the CMS metadata by calling the [[loadMetadata()]] on the SDK object.&lt;br /&gt;
*Call [[stop()]] when ending or pausing a viewing session.&lt;br /&gt;
*During session playback, call the SDK [[setPlayheadPosition()]] and / or [[sendID3()]]&lt;br /&gt;
**Call [[setPlayheadPosition()]] every one second until the stream is stopped or paused.&lt;br /&gt;
**Call [[sendID3()]] if the client relies on the Nielsen ID3 tags for its measurements; this call should happen whenever a new Nielsen ID3 metadata is available for processing. Normally this happens on DTVR and ID3 measurements.&lt;br /&gt;
Nielsen App SDK object handles filtering of ID3 tags and CMS tags, queuing/buffering of data, and all communications with Nielsen collection facility.&lt;br /&gt;
*The client’s app must clearly identify the mode of operation (live vs. VOD) and stick to the type of playhead coordinates until the playback is completed. The client must reliably provide the appropriated playhead position value depending on the type of content streamed.&lt;br /&gt;
*If streaming live video content, the client must pass the current Unix timestamp (seconds since Jan-1-1970 UTC) as playhead position.&lt;br /&gt;
*If streaming VOD (video on demand), the client must stream the offset from the beginning of the file as playhead position.&lt;br /&gt;
&lt;br /&gt;
== Retrieving ID3 Tags ==&lt;br /&gt;
ID3 tags have a payload of about 249 characters and start with &amp;quot;www.nielsen.com&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Sample ID3 tags ===&lt;br /&gt;
* &amp;lt;code&amp;gt;www.nielsen.com/X100zdCIGeIlgZnkYj6UvQ==/X100zdCIGeIlgZnkYj6UvQ==/AAAB2Jz2_k74GXSzx4npHuI_&amp;lt;wbr /&amp;gt;JwJd3QSUpW30rDkGTcbHEzIMWleCzM-uvNOP9fzJcQMWQLJqzXMCAxParOb5sGijSV9dNM3QiBniJYGZ5GI-lL1fXTTN0IgZ4iWBmeRiPpS9AAAAAAAAAAAAAAAAAAAAAFJWFM5SVhTONNU=/00000/00000/00&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;www.nielsen.com/X100zdCIGeIlgZnkYj6UvQ==/R8WHe7pEBeqBhu8jTeXydg==/AAICoyitYqlxT7n6aZ0oMCGhe&amp;lt;wbr /&amp;gt;Fi4CXFp46AMUPZz1lMr_M9tr3_cjee1SHqxrOiVerMDLeyn9xzocZSKwi746Re8vNOtpNCAZjYABs_J0R25IHpvOc1HS8&amp;lt;wbr /&amp;gt;QHGgD5TgOJeS6gX100zdCIGeIlgZnkYj6UvVJWFNhSVhTiPE0=/00000/46016/00&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': ID3 tags are not applicable for International (Germany)&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Extracting ID3 tags from Android Players ===&lt;br /&gt;
==== ID3 Support Matrix ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Player Name !! Minimum supported version !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Android Native Media Player || Android 6 || Android 6 Media Player allows apps to register a callback to be invoked, when a selected track has the timed metadata available. Currently, only HTTP Live Streaming (HLS) data URI’s embedded with timed ID3 tags, generates TimedMetaData.&lt;br /&gt;
|-&lt;br /&gt;
| Google ExoPlayer || Android 4.1 ||&lt;br /&gt;
|-&lt;br /&gt;
| Adobe PrimeTime Player || Android 4.2 ||&lt;br /&gt;
|-&lt;br /&gt;
| Brightcove Player || Android 4.1 || Support for Android versions 2.3.3 and 4.0 is now deprecated. Learn more about why Brightcove is removing support for these versions as of January 1, 2016 in this announcement: https://support.brightcove.com/en/perform/docs/announcement-brightcove-sdk-android-version-support&lt;br /&gt;
|-&lt;br /&gt;
| VisualOn Player || Android 2.3 || Android 5 is the latest supported version&lt;br /&gt;
|-&lt;br /&gt;
| NexStream Player || Android 1.6 || Supported till Android 6&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Android Native Media Player ====&lt;br /&gt;
As the Android Media Player versions (prior to Android 6 / Android API 23) do not support ID3, Nielsen has created a library that becomes an extension to the media player, thus MPX. This library extracts the ID3 tags and sends them to the app. For more information on how to use the MPX component, refer to the Nielsen-supplied sample application.&lt;br /&gt;
&lt;br /&gt;
Starting from '''Android 6 (Android API 23)''', Android Native Media Player allows apps to register a callback to be invoked, when a selected track has the timed metadata available. Currently, only HTTP Live Streaming (HLS) data URI’s embedded with timed ID3 tags generate TimedMetadata. Once the HLS video starts, call onTimedMetaDataAvailable() as and when the player observes a TimedMetadata (ID3 tag).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;@Override&lt;br /&gt;
   public void onTimedMetaDataAvailable(MediaPlayer mp, TimedMetaData data)&lt;br /&gt;
     {&lt;br /&gt;
       byte[] iD3PayloadArray = data.getMetaData();&lt;br /&gt;
       String iD3Payload = new String(iD3PayloadArray, StandardCharsets.UTF_8);&lt;br /&gt;
       if (null != iD3Payload &amp;amp;&amp;amp; iD3Payload.contains(&amp;quot;www.nielsen.com&amp;quot;))&lt;br /&gt;
         {&lt;br /&gt;
           int index = iD3Payload.indexOf(&amp;quot;www.nielsen.com&amp;quot;);&lt;br /&gt;
           String id3String = iD3Payload.substring(index, (index + 249));&lt;br /&gt;
           Log.d(TAG, &amp;quot;TimedMetaData ID3 Tag:&amp;quot; + id3String);&lt;br /&gt;
           appProcessID3tag(id3String);&lt;br /&gt;
         }&lt;br /&gt;
     }&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== ExoPlayer ====&lt;br /&gt;
he SDK is designed around an event-driven architecture where components emit events to allow other components to listen and respond to state changes.&lt;br /&gt;
&lt;br /&gt;
'''Player SDK Classes used:'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;com.google.android.exoplayer.demo.player.DemoPlayer&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Since Nielsen App SDK is interested in extracting the Timed Metadata (ID3 Tags) in HLS and VOD on the EXO Player, trace the ID3_TAG emitted during video content played using EXOPlayer component as below.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;DemoPlayer implements ExoPlayer.Listener&lt;br /&gt;
—————————————————–&lt;br /&gt;
/**&lt;br /&gt;
* A listener for receiving ID3 metadata parsed from the media stream.&lt;br /&gt;
*/&lt;br /&gt;
public interface Id3MetadataListener&lt;br /&gt;
{&lt;br /&gt;
  void onId3Metadata(Map&amp;lt;String, Object&amp;gt; metadata);&lt;br /&gt;
}&lt;br /&gt;
——————————————————-&lt;br /&gt;
MetadataTrackRenderer.MetadataRenderer&amp;lt;Map&amp;lt;String,&lt;br /&gt;
Object&amp;gt;&amp;gt; getId3MetadataRenderer()&lt;br /&gt;
  {&lt;br /&gt;
    return new MetadataTrackRenderer.MetadataRenderer&amp;lt;Map&amp;lt;String, Object&amp;gt;&amp;gt;()&lt;br /&gt;
      {&lt;br /&gt;
        @Override&lt;br /&gt;
        public void onMetadata(Map&amp;lt;String, Object&amp;gt; metadata)&lt;br /&gt;
          {&lt;br /&gt;
            if (id3MetadataListener != null)&lt;br /&gt;
              {&lt;br /&gt;
                id3MetadataListener.onId3Metadata(metadata);&lt;br /&gt;
              }&lt;br /&gt;
          }&lt;br /&gt;
      };&lt;br /&gt;
  }&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Also in ''Player.java'' class:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;Player implements DemoPlayer.Id3MetadataListener&lt;br /&gt;
—————————————————–&lt;br /&gt;
@SuppressWarnings(&amp;quot;rawtypes&amp;quot;)&lt;br /&gt;
@Override&lt;br /&gt;
public void onId3Metadata(Map&amp;lt;String, Object&amp;gt; metadata)&lt;br /&gt;
{&lt;br /&gt;
  try&lt;br /&gt;
    {&lt;br /&gt;
      for (Object o : metadata.entrySet())&lt;br /&gt;
        {&lt;br /&gt;
          Map.Entry pairs = (Map.Entry) o;&lt;br /&gt;
          if (metadata.containsKey(TxxxMetadata.TYPE))&lt;br /&gt;
            {&lt;br /&gt;
              TxxxMetadata txxxMetadata = (TxxxMetadata) metadata&lt;br /&gt;
              .get(TxxxMetadata.TYPE);&lt;br /&gt;
            }&lt;br /&gt;
          else&lt;br /&gt;
            {&lt;br /&gt;
              String aStr = new String((byte[]) pairs.getValue());&lt;br /&gt;
              MainActivity.mAppSdk.sendID3(aStr);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
  catch (Exception e)&lt;br /&gt;
    {&lt;br /&gt;
      e.printStackTrace();&lt;br /&gt;
      Log.d(TAG, &amp;quot;onId3Metadata(): No Id3 tags&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:andr-exo-retrievingID3tags.png|link=]]&lt;br /&gt;
&lt;br /&gt;
==== Brightcove Player ====&lt;br /&gt;
While the Brightcove player plays the content, EventListener triggers an event when an ID3 packet is received (&amp;lt;code&amp;gt;SeamlessVideoDisplayComponent.ID3_TAG&amp;lt;/code&amp;gt;). Upon receiving this event, collect the incoming ID3 tags and only pass the Nielsen payload of the PRIV frame to the App SDK for analysis.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;brightcoveVideoView.getEventEmitter().on(SeamlessVideoDisplayComponent.ID3_TAG, new EventListener()&lt;br /&gt;
  {&lt;br /&gt;
    public void processEvent(Event event)&lt;br /&gt;
      {&lt;br /&gt;
        NlsId3Tag nlsID3 = new NlsId3Tag(event.properties.get(SeamlessVideoDisplayComponent.ID3_DATA).toString());&lt;br /&gt;
        Log.w(&amp;quot;ID3&amp;quot;, nlsID3.NlsPayload);&lt;br /&gt;
        // Sent ID3 Tags to App&lt;br /&gt;
        appProcessID3tag(nlsID3.NlsPayload);&lt;br /&gt;
      }&lt;br /&gt;
      });&lt;br /&gt;
  }&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Adobe PrimeTime Player ====&lt;br /&gt;
While the Adobe PrimeTime player plays the content, MediaPlayer.PlaybackEventListener triggers a callback when an ID3 packet is received (onTimedMetadata). Upon receiving this event, collect the incoming ID3 tags and only pass the Nielsen payload of the PRIV frame to the App SDK for analysis.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;public void onTimedMetadata(TimedMetadata id3Metadata)&lt;br /&gt;
{&lt;br /&gt;
  NlsId3Tag nlsID3 = new NlsId3Tag(id3Metadata.getMetadata().toString());&lt;br /&gt;
  Log.w(LOG_TAG, &amp;quot;ID3 Timed Data –&amp;gt; &amp;quot; + nlsID3.NlsPayload);&lt;br /&gt;
  Log.w(LOG_TAG, &amp;quot;PayLoad Size –&amp;gt; &amp;quot; + nlsID3.NlsPayload.length());&lt;br /&gt;
  appProcessID3tag(nlsID3.NlsPayload);&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== VisualOn Player ====&lt;br /&gt;
While the VisualOn player plays the content, &amp;lt;code&amp;gt;VOCommonPlayerListener&amp;lt;/code&amp;gt; triggers an event when an ID3 packet is received (&amp;lt;code&amp;gt;VO_OSMP_SRC_CUSTOMERTAGID_TIMEDTAG&amp;lt;/code&amp;gt;). Upon receiving this event, collect the incoming ID3 tags and only pass the Nielsen payload of the PRIV frame to the App SDK for analysis.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;case VO_OSMP_SRC_CB_CUSTOMER_TAG:&lt;br /&gt;
{&lt;br /&gt;
  VO_OSMP_SRC_CUSTOMERTAGID tag = VO_OSMP_SRC_CUSTOMERTAGID.valueOf(nParam1);&lt;br /&gt;
  switch (tag)&lt;br /&gt;
    {&lt;br /&gt;
      case VO_OSMP_SRC_CUSTOMERTAGID_TIMEDTAG:&lt;br /&gt;
      // do something with this tag&lt;br /&gt;
      int time = nParam2;&lt;br /&gt;
      byte[] b = (byte[]) obj;&lt;br /&gt;
      String s = new String(b);&lt;br /&gt;
      NlsId3Tag nlsID3 = new NlsId3Tag(b);&lt;br /&gt;
      // Sent ID3 Tags to App&lt;br /&gt;
      appProcessID3tag(nlsID3.NlsPayload);&lt;br /&gt;
      if (appid3If != null)&lt;br /&gt;
      appid3If.onId3(nlsID3.NlsPayload);&lt;br /&gt;
      break;&lt;br /&gt;
      case VO_OSMP_SRC_CUSTOMERTAGID_MAX:&lt;br /&gt;
      // ignore this type of tag&lt;br /&gt;
      break;&lt;br /&gt;
      default:&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
      break;&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== NextStream Player ====&lt;br /&gt;
ID3 tags will be received in the NexStream Player through &amp;lt;code&amp;gt;onTimedMetaRenderRender(NexPlayer mp,NexID3TagInformation metadata)&amp;lt;/code&amp;gt; callback API. A sample implementation for the callback is shown below:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;public void onTimedMetaRenderRender(NexPlayer mp, NexID3TagInformation m)&lt;br /&gt;
  {&lt;br /&gt;
    text = m.getPrivateFrame();&lt;br /&gt;
    if (text != null)&lt;br /&gt;
      {&lt;br /&gt;
        data = text.getTextData();&lt;br /&gt;
        if (data != null)&lt;br /&gt;
          {&lt;br /&gt;
            // make sure to identify the beginning  of  the&lt;br /&gt;
            // Nielsen ID3 tag payload by searching for the&lt;br /&gt;
            // &amp;quot;www.nielsen.com&amp;quot; string on the ID3 tag and&lt;br /&gt;
            // passing to the App SDK all information that&lt;br /&gt;
            // follows. It should be:&lt;br /&gt;
            // nlsPayload = &amp;quot;www.nielsen.com&amp;quot; + dataFollowing&lt;br /&gt;
            nlsPayload = getDataAfterWwwNielsenCom(data);&lt;br /&gt;
            if (nlsPayload!= NULL)&lt;br /&gt;
            mAppSdk.sendID3(nlsPayload);&lt;br /&gt;
          }&lt;br /&gt;
      }&lt;br /&gt;
  }&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The [[sendID3()]] sends the extracted Nielsen ID3 payload to the App SDK for analysis.&lt;br /&gt;
&lt;br /&gt;
== Android SDK API Methods &amp;amp; Properties ==&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Scenario !! Method / Property !! DTVR !! DAR !! DCR !! International (Germany) !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Initialize || [[AppSDK()]] || ✔ || ✔ || ✔ || ✔ || Used to create a new instance of the SDK object&lt;br /&gt;
|-&lt;br /&gt;
| Measurement || [[play()]] || ✔ || ✔ || ✔ || ✔ || Used when there is an ID3 fed product such as DTVR and the client does not want to send in all the CMS metadata that is sent in loadMetadata. This allows the client to send in at least the required “channel name” value associated to the ID3 feed. If this is not called then the “channel name” value populated will be the default value of “defaultChannelName”.&lt;br /&gt;
|-&lt;br /&gt;
| Measurement || [[loadMetadata()]] || ✔ || ✔ || ✔ || ✔ || Used when there is a preroll ad that needs to be associated with content metadata. The loadmetadata will first be called to populate the content metadata values and then the loadMetadata for ad metadata will be called. This allows sending a content ping with the ad info, even if the user bails out during the preroll ad.&lt;br /&gt;
|-&lt;br /&gt;
| Measurement || [[sendID3()]] || ✔ || ✘ || ✘ || ✘ || Used to send the ID3 metadata.&lt;br /&gt;
|-&lt;br /&gt;
| Measurement || [[setPlayheadPosition()]] || ✘ || ✘ || ✔ || ✔ || Used to send the playhead position.&lt;br /&gt;
|-&lt;br /&gt;
| Measurement || [[stop()]] || ✔ || ✘ || ✔ || ✔ || Used when playback is paused and when switching between ad and content or content and ad.&lt;br /&gt;
|-&lt;br /&gt;
| Measurement || [[end()]] || ✔ || ✘ || ✔ || ✔ || Used when content playback is complete. This is triggered 1) at the end of the content stream, 2) if the user switches to another piece of content&lt;br /&gt;
|-&lt;br /&gt;
| Measurement || [[staticEnd()]] ||   ||   || ✔ || ✔ || Used with DCR Static duration in between loadMetadata calls for static content when section name is the same but a new static view event and duration measurement restart is desired &lt;br /&gt;
|-&lt;br /&gt;
| Measurement || [[updateOTT()]] || ✘ || ✘ || ✘ || ✔ || Used to notify App SDK that the remote OTT device (like Google ChromeCast, Roku, Amazon FireTV, etc.) is connected / disconnected (change of OTT status).&lt;br /&gt;
|-&lt;br /&gt;
| Opt-out || [[userOptOutURLString()]] || ✔ || ✔ || ✔ || ✔ || Used to fetch the Nielsen opt-out web page URL.&lt;br /&gt;
|-&lt;br /&gt;
| Opt-out || [[userOptOut()]] || ✔ || ✔ || ✔ || ✔ || Used to supply the response message from opt-out webpage to the SDK.&lt;br /&gt;
|-&lt;br /&gt;
| Opt-out || [[getOptOutStatus()]] || ✘ || ✘ || ✘ || ✔ || Call this API to retrieve the Opt-Out or Opt-In state.&lt;br /&gt;
|-&lt;br /&gt;
| Opt-out&lt;br /&gt;
| [[appDisableApi()]]&lt;br /&gt;
(kill switch) &lt;br /&gt;
|| ✔ || ✔ || ✔ || ✔ || Used to disable the SDK.&lt;br /&gt;
|-&lt;br /&gt;
| Opt-out || [[getAppDisable()]] || ✔ || ✔ || ✔ || ✔ || Used to query if the SDK is disabled or not.&lt;br /&gt;
|-&lt;br /&gt;
| Log || [[getLastEvent()]] || ✔ || ✔ || ✔ || ✔ || Used to query the SDK for the last status&lt;br /&gt;
|-&lt;br /&gt;
| Log || [[getLastError()]] || ✔ || ✔ || ✔ || ✔ || Used to query the SDK for the last error&lt;br /&gt;
|-&lt;br /&gt;
| Log || [[isValid()]] || ✔ || ✔ || ✔ || ✔ || Used to check if the SDK was successfully instantiated or not.&lt;br /&gt;
|-&lt;br /&gt;
| Log || [[getMeterVersion()]] || ✘ || ✘ || ✘ || ✔ || Returns the current SDK version.&lt;br /&gt;
|-&lt;br /&gt;
| Log || [[getNielsenId()]] || ✔ || ✔ || ✔ || ✔ || Used to get a string defining the Nielsen ID (NUID) number for the device.&lt;br /&gt;
|-&lt;br /&gt;
| Log || [[getDeviceId()]] || ✔ || ✔ || ✔ || ✔ || Returns the current device id.&lt;br /&gt;
|-&lt;br /&gt;
| Log || [[getDemographicId()]] || ✔ || ✔ || ✔ || ✔ || Returns the current UAID for SDK v10.0.0.0+. Previous versions, it returns Demographic/Device ID of the device.&lt;br /&gt;
|-&lt;br /&gt;
| Log || [[appInBackground()]] || ✘ || ✘ || ✔ || ✔ || Used to capture the event of app going to background.&lt;br /&gt;
|-&lt;br /&gt;
| Log || [[appInForeground()]] || ✘ || ✘ || ✔ || ✔ || Used to capture the event of app coming to foreground&lt;br /&gt;
|-&lt;br /&gt;
| Log || [[setDebug()]] || ✘ || ✘ || ✘ || ✔ || Used to enable/disable debug flags. Newly introduced in SDK version 5.0.0 for International (Germany)&lt;br /&gt;
|-&lt;br /&gt;
| Viewability&amp;lt;br/&amp;gt;Audibility&lt;br /&gt;
| [[trackViewability()]]&lt;br /&gt;
|| ✔ ||   || ✔ || ✔ || Used to start the viewability measurement.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Android Opt-Out Implementation ==&lt;br /&gt;
To opt out, users must have access to &amp;quot;About Nielsen Measurement&amp;quot; page. User can click this page from app settings screen.&lt;br /&gt;
&lt;br /&gt;
Include '''About Nielsen Measurement and Your Choices''' link in the Privacy Policy / EULA or as a button near the link to the app's Privacy Policy.&lt;br /&gt;
*URL to this web page should be called from SDK by invoking [[userOptOutURLString()]] and opened in 'WebView' / External browser.&lt;br /&gt;
*If the App SDK returns NULL as Opt-Out URL, handle the exception gracefully and retry later.&lt;br /&gt;
*To retrieve the current Opt-Out status of a device, use the [[getOptOutStatus()]] method.&lt;br /&gt;
&lt;br /&gt;
=== Displaying Opt-Out in a WebView ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
optOutUrl = mAppSdk.userOptOutURLString();&lt;br /&gt;
if(optOutUrl !=null)&lt;br /&gt;
{&lt;br /&gt;
   mWebView = (WebView) findViewById(R.id.webView);&lt;br /&gt;
   mWebView.getSettings().setJavaScriptEnabled(true);&lt;br /&gt;
   mWebView.getSettings().setBuiltInZoomControls(true);&lt;br /&gt;
   mWebView.getSettings().setDisplayZoomControls(false);&lt;br /&gt;
   mWebView.getSettings().setLoadWithOverviewMode(true);&lt;br /&gt;
   mWebView.getSettings().setUseWideViewPort(true);&lt;br /&gt;
   mWebView.setWebViewClient(new MonitorWebView());&lt;br /&gt;
   mWebView.setWebChromeClient(new WebChromeClient());&lt;br /&gt;
   mWebView.loadUrl(optOutUrl);&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
   //Handle it gracefully and Retry later&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The app must provide access to &amp;quot;About Nielsen Measurement&amp;quot; page for the users. Include &amp;quot;About Nielsen Measurement&amp;quot; and Your Choices link in the Privacy Policy / EULA or as a button near the link to the app's Privacy Policy.&lt;br /&gt;
&lt;br /&gt;
[[File:Privacy policy iOS.jpg|link=]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note:''' When ‘WebView’ / External browser is closed, do not pass the status returned from ‘WebView’ / External browser to the SDK within the app, as the new Opt-Out page will not return any response.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note:''' App SDK manages the user’s choice (Opt-Out / Opt-In), the app does not need to manage this status.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sequence Diagram ===&lt;br /&gt;
[[File:optoutsequence-andr.jpg|link=]]&lt;br /&gt;
&lt;br /&gt;
== Opt-out Android SDK Version '''5.1.1.18 or above''' ==&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note:''' If using legacy Android SDK Versions 5.1.1.14 or below, or are not using Google Play Services, skip ahead to: [[#Opt-out for legacy SDK versions prior to 5.1.1.18 or if host application does not leverage Google Play Services|Opt-out for legacy SDK versions prior to 5.1.1.18 or if host application does not leverage Google Play Services]]&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Starting from SDK version 5.1.1.18, Opt-Out related behavior has been changed in the following ways:&lt;br /&gt;
*SDK will be sending the data pings to census even though SDK is opted out (In earlier releases all the traffic from SDK to census will be ceased). However, all the outgoing pings will have the parameter uoo=true using which backend can ignore this data.&lt;br /&gt;
*Current Opt-Out page is now updated to have no hyperlinks for Opt-Out / Opt-In operations. SDK Opt-Out has to be done via&lt;br /&gt;
'''Google Settings → Ads → Opt out of Ads Personalization'''.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note:''' For Amazon devices, see [[#Opt-Out Implementation for Amazon Devices|Opt-Out Implementation for Amazon Devices]] below.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:andr-ads.jpg|link=]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note:''' For API Version 5.1 and above, App SDK will fire data pings and continue measurement even after the user has opted out from Nielsen measurement on a device. The data ping will be marked as opted-out ping.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Opt-out for legacy SDK versions prior to 5.1.1.18 or if host application does not leverage Google Play Services ==&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note:''' If using Android SDK Version 5.1.1.18 or above, refer to documentation above ([[#Opt-out Android SDK Version 5.1.1.18 or above|Opt-out Android SDK Version 5.1.1.18 or above]])&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When a user clicks the Opt-Out / Opt-In link, the application should invoke [[optOutURL]] to get the link to the Nielsen Privacy page from SDK.&lt;br /&gt;
=== Privacy Page ===&lt;br /&gt;
[[File:privacy-policy.jpg|link=]]&lt;br /&gt;
*There are two click here links – one for Opt-Out and one for Opt-In. Click the required link:&lt;br /&gt;
**Capture user’s selection&lt;br /&gt;
**Pass the selection back to the SDK via the [[userOptOut()]].&lt;br /&gt;
&lt;br /&gt;
=== Capture and forward user selection ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
private class MonitorWebView extends WebViewClient&lt;br /&gt;
{&lt;br /&gt;
  private static final String NIELSEN_URL_OPT_OUT = &amp;quot;nielsenappsdk://1&amp;quot;;&lt;br /&gt;
  private static final String NIELSEN_URL_OPT_IN = &amp;quot;nielsenappsdk://0&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
  @Override&lt;br /&gt;
  public boolean shouldOverrideUrlLoading(WebView view, String url)&lt;br /&gt;
  {&lt;br /&gt;
    if (NIELSEN_URL_OPT_OUT.equals(url)&lt;br /&gt;
      || NIELSEN_URL_OPT_IN.equals(url))&lt;br /&gt;
    {&lt;br /&gt;
      // Get AppSdk instance from the host&lt;br /&gt;
      AppSdk appSdk = HostApp.getAppSdk();&lt;br /&gt;
      // Send the URL to the AppSdk instance&lt;br /&gt;
      appSdk.userOptOut(url);&lt;br /&gt;
      return true;&lt;br /&gt;
    }&lt;br /&gt;
    return false;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note:''' When 'WebView' is closed, pass the status returned from 'WebView' to the SDK within the app.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note:''' App SDK manages the user's choice (Opt-Out / Opt-In), the app does not need to manage this status.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Opt-Out Implementation for Amazon Devices ==&lt;br /&gt;
Amazon device users can opt out or opt back into Nielsen Measurement, any time using the device’s setting – 'Limit Ad Tracking' (Interest-based ads).&lt;br /&gt;
&lt;br /&gt;
User is opted out of Nielsen Online Measurement when ‘Limit Ad Tracking’ is enabled.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''For devices running on Fire OS 5.1 and above, retrieve the Ad tracking value.'''&lt;br /&gt;
=== Retrieving Ad tracking Value ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
ContentResolver cr = getContentResolver();&lt;br /&gt;
int limitAdTracking = Secure.getInt(cr, &amp;quot;limit_ad_tracking&amp;quot;, 2);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
*Returns limit_ad_tracking value &amp;quot;0&amp;quot; if enabled&lt;br /&gt;
*Returns limit_ad_tracking value &amp;quot;1&amp;quot; if disabled&lt;br /&gt;
*Returns limit_ad_tracking value &amp;quot;2&amp;quot; if ad tracking is not supported (below Fire OS 5.1).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note:''' Google Play Services are not needed to retrieve ad tracking state on Amazon devices. Limit Ad Tracking can be accessed through '''Settings → Apps &amp;amp; Games → Advertising ID'''.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Nielsen Sample Applications ==&lt;br /&gt;
&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
=== Viewability testing ===&lt;br /&gt;
The sample applications shipped with client package have support for viewability metrics verification. The player view can be moved using a finger-dragging gesture or scrolling in the application window. This allows the tester to reduce the visible area of the player view and check the resulting data. Additional UI buttons:&lt;br /&gt;
*Cover View button opens a popup with multiple UI controls which allow changing a player view alpha and visibility as well as showing a cover view in front of the player view.&lt;br /&gt;
*Alert button allows for opening a native UI alert in the application.&lt;br /&gt;
[[File:PlayerView Zoomin.png|200px]]&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;[[File:PlayerView AlertView.png|200px]]&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;[[File:PlayerView Dragging.png|200px]]&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;[[File:PlayerView FriendlyViews.png|200px]]&lt;br /&gt;
&lt;br /&gt;
== Nielsen Privacy Requirements ==&lt;br /&gt;
Privacy protections that Nielsen ensures to have with each App SDK integration are as follows.&lt;br /&gt;
*Disclosure of viewership data collection in EULA / Privacy Policy&lt;br /&gt;
*A link in the EULA/Privacy policy, or in another conspicuous location within the App, to a Nielsen-hosted web page outlining what Nielsen is collecting and how it is being used&lt;br /&gt;
*Method for users to opt-out of Nielsen measurement, any time while using the application&lt;br /&gt;
&lt;br /&gt;
=== Ratings Data Flow ===&lt;br /&gt;
Every view of creditable and watermarked content is measured by Nielsen.&lt;br /&gt;
[[File:RatingsDataFlow.png]]&lt;br /&gt;
&lt;br /&gt;
'''Information NOT Shared'''&lt;br /&gt;
* '''With Nielsen'''&lt;br /&gt;
** User's Identity&lt;br /&gt;
* '''With Data Provider'''&lt;br /&gt;
** Content information&lt;br /&gt;
** Whether user is viewing an ad or video content&lt;br /&gt;
** Player used to play the streaming (audio / video, etc.)&lt;br /&gt;
** Values being de-duped / aggregating for&lt;br /&gt;
&lt;br /&gt;
Nielsen collects only what it needs for audience measurement. Every view of creditable, watermarked content will be measured by Nielsen.&lt;br /&gt;
&lt;br /&gt;
=== Data Collected ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type of Information !! Parameter !! Transmitted to Nielsen? !! Sent to Provider?&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;8&amp;quot; | Nielsen ID3 Watermark&lt;br /&gt;
|-&lt;br /&gt;
| FinalDistributor Timestamp || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| Program Content Timestamp || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| Mobile Breakout Code || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| Commercial Credit Code – Linear or Dynamic || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| Time ShiftedViewing Code || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| Segment Number || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| Segment View Pattern || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;10&amp;quot; | Device/App Info&lt;br /&gt;
|-&lt;br /&gt;
| Device OSVersion || Yes || Yes &lt;br /&gt;
|-&lt;br /&gt;
| Device Model || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| Device Advertiser ID (Apple IDFA or Google AdID/Android ID) || Yes || Yes &lt;br /&gt;
|-&lt;br /&gt;
| Cache Buster || Yes || Yes &lt;br /&gt;
|-&lt;br /&gt;
| App Version || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| App Name || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| SDKDisabled Flag || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| ServerCode || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| Channel or URL || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;9&amp;quot; | Nielsen Identifiers&lt;br /&gt;
|-&lt;br /&gt;
| Client ID || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| Campaign ID || Yes || Yes &lt;br /&gt;
|-&lt;br /&gt;
| Nielsen Unique Device ID || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| Application ID || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| DeviceGroup (ex. Tablet, Smartphone, Desktop) || Yes || Yes &lt;br /&gt;
|-&lt;br /&gt;
| OS Group (ex. Android, iOS, Windows) || Yes || Yes &lt;br /&gt;
|-&lt;br /&gt;
| SDKVersion || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| IP Address for DMA, Country Code || Yes || Yes &lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': Data is hashed, and encrypted using AES 128 before transmission to data provider.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Example ping sent to provider ====&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;https://provider.com/cgi-bin/brandlift.php&amp;lt;/nowiki&amp;gt;?campaign_id=ff12725d724fac7934cf6003f096b4cd&amp;lt;wbr /&amp;gt;&amp;amp;placement_id=a4164b8fba9ee7c873a9c72c7091bb58&amp;lt;wbr /&amp;gt;&amp;amp;creative_id=25280139b61a947e127a52f56c8a2fdd&amp;lt;wbr /&amp;gt;&amp;amp;segment1=9000&amp;lt;wbr /&amp;gt;&amp;amp;segment2=41&amp;lt;wbr /&amp;gt;&amp;amp;segment3=iOS&amp;lt;wbr /&amp;gt;&amp;amp;OSVer=iOS6.1&amp;lt;wbr /&amp;gt;&amp;amp;c9=&amp;lt;wbr /&amp;gt;&amp;amp;devgrp=tablet&amp;lt;wbr /&amp;gt;&amp;amp;h=f5f243fe6d&amp;lt;wbr /&amp;gt;&amp;amp;rnd=1376971827360&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This ping passes the following parameters to the provider:&lt;br /&gt;
* Campaign ID – (campaign, placement, creative)&lt;br /&gt;
* Country Code&lt;br /&gt;
* DMA&lt;br /&gt;
* OS Group (ex. iOS, Android)&lt;br /&gt;
* DeviceOS Version&lt;br /&gt;
* Device Advertiser ID&lt;br /&gt;
* DeviceGroup (ex. Tablet, Smartphone, Desktop)&lt;br /&gt;
* Cache Buster&lt;br /&gt;
&lt;br /&gt;
=== Nielsen Measurement Opt-Out ===&lt;br /&gt;
In accordance with Nielsen’s SDK licensing agreement, developers are required to provide basic informational data to users about Nielsen’s Privacy Policy with a navigation to additional information on Nielsen measurement.&lt;br /&gt;
&lt;br /&gt;
Nielsen currently uses Opt Out of Ads for Personalization for the latest versions of the SDK (5.1.1.18 and above). However, for older SDK versions, the app must provide a means for the user to opt out, or opt back in to Nielsen Measurement. Users can opt out of Nielsen online measurement research through this feature.&lt;br /&gt;
* If the user has this app running on more than one mobile device, the user will need to opt out of this measurement on each device.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': Opt Out feature does NOT rely on &amp;quot;Opt Out of Ads for Personalization&amp;quot; setting since Nielsen’s systems provide measurement metrics and do not serve ads to users.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Event and Error Handling ==&lt;br /&gt;
=== App SDK Event Codes ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Event Code !! Event Name !! Event Description&lt;br /&gt;
|-&lt;br /&gt;
| 2000 || EVENT_INITIATE || App SDK is initiated. It will happen as soon as the App SDK is initialized&lt;br /&gt;
|-&lt;br /&gt;
| 2001 || EVENT_STARTUP || App SDK has started up. It will happen only after App SDK has received a valid config file. This is the location in the code to acquire the value of [[userOptOutURLString()]].&lt;br /&gt;
|-&lt;br /&gt;
| 2002 || EVENT_SHUTDOWN || App SDK is shutting down. It will happen just before App SDK is destroyed&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== App SDK Error Codes ===&lt;br /&gt;
Constants with predefined error codes which the AppSdk object can generate.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Error Code !! Error Name !! Description !! Behavior&lt;br /&gt;
|-&lt;br /&gt;
| 1001 || ERROR_FAILED_CREATE_URL_STRING || Failed generating ping string due to error on parsing || Include last error message from URL parser&lt;br /&gt;
|-&lt;br /&gt;
| 1002 || ERROR_FAILED_RECEIVE_CONFIG || Failed to receive configuration file from Census || On 5th time, it will log event and keep requesting config 10 min apart&lt;br /&gt;
|-&lt;br /&gt;
| 1003 || ERROR_FAILED_PARSING_CONFIG || Failed parsing the config file JSON string || Include json error number/short message from iOS or Android&lt;br /&gt;
|-&lt;br /&gt;
| 1004 || ERROR_FAILED_PARSING_PLAY || Failed parsing the play() JSON string || Include JSON error number/short message from iOS or Android&lt;br /&gt;
|-&lt;br /&gt;
| 1005 || ERROR_FAILED_PARSING_METADATA || Failed parsing the play() JSON string || Include JSON error number/short message from iOS or Android&lt;br /&gt;
|-&lt;br /&gt;
| 1006 || ERROR_FAILED_GENERATING_PING || Failed creating ping before adding it to the UPLOAD table) || Include ping nol_url index, cadence to identify ping&lt;br /&gt;
|-&lt;br /&gt;
| 1007 || ERROR_FAILED_PROCESSOR_START || Failed starting data processor thread. Normally, that means a product || Include processor that failed to start&lt;br /&gt;
|-&lt;br /&gt;
| 1008 || ERROR_FAILED_PROCESS_ID3 || Failed processing data on a data processor. Normally, that means the input to a product || Include processor and data that failed to process (ID3 tag on a MTVR impression, for example)&lt;br /&gt;
|-&lt;br /&gt;
| 1009 || ERROR_FAILED_HTTP_SEND || Failed sending HTTP or HTTPS requests || Include HTTP error number&lt;br /&gt;
|-&lt;br /&gt;
| 1010 || ERROR_FAILED_SENDING_PING || Failed sending pings (on ANDROID, the ping on the UPLOAD table) || Include ping up to 80 char from the end&lt;br /&gt;
|-&lt;br /&gt;
| 1011 || ERROR_FAILED_SENDING_TSV || Failed sending TSV requests || Include TSV request message&lt;br /&gt;
|-&lt;br /&gt;
| 1012 || ERROR_FAILED_SENDING_STATION_ID || Failed sending Station ID requests || Include Station ID request message&lt;br /&gt;
|-&lt;br /&gt;
| 1013 || ERROR_FAILED_ACCESSING_DB || Failed read/write from/to database table || Include SQL statement and data and SQLite error number/message&lt;br /&gt;
|-&lt;br /&gt;
| 1014 || ERROR_CHANGED_DEVICE_ID || Device ID changed ||&lt;br /&gt;
|-&lt;br /&gt;
| 1015 || ERROR_CHANGED_NUID || NUID changed ||&lt;br /&gt;
|-&lt;br /&gt;
| 1016 || ERROR_SDK_NOT_INITIALIZED || App SDK initialization failed ||&lt;br /&gt;
|-&lt;br /&gt;
| 1017 || ERROR_FAILED_SDK_SUSPEND || App SDK failed to suspend activities ||&lt;br /&gt;
|-&lt;br /&gt;
| 1018 || ERROR_INVALID_PARAMETERS || App SDK invalid parameters ||&lt;br /&gt;
|-&lt;br /&gt;
| 1019 || ERROR_INVALID_STATE || App SDK called in incorrect state ||&lt;br /&gt;
|-&lt;br /&gt;
| 1020 || ERROR_FAILED_PROCESS_PLAYHEAD || App SDK failed processing playhead position ||&lt;br /&gt;
|-&lt;br /&gt;
| 1021 || ERROR_FAILED_PROCESS_METADATA || App SDK failed processing not-null, syntax valid JSON metadada ||&lt;br /&gt;
|-&lt;br /&gt;
| 1022 || ERROR_FAILED_PROCESS_STOP || App SDK failed processing stop ||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Viewability and Audibility Implementation ==&lt;br /&gt;
Viewability metrics will allow AppSDK to track the visibility of the player and collect information about how much the player container is visible to the end user while playback is occurring. &lt;br /&gt;
&lt;br /&gt;
The viewability pings will be fired following the same rules as for measurement pings. These pings will be POST requests, not GET requests like other data pings. POST body for viewability requests will contain the key-value pairs in JSON format. The key parameters in the URL schemes are '''invs, inau, inss, invp''' and '''ines''' which will contain the collected viewability data. This data will be formatted according to the specific rules so that downstream it will be possible to match measurement and viewability data for a session.&lt;br /&gt;
&lt;br /&gt;
Audibility metrics will capture the volume level as well as mute/unmute state of the device while playback is occurring.&lt;br /&gt;
&lt;br /&gt;
=== Data Collected ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Measured Value || Value is different for different request parameters:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''invs''' ||  Intersection ratio for the target view in percent (from 0 to 100). Default threshold for this value is 5. Example: ['''50''',1,1528457356,10]&lt;br /&gt;
|-&lt;br /&gt;
| '''inau''' || Volume level on the device in percent (from 0 to 100), where 0 - mute, 100 - max volume level. Default threshold for this value is 1. Example: ['''30''',1,1528457356,10]&lt;br /&gt;
|-&lt;br /&gt;
| '''inss''' || Device screen size as &amp;quot;WxH&amp;quot;, where W - is width in pixels, H - is height in pixels. Example: ['''&amp;quot;1024x768&amp;quot;''',1,1528457356,10]&lt;br /&gt;
|-&lt;br /&gt;
| '''invp''' || Current window size. It is different than the device screen size in a multiple scene mode or on a desktop. Format is &amp;quot;WxH&amp;quot;, where W - is width in pixels, H - is height in pixels. Example: ['''&amp;quot;800x600&amp;quot;''',1,1528457356,10]&lt;br /&gt;
|-&lt;br /&gt;
| '''ines''' || Player view size as &amp;quot;WxH&amp;quot;, where W - is width in pixels, H - is height in pixels. Example: ['''&amp;quot;300x200&amp;quot;''',1,1528457356,10]&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| Start offset || Value contains the first playhead or the first id3 offset with non-null CID after start, flush or resume. Example playhead: [50,'''1''',1528457356,10]. Example id3 offset: [50,'''70100''',1528457356,10]&lt;br /&gt;
|-&lt;br /&gt;
| Start timestamp || Timestamp value when the time period related to this time series item was started. Example: [50,1,'''1528457356''',10]&lt;br /&gt;
|-&lt;br /&gt;
| Duration || Duration value is calculated as a difference between the last playhead and the first playhead for the current time series item. Example: [50,1,1528457356,'''10''']&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Viewability support requires additional parameters to be provided from player applications to the SDK. In order to provide these parameters and to start the viewability measurement the following method has been added to the public SDK API (please refer to the [[trackViewability()|trackViewability public API reference]] for the details and usage examples):&lt;br /&gt;
&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
void  trackViewability(JSONObject);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
For Audibility measurement APPSDK uses android system API in order to get an volume level for the device:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
AudioManager audio = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);&lt;br /&gt;
float currentVolume = audio.getStreamVolume(AudioManager.STREAM_MUSIC);&lt;br /&gt;
float maxVolume = audio.getStreamMaxVolume(AudioManager.STREAM_MUSIC);&lt;br /&gt;
int volumeLevel = (int) ((currentVolume/maxVolume) * 100);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>AnkitAgrawal</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=getDemographicId()&amp;diff=7251</id>
		<title>getDemographicId()</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=getDemographicId()&amp;diff=7251"/>
		<updated>2025-04-03T15:28:25Z</updated>

		<summary type="html">&lt;p&gt;AnkitAgrawal: v10.0.0.0 Changes&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|Android SDK API Reference}} {{CurrentBreadcrumb}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This API gets the current UAID for SDK v10.0.0.0+. Previous versions, it gets Demographic ID of the device. &lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
[[Category:Android SDK API Reference]]&lt;br /&gt;
'''Warning:''' calling getDemographicId() in main thread may cause deadlock, be sure to call in a background thread.&lt;br /&gt;
&lt;br /&gt;
== Syntax ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public String getDemographicId()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Input Parameters ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
| None || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Output Parameters ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Output Parameters (Return value) !! Description&lt;br /&gt;
|-&lt;br /&gt;
| String || Returns Demographic ID of the device.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>AnkitAgrawal</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=iOS_SDK_API_Reference&amp;diff=7250</id>
		<title>iOS SDK API Reference</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=iOS_SDK_API_Reference&amp;diff=7250"/>
		<updated>2025-04-03T15:25:30Z</updated>

		<summary type="html">&lt;p&gt;AnkitAgrawal: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
== Overview ==&lt;br /&gt;
The Nielsen SDK is one of multiple framework SDKs that Nielsen provides to enable measuring linear (live) and on-demand TV viewing using TVs, mobile devices, etc.&lt;br /&gt;
The App SDK is the framework for mobile application developers to integrate Nielsen Measurement into their media player applications. It supports a variety of Nielsen Measurement Products like Digital in TV Ratings, Digital Content Ratings ([[DCR &amp;amp; DTVR]]), and [[Digital Ad Ratings]] (DAR). Nielsen SDKs are also equipped to measure static content and can track key life cycle events of an application like:&lt;br /&gt;
*Application launch events and how long app was running&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
To start using the App SDK, the following items are required:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 30px;&amp;quot; |&lt;br /&gt;
! style=&amp;quot;width: 15%;&amp;quot; | Item&lt;br /&gt;
! Description&lt;br /&gt;
! Source&lt;br /&gt;
|-&lt;br /&gt;
|| ☑ || '''App ID (appid)''' || Unique ID assigned to the player/site and configured by product. || Contact Nielsen&lt;br /&gt;
|-&lt;br /&gt;
|| ☑ || '''sfcode''' || Environment that the SDK must point to || Contact Nielsen&lt;br /&gt;
|-&lt;br /&gt;
|| ☑ || '''Nielsen SDK''' || Includes SDK frameworks and '''sample implementation'''; ''See [[iOS SDK Release Notes]]'' || [[Special:Downloads|Download]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
If you do not have any of these pre-requisites or if you have any questions, please contact our SDK sales support team.&lt;br /&gt;
Refer to [[Digital Measurement Onboarding]] guide for information on how to get a Nielsen App SDK and appid.&lt;br /&gt;
==SDK Implementation==&lt;br /&gt;
Information on how to obtain, how to configure your development environment, and how to Initialize the Nielsen SDK is located in either the [[DCR Video iOS SDK|DCR Implementation Guide,]] or the [[DTVR iOS SDK|DTVR Implementation Guide]] depending on your requirements.&lt;br /&gt;
___TOC___&lt;br /&gt;
&lt;br /&gt;
== Nielsen iOS App SDK Application Life Cycle ==&lt;br /&gt;
&lt;br /&gt;
[[File:initialization_appcycle.png|center|link=]]&lt;br /&gt;
&lt;br /&gt;
Life cycle of SDK instance includes four general states:&lt;br /&gt;
# '''Initial state''' – The SDK is not initialized and hence, not ready to process playing information. Once the SDK is moved out of this state, it needs instantiation of the new SDK instance in order to get the instance in the '''Idle state'''.&lt;br /&gt;
# '''Idle state''' – The SDK is initialized and is ready to process playing information. Once Initialized, the SDK instance is not processing any data, but is listening for an event to occur.&lt;br /&gt;
# '''Processing state''' – The SDK instance is processing playing information. The &amp;lt;code&amp;gt;'''play'''&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;'''loadMetadata''' &amp;lt;/code&amp;gt; calls move the SDK instance into this state. In this state, the SDK instance will be able to process the following calls.&lt;br /&gt;
## &amp;lt;code&amp;gt;'''playheadPosition'''&amp;lt;/code&amp;gt; – Call this API every one second when playhead position is active.  If a LIVE event, use the current UNIX timestamp (seconds since Jan-1-1970 UTC).&lt;br /&gt;
## &amp;lt;code&amp;gt;'''stop'''&amp;lt;/code&amp;gt; – Call this API when the playback is paused, switches between content and ad (within the same content playback) or encounters interruptions.&lt;br /&gt;
## &amp;lt;code&amp;gt;'''end'''&amp;lt;/code&amp;gt; – SDK instance exits from Processing state when this API is called.&lt;br /&gt;
# '''Disabled state''' – The SDK instance is disabled and is not processing playing information. &lt;br /&gt;
## &amp;lt;code&amp;gt;'''appDisableApi'''&amp;lt;/code&amp;gt; is set to &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note:''' For API Version 5.1 and above, App SDK will fire data pings and continue measurement even after the user has opted out from Nielsen measurement on a device. The data ping will be marked as opted-out ping.&lt;br /&gt;
&lt;br /&gt;
'''Note''': In case of any interruptions during playback due to alarm, calendar, call, flight mode, Wi-Fi toggle, channel change, etc., call [[stop]] to stop the measurement.&lt;br /&gt;
* As soon as the playback resumes, call &amp;lt;code&amp;gt;'''play'''&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;'''loadMetadata''' &amp;lt;/code&amp;gt; and   &amp;lt;code&amp;gt;'''playheadPosition'''&amp;lt;/code&amp;gt; &amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:appsdkTimeline-DCR.png|icon|link=]]&lt;br /&gt;
=== Finite-state machine table ===&lt;br /&gt;
This table provides the possible changes of state for the SDK instance, when it is in a specific state and receives an API call.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! API call received !! Initial State !! Idle State !! Processing State !! Disabled State&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;[[initWithAppInfo:delegate:]]&amp;lt;/code&amp;gt; || IDLE STATE (OR)&lt;br /&gt;
&lt;br /&gt;
DISABLED STATE&lt;br /&gt;
|| IDLE STATE || - || -&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;[[play]]&amp;lt;/code&amp;gt; &amp;amp; &amp;lt;code&amp;gt;[[loadMetadata]]&amp;lt;/code&amp;gt;|| - || PROCESSING&lt;br /&gt;
&lt;br /&gt;
STATE&lt;br /&gt;
|| - || -&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;[[playheadPosition]]&amp;lt;/code&amp;gt; || - || - || PROCESSING&lt;br /&gt;
&lt;br /&gt;
STATE&lt;br /&gt;
|| -&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;[[sendID3]]&amp;lt;/code&amp;gt; || - || - || PROCESSING&lt;br /&gt;
&lt;br /&gt;
STATE&lt;br /&gt;
|| -&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;[[stop]]&amp;lt;/code&amp;gt; || - || - || IDLE STATE || -&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;[[end]]&amp;lt;/code&amp;gt; || - || - || IDLE STATE || -&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;[[appDisableApi]]&amp;lt;/code&amp;gt;: YES || - || DISABLED&lt;br /&gt;
&lt;br /&gt;
STATE&lt;br /&gt;
|| - || -&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;[[appDisableApi]]&amp;lt;/code&amp;gt;: NO || - || - || - || IDLE STATE (OR)&lt;br /&gt;
&lt;br /&gt;
DISABLED STATE&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;[[userOptOut]]&amp;lt;/code&amp;gt;: YES || - || - || IDLE STATE || -&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;[[userOptOut]]&amp;lt;/code&amp;gt;: NO || - || PROCESSING&lt;br /&gt;
&lt;br /&gt;
STATE&lt;br /&gt;
| - &lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
| colspan = 5 | '-' indicates that no API call is expected.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Handling JSON Metadata ===&lt;br /&gt;
All the SDK methods handles only two types of objects: NSString, NSDictionary. The parameters passed must be either a JSON formatted string or a NSDictionary object. The JSON passed in the SDK must be well-formed.&lt;br /&gt;
* NSDictionary object&lt;br /&gt;
** If an object of unexpected type is passed to the method, the error message will be logged.&lt;br /&gt;
** If string has invalid JSON format, the error message will be logged.&lt;br /&gt;
* JSON value must be string value.&lt;br /&gt;
** This includes boolean and numeric values. For example, a value of true should be represented with &amp;quot;true&amp;quot;, number value 123 should be &amp;quot;123&amp;quot;.&lt;br /&gt;
** All the Variable Names like appid, appname, sfcode, dataSrc, title, type etc. are case-sensitive. Use the correct variable name as specified in the documentation.&lt;br /&gt;
* JSON string can be prepared using either raw NSString or serialized NSDictionary.&lt;br /&gt;
The below is a sample - detailed information on the '''metadata requirements''' are located in either the [[DCR Video iOS SDK|DCR Implementation Guide,]] or the [[DTVR iOS SDK|DTVR Implementation Guide]] &lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Swift = &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
let contentMetadata = [&lt;br /&gt;
    &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;,&lt;br /&gt;
    &amp;quot;assetid&amp;quot;: &amp;quot;C77664&amp;quot;,&lt;br /&gt;
    &amp;quot;title&amp;quot;: &amp;quot;Program S2, E3&amp;quot;,&lt;br /&gt;
    &amp;quot;isfullepisode&amp;quot;: &amp;quot;Yes&amp;quot;,&lt;br /&gt;
    &amp;quot;program&amp;quot;: &amp;quot;Program Name&amp;quot;,&lt;br /&gt;
    &amp;quot;length&amp;quot;: &amp;quot;3600&amp;quot;,&lt;br /&gt;
    &amp;quot;airdate&amp;quot;: &amp;quot;20171020 10:05:00&amp;quot;,&lt;br /&gt;
    &amp;quot;adloadtype&amp;quot;: &amp;quot;2&amp;quot;,&lt;br /&gt;
    &amp;quot;segB&amp;quot;: &amp;quot;CustomSegmentValueB&amp;quot;, //optional&lt;br /&gt;
    &amp;quot;segC&amp;quot;: &amp;quot;CustomSegmentValueC&amp;quot;, //optional&lt;br /&gt;
];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;     &lt;br /&gt;
|Objective C = &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt; &lt;br /&gt;
NSDictionary * contentMetadata = @ {&lt;br /&gt;
    @ &amp;quot;type&amp;quot;: @ &amp;quot;content&amp;quot;,&lt;br /&gt;
        @ &amp;quot;assetid&amp;quot;: @ &amp;quot;C77664&amp;quot;,&lt;br /&gt;
        @ &amp;quot;title&amp;quot;: @ &amp;quot;S2,E3&amp;quot;,&lt;br /&gt;
        @ &amp;quot;isfullepisode&amp;quot;: @ &amp;quot;y&amp;quot;,  &lt;br /&gt;
        @ &amp;quot;program&amp;quot;: @ &amp;quot;Program Name&amp;quot;,&lt;br /&gt;
        @ &amp;quot;length&amp;quot;: @ &amp;quot;3600&amp;quot;,&lt;br /&gt;
        @ &amp;quot;airdate&amp;quot;: @ &amp;quot;20180120 10:00:00&amp;quot;,&lt;br /&gt;
        @ &amp;quot;adloadtype&amp;quot;: @ &amp;quot;2&amp;quot;,&lt;br /&gt;
        @ &amp;quot;segB&amp;quot;: @ &amp;quot;CustomSegmentValueB&amp;quot;, //optional&lt;br /&gt;
        @ &amp;quot;segC&amp;quot;: @ &amp;quot;CustomSegmentValueC&amp;quot;, //optional&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Retrieving ID3 Tags ==&lt;br /&gt;
'''Only required for DTVR clients'''&amp;lt;br&amp;gt;&lt;br /&gt;
'''Not applicable for German Clients'''&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ID3 tags have a payload of about 249 characters and start with &amp;quot;www.nielsen.com&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
ID3 tags are extracted by observing a property called timedMetadata on the iOS player item. Now this is done via a concept called KVO (Key Value Observing), where you register interest in a property, and the runtime will let you know when it has changed.&lt;br /&gt;
&lt;br /&gt;
Both the iOS native players have the ability to extract ID3 tags, If any other player apart from iOS native players (AVPlayer, MPMoviePlayer) is used, check and ensure that the player has the capability to extract ID3 tags.&lt;br /&gt;
&lt;br /&gt;
=== Examples of extracting ID3 tags from the iOS Native Player ===&lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Objective C = &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
    //Adding observer to player to track play,pause and reverse&lt;br /&gt;
    [player addObserver:self&lt;br /&gt;
             forKeyPath:@&amp;quot;rate&amp;quot;&lt;br /&gt;
                options:(NSKeyValueObservingOptionNew)&lt;br /&gt;
                context:nil];&lt;br /&gt;
  &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
------------------------------&lt;br /&gt;
  &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;       &lt;br /&gt;
        //Setting observer to track timedMetadata&lt;br /&gt;
        [player addObserver:self&lt;br /&gt;
                 forKeyPath: timedMetadataKey&lt;br /&gt;
                    options: (NSKeyValueObservingOptionNew)&lt;br /&gt;
                    context: &amp;amp;TimedMetadataObserverContext];&lt;br /&gt;
  &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
------------------------------&lt;br /&gt;
  &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;     &lt;br /&gt;
- (void)observeValueForKeyPath:(NSString *)keyPath&lt;br /&gt;
                      ofObject:(id)object&lt;br /&gt;
                        change:(NSDictionary *)change&lt;br /&gt;
                       context:(void *)context&lt;br /&gt;
{&lt;br /&gt;
    if(keyPath == timedMetadataKey){&lt;br /&gt;
        if(context == &amp;amp;TimedMetadataObserverContext){&lt;br /&gt;
            &lt;br /&gt;
            id newMetadataArray = [change objectForKey:NSKeyValueChangeNewKey];&lt;br /&gt;
            if (newMetadataArray != [NSNull null])&lt;br /&gt;
            {&lt;br /&gt;
                array = newMetadataArray;&lt;br /&gt;
                for (AVMetadataItem *metadataItem in array)&lt;br /&gt;
                {&lt;br /&gt;
                    //Handling TimedMetadata&lt;br /&gt;
                    [self handleTimedMetadata: metadataItem];&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
------------------------------&lt;br /&gt;
  &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;     &lt;br /&gt;
- (void)handleTimedMetadata:(AVMetadataItem *)timedMetadata&lt;br /&gt;
{&lt;br /&gt;
    // We expect the content to contain plists encoded as timed metadata&lt;br /&gt;
    // AVPlayer turns these into NSDictionaries&lt;br /&gt;
    &lt;br /&gt;
    id extraAttributeType = [timedMetadata extraAttributes];&lt;br /&gt;
    NSString *extraString = nil;&lt;br /&gt;
    if ([extraAttributeType isKindOfClass:[NSDictionary class]])&lt;br /&gt;
    {&lt;br /&gt;
        extraString = [extraAttributeType valueForKey:@&amp;quot;info&amp;quot;];&lt;br /&gt;
    }&lt;br /&gt;
    else if ([extraAttributeType isKindOfClass:[NSString class]])&lt;br /&gt;
    {&lt;br /&gt;
        extraString = extraAttributeType;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    NSString *key = [NSString stringWithFormat:@&amp;quot;%@&amp;quot;, [timedMetadata key]];&lt;br /&gt;
    &lt;br /&gt;
    //If tag starts with &amp;quot;www.nielsen.com&amp;quot;, then only sending to SDK&lt;br /&gt;
    if ([key isEqualToString:@&amp;quot;PRIV&amp;quot;] &amp;amp;&amp;amp; [extraString rangeOfString:@&amp;quot;www.nielsen.com&amp;quot;].length &amp;gt; 0)&lt;br /&gt;
    {&lt;br /&gt;
        &lt;br /&gt;
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{&lt;br /&gt;
            [nielsenApi sendID3:extraString];&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Swift = &amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt; &lt;br /&gt;
      //Setting observer to track timedMetadata&lt;br /&gt;
            player.addObserver(self, forKeyPath: timedMetadataKey, options: NSKeyValueObservingOptions.new, context: &amp;amp;TimedMetadataObserverContext)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
------------------------------------------------------&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt; &lt;br /&gt;
   override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {&lt;br /&gt;
        &lt;br /&gt;
        if keyPath == timedMetadataKey {&lt;br /&gt;
            if(context == &amp;amp;TimedMetadataObserverContext){&lt;br /&gt;
                if change != nil {&lt;br /&gt;
                    let timedMetadataArray = change![.newKey]&lt;br /&gt;
                    if timedMetadataArray != nil &amp;amp;&amp;amp; (timedMetadataArray! as AnyObject) is Array&amp;lt;Any&amp;gt; {&lt;br /&gt;
                        for item in timedMetadataArray as! [AVMetadataItem]  {&lt;br /&gt;
                            //Handling TimedMetadata&lt;br /&gt;
                            self.handleTimedMetadata(metadataItem: item)&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
------------------------------------------------------&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt; &lt;br /&gt;
 func handleTimedMetadata(metadataItem: AVMetadataItem) {&lt;br /&gt;
        guard let extraAttributeType = metadataItem.extraAttributes else {&lt;br /&gt;
            return&lt;br /&gt;
        }&lt;br /&gt;
        let info : AVMetadataExtraAttributeKey = AVMetadataExtraAttributeKey(rawValue: &amp;quot;info&amp;quot;)&lt;br /&gt;
        let extraString = extraAttributeType[info] as AnyObject&lt;br /&gt;
        let key = metadataItem.key as! String&lt;br /&gt;
        &lt;br /&gt;
        //If tag starts with &amp;quot;www.nielsen.com&amp;quot;, then only sending to SDK&lt;br /&gt;
        if key == &amp;quot;PRIV&amp;quot; &amp;amp;&amp;amp; extraString.range(of: &amp;quot;www.nielsen.com&amp;quot;).length &amp;gt; 0 {&lt;br /&gt;
            &lt;br /&gt;
            DispatchQueue.global(qos: .default).async { () -&amp;gt; Void in&lt;br /&gt;
                self.nielsenApi?.sendID3(extraString as! String)&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note:''' ID3 tags are not applicable for International (Germany)&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== IOS SDK API Methods &amp;amp; Properties ==&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Scenario !! Method / Property !! DTVR !! DAR !! DCR !! International (Germany) !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Initialize || [[initWithAppInfo:delegate:]] || ✔ || ✔ || ✔ || ✔ || Used to create a new instance of the SDK object&lt;br /&gt;
|-&lt;br /&gt;
| Measurement || [[play]] || ✔ || ✔ || ✔ || ✔ || Used when there is an ID3 fed product such as DTVR and the client does not want to send in all the CMS metadata that is sent in loadMetadata. This allows the client to send in at least the required “channel name” value associated to the ID3 feed. If this is not called then the “channel name” value populated will be the default value of “defaultChannelName”.&lt;br /&gt;
|-&lt;br /&gt;
| Measurement || [[loadMetadata]] || ✔ || ✔ || ✔ || ✔ || Used to send ad or content metadata to the SDK in the form of JSON string. Application constructs a JSON hashmap and calls this API.&lt;br /&gt;
|-&lt;br /&gt;
| Measurement || [[sendID3]] || ✔ ||   ||   ||   || Used to send the ID3 metadata.&lt;br /&gt;
|-&lt;br /&gt;
| Measurement || [[playheadPosition]] ||   ||   || ✔ || ✔ || Used to send the playhead position.&lt;br /&gt;
|-&lt;br /&gt;
| Measurement || [[stop]] || ✔ ||   || ✔ || ✔ || Used when playback is paused and when switching between ad and content or content and ad.&lt;br /&gt;
|-&lt;br /&gt;
| Measurement || [[end]] || ✔ || ✔ || ✔ || ✔ || Used when content playback is complete. This is triggered 1) at the end of the content stream, 2) if the user switches to another piece of content&lt;br /&gt;
|-&lt;br /&gt;
| Measurement || [[staticEnd]] ||   ||   || ✔ || ✔ || Used with DCR Static duration in between loadMetadata calls for static content when section name is the same but a new static view event and duration measurement restart is desired &lt;br /&gt;
|-&lt;br /&gt;
| Measurement || [[updateOTT]] ||   ||   ||   || ✔ || Used to notify App SDK that the remote OTT device (like Google ChromeCast, Roku, Amazon FireTV, etc.) is connected / disconnected (change of OTT status).&lt;br /&gt;
|-&lt;br /&gt;
| Opt-out || [[optOutURL]] || ✔ || ✔ || ✔ || ✔ || Used to fetch the Nielsen opt-out web page URL.&lt;br /&gt;
|-&lt;br /&gt;
| Opt-out || [[userOptOut]] || ✔ || ✔ || ✔ || ✔ || Used to supply the response message from opt-out webpage to the SDK.&lt;br /&gt;
|-&lt;br /&gt;
| Opt-out || [[optOutStatus]] || ✔ || ✔ || ✔ || ✔ || Call this API to retrieve the Opt-Out or Opt-In state.&lt;br /&gt;
|-&lt;br /&gt;
| Opt-out&lt;br /&gt;
| [[appDisableApi]]&lt;br /&gt;
(kill switch) &lt;br /&gt;
|| ✔ || ✔ || ✔ || ✔ || Used to disable the SDK.&lt;br /&gt;
|-&lt;br /&gt;
| Viewability&amp;lt;br/&amp;gt;Audibility&lt;br /&gt;
| [[trackViewability]]&lt;br /&gt;
|| ✔ ||   || ✔ || ✔ || Used to start the viewability measurement.&lt;br /&gt;
|-&lt;br /&gt;
| Log || [[lastErrorDict]] || ✔ || ✔ || ✔ || ✔ || Returns SDK error in the form of dictionary if any error has occurred.&lt;br /&gt;
|-&lt;br /&gt;
| Log || [[lastEventDict]] || ✔ || ✔ || ✔ || ✔ || Returns SDK event in the form of dictionary if any event has occurred.&lt;br /&gt;
|-&lt;br /&gt;
| Log || [[meterVersion]] || ✔ || ✔ || ✔ || ✔ || Returns the current SDK version.&lt;br /&gt;
|-&lt;br /&gt;
| Log || [[nielsenId]] || ✔ || ✔ || ✔ || ✔ || Used to get a string defining the Nielsen ID (NUID) number for the device.&lt;br /&gt;
|-&lt;br /&gt;
| Log || [[demographicId]] || ✔ || ✔ || ✔ || ✔ || Used to retrieve UAID(v10.0.0.0+)/Demographic ID (Device ID) of the current device.&lt;br /&gt;
|-&lt;br /&gt;
| Log || [[deviceId]] || ✔ || ✔ || ✔ || ✔ || Used to get a Device ID of the current device(Introduced in v10.0.0.0).&lt;br /&gt;
|-&lt;br /&gt;
| Log || [[debug]] || ✔ || ✔ || ✔ || ✔ || Used to enable/disable debug flags. Newly introduced in SDK version 5.0.0 for International (Germany)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== NielsenAppApi Class Description ==&lt;br /&gt;
The NielsenAppApi class is the primary application interface to the Nielsen App SDK. For example, after an instance object of the NielsenAppApi class is created and initialized, it can be used by the calling application to collect HLS timed metadata using the SDK’s [[sendID3]]: method. These are the public methods and properties exposed by the NielsenAppApi class:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
@interface NielsenAppApi: NSObject&lt;br /&gt;
&lt;br /&gt;
  @property (readonly) BOOL optOutStatus;&lt;br /&gt;
  @property (assign) BOOL appDisableApi;&lt;br /&gt;
  @property (assign) BOOL debug;&lt;br /&gt;
  @property (readonly, nonnull) NSString *nielsenId;&lt;br /&gt;
  @property (readonly, nonnull) NSString *demographicId;&lt;br /&gt;
  @property (readonly, nonnull) NSString *deviceId;&lt;br /&gt;
  @property (readonly, nonnull) NSString *firstPartyId;&lt;br /&gt;
  @property (readonly, nonnull) NSString *vendorId;&lt;br /&gt;
  @property (readonly, nonnull) NSString *optOutURL;&lt;br /&gt;
  @property (readonly, nullable) NSString *meterVersion;&lt;br /&gt;
  @property (readonly, nullable) NSDictionary *lastEventDict;&lt;br /&gt;
  @property (readonly, nullable) NSDictionary *lastErrorDict;&lt;br /&gt;
&lt;br /&gt;
  - (nullable instancetype)initWithAppInfo:(nonnull id)appInfo delegate:(nullable id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate&lt;br /&gt;
&lt;br /&gt;
  - (void)play:(nullable id)channelInfo;&lt;br /&gt;
  - (void)loadMetadata:(nullable id)metadata;&lt;br /&gt;
  – (void)stop;&lt;br /&gt;
  – (void)end;&lt;br /&gt;
  - (void)playheadPosition:(long long)playheadPos;&lt;br /&gt;
  - (void)sendID3:(nonnull NSString *)data;&lt;br /&gt;
  - (void)updateOTT:(nonnull id)ottInfo;&lt;br /&gt;
  - (BOOL)userOptOut:(nonnull NSString *)optOut;&lt;br /&gt;
  - (void)trackViewability:(nonnull NSDictionary *)data;&lt;br /&gt;
&lt;br /&gt;
  - (nonnull NSString *)getNielsenId __attribute((deprecated((&amp;quot;nielsenId is not used by the SDK anymore&amp;quot;))));&lt;br /&gt;
  - (nonnull NSString *)optOutURLString __attribute((deprecated((&amp;quot;Please use optOutURL property instead.&amp;quot;))));&lt;br /&gt;
  - (nullable NSString *)getMeterVersion __attribute((deprecated((&amp;quot;Please use meterVersion property instead.&amp;quot;))));&lt;br /&gt;
  - (nullable NSDictionary *)getLastEventDict __attribute((deprecated((&amp;quot;Please use lastEventDict property instead.&amp;quot;))));&lt;br /&gt;
  - (nullable NSDictionary *)getLastErrorDict __attribute((deprecated((&amp;quot;Please use lastErrorDict property instead.&amp;quot;)))); &lt;br /&gt;
&lt;br /&gt;
  @protocol NielsenAppApiDelegate &amp;lt;NSObject&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  @optional&lt;br /&gt;
  - (void)nielsenAppApi:(nonnull NielsenAppApi *)appApi eventOccurred:(nonnull NSDictionary *)event;&lt;br /&gt;
  - (void)nielsenAppApi:(nonnull NielsenAppApi *)appApi errorOccurred:(nonnull NSDictionary *)error;&lt;br /&gt;
&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== AppApiEventCode ===&lt;br /&gt;
An enumeration with predefined App SDK event state transition codes.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
typedef NS_ENUM(unsigned int, AppApiEventCode)&lt;br /&gt;
{&lt;br /&gt;
     AppApiStartup = 2001,&lt;br /&gt;
     AppApiShutdown = 2002,&lt;br /&gt;
}AppApiEventCode;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== App SDK Event Codes ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Event Code !! Event Name !! Event Description&lt;br /&gt;
|-&lt;br /&gt;
| 2001 || AppApiStartup || App SDK has initialized successfully. It will happen only after App SDK has received a valid config file&lt;br /&gt;
|-&lt;br /&gt;
| 2002 || AppApiShutdown || App SDK is shutting down. It will happen just before App SDK is destroyed&lt;br /&gt;
|}&lt;br /&gt;
=== AppApiErrorCode ===&lt;br /&gt;
iOS contains two types of error codes, 1-15 and 1001-1009.&lt;br /&gt;
&lt;br /&gt;
For, 1-15, an enumeration with predefined error codes which the App SDK object can generate.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;typedef NS_ENUM(unsigned int, LogCode) {&lt;br /&gt;
    LogCodeFailedParseStartInfo, // 1.&lt;br /&gt;
    LogCodeFailedParseMetadata, // 2.&lt;br /&gt;
    LogCodeFailedProcessID3, // 3.&lt;br /&gt;
    LogCodeFailedReceiveConfig, // 4.&lt;br /&gt;
    LogCodeFailedParseConfig, // 5.&lt;br /&gt;
    LogCodeFailedStartProcessor, // 6.&lt;br /&gt;
    LogCodeFailedCreateUrl, // 7.&lt;br /&gt;
    LogCodeFailedCreateRequest, // 8.&lt;br /&gt;
    LogCodeFailedSendHttpRequest, // 9.&lt;br /&gt;
    LogCodeFailedSendPing, // 10.&lt;br /&gt;
    LogCodeFailedSendTSV, // 11.&lt;br /&gt;
    LogCodeFailedSendStationRequest, // 12.&lt;br /&gt;
    LogCodeFailedAccessDatabase, // 13.&lt;br /&gt;
    LogCodeException, // 14.&lt;br /&gt;
    LogCodeInvalidPlayheadPosition, // 15.&lt;br /&gt;
    LogCodeLongAd, // 16.&lt;br /&gt;
    LogCodeIncorrectSfcode, // 17.&lt;br /&gt;
    LogCodeHemUidExceedLimit, // 18.&lt;br /&gt;
    LogCodeViewabilityUnableFindView // 19.&lt;br /&gt;
};&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For, 1001-1009, an enumeration with predefined error codes which the App SDK object can generate.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
typedef NS_ENUM(unsigned int, AppApiErrorCode)&lt;br /&gt;
{&lt;br /&gt;
   AppApiNetworkConnectionFailure = 1001,&lt;br /&gt;
   AppApiFileWriteFailure = 1002,&lt;br /&gt;
   AppApiFileReadFailure = 1003,&lt;br /&gt;
   AppApiEmptyValue = 1004,&lt;br /&gt;
   AppApiEmptyAppName = 1005,&lt;br /&gt;
   AppApiEmptyAppVersion = 1006,&lt;br /&gt;
   AppApiEmptyAppId = 1007,&lt;br /&gt;
   AppApiAnExceptionOccured = 1008,&lt;br /&gt;
   AppApiUnknownExceptionOccured = 1009&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== App SDK Error Codes ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Error Code !! Error Name !! Error Description&lt;br /&gt;
|-&lt;br /&gt;
| 1 || LogCodeFailedParseStartInfo || Failed to parse the play() JSON string&lt;br /&gt;
|-&lt;br /&gt;
| 2 || LogCodeFailedParseMetadata || Failed to parse the loadMetadata() JSON string&lt;br /&gt;
|-&lt;br /&gt;
| 3 || LogCodeFailedProcessID3 || Failed to process ID3 data on a data processor&lt;br /&gt;
|-&lt;br /&gt;
| 4 || LogCodeFailedReceiveConfig || Failed to receive configuration file from Census&lt;br /&gt;
|-&lt;br /&gt;
| 5 || LogCodeFailedParseConfig || Failed to parse the config file JSON string&lt;br /&gt;
|-&lt;br /&gt;
| 6 || LogCodeFailedStartProcessor || Failed to create SDK processor&lt;br /&gt;
|-&lt;br /&gt;
| 7 || LogCodeFailedCreateUrl || Failed to generate URL due to missing mandatory parameter&lt;br /&gt;
|-&lt;br /&gt;
| 8 || LogCodeFailedCreateRequest || Failed to create request in HTTP client&lt;br /&gt;
|-&lt;br /&gt;
| 9 || LogCodeFailedSendHttpRequest || Failed sending HTTP or HTTPS request&lt;br /&gt;
|-&lt;br /&gt;
| 10 || LogCodeFailedSendPing || Failed to send ping&lt;br /&gt;
|-&lt;br /&gt;
| 11 || LogCodeFailedSendTSV || Failed to send TSV request&lt;br /&gt;
|-&lt;br /&gt;
| 12 || LogCodeFailedSendStationRequest || Failed to send StationId request&lt;br /&gt;
|-&lt;br /&gt;
| 13 || LogCodeFailedAccessDatabase || Failed to read/write from/to database table&lt;br /&gt;
|-&lt;br /&gt;
| 14 || LogCodeException || Any exception handled by SDK code&lt;br /&gt;
|-&lt;br /&gt;
| 15 || LogCodeInvalidPlayheadPosition || Invalid playhead position&lt;br /&gt;
|-&lt;br /&gt;
| 16 || LogCodeLongAd || Long ad&lt;br /&gt;
|-&lt;br /&gt;
| 17 || LogCodeIncorrectSfcode || Incorrect client supplied sfcode&lt;br /&gt;
|-&lt;br /&gt;
| 18 || LogCodeHemUidExceedLimit || Exceeded limit of chars for hem uid&lt;br /&gt;
|-&lt;br /&gt;
| 19 || LogCodeViewabilityUnableFindView || Viewability unable to find a view with the specificed tag&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Error Code !! Error Name !! Error Description&lt;br /&gt;
|-&lt;br /&gt;
| 1001 || AppApiNetworkConnectionFailure || App SDK Could not connect to server&lt;br /&gt;
|-&lt;br /&gt;
| 1002 || AppApiFileWriteFailure || App SDK Could not write to file&lt;br /&gt;
|-&lt;br /&gt;
| 1003 || AppApiFileReadFailure || App SDK Could not read data from file&lt;br /&gt;
|-&lt;br /&gt;
| 1004 || AppApiEmptyValue || Empty value Found.&lt;br /&gt;
|-&lt;br /&gt;
| 1005 || AppApiEmptyAppName || Cannot initialize SDK Object without an AppName(Player Name)&lt;br /&gt;
|-&lt;br /&gt;
| 1006 || AppApiEmptyAppVersion || Cannot initialize API Object without an AppVersion&lt;br /&gt;
|-&lt;br /&gt;
| 1007 || AppApiEmptyAppId || Cannot initialize API Object without an AppId&lt;br /&gt;
|-&lt;br /&gt;
| 1008 || AppApiAnExceptionOccured || Exception occurred&lt;br /&gt;
|-&lt;br /&gt;
| 1009 || AppApiUnknownExceptionOccured || Unknown exception occurred&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Nielsen Sample Applications ==&lt;br /&gt;
Nielsen SDK client package contains iOS sample player applications based on native Players integrated with SDK framework. The players demonstrate all the supported functions of the SDK and show the integration details for both legacy and trackEvent API. There are players developed on Objective C and Swift. Implementation of the sample apps is based on native iOS AVPlayer.&lt;br /&gt;
&lt;br /&gt;
The UI components of the iOS App SDK sample applications are common to both as shown below.&lt;br /&gt;
*From the Channel Selection buttons ⬇️ &amp;amp; ⬆️ , the user will be able select the channels to stream.&lt;br /&gt;
*The Info button ℹ️ displays information of the SDK version, current Nielsen ID used for the device, and the option for opt-out/opt-in.&lt;br /&gt;
*The Play ▶️ and Pause ⏸️ buttons will control the streaming of the selected channel.&lt;br /&gt;
*The area at the bottom of the window displays the current stream status.&lt;br /&gt;
*The Clear button 🔃 clears out the status window.&lt;br /&gt;
*The Email button 📧 can be used to email the tags and status in a text file to Nielsen.&lt;br /&gt;
If target device supports Picture-in-Picture playing, it could be activated by PIP button in the Video player window.&lt;br /&gt;
*Channel URLs and metadata are obtained from the JSON file named appConfig.json and stored in the application bundle.&lt;br /&gt;
=== Viewability testing ===&lt;br /&gt;
The sample applications shipped with the client package has support for viewability metrics verification. The player view can be moved using a finger-dragging gesture in the application window. This allows the tester to reduce the visible area of the player view and check the resulting data. There are additional UI buttons:&lt;br /&gt;
*Cover View button opens a popup with multiple UI controls which allow changing a player-view alpha and/or visibility as well to show a cover view in front of the player view.&lt;br /&gt;
*Alert button to open a native UI alert in the application.&amp;lt;br/&amp;gt;&lt;br /&gt;
[[File:PlayerView AlertView1.png|200px]]&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;[[File:PlayerViewDragging.png|200px]]&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;[[File:PlayerView CustomView.png|200px]]&lt;br /&gt;
&lt;br /&gt;
== Nielsen Privacy Requirements ==&lt;br /&gt;
There are three primary methods for implementing user Opt-out preferences:&lt;br /&gt;
# [[Template:iOS_Privacy_and_Opt-Out#OS-level_Opt-out|OS-level Opt-out]] - managed by ''Limit Ad Tracking'' setting on device ('''preferred approach''').&lt;br /&gt;
# [[Template:iOS_Privacy_and_Opt-Out#Legacy_Opt-out|Legacy Opt-out]] - Direct call to SDK; used only for older versions of Nielsen iOS SDK (&amp;lt; 5.1.1.18)&lt;br /&gt;
# [https://engineeringportal.nielsen.com/docs/iOS_SDK_App_Level_Opt_Out App Level Opt-Out] - Where [https://developer.apple.com/documentation/adsupport Ad Framework] cannot be leveraged&lt;br /&gt;
=== Privacy Protections ===&lt;br /&gt;
Privacy protections that Nielsen ensures to have with each App SDK integration are as follows.&lt;br /&gt;
*Disclosure of viewership data collection in EULA / Privacy Policy&lt;br /&gt;
*A link in the EULA/Privacy policy, or in another conspicuous location within the App, to a Nielsen-hosted web page outlining what Nielsen is collecting and how it is being used&lt;br /&gt;
*Method for users to opt-out of Nielsen measurement, any time while using the application&lt;br /&gt;
&lt;br /&gt;
=== Ratings Data Flow ===&lt;br /&gt;
Every view of creditable and watermarked content is measured by Nielsen.&lt;br /&gt;
[[File:RatingsDataFlow.png]]&lt;br /&gt;
&lt;br /&gt;
'''Information NOT Shared'''&lt;br /&gt;
* '''With Nielsen'''&lt;br /&gt;
** User's Identity&lt;br /&gt;
* '''With Data Provider'''&lt;br /&gt;
** Content information&lt;br /&gt;
** Whether user is viewing an ad or video content&lt;br /&gt;
** Player used to play the streaming (audio / video, etc.)&lt;br /&gt;
** Values being de-duped / aggregating for&lt;br /&gt;
&lt;br /&gt;
Nielsen collects only what it needs for audience measurement. Every view of creditable, watermarked content will be measured by Nielsen.&lt;br /&gt;
&lt;br /&gt;
=== Data Collected ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type of Information !! Parameter !! Transmitted to Nielsen? !! Sent to Provider?&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;8&amp;quot; | Nielsen ID3 Watermark&lt;br /&gt;
|-&lt;br /&gt;
| FinalDistributor Timestamp || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| Program Content Timestamp || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| Mobile Breakout Code || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| Commercial Credit Code – Linear or Dynamic || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| Time ShiftedViewing Code || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| Segment Number || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| Segment View Pattern || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;10&amp;quot; | Device/App Info&lt;br /&gt;
|-&lt;br /&gt;
| Device OSVersion || Yes || Yes &lt;br /&gt;
|-&lt;br /&gt;
| Device Model || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| Device Advertiser ID (Apple IDFA or Google AdID/Android ID) || Yes || Yes &lt;br /&gt;
|-&lt;br /&gt;
| Cache Buster || Yes || Yes &lt;br /&gt;
|-&lt;br /&gt;
| App Version || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| App Name || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| SDKDisabled Flag || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| ServerCode || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| Channel or URL || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;9&amp;quot; | Nielsen Identifiers&lt;br /&gt;
|-&lt;br /&gt;
| Client ID || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| Campaign ID || Yes || Yes &lt;br /&gt;
|-&lt;br /&gt;
| Nielsen Unique Device ID || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| Application ID || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| DeviceGroup (ex. Tablet, Smartphone, Desktop) || Yes || Yes &lt;br /&gt;
|-&lt;br /&gt;
| OS Group (ex. Android, iOS, Windows) || Yes || Yes &lt;br /&gt;
|-&lt;br /&gt;
| SDKVersion || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| IP Address for DMA, Country Code || Yes || Yes &lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': Data is hashed, and encrypted using AES 128 before transmission to data provider.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Example ping sent to provider ====&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;https://provider.com/cgi-bin/brandlift.php&amp;lt;/nowiki&amp;gt;?campaign_id=ff12725d724fac7934cf6003f096b4cd&amp;lt;wbr /&amp;gt;&amp;amp;placement_id=a4164b8fba9ee7c873a9c72c7091bb58&amp;lt;wbr /&amp;gt;&amp;amp;creative_id=25280139b61a947e127a52f56c8a2fdd&amp;lt;wbr /&amp;gt;&amp;amp;segment1=9000&amp;lt;wbr /&amp;gt;&amp;amp;segment2=41&amp;lt;wbr /&amp;gt;&amp;amp;segment3=iOS&amp;lt;wbr /&amp;gt;&amp;amp;OSVer=iOS6.1&amp;lt;wbr /&amp;gt;&amp;amp;c9=&amp;lt;wbr /&amp;gt;&amp;amp;devgrp=tablet&amp;lt;wbr /&amp;gt;&amp;amp;h=f5f243fe6d&amp;lt;wbr /&amp;gt;&amp;amp;rnd=1376971827360&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This ping passes the following parameters to the provider:&lt;br /&gt;
* Campaign ID – (campaign, placement, creative)&lt;br /&gt;
* Country Code&lt;br /&gt;
* DMA&lt;br /&gt;
* OS Group (ex. iOS, Android)&lt;br /&gt;
* DeviceOS Version&lt;br /&gt;
* Device Advertiser ID&lt;br /&gt;
* DeviceGroup (ex. Tablet, Smartphone, Desktop)&lt;br /&gt;
* Cache Buster&lt;br /&gt;
&lt;br /&gt;
=== TVOS Opt-out ===&lt;br /&gt;
To Opt-Out, users must have access to “About Nielsen Measurement” page.&lt;br /&gt;
&lt;br /&gt;
TVOS does not support creating instances of UIWebView and display web pages. Instead it makes use of a TVML page (built on TVML template) which displays information in a specific order.&lt;br /&gt;
&lt;br /&gt;
Opt-Out page is built on descriptiveAlertTemplate and appears as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:TVOs OptOut LimitAdTracking1.png|link=]]&lt;br /&gt;
&lt;br /&gt;
[[File:TVOs OptOut LimitAdTracking2.png|link=]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Opt-out wording ===&lt;br /&gt;
&amp;lt;blockquote&amp;gt;About Nielsen Measurement&lt;br /&gt;
&lt;br /&gt;
YOUR CHOICES &lt;br /&gt;
&lt;br /&gt;
Television and the way we watch it have come a long way since Nielsen began measuring TV audiences in 1950. Today, the ability to watch programs at any time and on multiple devices amplifies the need for exceptionally adept and flexible audience measurement capabilities. &lt;br /&gt;
	Consumers are changing with the times, and the same goes for Nielsen. As technology continues to evolve and media companies try new ways to attract viewers, understanding what consumers are watching — and what they're watching on — is more important than ever. Today, viewing video is a personal and mobile experience —anytime and anywhere. Our capabilities provide relevant metrics that are necessary to inform successful marketing and programming and drive continued growth.&lt;br /&gt;
	As a global information and measurement leader, we are committed to protecting the privacy and security of the data we collect, process and use. While our digital measurement products are not used to identify you in any way, they help us and our clients measure and analyze how consumers engage with media across online, mobile and emerging technologies, and offer insights into consumer behavior.&lt;br /&gt;
	Nielsen believes that you should have a choice about whether to contribute to our research and insights. To opt out of Nielsen measurement on this device, you need only to activate the “Limit Ad Tracking” option in your device's settings. If you have this app on more than one mobile device, you will need to change the settings on each device. &lt;br /&gt;
	If, after you have opted out, you change your mind and would like to opt back in, please deactivate the “Limit Ad Tracking” option in your device's settings. &lt;br /&gt;
	To learn more about our digital measurement products and your choices in regard to them, please visit https://www.nielsen.com/digitaIprivacy.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Users need to toggle the “Limit Ad Tracking” option in order to Opt-In / Opt-Out of Nielsen Measurement.&lt;br /&gt;
&lt;br /&gt;
To retrieve the current Opt-Out status of a device, use the [[optOutStatus]] method.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note:''' For API Version 5.1 and above, App SDK will fire data pings and continue measurement even after the user has opted out from Nielsen measurement on a device. The data ping will be marked as opted-out ping.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Viewability and Audibility Implementation ==&lt;br /&gt;
Viewability metrics allow AppSDK to track the visibility of the player and collect information about how much of the player container is visible to the end user during playback. &lt;br /&gt;
&lt;br /&gt;
The viewability pings will be fired following the same rules as measurement pings. Viewability pings will be POST requests, not GET requests like other data pings. POST body for viewability requests will contain the key-value pairs in JSON format. The key parameters in the URL schemes are '''invs, inau, inss, invp''' and '''ines''' which will contain the collected viewability data. This data will be formatted according to the specific rules so that downstream it will be possible to match measurement and viewability data for a session.&lt;br /&gt;
&lt;br /&gt;
Audibility metrics will capture the volume level as well as mute/unmute state of the device during playback.&lt;br /&gt;
&lt;br /&gt;
=== Data Collected ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Measured Value || Value is different for different request parameters:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''invs''' ||  Intersection ratio for the target view in percent (from 0 to 100). Default threshold for this value is 5. Example: ['''50''',1,1528457356,10]&lt;br /&gt;
|-&lt;br /&gt;
| '''inau''' || Volume level on the device in percent (from 0 to 100), where 0 - mute, 100 - max volume level. Default threshold for this value is 1. Example: ['''30''',1,1528457356,10]&lt;br /&gt;
|-&lt;br /&gt;
| '''inss''' || Device screen size as &amp;quot;WxH&amp;quot;, where W - is width in pixels, H - is height in pixels. Example: ['''&amp;quot;1024x768&amp;quot;''',1,1528457356,10]&lt;br /&gt;
|-&lt;br /&gt;
| '''invp''' || Current window size. This is different than the device screen size in a multiple scene mode or on a desktop. Format is &amp;quot;WxH&amp;quot;, where W - is width in pixels, H - is height in pixels. Example: ['''&amp;quot;800x600&amp;quot;''',1,1528457356,10]&lt;br /&gt;
|-&lt;br /&gt;
| '''ines''' || Player view size as &amp;quot;WxH&amp;quot;, where W - is width in pixels, H - is height in pixels. Example: ['''&amp;quot;300x200&amp;quot;''',1,1528457356,10]&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| Start offset || Value contains the first playhead or the first id3 offset with non-null CID after start, flush or resume. Example playhead: [50,'''1''',1528457356,10]. Example id3 offset: [50,'''70100''',1528457356,10]&lt;br /&gt;
|-&lt;br /&gt;
| Start timestamp || Timestamp value when the time period related to this time series item was started. Example: [50,1,'''1528457356''',10]&lt;br /&gt;
|-&lt;br /&gt;
| Duration || Duration value is calculated as a difference between the last playhead and the first playhead for the current time series item. Example: [50,1,1528457356,'''10''']&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Viewability support requires additional parameters to be provided from player applications to the SDK. In order to provide these parameters and to start the viewability measurement, the following method has been added to the public SDK API (please refer to the [[trackViewability|trackViewability public API reference]] for details and usage examples):&lt;br /&gt;
&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
'''Objective C'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
- (void)trackViewability:(nonnull NSDictionary *)data;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
'''Swift'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
func trackViewability(_ data: [String : Any])&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
For Audibility measurement SDK uses iOS system API in order to get the volume level for the device:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
AVAudioSession.sharedInstance().outputVolume&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>AnkitAgrawal</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=iOS_SDK_API_Reference&amp;diff=7249</id>
		<title>iOS SDK API Reference</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=iOS_SDK_API_Reference&amp;diff=7249"/>
		<updated>2025-04-03T15:22:41Z</updated>

		<summary type="html">&lt;p&gt;AnkitAgrawal: /* IOS SDK API Methods &amp;amp; Properties */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
== Overview ==&lt;br /&gt;
The Nielsen SDK is one of multiple framework SDKs that Nielsen provides to enable measuring linear (live) and on-demand TV viewing using TVs, mobile devices, etc.&lt;br /&gt;
The App SDK is the framework for mobile application developers to integrate Nielsen Measurement into their media player applications. It supports a variety of Nielsen Measurement Products like Digital in TV Ratings, Digital Content Ratings ([[DCR &amp;amp; DTVR]]), and [[Digital Ad Ratings]] (DAR). Nielsen SDKs are also equipped to measure static content and can track key life cycle events of an application like:&lt;br /&gt;
*Application launch events and how long app was running&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
To start using the App SDK, the following items are required:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 30px;&amp;quot; |&lt;br /&gt;
! style=&amp;quot;width: 15%;&amp;quot; | Item&lt;br /&gt;
! Description&lt;br /&gt;
! Source&lt;br /&gt;
|-&lt;br /&gt;
|| ☑ || '''App ID (appid)''' || Unique ID assigned to the player/site and configured by product. || Contact Nielsen&lt;br /&gt;
|-&lt;br /&gt;
|| ☑ || '''sfcode''' || Environment that the SDK must point to || Contact Nielsen&lt;br /&gt;
|-&lt;br /&gt;
|| ☑ || '''Nielsen SDK''' || Includes SDK frameworks and '''sample implementation'''; ''See [[iOS SDK Release Notes]]'' || [[Special:Downloads|Download]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
If you do not have any of these pre-requisites or if you have any questions, please contact our SDK sales support team.&lt;br /&gt;
Refer to [[Digital Measurement Onboarding]] guide for information on how to get a Nielsen App SDK and appid.&lt;br /&gt;
==SDK Implementation==&lt;br /&gt;
Information on how to obtain, how to configure your development environment, and how to Initialize the Nielsen SDK is located in either the [[DCR Video iOS SDK|DCR Implementation Guide,]] or the [[DTVR iOS SDK|DTVR Implementation Guide]] depending on your requirements.&lt;br /&gt;
___TOC___&lt;br /&gt;
&lt;br /&gt;
== Nielsen iOS App SDK Application Life Cycle ==&lt;br /&gt;
&lt;br /&gt;
[[File:initialization_appcycle.png|center|link=]]&lt;br /&gt;
&lt;br /&gt;
Life cycle of SDK instance includes four general states:&lt;br /&gt;
# '''Initial state''' – The SDK is not initialized and hence, not ready to process playing information. Once the SDK is moved out of this state, it needs instantiation of the new SDK instance in order to get the instance in the '''Idle state'''.&lt;br /&gt;
# '''Idle state''' – The SDK is initialized and is ready to process playing information. Once Initialized, the SDK instance is not processing any data, but is listening for an event to occur.&lt;br /&gt;
# '''Processing state''' – The SDK instance is processing playing information. The &amp;lt;code&amp;gt;'''play'''&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;'''loadMetadata''' &amp;lt;/code&amp;gt; calls move the SDK instance into this state. In this state, the SDK instance will be able to process the following calls.&lt;br /&gt;
## &amp;lt;code&amp;gt;'''playheadPosition'''&amp;lt;/code&amp;gt; – Call this API every one second when playhead position is active.  If a LIVE event, use the current UNIX timestamp (seconds since Jan-1-1970 UTC).&lt;br /&gt;
## &amp;lt;code&amp;gt;'''stop'''&amp;lt;/code&amp;gt; – Call this API when the playback is paused, switches between content and ad (within the same content playback) or encounters interruptions.&lt;br /&gt;
## &amp;lt;code&amp;gt;'''end'''&amp;lt;/code&amp;gt; – SDK instance exits from Processing state when this API is called.&lt;br /&gt;
# '''Disabled state''' – The SDK instance is disabled and is not processing playing information. &lt;br /&gt;
## &amp;lt;code&amp;gt;'''appDisableApi'''&amp;lt;/code&amp;gt; is set to &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note:''' For API Version 5.1 and above, App SDK will fire data pings and continue measurement even after the user has opted out from Nielsen measurement on a device. The data ping will be marked as opted-out ping.&lt;br /&gt;
&lt;br /&gt;
'''Note''': In case of any interruptions during playback due to alarm, calendar, call, flight mode, Wi-Fi toggle, channel change, etc., call [[stop]] to stop the measurement.&lt;br /&gt;
* As soon as the playback resumes, call &amp;lt;code&amp;gt;'''play'''&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;'''loadMetadata''' &amp;lt;/code&amp;gt; and   &amp;lt;code&amp;gt;'''playheadPosition'''&amp;lt;/code&amp;gt; &amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:appsdkTimeline-DCR.png|icon|link=]]&lt;br /&gt;
=== Finite-state machine table ===&lt;br /&gt;
This table provides the possible changes of state for the SDK instance, when it is in a specific state and receives an API call.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! API call received !! Initial State !! Idle State !! Processing State !! Disabled State&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;[[initWithAppInfo:delegate:]]&amp;lt;/code&amp;gt; || IDLE STATE (OR)&lt;br /&gt;
&lt;br /&gt;
DISABLED STATE&lt;br /&gt;
|| IDLE STATE || - || -&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;[[play]]&amp;lt;/code&amp;gt; &amp;amp; &amp;lt;code&amp;gt;[[loadMetadata]]&amp;lt;/code&amp;gt;|| - || PROCESSING&lt;br /&gt;
&lt;br /&gt;
STATE&lt;br /&gt;
|| - || -&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;[[playheadPosition]]&amp;lt;/code&amp;gt; || - || - || PROCESSING&lt;br /&gt;
&lt;br /&gt;
STATE&lt;br /&gt;
|| -&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;[[sendID3]]&amp;lt;/code&amp;gt; || - || - || PROCESSING&lt;br /&gt;
&lt;br /&gt;
STATE&lt;br /&gt;
|| -&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;[[stop]]&amp;lt;/code&amp;gt; || - || - || IDLE STATE || -&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;[[end]]&amp;lt;/code&amp;gt; || - || - || IDLE STATE || -&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;[[appDisableApi]]&amp;lt;/code&amp;gt;: YES || - || DISABLED&lt;br /&gt;
&lt;br /&gt;
STATE&lt;br /&gt;
|| - || -&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;[[appDisableApi]]&amp;lt;/code&amp;gt;: NO || - || - || - || IDLE STATE (OR)&lt;br /&gt;
&lt;br /&gt;
DISABLED STATE&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;[[userOptOut]]&amp;lt;/code&amp;gt;: YES || - || - || IDLE STATE || -&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;[[userOptOut]]&amp;lt;/code&amp;gt;: NO || - || PROCESSING&lt;br /&gt;
&lt;br /&gt;
STATE&lt;br /&gt;
| - &lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
| colspan = 5 | '-' indicates that no API call is expected.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Handling JSON Metadata ===&lt;br /&gt;
All the SDK methods handles only two types of objects: NSString, NSDictionary. The parameters passed must be either a JSON formatted string or a NSDictionary object. The JSON passed in the SDK must be well-formed.&lt;br /&gt;
* NSDictionary object&lt;br /&gt;
** If an object of unexpected type is passed to the method, the error message will be logged.&lt;br /&gt;
** If string has invalid JSON format, the error message will be logged.&lt;br /&gt;
* JSON value must be string value.&lt;br /&gt;
** This includes boolean and numeric values. For example, a value of true should be represented with &amp;quot;true&amp;quot;, number value 123 should be &amp;quot;123&amp;quot;.&lt;br /&gt;
** All the Variable Names like appid, appname, sfcode, dataSrc, title, type etc. are case-sensitive. Use the correct variable name as specified in the documentation.&lt;br /&gt;
* JSON string can be prepared using either raw NSString or serialized NSDictionary.&lt;br /&gt;
The below is a sample - detailed information on the '''metadata requirements''' are located in either the [[DCR Video iOS SDK|DCR Implementation Guide,]] or the [[DTVR iOS SDK|DTVR Implementation Guide]] &lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Swift = &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
let contentMetadata = [&lt;br /&gt;
    &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;,&lt;br /&gt;
    &amp;quot;assetid&amp;quot;: &amp;quot;C77664&amp;quot;,&lt;br /&gt;
    &amp;quot;title&amp;quot;: &amp;quot;Program S2, E3&amp;quot;,&lt;br /&gt;
    &amp;quot;isfullepisode&amp;quot;: &amp;quot;Yes&amp;quot;,&lt;br /&gt;
    &amp;quot;program&amp;quot;: &amp;quot;Program Name&amp;quot;,&lt;br /&gt;
    &amp;quot;length&amp;quot;: &amp;quot;3600&amp;quot;,&lt;br /&gt;
    &amp;quot;airdate&amp;quot;: &amp;quot;20171020 10:05:00&amp;quot;,&lt;br /&gt;
    &amp;quot;adloadtype&amp;quot;: &amp;quot;2&amp;quot;,&lt;br /&gt;
    &amp;quot;segB&amp;quot;: &amp;quot;CustomSegmentValueB&amp;quot;, //optional&lt;br /&gt;
    &amp;quot;segC&amp;quot;: &amp;quot;CustomSegmentValueC&amp;quot;, //optional&lt;br /&gt;
];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;     &lt;br /&gt;
|Objective C = &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt; &lt;br /&gt;
NSDictionary * contentMetadata = @ {&lt;br /&gt;
    @ &amp;quot;type&amp;quot;: @ &amp;quot;content&amp;quot;,&lt;br /&gt;
        @ &amp;quot;assetid&amp;quot;: @ &amp;quot;C77664&amp;quot;,&lt;br /&gt;
        @ &amp;quot;title&amp;quot;: @ &amp;quot;S2,E3&amp;quot;,&lt;br /&gt;
        @ &amp;quot;isfullepisode&amp;quot;: @ &amp;quot;y&amp;quot;,  &lt;br /&gt;
        @ &amp;quot;program&amp;quot;: @ &amp;quot;Program Name&amp;quot;,&lt;br /&gt;
        @ &amp;quot;length&amp;quot;: @ &amp;quot;3600&amp;quot;,&lt;br /&gt;
        @ &amp;quot;airdate&amp;quot;: @ &amp;quot;20180120 10:00:00&amp;quot;,&lt;br /&gt;
        @ &amp;quot;adloadtype&amp;quot;: @ &amp;quot;2&amp;quot;,&lt;br /&gt;
        @ &amp;quot;segB&amp;quot;: @ &amp;quot;CustomSegmentValueB&amp;quot;, //optional&lt;br /&gt;
        @ &amp;quot;segC&amp;quot;: @ &amp;quot;CustomSegmentValueC&amp;quot;, //optional&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Retrieving ID3 Tags ==&lt;br /&gt;
'''Only required for DTVR clients'''&amp;lt;br&amp;gt;&lt;br /&gt;
'''Not applicable for German Clients'''&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ID3 tags have a payload of about 249 characters and start with &amp;quot;www.nielsen.com&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
ID3 tags are extracted by observing a property called timedMetadata on the iOS player item. Now this is done via a concept called KVO (Key Value Observing), where you register interest in a property, and the runtime will let you know when it has changed.&lt;br /&gt;
&lt;br /&gt;
Both the iOS native players have the ability to extract ID3 tags, If any other player apart from iOS native players (AVPlayer, MPMoviePlayer) is used, check and ensure that the player has the capability to extract ID3 tags.&lt;br /&gt;
&lt;br /&gt;
=== Examples of extracting ID3 tags from the iOS Native Player ===&lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Objective C = &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
    //Adding observer to player to track play,pause and reverse&lt;br /&gt;
    [player addObserver:self&lt;br /&gt;
             forKeyPath:@&amp;quot;rate&amp;quot;&lt;br /&gt;
                options:(NSKeyValueObservingOptionNew)&lt;br /&gt;
                context:nil];&lt;br /&gt;
  &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
------------------------------&lt;br /&gt;
  &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;       &lt;br /&gt;
        //Setting observer to track timedMetadata&lt;br /&gt;
        [player addObserver:self&lt;br /&gt;
                 forKeyPath: timedMetadataKey&lt;br /&gt;
                    options: (NSKeyValueObservingOptionNew)&lt;br /&gt;
                    context: &amp;amp;TimedMetadataObserverContext];&lt;br /&gt;
  &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
------------------------------&lt;br /&gt;
  &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;     &lt;br /&gt;
- (void)observeValueForKeyPath:(NSString *)keyPath&lt;br /&gt;
                      ofObject:(id)object&lt;br /&gt;
                        change:(NSDictionary *)change&lt;br /&gt;
                       context:(void *)context&lt;br /&gt;
{&lt;br /&gt;
    if(keyPath == timedMetadataKey){&lt;br /&gt;
        if(context == &amp;amp;TimedMetadataObserverContext){&lt;br /&gt;
            &lt;br /&gt;
            id newMetadataArray = [change objectForKey:NSKeyValueChangeNewKey];&lt;br /&gt;
            if (newMetadataArray != [NSNull null])&lt;br /&gt;
            {&lt;br /&gt;
                array = newMetadataArray;&lt;br /&gt;
                for (AVMetadataItem *metadataItem in array)&lt;br /&gt;
                {&lt;br /&gt;
                    //Handling TimedMetadata&lt;br /&gt;
                    [self handleTimedMetadata: metadataItem];&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
------------------------------&lt;br /&gt;
  &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;     &lt;br /&gt;
- (void)handleTimedMetadata:(AVMetadataItem *)timedMetadata&lt;br /&gt;
{&lt;br /&gt;
    // We expect the content to contain plists encoded as timed metadata&lt;br /&gt;
    // AVPlayer turns these into NSDictionaries&lt;br /&gt;
    &lt;br /&gt;
    id extraAttributeType = [timedMetadata extraAttributes];&lt;br /&gt;
    NSString *extraString = nil;&lt;br /&gt;
    if ([extraAttributeType isKindOfClass:[NSDictionary class]])&lt;br /&gt;
    {&lt;br /&gt;
        extraString = [extraAttributeType valueForKey:@&amp;quot;info&amp;quot;];&lt;br /&gt;
    }&lt;br /&gt;
    else if ([extraAttributeType isKindOfClass:[NSString class]])&lt;br /&gt;
    {&lt;br /&gt;
        extraString = extraAttributeType;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    NSString *key = [NSString stringWithFormat:@&amp;quot;%@&amp;quot;, [timedMetadata key]];&lt;br /&gt;
    &lt;br /&gt;
    //If tag starts with &amp;quot;www.nielsen.com&amp;quot;, then only sending to SDK&lt;br /&gt;
    if ([key isEqualToString:@&amp;quot;PRIV&amp;quot;] &amp;amp;&amp;amp; [extraString rangeOfString:@&amp;quot;www.nielsen.com&amp;quot;].length &amp;gt; 0)&lt;br /&gt;
    {&lt;br /&gt;
        &lt;br /&gt;
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{&lt;br /&gt;
            [nielsenApi sendID3:extraString];&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Swift = &amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt; &lt;br /&gt;
      //Setting observer to track timedMetadata&lt;br /&gt;
            player.addObserver(self, forKeyPath: timedMetadataKey, options: NSKeyValueObservingOptions.new, context: &amp;amp;TimedMetadataObserverContext)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
------------------------------------------------------&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt; &lt;br /&gt;
   override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {&lt;br /&gt;
        &lt;br /&gt;
        if keyPath == timedMetadataKey {&lt;br /&gt;
            if(context == &amp;amp;TimedMetadataObserverContext){&lt;br /&gt;
                if change != nil {&lt;br /&gt;
                    let timedMetadataArray = change![.newKey]&lt;br /&gt;
                    if timedMetadataArray != nil &amp;amp;&amp;amp; (timedMetadataArray! as AnyObject) is Array&amp;lt;Any&amp;gt; {&lt;br /&gt;
                        for item in timedMetadataArray as! [AVMetadataItem]  {&lt;br /&gt;
                            //Handling TimedMetadata&lt;br /&gt;
                            self.handleTimedMetadata(metadataItem: item)&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
------------------------------------------------------&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt; &lt;br /&gt;
 func handleTimedMetadata(metadataItem: AVMetadataItem) {&lt;br /&gt;
        guard let extraAttributeType = metadataItem.extraAttributes else {&lt;br /&gt;
            return&lt;br /&gt;
        }&lt;br /&gt;
        let info : AVMetadataExtraAttributeKey = AVMetadataExtraAttributeKey(rawValue: &amp;quot;info&amp;quot;)&lt;br /&gt;
        let extraString = extraAttributeType[info] as AnyObject&lt;br /&gt;
        let key = metadataItem.key as! String&lt;br /&gt;
        &lt;br /&gt;
        //If tag starts with &amp;quot;www.nielsen.com&amp;quot;, then only sending to SDK&lt;br /&gt;
        if key == &amp;quot;PRIV&amp;quot; &amp;amp;&amp;amp; extraString.range(of: &amp;quot;www.nielsen.com&amp;quot;).length &amp;gt; 0 {&lt;br /&gt;
            &lt;br /&gt;
            DispatchQueue.global(qos: .default).async { () -&amp;gt; Void in&lt;br /&gt;
                self.nielsenApi?.sendID3(extraString as! String)&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note:''' ID3 tags are not applicable for International (Germany)&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== IOS SDK API Methods &amp;amp; Properties ==&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Scenario !! Method / Property !! DTVR !! DAR !! DCR !! International (Germany) !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Initialize || [[initWithAppInfo:delegate:]] || ✔ || ✔ || ✔ || ✔ || Used to create a new instance of the SDK object&lt;br /&gt;
|-&lt;br /&gt;
| Measurement || [[play]] || ✔ || ✔ || ✔ || ✔ || Used when there is an ID3 fed product such as DTVR and the client does not want to send in all the CMS metadata that is sent in loadMetadata. This allows the client to send in at least the required “channel name” value associated to the ID3 feed. If this is not called then the “channel name” value populated will be the default value of “defaultChannelName”.&lt;br /&gt;
|-&lt;br /&gt;
| Measurement || [[loadMetadata]] || ✔ || ✔ || ✔ || ✔ || Used to send ad or content metadata to the SDK in the form of JSON string. Application constructs a JSON hashmap and calls this API.&lt;br /&gt;
|-&lt;br /&gt;
| Measurement || [[sendID3]] || ✔ ||   ||   ||   || Used to send the ID3 metadata.&lt;br /&gt;
|-&lt;br /&gt;
| Measurement || [[playheadPosition]] ||   ||   || ✔ || ✔ || Used to send the playhead position.&lt;br /&gt;
|-&lt;br /&gt;
| Measurement || [[stop]] || ✔ ||   || ✔ || ✔ || Used when playback is paused and when switching between ad and content or content and ad.&lt;br /&gt;
|-&lt;br /&gt;
| Measurement || [[end]] || ✔ || ✔ || ✔ || ✔ || Used when content playback is complete. This is triggered 1) at the end of the content stream, 2) if the user switches to another piece of content&lt;br /&gt;
|-&lt;br /&gt;
| Measurement || [[staticEnd]] ||   ||   || ✔ || ✔ || Used with DCR Static duration in between loadMetadata calls for static content when section name is the same but a new static view event and duration measurement restart is desired &lt;br /&gt;
|-&lt;br /&gt;
| Measurement || [[updateOTT]] ||   ||   ||   || ✔ || Used to notify App SDK that the remote OTT device (like Google ChromeCast, Roku, Amazon FireTV, etc.) is connected / disconnected (change of OTT status).&lt;br /&gt;
|-&lt;br /&gt;
| Opt-out || [[optOutURL]] || ✔ || ✔ || ✔ || ✔ || Used to fetch the Nielsen opt-out web page URL.&lt;br /&gt;
|-&lt;br /&gt;
| Opt-out || [[userOptOut]] || ✔ || ✔ || ✔ || ✔ || Used to supply the response message from opt-out webpage to the SDK.&lt;br /&gt;
|-&lt;br /&gt;
| Opt-out || [[optOutStatus]] || ✔ || ✔ || ✔ || ✔ || Call this API to retrieve the Opt-Out or Opt-In state.&lt;br /&gt;
|-&lt;br /&gt;
| Opt-out&lt;br /&gt;
| [[appDisableApi]]&lt;br /&gt;
(kill switch) &lt;br /&gt;
|| ✔ || ✔ || ✔ || ✔ || Used to disable the SDK.&lt;br /&gt;
|-&lt;br /&gt;
| Viewability&amp;lt;br/&amp;gt;Audibility&lt;br /&gt;
| [[trackViewability]]&lt;br /&gt;
|| ✔ ||   || ✔ || ✔ || Used to start the viewability measurement.&lt;br /&gt;
|-&lt;br /&gt;
| Log || [[lastErrorDict]] || ✔ || ✔ || ✔ || ✔ || Returns SDK error in the form of dictionary if any error has occurred.&lt;br /&gt;
|-&lt;br /&gt;
| Log || [[lastEventDict]] || ✔ || ✔ || ✔ || ✔ || Returns SDK event in the form of dictionary if any event has occurred.&lt;br /&gt;
|-&lt;br /&gt;
| Log || [[meterVersion]] || ✔ || ✔ || ✔ || ✔ || Returns the current SDK version.&lt;br /&gt;
|-&lt;br /&gt;
| Log || [[nielsenId]] || ✔ || ✔ || ✔ || ✔ || Used to get a string defining the Nielsen ID (NUID) number for the device.&lt;br /&gt;
|-&lt;br /&gt;
| Log || [[demographicId]] || ✔ || ✔ || ✔ || ✔ || Used to retrieve UAID(v10.0.0.0+)/Demographic ID (Device ID) of the current device.&lt;br /&gt;
|-&lt;br /&gt;
| Log || [[deviceId]] || ✔ || ✔ || ✔ || ✔ || Used to get a Device ID of the current device(Introduced in v10.0.0.0).&lt;br /&gt;
|-&lt;br /&gt;
| Log || [[debug]] || ✔ || ✔ || ✔ || ✔ || Used to enable/disable debug flags. Newly introduced in SDK version 5.0.0 for International (Germany)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== NielsenAppApi Class Description ==&lt;br /&gt;
The NielsenAppApi class is the primary application interface to the Nielsen App SDK. For example, after an instance object of the NielsenAppApi class is created and initialized, it can be used by the calling application to collect HLS timed metadata using the SDK’s [[sendID3]]: method. These are the public methods and properties exposed by the NielsenAppApi class:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
@interface NielsenAppApi: NSObject&lt;br /&gt;
&lt;br /&gt;
  @property (readonly) BOOL optOutStatus;&lt;br /&gt;
  @property (assign) BOOL appDisableApi;&lt;br /&gt;
  @property (assign) BOOL debug;&lt;br /&gt;
  @property (readonly, nonnull) NSString *nielsenId;&lt;br /&gt;
  @property (readonly, nonnull) NSString *demographicId;&lt;br /&gt;
  @property (readonly, nonnull) NSString *firstPartyId;&lt;br /&gt;
  @property (readonly, nonnull) NSString *vendorId;&lt;br /&gt;
  @property (readonly, nonnull) NSString *optOutURL;&lt;br /&gt;
  @property (readonly, nullable) NSString *meterVersion;&lt;br /&gt;
  @property (readonly, nullable) NSDictionary *lastEventDict;&lt;br /&gt;
  @property (readonly, nullable) NSDictionary *lastErrorDict;&lt;br /&gt;
&lt;br /&gt;
  - (nullable instancetype)initWithAppInfo:(nonnull id)appInfo delegate:(nullable id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate&lt;br /&gt;
&lt;br /&gt;
  - (void)play:(nullable id)channelInfo;&lt;br /&gt;
  - (void)loadMetadata:(nullable id)metadata;&lt;br /&gt;
  – (void)stop;&lt;br /&gt;
  – (void)end;&lt;br /&gt;
  - (void)playheadPosition:(long long)playheadPos;&lt;br /&gt;
  - (void)sendID3:(nonnull NSString *)data;&lt;br /&gt;
  - (void)updateOTT:(nonnull id)ottInfo;&lt;br /&gt;
  - (BOOL)userOptOut:(nonnull NSString *)optOut;&lt;br /&gt;
  - (void)trackViewability:(nonnull NSDictionary *)data;&lt;br /&gt;
&lt;br /&gt;
  - (nonnull NSString *)getNielsenId __attribute((deprecated((&amp;quot;nielsenId is not used by the SDK anymore&amp;quot;))));&lt;br /&gt;
  - (nonnull NSString *)optOutURLString __attribute((deprecated((&amp;quot;Please use optOutURL property instead.&amp;quot;))));&lt;br /&gt;
  - (nullable NSString *)getMeterVersion __attribute((deprecated((&amp;quot;Please use meterVersion property instead.&amp;quot;))));&lt;br /&gt;
  - (nullable NSDictionary *)getLastEventDict __attribute((deprecated((&amp;quot;Please use lastEventDict property instead.&amp;quot;))));&lt;br /&gt;
  - (nullable NSDictionary *)getLastErrorDict __attribute((deprecated((&amp;quot;Please use lastErrorDict property instead.&amp;quot;)))); &lt;br /&gt;
&lt;br /&gt;
  @protocol NielsenAppApiDelegate &amp;lt;NSObject&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  @optional&lt;br /&gt;
  - (void)nielsenAppApi:(nonnull NielsenAppApi *)appApi eventOccurred:(nonnull NSDictionary *)event;&lt;br /&gt;
  - (void)nielsenAppApi:(nonnull NielsenAppApi *)appApi errorOccurred:(nonnull NSDictionary *)error;&lt;br /&gt;
&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== AppApiEventCode ===&lt;br /&gt;
An enumeration with predefined App SDK event state transition codes.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
typedef NS_ENUM(unsigned int, AppApiEventCode)&lt;br /&gt;
{&lt;br /&gt;
     AppApiStartup = 2001,&lt;br /&gt;
     AppApiShutdown = 2002,&lt;br /&gt;
}AppApiEventCode;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== App SDK Event Codes ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Event Code !! Event Name !! Event Description&lt;br /&gt;
|-&lt;br /&gt;
| 2001 || AppApiStartup || App SDK has initialized successfully. It will happen only after App SDK has received a valid config file&lt;br /&gt;
|-&lt;br /&gt;
| 2002 || AppApiShutdown || App SDK is shutting down. It will happen just before App SDK is destroyed&lt;br /&gt;
|}&lt;br /&gt;
=== AppApiErrorCode ===&lt;br /&gt;
iOS contains two types of error codes, 1-15 and 1001-1009.&lt;br /&gt;
&lt;br /&gt;
For, 1-15, an enumeration with predefined error codes which the App SDK object can generate.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;typedef NS_ENUM(unsigned int, LogCode) {&lt;br /&gt;
    LogCodeFailedParseStartInfo, // 1.&lt;br /&gt;
    LogCodeFailedParseMetadata, // 2.&lt;br /&gt;
    LogCodeFailedProcessID3, // 3.&lt;br /&gt;
    LogCodeFailedReceiveConfig, // 4.&lt;br /&gt;
    LogCodeFailedParseConfig, // 5.&lt;br /&gt;
    LogCodeFailedStartProcessor, // 6.&lt;br /&gt;
    LogCodeFailedCreateUrl, // 7.&lt;br /&gt;
    LogCodeFailedCreateRequest, // 8.&lt;br /&gt;
    LogCodeFailedSendHttpRequest, // 9.&lt;br /&gt;
    LogCodeFailedSendPing, // 10.&lt;br /&gt;
    LogCodeFailedSendTSV, // 11.&lt;br /&gt;
    LogCodeFailedSendStationRequest, // 12.&lt;br /&gt;
    LogCodeFailedAccessDatabase, // 13.&lt;br /&gt;
    LogCodeException, // 14.&lt;br /&gt;
    LogCodeInvalidPlayheadPosition, // 15.&lt;br /&gt;
    LogCodeLongAd, // 16.&lt;br /&gt;
    LogCodeIncorrectSfcode, // 17.&lt;br /&gt;
    LogCodeHemUidExceedLimit, // 18.&lt;br /&gt;
    LogCodeViewabilityUnableFindView // 19.&lt;br /&gt;
};&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For, 1001-1009, an enumeration with predefined error codes which the App SDK object can generate.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
typedef NS_ENUM(unsigned int, AppApiErrorCode)&lt;br /&gt;
{&lt;br /&gt;
   AppApiNetworkConnectionFailure = 1001,&lt;br /&gt;
   AppApiFileWriteFailure = 1002,&lt;br /&gt;
   AppApiFileReadFailure = 1003,&lt;br /&gt;
   AppApiEmptyValue = 1004,&lt;br /&gt;
   AppApiEmptyAppName = 1005,&lt;br /&gt;
   AppApiEmptyAppVersion = 1006,&lt;br /&gt;
   AppApiEmptyAppId = 1007,&lt;br /&gt;
   AppApiAnExceptionOccured = 1008,&lt;br /&gt;
   AppApiUnknownExceptionOccured = 1009&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== App SDK Error Codes ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Error Code !! Error Name !! Error Description&lt;br /&gt;
|-&lt;br /&gt;
| 1 || LogCodeFailedParseStartInfo || Failed to parse the play() JSON string&lt;br /&gt;
|-&lt;br /&gt;
| 2 || LogCodeFailedParseMetadata || Failed to parse the loadMetadata() JSON string&lt;br /&gt;
|-&lt;br /&gt;
| 3 || LogCodeFailedProcessID3 || Failed to process ID3 data on a data processor&lt;br /&gt;
|-&lt;br /&gt;
| 4 || LogCodeFailedReceiveConfig || Failed to receive configuration file from Census&lt;br /&gt;
|-&lt;br /&gt;
| 5 || LogCodeFailedParseConfig || Failed to parse the config file JSON string&lt;br /&gt;
|-&lt;br /&gt;
| 6 || LogCodeFailedStartProcessor || Failed to create SDK processor&lt;br /&gt;
|-&lt;br /&gt;
| 7 || LogCodeFailedCreateUrl || Failed to generate URL due to missing mandatory parameter&lt;br /&gt;
|-&lt;br /&gt;
| 8 || LogCodeFailedCreateRequest || Failed to create request in HTTP client&lt;br /&gt;
|-&lt;br /&gt;
| 9 || LogCodeFailedSendHttpRequest || Failed sending HTTP or HTTPS request&lt;br /&gt;
|-&lt;br /&gt;
| 10 || LogCodeFailedSendPing || Failed to send ping&lt;br /&gt;
|-&lt;br /&gt;
| 11 || LogCodeFailedSendTSV || Failed to send TSV request&lt;br /&gt;
|-&lt;br /&gt;
| 12 || LogCodeFailedSendStationRequest || Failed to send StationId request&lt;br /&gt;
|-&lt;br /&gt;
| 13 || LogCodeFailedAccessDatabase || Failed to read/write from/to database table&lt;br /&gt;
|-&lt;br /&gt;
| 14 || LogCodeException || Any exception handled by SDK code&lt;br /&gt;
|-&lt;br /&gt;
| 15 || LogCodeInvalidPlayheadPosition || Invalid playhead position&lt;br /&gt;
|-&lt;br /&gt;
| 16 || LogCodeLongAd || Long ad&lt;br /&gt;
|-&lt;br /&gt;
| 17 || LogCodeIncorrectSfcode || Incorrect client supplied sfcode&lt;br /&gt;
|-&lt;br /&gt;
| 18 || LogCodeHemUidExceedLimit || Exceeded limit of chars for hem uid&lt;br /&gt;
|-&lt;br /&gt;
| 19 || LogCodeViewabilityUnableFindView || Viewability unable to find a view with the specificed tag&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Error Code !! Error Name !! Error Description&lt;br /&gt;
|-&lt;br /&gt;
| 1001 || AppApiNetworkConnectionFailure || App SDK Could not connect to server&lt;br /&gt;
|-&lt;br /&gt;
| 1002 || AppApiFileWriteFailure || App SDK Could not write to file&lt;br /&gt;
|-&lt;br /&gt;
| 1003 || AppApiFileReadFailure || App SDK Could not read data from file&lt;br /&gt;
|-&lt;br /&gt;
| 1004 || AppApiEmptyValue || Empty value Found.&lt;br /&gt;
|-&lt;br /&gt;
| 1005 || AppApiEmptyAppName || Cannot initialize SDK Object without an AppName(Player Name)&lt;br /&gt;
|-&lt;br /&gt;
| 1006 || AppApiEmptyAppVersion || Cannot initialize API Object without an AppVersion&lt;br /&gt;
|-&lt;br /&gt;
| 1007 || AppApiEmptyAppId || Cannot initialize API Object without an AppId&lt;br /&gt;
|-&lt;br /&gt;
| 1008 || AppApiAnExceptionOccured || Exception occurred&lt;br /&gt;
|-&lt;br /&gt;
| 1009 || AppApiUnknownExceptionOccured || Unknown exception occurred&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Nielsen Sample Applications ==&lt;br /&gt;
Nielsen SDK client package contains iOS sample player applications based on native Players integrated with SDK framework. The players demonstrate all the supported functions of the SDK and show the integration details for both legacy and trackEvent API. There are players developed on Objective C and Swift. Implementation of the sample apps is based on native iOS AVPlayer.&lt;br /&gt;
&lt;br /&gt;
The UI components of the iOS App SDK sample applications are common to both as shown below.&lt;br /&gt;
*From the Channel Selection buttons ⬇️ &amp;amp; ⬆️ , the user will be able select the channels to stream.&lt;br /&gt;
*The Info button ℹ️ displays information of the SDK version, current Nielsen ID used for the device, and the option for opt-out/opt-in.&lt;br /&gt;
*The Play ▶️ and Pause ⏸️ buttons will control the streaming of the selected channel.&lt;br /&gt;
*The area at the bottom of the window displays the current stream status.&lt;br /&gt;
*The Clear button 🔃 clears out the status window.&lt;br /&gt;
*The Email button 📧 can be used to email the tags and status in a text file to Nielsen.&lt;br /&gt;
If target device supports Picture-in-Picture playing, it could be activated by PIP button in the Video player window.&lt;br /&gt;
*Channel URLs and metadata are obtained from the JSON file named appConfig.json and stored in the application bundle.&lt;br /&gt;
=== Viewability testing ===&lt;br /&gt;
The sample applications shipped with the client package has support for viewability metrics verification. The player view can be moved using a finger-dragging gesture in the application window. This allows the tester to reduce the visible area of the player view and check the resulting data. There are additional UI buttons:&lt;br /&gt;
*Cover View button opens a popup with multiple UI controls which allow changing a player-view alpha and/or visibility as well to show a cover view in front of the player view.&lt;br /&gt;
*Alert button to open a native UI alert in the application.&amp;lt;br/&amp;gt;&lt;br /&gt;
[[File:PlayerView AlertView1.png|200px]]&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;[[File:PlayerViewDragging.png|200px]]&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;[[File:PlayerView CustomView.png|200px]]&lt;br /&gt;
&lt;br /&gt;
== Nielsen Privacy Requirements ==&lt;br /&gt;
There are three primary methods for implementing user Opt-out preferences:&lt;br /&gt;
# [[Template:iOS_Privacy_and_Opt-Out#OS-level_Opt-out|OS-level Opt-out]] - managed by ''Limit Ad Tracking'' setting on device ('''preferred approach''').&lt;br /&gt;
# [[Template:iOS_Privacy_and_Opt-Out#Legacy_Opt-out|Legacy Opt-out]] - Direct call to SDK; used only for older versions of Nielsen iOS SDK (&amp;lt; 5.1.1.18)&lt;br /&gt;
# [https://engineeringportal.nielsen.com/docs/iOS_SDK_App_Level_Opt_Out App Level Opt-Out] - Where [https://developer.apple.com/documentation/adsupport Ad Framework] cannot be leveraged&lt;br /&gt;
=== Privacy Protections ===&lt;br /&gt;
Privacy protections that Nielsen ensures to have with each App SDK integration are as follows.&lt;br /&gt;
*Disclosure of viewership data collection in EULA / Privacy Policy&lt;br /&gt;
*A link in the EULA/Privacy policy, or in another conspicuous location within the App, to a Nielsen-hosted web page outlining what Nielsen is collecting and how it is being used&lt;br /&gt;
*Method for users to opt-out of Nielsen measurement, any time while using the application&lt;br /&gt;
&lt;br /&gt;
=== Ratings Data Flow ===&lt;br /&gt;
Every view of creditable and watermarked content is measured by Nielsen.&lt;br /&gt;
[[File:RatingsDataFlow.png]]&lt;br /&gt;
&lt;br /&gt;
'''Information NOT Shared'''&lt;br /&gt;
* '''With Nielsen'''&lt;br /&gt;
** User's Identity&lt;br /&gt;
* '''With Data Provider'''&lt;br /&gt;
** Content information&lt;br /&gt;
** Whether user is viewing an ad or video content&lt;br /&gt;
** Player used to play the streaming (audio / video, etc.)&lt;br /&gt;
** Values being de-duped / aggregating for&lt;br /&gt;
&lt;br /&gt;
Nielsen collects only what it needs for audience measurement. Every view of creditable, watermarked content will be measured by Nielsen.&lt;br /&gt;
&lt;br /&gt;
=== Data Collected ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type of Information !! Parameter !! Transmitted to Nielsen? !! Sent to Provider?&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;8&amp;quot; | Nielsen ID3 Watermark&lt;br /&gt;
|-&lt;br /&gt;
| FinalDistributor Timestamp || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| Program Content Timestamp || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| Mobile Breakout Code || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| Commercial Credit Code – Linear or Dynamic || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| Time ShiftedViewing Code || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| Segment Number || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| Segment View Pattern || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;10&amp;quot; | Device/App Info&lt;br /&gt;
|-&lt;br /&gt;
| Device OSVersion || Yes || Yes &lt;br /&gt;
|-&lt;br /&gt;
| Device Model || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| Device Advertiser ID (Apple IDFA or Google AdID/Android ID) || Yes || Yes &lt;br /&gt;
|-&lt;br /&gt;
| Cache Buster || Yes || Yes &lt;br /&gt;
|-&lt;br /&gt;
| App Version || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| App Name || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| SDKDisabled Flag || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| ServerCode || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| Channel or URL || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;9&amp;quot; | Nielsen Identifiers&lt;br /&gt;
|-&lt;br /&gt;
| Client ID || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| Campaign ID || Yes || Yes &lt;br /&gt;
|-&lt;br /&gt;
| Nielsen Unique Device ID || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| Application ID || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| DeviceGroup (ex. Tablet, Smartphone, Desktop) || Yes || Yes &lt;br /&gt;
|-&lt;br /&gt;
| OS Group (ex. Android, iOS, Windows) || Yes || Yes &lt;br /&gt;
|-&lt;br /&gt;
| SDKVersion || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| IP Address for DMA, Country Code || Yes || Yes &lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': Data is hashed, and encrypted using AES 128 before transmission to data provider.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Example ping sent to provider ====&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;https://provider.com/cgi-bin/brandlift.php&amp;lt;/nowiki&amp;gt;?campaign_id=ff12725d724fac7934cf6003f096b4cd&amp;lt;wbr /&amp;gt;&amp;amp;placement_id=a4164b8fba9ee7c873a9c72c7091bb58&amp;lt;wbr /&amp;gt;&amp;amp;creative_id=25280139b61a947e127a52f56c8a2fdd&amp;lt;wbr /&amp;gt;&amp;amp;segment1=9000&amp;lt;wbr /&amp;gt;&amp;amp;segment2=41&amp;lt;wbr /&amp;gt;&amp;amp;segment3=iOS&amp;lt;wbr /&amp;gt;&amp;amp;OSVer=iOS6.1&amp;lt;wbr /&amp;gt;&amp;amp;c9=&amp;lt;wbr /&amp;gt;&amp;amp;devgrp=tablet&amp;lt;wbr /&amp;gt;&amp;amp;h=f5f243fe6d&amp;lt;wbr /&amp;gt;&amp;amp;rnd=1376971827360&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This ping passes the following parameters to the provider:&lt;br /&gt;
* Campaign ID – (campaign, placement, creative)&lt;br /&gt;
* Country Code&lt;br /&gt;
* DMA&lt;br /&gt;
* OS Group (ex. iOS, Android)&lt;br /&gt;
* DeviceOS Version&lt;br /&gt;
* Device Advertiser ID&lt;br /&gt;
* DeviceGroup (ex. Tablet, Smartphone, Desktop)&lt;br /&gt;
* Cache Buster&lt;br /&gt;
&lt;br /&gt;
=== TVOS Opt-out ===&lt;br /&gt;
To Opt-Out, users must have access to “About Nielsen Measurement” page.&lt;br /&gt;
&lt;br /&gt;
TVOS does not support creating instances of UIWebView and display web pages. Instead it makes use of a TVML page (built on TVML template) which displays information in a specific order.&lt;br /&gt;
&lt;br /&gt;
Opt-Out page is built on descriptiveAlertTemplate and appears as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:TVOs OptOut LimitAdTracking1.png|link=]]&lt;br /&gt;
&lt;br /&gt;
[[File:TVOs OptOut LimitAdTracking2.png|link=]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Opt-out wording ===&lt;br /&gt;
&amp;lt;blockquote&amp;gt;About Nielsen Measurement&lt;br /&gt;
&lt;br /&gt;
YOUR CHOICES &lt;br /&gt;
&lt;br /&gt;
Television and the way we watch it have come a long way since Nielsen began measuring TV audiences in 1950. Today, the ability to watch programs at any time and on multiple devices amplifies the need for exceptionally adept and flexible audience measurement capabilities. &lt;br /&gt;
	Consumers are changing with the times, and the same goes for Nielsen. As technology continues to evolve and media companies try new ways to attract viewers, understanding what consumers are watching — and what they're watching on — is more important than ever. Today, viewing video is a personal and mobile experience —anytime and anywhere. Our capabilities provide relevant metrics that are necessary to inform successful marketing and programming and drive continued growth.&lt;br /&gt;
	As a global information and measurement leader, we are committed to protecting the privacy and security of the data we collect, process and use. While our digital measurement products are not used to identify you in any way, they help us and our clients measure and analyze how consumers engage with media across online, mobile and emerging technologies, and offer insights into consumer behavior.&lt;br /&gt;
	Nielsen believes that you should have a choice about whether to contribute to our research and insights. To opt out of Nielsen measurement on this device, you need only to activate the “Limit Ad Tracking” option in your device's settings. If you have this app on more than one mobile device, you will need to change the settings on each device. &lt;br /&gt;
	If, after you have opted out, you change your mind and would like to opt back in, please deactivate the “Limit Ad Tracking” option in your device's settings. &lt;br /&gt;
	To learn more about our digital measurement products and your choices in regard to them, please visit https://www.nielsen.com/digitaIprivacy.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Users need to toggle the “Limit Ad Tracking” option in order to Opt-In / Opt-Out of Nielsen Measurement.&lt;br /&gt;
&lt;br /&gt;
To retrieve the current Opt-Out status of a device, use the [[optOutStatus]] method.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note:''' For API Version 5.1 and above, App SDK will fire data pings and continue measurement even after the user has opted out from Nielsen measurement on a device. The data ping will be marked as opted-out ping.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Viewability and Audibility Implementation ==&lt;br /&gt;
Viewability metrics allow AppSDK to track the visibility of the player and collect information about how much of the player container is visible to the end user during playback. &lt;br /&gt;
&lt;br /&gt;
The viewability pings will be fired following the same rules as measurement pings. Viewability pings will be POST requests, not GET requests like other data pings. POST body for viewability requests will contain the key-value pairs in JSON format. The key parameters in the URL schemes are '''invs, inau, inss, invp''' and '''ines''' which will contain the collected viewability data. This data will be formatted according to the specific rules so that downstream it will be possible to match measurement and viewability data for a session.&lt;br /&gt;
&lt;br /&gt;
Audibility metrics will capture the volume level as well as mute/unmute state of the device during playback.&lt;br /&gt;
&lt;br /&gt;
=== Data Collected ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Measured Value || Value is different for different request parameters:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''invs''' ||  Intersection ratio for the target view in percent (from 0 to 100). Default threshold for this value is 5. Example: ['''50''',1,1528457356,10]&lt;br /&gt;
|-&lt;br /&gt;
| '''inau''' || Volume level on the device in percent (from 0 to 100), where 0 - mute, 100 - max volume level. Default threshold for this value is 1. Example: ['''30''',1,1528457356,10]&lt;br /&gt;
|-&lt;br /&gt;
| '''inss''' || Device screen size as &amp;quot;WxH&amp;quot;, where W - is width in pixels, H - is height in pixels. Example: ['''&amp;quot;1024x768&amp;quot;''',1,1528457356,10]&lt;br /&gt;
|-&lt;br /&gt;
| '''invp''' || Current window size. This is different than the device screen size in a multiple scene mode or on a desktop. Format is &amp;quot;WxH&amp;quot;, where W - is width in pixels, H - is height in pixels. Example: ['''&amp;quot;800x600&amp;quot;''',1,1528457356,10]&lt;br /&gt;
|-&lt;br /&gt;
| '''ines''' || Player view size as &amp;quot;WxH&amp;quot;, where W - is width in pixels, H - is height in pixels. Example: ['''&amp;quot;300x200&amp;quot;''',1,1528457356,10]&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| Start offset || Value contains the first playhead or the first id3 offset with non-null CID after start, flush or resume. Example playhead: [50,'''1''',1528457356,10]. Example id3 offset: [50,'''70100''',1528457356,10]&lt;br /&gt;
|-&lt;br /&gt;
| Start timestamp || Timestamp value when the time period related to this time series item was started. Example: [50,1,'''1528457356''',10]&lt;br /&gt;
|-&lt;br /&gt;
| Duration || Duration value is calculated as a difference between the last playhead and the first playhead for the current time series item. Example: [50,1,1528457356,'''10''']&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Viewability support requires additional parameters to be provided from player applications to the SDK. In order to provide these parameters and to start the viewability measurement, the following method has been added to the public SDK API (please refer to the [[trackViewability|trackViewability public API reference]] for details and usage examples):&lt;br /&gt;
&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
'''Objective C'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
- (void)trackViewability:(nonnull NSDictionary *)data;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
'''Swift'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
func trackViewability(_ data: [String : Any])&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
For Audibility measurement SDK uses iOS system API in order to get the volume level for the device:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
AVAudioSession.sharedInstance().outputVolume&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>AnkitAgrawal</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=deviceId&amp;diff=7248</id>
		<title>deviceId</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=deviceId&amp;diff=7248"/>
		<updated>2025-04-03T15:22:13Z</updated>

		<summary type="html">&lt;p&gt;AnkitAgrawal: v10.0.0.0 Changes&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|iOS SDK API Reference}}  {{CurrentBreadcrumb}} Retrieves Device ID of the current device. Introduced in SDK v10.0.0.0.&lt;br /&gt;
==Syntax==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
@property (readonly) NSString *deviceId;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==Input Parameters==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Parameter!!Description&lt;br /&gt;
|-&lt;br /&gt;
|None||&lt;br /&gt;
|}&lt;br /&gt;
==Output Parameters==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Output Parameters (Return value)!!Description&lt;br /&gt;
|-&lt;br /&gt;
|deviceId||Returns a NSString object containing the Device ID.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>AnkitAgrawal</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=Digital_Measurement_iOS_Suffix_Guide&amp;diff=7247</id>
		<title>Digital Measurement iOS Suffix Guide</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=Digital_Measurement_iOS_Suffix_Guide&amp;diff=7247"/>
		<updated>2025-04-03T14:20:56Z</updated>

		<summary type="html">&lt;p&gt;AnkitAgrawal: Support for VisionOS v10.0.0.0&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|DCR &amp;amp; DTVR}} {{Breadcrumb|Digital Measurement iOS Artifactory Guide}} {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
The Nielsen AppSDK has various configurations per market and distribution type, which can be determined by reviewing the sdk suffix.  The first part will be the SDK version: 3 digits for the major SDK version and 1 digit for the minor SDK version. EG: &amp;lt;code&amp;gt;ai.8.1.0.0_abc&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= iOS app sdk version suffix=&lt;br /&gt;
Below are details of possible suffix characters with description.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Character Index in suffix !! Possible Values!! Description&lt;br /&gt;
|-&lt;br /&gt;
|0 (first character in suffix)||g,a and v||&amp;lt;code&amp;gt;g&amp;lt;/code&amp;gt; means it's the GLOBAL flavored sdk (Default).&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt; means the build was designed for AGF.&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;v&amp;lt;/code&amp;gt; identifies the VRI flavoured sdk.&lt;br /&gt;
|-&lt;br /&gt;
|1 (second character in suffix)||a,s and l ||&amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt; means Artifactory Cocoapods/SPM/Carthage&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt; Standard Framework.&amp;lt;br&amp;gt; &amp;lt;code&amp;gt;l&amp;lt;/code&amp;gt; Adobe Launch Extension.&lt;br /&gt;
|-&lt;br /&gt;
|2 (third character in suffix)||s,d,c or x ||&amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt; means Static Linking.&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;d&amp;lt;/code&amp;gt; means Dynamic Linking.&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;c&amp;lt;/code&amp;gt; means Static xcframework.&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; means Dynamic xcframework.&amp;lt;br&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|3 (fourth character in suffix)||a,n or k||&amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt; means AdSupport is included. &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; AdSupport is NOT included&amp;lt;br&amp;gt; &amp;lt;code&amp;gt;k&amp;lt;/code&amp;gt; No IDFA or IDFV (kids framework).&lt;br /&gt;
|-&lt;br /&gt;
|4 (fifth character in suffix)||t and o||&amp;lt;code&amp;gt;t&amp;lt;/code&amp;gt;instantiated using NielsenEventTracker class.&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;o&amp;lt;/code&amp;gt; means sdk is getting instantiated using AppSdk class (Default).&lt;br /&gt;
|-&lt;br /&gt;
|5 (sixth character in suffix)||h,w,r and n||&amp;lt;code&amp;gt;h&amp;lt;/code&amp;gt; then sdk supports Hybrid Webviews.&amp;lt;br&amp;gt; &amp;lt;code&amp;gt;w&amp;lt;/code&amp;gt; identifies React Native Webview support.&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;r&amp;lt;/code&amp;gt; sdk supports React Native standard bridge.&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; means sdk supports Native apps.&lt;br /&gt;
|-&lt;br /&gt;
|6 (seventh character in suffix)||t,i,m,c and v||&amp;lt;code&amp;gt;t&amp;lt;/code&amp;gt; then sdk running on tvOS.&amp;lt;br&amp;gt; &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; sdk running on iOS App on iPhone or iPad.&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;m&amp;lt;/code&amp;gt; sdk running on  iOS App on Mac M1.&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;c&amp;lt;/code&amp;gt; means sdk running on Catalyst App.&lt;br /&gt;
&amp;lt;code&amp;gt;v&amp;lt;/code&amp;gt; means sdk running on VisionOS App.&lt;br /&gt;
|}&lt;br /&gt;
Here is an example of a possible suffix in app sdk meter version &lt;br /&gt;
&lt;br /&gt;
* '''ai.8.1.0.0_gadaoni'''&lt;br /&gt;
** Sdk version 8.1.0.0 with '''Global flavor'''&lt;br /&gt;
** integrated as a '''cocoapod'''&lt;br /&gt;
** supporting '''Dynamic Framework''' &lt;br /&gt;
** '''Adsupport'''&lt;br /&gt;
** '''AppSdk class''' to instantiate&lt;br /&gt;
** supporting '''native apps'''&lt;br /&gt;
** running on  '''iOS App on iPhone or iPad'''.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
.&lt;/div&gt;</summary>
		<author><name>AnkitAgrawal</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=Digital_Measurement_Android_Artifactory_Guide&amp;diff=7123</id>
		<title>Digital Measurement Android Artifactory Guide</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=Digital_Measurement_Android_Artifactory_Guide&amp;diff=7123"/>
		<updated>2024-12-02T16:48:22Z</updated>

		<summary type="html">&lt;p&gt;AnkitAgrawal: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|Digital Downloads}} {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
__NOTOC__&lt;br /&gt;
The Nielsen AppSDK can either be downloaded directly from the [http://engineeringportal.nielsen.com Engineering Portal], or can be integrated directly within an application through the use of a CocoaPod or Gradle.&lt;br /&gt;
&lt;br /&gt;
= How to install the Nielsen AppSDK using Gradle for Android =&lt;br /&gt;
Below are the steps which need to be performed by app developers to integrate the Nielsen App SDK within an Android application.&lt;br /&gt;
&lt;br /&gt;
== Add Nielsen Maven Repository ==&lt;br /&gt;
&lt;br /&gt;
Please add the Nielsen maven repository inside the repositories section of your app's module build.gradle file like below:&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;android&amp;quot;&amp;gt;&lt;br /&gt;
repositories {&lt;br /&gt;
   //Copy below code inside repository section of app’s build.gradle file&lt;br /&gt;
maven { url 'https://raw.githubusercontent.com/NielsenDigitalSDK/nielsenappsdk-android/master/'&lt;br /&gt;
            }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
[[Image:AlertIcon.png|left|60px|link=|class=smallIcon]] Starting on Sept 21, 2021 the Nielsen SDK has moved to a public repository. Credentials are no longer required.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Add gradle dependency ==&lt;br /&gt;
&lt;br /&gt;
Please add Nielsen app SDK as compile time dependency inside build.gradle file as below&lt;br /&gt;
=== grade 4.x and above ===&lt;br /&gt;
For gradle version starting with 4.x add the following line inside dependencies section of build.gradle file.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;html&amp;quot;&amp;gt;implementation 'com.nielsenappsdk.${market}:${flavor}:${version}'&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
dependencies { ....&lt;br /&gt;
implementation 'com.nielsenappsdk.global:ad:+'  // Using + will provide the latest version&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== grade prior to 4.x ===&lt;br /&gt;
For gradle version previous to 4.x add below line inside dependencies section of build.gradle file.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;html&amp;quot;&amp;gt;compile 'com.nielsenappsdk.${market}:${flavor}:${version}'&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
dependencies { ....&lt;br /&gt;
compile 'com.nielsenappsdk.global:ad:+'  // Using + will provide the latest version&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Version and Flavor Control ==&lt;br /&gt;
With version 8.1.0.0+ of the Nielsen appSDK, it is possible to request a specific '''${flavor}''' that reads the '''Google Ad ID''', '''Android ID''', or is '''Kid app''' friendly (noID).  For example:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;html&amp;quot;&amp;gt;implementation 'com.nielsenappsdk.${market}:${flavor}:${version}'&amp;lt;/source&amp;gt;&lt;br /&gt;
* if the flavor selected is equal to &amp;lt;code&amp;gt;ad&amp;lt;/code&amp;gt; the Nielsen SDK will try to obtain the googleAdID if the user has not opted out. &lt;br /&gt;
* If the flavor is &amp;lt;code&amp;gt;noad&amp;lt;/code&amp;gt; then the Nielsen SDK will attempt to obtain the AndroidID. &lt;br /&gt;
* If the flavor selected is &amp;lt;code&amp;gt;noid&amp;lt;/code&amp;gt; then the Nielsen SDK will not request any identifier which is required for many kid apps.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;To ensure backward compatability, &amp;lt;code&amp;gt; implementation 'com.nielsenappsdk:${market}:${version}'&amp;lt;/code&amp;gt; will continue to be supported.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
! SDK  Version&lt;br /&gt;
! ${market}&lt;br /&gt;
! ${flavor}&lt;br /&gt;
! ${version}&lt;br /&gt;
! Examples&lt;br /&gt;
|-&lt;br /&gt;
| Appsdk 8.1.0.0+&lt;br /&gt;
|&amp;lt;code&amp;gt;global&amp;lt;/code&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;code&amp;gt;agf&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;ad&amp;lt;/code&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;code&amp;gt;noad&amp;lt;/code&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;code&amp;gt;noid&amp;lt;/code&amp;gt;&lt;br /&gt;
| + is most recent version&amp;lt;br /&amp;gt;&amp;lt;code&amp;gt;8.1.0.0&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;'com.nielsenappsdk.global:ad:+'&amp;lt;br /&amp;gt;'com.nielsenappsdk.global:noad:+'&amp;lt;br /&amp;gt;'com.nielsenappsdk.global:noad:8.1.0.0'&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| AppSDK 7 to 8.0.0.0&lt;br /&gt;
|&amp;lt;code&amp;gt;globalx&amp;lt;/code&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;code&amp;gt;global&amp;lt;/code&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;code&amp;gt;agf&amp;lt;/code&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;code&amp;gt;agfx&amp;lt;/code&amp;gt;&lt;br /&gt;
|not used&lt;br /&gt;
| + is most recent version&amp;lt;br /&amp;gt;&amp;lt;code&amp;gt;7.1.0.0&amp;lt;/code&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;code&amp;gt;8.0.0.0&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;'com.nielsenappsdk:globalx:+'&amp;lt;br /&amp;gt;'com.nielsenappsdk:global:8.0.0.0'&amp;lt;br /&amp;gt;'com.nielsenappsdk:agf:8.0.0.0'&amp;lt;/code&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;blockquote&amp;gt;If using version control, a warning message will be displayed within the console trace during the build of your app,&lt;br /&gt;
and it will show all sdk versions released to-date, allowing a developer to select a more recent build if desired. &amp;lt;/blockquote&amp;gt; Starting with Version 8.x, the Nielsen SDK will only support Androidx.&lt;br /&gt;
&lt;br /&gt;
== Ensuring you have the latest release information ==&lt;br /&gt;
It is recommended to use &amp;lt;code&amp;gt;+&amp;lt;/code&amp;gt; for &amp;lt;code&amp;gt;${version}&amp;lt;/code&amp;gt; to ensure you receive the most recent version of the NielsenSDK; however, if you are specifying the exact version of the SDK, please use only the first 3 digits.  EG: 8.1.0&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A sample if using AppSDK 8.1.0.0 + would be:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
dependencies { ....&lt;br /&gt;
implementation 'com.nielsenappsdk.global:ad:+'&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
If using AppSDK 7 to 8.0.0.0&lt;br /&gt;
&amp;lt;source lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
dependencies { ....&lt;br /&gt;
implementation 'com.nielsenappsdk:globalx:8.0.0'&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition, please add below gradle task inside your &amp;lt;code&amp;gt; build.gradle (Module:app)&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;build.gradle(Project:My-app)&amp;lt;/code&amp;gt; file to fetch latest release details of nielsen app sdk as below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Please note: The &amp;lt;code&amp;gt; build.gradle (Module:app)&amp;lt;/code&amp;gt;  can overwrite the &amp;lt;code&amp;gt;build.gradle(Project:My-app)&amp;lt;/code&amp;gt;.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;java&amp;quot;&amp;gt;task NielsenSdkReleaseCheck {&lt;br /&gt;
    def p = ['curl',&amp;quot;https://raw.githubusercontent.com/NielsenDigitalSDK/&amp;quot; +&lt;br /&gt;
            &amp;quot;nielsenappsdk-android/master/com/nielsenappsdk/global/&amp;quot; +&lt;br /&gt;
            &amp;quot;NielsenAppSdk-ReadMe.md&amp;quot;].execute().text&lt;br /&gt;
    project.logger.log(LogLevel.ERROR,p)&lt;br /&gt;
}&lt;br /&gt;
preBuild.dependsOn('NielsenSdkReleaseCheck')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== App Suffix Reference ===&lt;br /&gt;
The Nielsen AppSDK has various configurations per market and distribution type, which can be determined by reviewing the [[Digital Measurement Android Suffix Guide|sdk suffix]].  The first part will be the SDK version: 3 digits for the major SDK version and 1 digit for the minor SDK version. EG: &amp;lt;code&amp;gt;aa.8.1.0.0_abc&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Proguard Obfuscation ==&lt;br /&gt;
&lt;br /&gt;
AppSDK internally obfuscate all non-public classes during the build process using Proguard. Please use the below filter to avoid further obfuscation of AppSDK classes if Client app is also using proguard tool  &lt;br /&gt;
&lt;br /&gt;
&amp;quot;''-keep class com.nielsen.app.sdk.** { *; }''&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Sync ==&lt;br /&gt;
&lt;br /&gt;
If you are finished with all previous steps then you can sync your build.gradle and after successful build you are ready to use Nielsen App SDK library in your code.&lt;br /&gt;
&lt;br /&gt;
== Sample file ==&lt;br /&gt;
The below is an example of a very basic app build.gradle file&lt;br /&gt;
&amp;lt;syntaxhighlight lang=Java&amp;gt;&lt;br /&gt;
plugins {&lt;br /&gt;
    id 'com.android.application'&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
android {&lt;br /&gt;
    compileSdkVersion 30&lt;br /&gt;
    buildToolsVersion &amp;quot;30.0.3&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    defaultConfig {&lt;br /&gt;
        applicationId &amp;quot;com.nielsen.simplestandardandroidart&amp;quot;&lt;br /&gt;
        minSdkVersion 23&lt;br /&gt;
        targetSdkVersion 30&lt;br /&gt;
        versionCode 1&lt;br /&gt;
        versionName &amp;quot;1.0&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        testInstrumentationRunner &amp;quot;androidx.test.runner.AndroidJUnitRunner&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    buildTypes {&lt;br /&gt;
        release {&lt;br /&gt;
            minifyEnabled false&lt;br /&gt;
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    repositories {&lt;br /&gt;
        //Copy below code inside repository section of app’s build.gradle file&lt;br /&gt;
        maven { url 'https://raw.githubusercontent.com/NielsenDigitalSDK/nielsenappsdk-android/master/'&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    compileOptions {&lt;br /&gt;
        sourceCompatibility JavaVersion.VERSION_1_8&lt;br /&gt;
        targetCompatibility JavaVersion.VERSION_1_8&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
dependencies {&lt;br /&gt;
&lt;br /&gt;
    implementation 'androidx.appcompat:appcompat:1.2.0'&lt;br /&gt;
    implementation 'com.google.android.material:material:1.1.0'&lt;br /&gt;
    implementation 'androidx.constraintlayout:constraintlayout:2.0.4'&lt;br /&gt;
    testImplementation 'junit:junit:4.+'&lt;br /&gt;
    androidTestImplementation 'androidx.test.ext:junit:1.1.2'&lt;br /&gt;
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'&lt;br /&gt;
    implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'&lt;br /&gt;
    implementation 'com.google.android.gms:play-services-ads:20.3.0'&lt;br /&gt;
    implementation 'com.nielsenappsdk.global:ad:+'&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
task NielsenSdkReleaseCheck {&lt;br /&gt;
    def p = ['curl',&amp;quot;https://raw.githubusercontent.com/NielsenDigitalSDK/&amp;quot; +&lt;br /&gt;
            &amp;quot;nielsenappsdk-android/master/com/nielsenappsdk/global/&amp;quot; +&lt;br /&gt;
            &amp;quot;NielsenAppSdk-ReadMe.md&amp;quot;].execute().text&lt;br /&gt;
    project.logger.log(LogLevel.ERROR,p)&lt;br /&gt;
}&lt;br /&gt;
preBuild.dependsOn('NielsenSdkReleaseCheck')&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>AnkitAgrawal</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=Digital_Measurement_Android_Artifactory_Guide&amp;diff=7122</id>
		<title>Digital Measurement Android Artifactory Guide</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=Digital_Measurement_Android_Artifactory_Guide&amp;diff=7122"/>
		<updated>2024-12-02T16:46:57Z</updated>

		<summary type="html">&lt;p&gt;AnkitAgrawal: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|Digital Downloads}} {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
__NOTOC__&lt;br /&gt;
The Nielsen AppSDK can either be downloaded directly from the [http://engineeringportal.nielsen.com Engineering Portal], or can be integrated directly within an application through the use of a CocoaPod or Gradle.&lt;br /&gt;
&lt;br /&gt;
= How to install the Nielsen AppSDK using Gradle for Android =&lt;br /&gt;
Below are the steps which need to be performed by app developers to integrate the Nielsen App SDK within an Android application.&lt;br /&gt;
&lt;br /&gt;
== Add Nielsen Maven Repository ==&lt;br /&gt;
&lt;br /&gt;
Please add the Nielsen maven repository inside the repositories section of your app's module build.gradle file like below:&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;android&amp;quot;&amp;gt;&lt;br /&gt;
repositories {&lt;br /&gt;
   //Copy below code inside repository section of app’s build.gradle file&lt;br /&gt;
maven { url 'https://raw.githubusercontent.com/NielsenDigitalSDK/nielsenappsdk-android/master/'&lt;br /&gt;
            }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
[[Image:AlertIcon.png|left|60px|link=|class=smallIcon]] Starting on Sept 21, 2021 the Nielsen SDK has moved to a public repository. Credentials are no longer required.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Add gradle dependency ==&lt;br /&gt;
&lt;br /&gt;
Please add Nielsen app SDK as compile time dependency inside build.gradle file as below&lt;br /&gt;
=== grade 4.x and above ===&lt;br /&gt;
For gradle version starting with 4.x add the following line inside dependencies section of build.gradle file.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;html&amp;quot;&amp;gt;implementation 'com.nielsenappsdk.${market}:${flavor}:${version}'&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
dependencies { ....&lt;br /&gt;
implementation 'com.nielsenappsdk.global:ad:+'  // Using + will provide the latest version&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== grade prior to 4.x ===&lt;br /&gt;
For gradle version previous to 4.x add below line inside dependencies section of build.gradle file.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;html&amp;quot;&amp;gt;compile 'com.nielsenappsdk.${market}:${flavor}:${version}'&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
dependencies { ....&lt;br /&gt;
compile 'com.nielsenappsdk.global:ad:+'  // Using + will provide the latest version&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Version and Flavor Control ==&lt;br /&gt;
With version 8.1.0.0+ of the Nielsen appSDK, it is possible to request a specific '''${flavor}''' that reads the '''Google Ad ID''', '''Android ID''', or is '''Kid app''' friendly (noID).  For example:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;html&amp;quot;&amp;gt;implementation 'com.nielsenappsdk.${market}:${flavor}:${version}'&amp;lt;/source&amp;gt;&lt;br /&gt;
* if the flavor selected is equal to &amp;lt;code&amp;gt;ad&amp;lt;/code&amp;gt; the Nielsen SDK will try to obtain the googleAdID if the user has not opted out. &lt;br /&gt;
* If the flavor is &amp;lt;code&amp;gt;noad&amp;lt;/code&amp;gt; then the Nielsen SDK will attempt to obtain the AndroidID. &lt;br /&gt;
* If the flavor selected is &amp;lt;code&amp;gt;noid&amp;lt;/code&amp;gt; then the Nielsen SDK will not request any identifier which is required for many kid apps.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;To ensure backward compatability, &amp;lt;code&amp;gt; implementation 'com.nielsenappsdk:${market}:${version}'&amp;lt;/code&amp;gt; will continue to be supported.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
! SDK  Version&lt;br /&gt;
! ${market}&lt;br /&gt;
! ${flavor}&lt;br /&gt;
! ${version}&lt;br /&gt;
! Examples&lt;br /&gt;
|-&lt;br /&gt;
| Appsdk 8.1.0.0+&lt;br /&gt;
|&amp;lt;code&amp;gt;global&amp;lt;/code&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;code&amp;gt;agf&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;ad&amp;lt;/code&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;code&amp;gt;noad&amp;lt;/code&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;code&amp;gt;noid&amp;lt;/code&amp;gt;&lt;br /&gt;
| + is most recent version&amp;lt;br /&amp;gt;&amp;lt;code&amp;gt;8.1.0.0&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;'com.nielsenappsdk.global:ad:+'&amp;lt;br /&amp;gt;'com.nielsenappsdk.global:noad:+'&amp;lt;br /&amp;gt;'com.nielsenappsdk.global:noad:8.1.0.0'&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| AppSDK 7 to 8.0.0.0&lt;br /&gt;
|&amp;lt;code&amp;gt;globalx&amp;lt;/code&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;code&amp;gt;global&amp;lt;/code&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;code&amp;gt;agf&amp;lt;/code&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;code&amp;gt;agfx&amp;lt;/code&amp;gt;&lt;br /&gt;
|not used&lt;br /&gt;
| + is most recent version&amp;lt;br /&amp;gt;&amp;lt;code&amp;gt;7.1.0.0&amp;lt;/code&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;code&amp;gt;8.0.0.0&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;'com.nielsenappsdk:globalx:+'&amp;lt;br /&amp;gt;'com.nielsenappsdk:global:8.0.0.0'&amp;lt;br /&amp;gt;'com.nielsenappsdk:agf:8.0.0.0'&amp;lt;/code&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;blockquote&amp;gt;If using version control, a warning message will be displayed within the console trace during the build of your app,&lt;br /&gt;
and it will show all sdk versions released to-date, allowing a developer to select a more recent build if desired. &amp;lt;/blockquote&amp;gt; Starting with Version 8.x, the Nielsen SDK will only support Androidx.&lt;br /&gt;
&lt;br /&gt;
== Ensuring you have the latest release information ==&lt;br /&gt;
It is recommended to use &amp;lt;code&amp;gt;+&amp;lt;/code&amp;gt; for &amp;lt;code&amp;gt;${version}&amp;lt;/code&amp;gt; to ensure you receive the most recent version of the NielsenSDK; however, if you are specifying the exact version of the SDK, please use only the first 3 digits.  EG: 8.1.0&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A sample if using AppSDK 8.1.0.0 + would be:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
dependencies { ....&lt;br /&gt;
implementation 'com.nielsenappsdk.global:ad:+'&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
If using AppSDK 7 to 8.0.0.0&lt;br /&gt;
&amp;lt;source lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
dependencies { ....&lt;br /&gt;
implementation 'com.nielsenappsdk:globalx:8.0.0'&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition, please add below gradle task inside your &amp;lt;code&amp;gt; build.gradle (Module:app)&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;build.gradle(Project:My-app)&amp;lt;/code&amp;gt; file to fetch latest release details of nielsen app sdk as below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Please note: The &amp;lt;code&amp;gt; build.gradle (Module:app)&amp;lt;/code&amp;gt;  can overwrite the &amp;lt;code&amp;gt;build.gradle(Project:My-app)&amp;lt;/code&amp;gt;.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;java&amp;quot;&amp;gt;task NielsenSdkReleaseCheck {&lt;br /&gt;
    def p = ['curl',&amp;quot;https://raw.githubusercontent.com/NielsenDigitalSDK/&amp;quot; +&lt;br /&gt;
            &amp;quot;nielsenappsdk-android/master/com/nielsenappsdk/global/&amp;quot; +&lt;br /&gt;
            &amp;quot;NielsenAppSdk-ReadMe.md&amp;quot;].execute().text&lt;br /&gt;
    project.logger.log(LogLevel.ERROR,p)&lt;br /&gt;
}&lt;br /&gt;
preBuild.dependsOn('NielsenSdkReleaseCheck')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== App Suffix Reference ===&lt;br /&gt;
The Nielsen AppSDK has various configurations per market and distribution type, which can be determined by reviewing the [[Digital Measurement Android Suffix Guide|sdk suffix]].  The first part will be the SDK version: 3 digits for the major SDK version and 1 digit for the minor SDK version. EG: &amp;lt;code&amp;gt;aa.8.1.0.0_abc&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Proguard Obfuscation ==&lt;br /&gt;
&lt;br /&gt;
AppSDK internally obfuscate all non-public classes during the build process using Proguard. Please use the below filter to avoid  obfuscation of AppSDK classes if Client app is also using proguard tool &lt;br /&gt;
&lt;br /&gt;
&amp;quot;''-keep class com.nielsen.app.sdk.** { *; }''&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Sync ==&lt;br /&gt;
&lt;br /&gt;
If you are finished with all previous steps then you can sync your build.gradle and after successful build you are ready to use Nielsen App SDK library in your code.&lt;br /&gt;
&lt;br /&gt;
== Sample file ==&lt;br /&gt;
The below is an example of a very basic app build.gradle file&lt;br /&gt;
&amp;lt;syntaxhighlight lang=Java&amp;gt;&lt;br /&gt;
plugins {&lt;br /&gt;
    id 'com.android.application'&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
android {&lt;br /&gt;
    compileSdkVersion 30&lt;br /&gt;
    buildToolsVersion &amp;quot;30.0.3&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    defaultConfig {&lt;br /&gt;
        applicationId &amp;quot;com.nielsen.simplestandardandroidart&amp;quot;&lt;br /&gt;
        minSdkVersion 23&lt;br /&gt;
        targetSdkVersion 30&lt;br /&gt;
        versionCode 1&lt;br /&gt;
        versionName &amp;quot;1.0&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        testInstrumentationRunner &amp;quot;androidx.test.runner.AndroidJUnitRunner&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    buildTypes {&lt;br /&gt;
        release {&lt;br /&gt;
            minifyEnabled false&lt;br /&gt;
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    repositories {&lt;br /&gt;
        //Copy below code inside repository section of app’s build.gradle file&lt;br /&gt;
        maven { url 'https://raw.githubusercontent.com/NielsenDigitalSDK/nielsenappsdk-android/master/'&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    compileOptions {&lt;br /&gt;
        sourceCompatibility JavaVersion.VERSION_1_8&lt;br /&gt;
        targetCompatibility JavaVersion.VERSION_1_8&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
dependencies {&lt;br /&gt;
&lt;br /&gt;
    implementation 'androidx.appcompat:appcompat:1.2.0'&lt;br /&gt;
    implementation 'com.google.android.material:material:1.1.0'&lt;br /&gt;
    implementation 'androidx.constraintlayout:constraintlayout:2.0.4'&lt;br /&gt;
    testImplementation 'junit:junit:4.+'&lt;br /&gt;
    androidTestImplementation 'androidx.test.ext:junit:1.1.2'&lt;br /&gt;
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'&lt;br /&gt;
    implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'&lt;br /&gt;
    implementation 'com.google.android.gms:play-services-ads:20.3.0'&lt;br /&gt;
    implementation 'com.nielsenappsdk.global:ad:+'&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
task NielsenSdkReleaseCheck {&lt;br /&gt;
    def p = ['curl',&amp;quot;https://raw.githubusercontent.com/NielsenDigitalSDK/&amp;quot; +&lt;br /&gt;
            &amp;quot;nielsenappsdk-android/master/com/nielsenappsdk/global/&amp;quot; +&lt;br /&gt;
            &amp;quot;NielsenAppSdk-ReadMe.md&amp;quot;].execute().text&lt;br /&gt;
    project.logger.log(LogLevel.ERROR,p)&lt;br /&gt;
}&lt;br /&gt;
preBuild.dependsOn('NielsenSdkReleaseCheck')&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>AnkitAgrawal</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=Browser_SDK_API_Reference&amp;diff=6975</id>
		<title>Browser SDK API Reference</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=Browser_SDK_API_Reference&amp;diff=6975"/>
		<updated>2024-09-03T20:26:18Z</updated>

		<summary type="html">&lt;p&gt;AnkitAgrawal: /* Configure Browser SDK */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
== Setting up Development Environment ==&lt;br /&gt;
=== Step 1: Configure Content Management System (CMS) ===&lt;br /&gt;
Configure CMS to send the required values (see table below). Any internal CMS_variable names can be used for passing the data.&lt;br /&gt;
&lt;br /&gt;
Ensure to capture these CMS_variable names in the SDK Configuration Form.&lt;br /&gt;
&lt;br /&gt;
For more information on setting variable names, see the SDK Configuration Form included within the SDK package.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Required Data !! Description !! Value&lt;br /&gt;
|-&lt;br /&gt;
| dataSrc || Used when both CMS metadata and ID3 data are present in the player. Setting this field tells the SDK whether to use the CMS metadata or the ID3 payload to derive the pings || cms&lt;br /&gt;
|-&lt;br /&gt;
| type || Type of asset: ad or content || preroll, midroll, postroll, or content&lt;br /&gt;
|-&lt;br /&gt;
| assetid || unique ID assigned to asset || custom &amp;lt;br&amp;gt;(no [[Special Characters]])&lt;br /&gt;
|-&lt;br /&gt;
| OCR Tag || OCR tag provided by Nielsen for implementation on the ad unit || Complete OCR URL&lt;br /&gt;
|-&lt;br /&gt;
| program || Name of program (25 character limit) || custom&lt;br /&gt;
|-&lt;br /&gt;
| title || Episode title (40 character limit) || custom&lt;br /&gt;
|-&lt;br /&gt;
| length || Length of content in seconds || Length in seconds, 0 for live stream&lt;br /&gt;
|-&lt;br /&gt;
| adloadtype || Type of ad load || &amp;quot;1&amp;quot; - Linear &amp;quot;2&amp;quot; - Dynamic(default)&lt;br /&gt;
|-&lt;br /&gt;
| hasAds || Identify if content includes Ads ||  &amp;quot;0&amp;quot; - no ads &amp;quot;1&amp;quot; - includes ads &amp;quot;2&amp;quot; - unknown(default)&lt;br /&gt;
|-&lt;br /&gt;
| isfullepisode || Full episode flag	|| &amp;quot;y&amp;quot; - full episode &amp;quot;n&amp;quot; - non full episode&lt;br /&gt;
|-&lt;br /&gt;
| segA || Segment A (this is not available for video reporting as the episode title is reported) || custom value&lt;br /&gt;
|-&lt;br /&gt;
| segB || Custom segment B || custom value&lt;br /&gt;
|-&lt;br /&gt;
| segC || Custom segment C || custom value&lt;br /&gt;
|-&lt;br /&gt;
| crossId1 || Standard episode ID || custom value&lt;br /&gt;
|-&lt;br /&gt;
| crossId2 || Content originator (required only for distributors) || custom value&lt;br /&gt;
|-&lt;br /&gt;
| airdate || Original air date and time in Eastern Time. For non-US countries, it should be local time. || YYYYMMDD HH24:MI:SS&lt;br /&gt;
|-&lt;br /&gt;
| containerId || HTML DOM element of the Player container (for Viewability&amp;amp;Audibility feature only) || custom value &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Step 2: Complete the Nielsen SDK Configuration Form ===&lt;br /&gt;
The SDK is designed to map the &amp;lt;code&amp;gt;CMS_variable names&amp;lt;/code&amp;gt;. To support the custom mapping, the developer is required to complete the SDK Configuration Form. The form will be provided during onboarding along with this guide.&lt;br /&gt;
&lt;br /&gt;
== Initialization ==&lt;br /&gt;
=== Obtain the Nielsen Application ID (apid) and Browser SDK URLs ===&lt;br /&gt;
The Nielsen &amp;lt;code&amp;gt;apid&amp;lt;/code&amp;gt; is required to enable SDK functionality. Technical Account Manager will provide an apid for each player configuration.  &lt;br /&gt;
Browser SDK can support URLs that use any of the protocols – HTTPS and HTTP.  &lt;br /&gt;
&lt;br /&gt;
=== Configure Browser SDK ===&lt;br /&gt;
There are two steps required for configuring the SDK:&lt;br /&gt;
&lt;br /&gt;
'''Add Static Queue Snippet'''&lt;br /&gt;
&lt;br /&gt;
*Add Static Queue Snippet&lt;br /&gt;
*Create SDK Instance&lt;br /&gt;
&lt;br /&gt;
Add the following script tag to the website:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
    // Static Queue Snippet&lt;br /&gt;
    !function (e, n) {&lt;br /&gt;
      function t(e) {&lt;br /&gt;
        return &amp;quot;object&amp;quot; == typeof e ? JSON.parse(JSON.stringify(e)) : e&lt;br /&gt;
      }&lt;br /&gt;
      e[n] = e[n] ||&lt;br /&gt;
      {&lt;br /&gt;
        nlsQ: function (o, r, c) {&lt;br /&gt;
          var s = e.document,&lt;br /&gt;
            a = s.createElement(&amp;quot;script&amp;quot;);&lt;br /&gt;
          a.async = 1,&lt;br /&gt;
            a.src = (&amp;quot;http:&amp;quot; === e.location.protocol ? &amp;quot;http:&amp;quot; : &amp;quot;https:&amp;quot;) + &amp;quot;//cdn-gl.imrworldwide.com/conf/&amp;quot; + o + &amp;quot;.js#name=&amp;quot; + r + &amp;quot;&amp;amp;ns=&amp;quot; + n;&lt;br /&gt;
          var i = s.getElementsByTagName(&amp;quot;script&amp;quot;)[0];&lt;br /&gt;
          return i.parentNode.insertBefore(a, i),&lt;br /&gt;
            e[n][r] = e[n][r] || {&lt;br /&gt;
              g: c || {},&lt;br /&gt;
              ggPM: function (o, c, s, a, i) { e[n][r].q = e[n][r].q || []; try { var l = t([o, c, s, a, i]); e[n][r].q.push(l) } catch (e) { console &amp;amp;&amp;amp; console.log &amp;amp;&amp;amp; console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;) } },&lt;br /&gt;
              trackEvent: function (o) { e[n][r].te = e[n][r].te || []; try { var c = t(o); e[n][r].te.push(c) } catch (e) { console &amp;amp;&amp;amp; console.log &amp;amp;&amp;amp; console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;) } }&lt;br /&gt;
            },&lt;br /&gt;
            e[n][r]&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }(window, &amp;quot;NOLBUNDLE&amp;quot;);&lt;br /&gt;
  &amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The static queue snippet allows the SDK APIs to be called while the actual SDK and configuration file are still being downloaded. As the queue can capture all API calls before the download completes, there is no wait time. Once the SDK is available, the API calls will transition from directing to the queue to the SDK seamlessly.&lt;br /&gt;
&lt;br /&gt;
'''Create SDK Instance'''&lt;br /&gt;
&lt;br /&gt;
To initialize the SDK, create an SDK instance by making the initialization call:&lt;br /&gt;
&lt;br /&gt;
'''Initialization API Call'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NOLBUNDLE.nlsQ(&amp;quot;&amp;lt;apid&amp;gt;&amp;quot;, &amp;quot;&amp;lt;instanceName&amp;gt;&amp;quot;,{nol_sdkDebug: &amp;quot;debug&amp;quot;})&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When creating an instance, pass the following three values:&lt;br /&gt;
&lt;br /&gt;
=== SDK Initialization – Global Parameters ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameters !! Description !! Value&lt;br /&gt;
|-&lt;br /&gt;
| apid || UniqueID assigned to player/site. || 	'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'&lt;br /&gt;
|-&lt;br /&gt;
| instanceName || Name of SDK instance || &amp;quot;any string value&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| nol_sdkDebug || Enables Nielsen console logging. Only required for testing || &amp;quot;{nol_sdkDebug: &amp;quot;debug&amp;quot;})&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| containerId || HTML DOM element id of the player container. Only for Viewability &amp;amp; Audibility feature. || {containerId: &amp;quot;playerId1&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| hem_sha256 || SHA256-hashed email address (client-supplied unique 32-character hexadecimal string) || &amp;quot;tMmiiTI7IaAcPpQPFQ65uMVCWH8av9jw4cwf/F5HVRQ=&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| hem_sha1 || SHA1-hashed email address (client-supplied unique 32-character hexadecimal string) || &amp;quot;XvBniTI7IaAcPpQPFQ65uMVCWH8av9jw4cwf/F5HVRQ=&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| hem_md5 || MD5-hashed email address (client-supplied unique 32-character hexadecimal string) || &amp;quot;JnIbdTI7IaAcPpQPFQ65uMVCWH8av9jw4cwf/F5HVRQ=&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| uid2 || An identifier based on a user’s verifiable PII (e.g. hashed email). UID2.0 was initially created by The Trade Desk (TTD) and is now managed by Prebid. || &amp;quot;MTKVpUAzwYAPnHrtfE0wlINOMzhU7UUEjjVdCdRu63k=&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| uid2_token || Encrypted Unified ID 2.0 || &amp;quot;AgAAAAPFR0zA5ogv/yaAPiUsAdZPsfqS8Ql&lt;br /&gt;
DSGxAB+rr8yekFs3AjLYVk5qqqiyV2XHbSuwzHmxSlLeQeK&lt;br /&gt;
QI1mp015jsNnpX5/xGgXldcgVz+gFnyh3T8/3agMwRmyrhC&lt;br /&gt;
xG4oH2C7fc48AQk2eotE7FW0ZDEYM8fD9ZxDaxFUC/OV3OuZA&amp;amp;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|luid&lt;br /&gt;
|Living Unit ID - Experian Household ID&lt;br /&gt;
'''Note: This parameter is applicable only for CTV and First Party Livestream data'''&lt;br /&gt;
|&amp;quot;B0EOFEDgD&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{{example_bsdk_init}}&lt;br /&gt;
&lt;br /&gt;
'''Example SDK Configuration'''&lt;br /&gt;
&lt;br /&gt;
The configuration should include the Static Queue Snippet and an SDK Instance for an unique App ID as shown in the example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
!function(t,n)&lt;br /&gt;
{&lt;br /&gt;
  t[n]=t[n]||&lt;br /&gt;
  {&lt;br /&gt;
    nlsQ:function(e,o,c,r,s,i)&lt;br /&gt;
    {&lt;br /&gt;
     return s=t.document,&lt;br /&gt;
     r=s.createElement(&amp;quot;script&amp;quot;),&lt;br /&gt;
     r.async=1,&lt;br /&gt;
     r.src=(&amp;quot;http:&amp;quot;===t.location.protocol?&amp;quot;http:&amp;quot;:&amp;quot;https:&amp;quot;)+&amp;quot;//cdn-gl.imrworldwide.com/conf/&amp;quot;+e+&amp;quot;.js#name=&amp;quot;+o+&amp;quot;&amp;amp;ns=&amp;quot;+n,&lt;br /&gt;
     i=s.getElementsByTagName(&amp;quot;script&amp;quot;)[0],&lt;br /&gt;
     i.parentNode.insertBefore(r,i),&lt;br /&gt;
     t[n][o]=t[n][o]||{g:c||{},&lt;br /&gt;
     ggPM:function(e,c,r,s,i){(t[n][o].q=t[n][o].q||[]).push([e,c,r,s,i])}},t[n][o]&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
(window,&amp;quot;NOLBUNDLE&amp;quot;);&lt;br /&gt;
  // Created SDK Instance&lt;br /&gt;
  var nSdkInstance = NOLBUNDLE.nlsQ(&amp;quot;XXXXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX&amp;quot;,&amp;quot;nlsnInstance&amp;quot;, {nol_sdkDebug: &amp;quot;debug&amp;quot;});&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== SDK Initialization to measure the Viewability &amp;amp; Audibility ===&lt;br /&gt;
To support viewability metrics in the web page the integrator has to provide a tag value of the player view to let Nielsen SDK know that there is a player that needs to be tracked. It’s called the ‘containerId’ and it should be passed in the as string while initializing the Nielsen browser SDK.&lt;br /&gt;
&lt;br /&gt;
NOLBUNDLE.nlsQ(&amp;quot;&amp;lt;apid&amp;gt;&amp;quot;, &amp;quot;&amp;lt;instanceName&amp;gt;&amp;quot;,{containerId: &amp;lt;playerElementID&amp;gt;, nol_sdkDebug: &amp;quot;debug&amp;quot;})&lt;br /&gt;
&lt;br /&gt;
'''Example SDK Initialization for Viewability'''&lt;br /&gt;
&lt;br /&gt;
Your configuration should include the Static Queue Snippet and an SDK Instance for your unique App ID as shown in the example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
//Add Static Queue Snippet&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
    !function (e, n) {&lt;br /&gt;
      function t(e) {&lt;br /&gt;
        return &amp;quot;object&amp;quot; == typeof e ? JSON.parse(JSON.stringify(e)) : e&lt;br /&gt;
      }&lt;br /&gt;
      e[n] = e[n] ||&lt;br /&gt;
      {&lt;br /&gt;
        nlsQ: function (o, r, c) {&lt;br /&gt;
          var s = e.document,&lt;br /&gt;
            a = s.createElement(&amp;quot;script&amp;quot;);&lt;br /&gt;
          a.async = 1,&lt;br /&gt;
            a.src = (&amp;quot;http:&amp;quot; === e.location.protocol ? &amp;quot;http:&amp;quot; : &amp;quot;https:&amp;quot;) + &amp;quot;//cdn-gl.imrworldwide.com/conf/&amp;quot; + o + &amp;quot;.js#name=&amp;quot; + r + &amp;quot;&amp;amp;ns=&amp;quot; + n;&lt;br /&gt;
          var i = s.getElementsByTagName(&amp;quot;script&amp;quot;)[0];&lt;br /&gt;
          return i.parentNode.insertBefore(a, i),&lt;br /&gt;
            e[n][r] = e[n][r] || {&lt;br /&gt;
              g: c || {},&lt;br /&gt;
              ggPM: function (o, c, s, a, i) { e[n][r].q = e[n][r].q || []; try { var l = t([o, c, s, a, i]); e[n][r].q.push(l) } catch (e) { console &amp;amp;&amp;amp; console.log &amp;amp;&amp;amp; console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;) } },&lt;br /&gt;
              trackEvent: function (o) { e[n][r].te = e[n][r].te || []; try { var c = t(o); e[n][r].te.push(c) } catch (e) { console &amp;amp;&amp;amp; console.log &amp;amp;&amp;amp; console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;) } }&lt;br /&gt;
            },&lt;br /&gt;
            e[n][r]&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }(window, &amp;quot;NOLBUNDLE&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
//Create SDK Instance&lt;br /&gt;
var nSdkInstance = NOLBUNDLE.nlsQ(&amp;quot;XXXXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX&amp;quot;, &amp;quot;nlsnInstance&amp;quot;, {containerId: “player1”, nol_sdkDebug: &amp;quot;debug&amp;quot;});&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Browser SDK API Methods &amp;amp; Properties ==&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Method / Property !! Event # !! DTVR !! DAR !! DCR !! Description&lt;br /&gt;
|-&lt;br /&gt;
| [[loadMetadata (Browser)|loadMetadata]] || 15 || ✔ || ✔ || ✔ || Used when there is a preroll ad that needs to be associated with content metadata. The loadMetadata will first be called to populate the content metadata values and then the loadMetadata for ad metadata will be called. This allows sending a content ping with the ad info, even if the user bails out during the preroll ad.&lt;br /&gt;
|-&lt;br /&gt;
| [[play (Browser)|play]] || 5 || ✔ || ✘ || ✔ || Used when there is an ID3 fed product such as DTVR and the client does not want to send in all the CMS metadata that is sent in loadMetadata. This allows the client to send in at least the required “channel name” value associated to the ID3 feed. When the client passes in the channelName, they can change the CMS data stored by passing new values. If this event is not called then the “channel name” value populated will be the default value of “defaultChannelName”.&lt;br /&gt;
|-&lt;br /&gt;
| [[sendID3 (Browser)|sendID3]] || 55 || ✔ || ✘ || ✘ || Used to send the ID3 metadata.&lt;br /&gt;
|-&lt;br /&gt;
| [[setPlayheadPosition (Browser)|setPlayheadPosition]] || 49 || ✘ || ✘ || ✔ || Used to send the playhead position.&lt;br /&gt;
|-&lt;br /&gt;
| [[stop (Browser)|stop]] || 7 || ✘ || ✘ || ✔ || Used when switching between ad and content or content and ad.&lt;br /&gt;
|-&lt;br /&gt;
| [[end (Browser)|end]] || 57 || ✔ || ✘ || ✔ || This is triggered 1) at the end of the content stream, 2) if the user switches to another piece of content 3) when the browser is refreshed or closed&lt;br /&gt;
|-&lt;br /&gt;
| [[staticstart (Browser)|staticstart]] || 14 || ✘ || ✘ || ✔ || Used to send the metadata for the static page.&lt;br /&gt;
|-&lt;br /&gt;
| [[StaticEnd (Browser)|staticend]] || 56 || ✘ || ✘ || ✔ || In Single Page Application (SPA) it is imperative that staticend is called prior to the loading of new metadata. This allows the Browser SDK to properly credit the previous section/content being viewed before measuring the new one.&lt;br /&gt;
|-&lt;br /&gt;
| [[updateOTT (Browser)|updateOTT]] || - || ✘ || ✘ || ✔ || Used to notify Browser SDK that the remote OTT device (like Google ChromeCast, Roku, Amazon FireTV, etc.) is connected / disconnected (change of OTT status).&lt;br /&gt;
|-&lt;br /&gt;
| [[ onPaginate (Browser)|onPaginate]] || 30 || ✘ || ✘ || ✔ || Used to create a new instance of the SDK object&lt;br /&gt;
|-&lt;br /&gt;
| [[updateMetadata (Browser)|updateMetadata]] || 35 || ✔ || ✔ || ✔ || This event is used for updating metadata parameters for the content or ad that is being played.&lt;br /&gt;
|-&lt;br /&gt;
| [[setVolume_(Browser)|setVolume]] || 61 || ✔ || ✘ || ✔ || Used to pass in the player volume levels in %. Default value is -1.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Retrieving ID3 Tags ==&lt;br /&gt;
The video player must have the ability to extract ID3 tags and supply them to the Browser SDK, based on the HLS standard.&lt;br /&gt;
*An ID3 tag spans two PES packets.&lt;br /&gt;
**In the first PES packet, look for www.nielsen.com, this is the start of the ID3 tag. Continue to parse the first PES packet until the undefined char &amp;quot;\ufffd&amp;quot; is found. This forms the first half of the ID3 tag&lt;br /&gt;
**In the second PES packet, identify the end pattern – a regEx of /(\/\d+){3}/ and look to remove the lowest index of either &amp;quot;\x00&amp;quot; and/or &amp;quot;\ufffd&amp;quot;. Now the second packet has been appended and the demarcation of the Nielsen-specific data has been defined.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Follow the procedure below, to extract Nielsen ID3 tags from an MPEG-2 transport stream (including HLS streams).&lt;br /&gt;
#Parse the Program Map Table (PMT) to find the PID of the metadata stream. Confirm the presence of the metadata descriptor described in section 2.3.3 of Apple’s “HTTP Live Streaming Metadata Spec.pdf”. Only private streams with metadata descriptor present should be considered as ID3-tag metadata streams.&lt;br /&gt;
#Parse the HLS/Transport stream for any '''PES header''' with the PID found in step 1.&lt;br /&gt;
#Follow standard MPEG-2 parsing procedures to locate the start of the payload of the PES packet.&lt;br /&gt;
#Copy the PES payload into a buffer.&lt;br /&gt;
#The ID3 tag spans 2 PES packets. Parse the stream for the next packet whose PID is set to the PID found in step 1. Typically the ID3 Tag is of 249 bytes. The steps below guide towards extraction of the ID3 tag&lt;br /&gt;
##In the first PES packet, look for &amp;quot;www.nielsen.com&amp;quot; , this is the start of the ID3 tag. Keep on parsing the first PES packet until the undefined char &amp;quot;\ufffd&amp;quot; is found. This forms the first half of the ID3 tag&lt;br /&gt;
##In the second PES packet, identify the end pattern, a regEx of /(\/\d+){3}/ and look to remove the lowest index of either “\x00” and/or “\ufffd”. Now the second packet has been appended and the demarcation of the Nielsen specific data has been defined. This segment can be simply substringed.&lt;br /&gt;
##Concatenate this substringed segment with the payload derived from the first packet get the ID3 payload.&lt;br /&gt;
#Check the length of the contents in the buffer to make sure that it is equal to the size of a Nielsen ID3 tag.&lt;br /&gt;
#Ensure that the ID3 byte array is converted into the string and escape it, so that the SDK can consume it.&lt;br /&gt;
Repeat steps 2 through 7 for all ID3 tags in the stream.&lt;br /&gt;
&lt;br /&gt;
'''References'''&lt;br /&gt;
*[http://www.iso.org/iso/catalogue_detail?csnumber=44169. ISO/IEC 13818-1:2007] Information technology – Generic coding of moving pictures and associated audio information: Systems&lt;br /&gt;
*https://developer.apple.com/library/content/documentation/AudioVideo/Conceptual/HTTP_Live_Streaming_Metadata_Spec/&lt;br /&gt;
&lt;br /&gt;
=== Sample ID3 tags ===&lt;br /&gt;
* &amp;lt;code&amp;gt;www.nielsen.com/X100zdCIGeIlgZnkYj6UvQ==/X100zdCIGeIlgZnkYj6UvQ==/AAAB2Jz2_k74GXSzx4npHuI_&amp;lt;wbr /&amp;gt;JwJd3QSUpW30rDkGTcbHEzIMWleCzM-uvNOP9fzJcQMWQLJqzXMCAxParOb5sGijSV9dNM3QiBniJYGZ5GI-lL1fXTTN0IgZ4iWBmeRiPpS9AAAAAAAAAAAAAAAAAAAAAFJWFM5SVhTONNU=/00000/00000/00&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;www.nielsen.com/X100zdCIGeIlgZnkYj6UvQ==/R8WHe7pEBeqBhu8jTeXydg==/AAICoyitYqlxT7n6aZ0oMCGhe&amp;lt;wbr /&amp;gt;Fi4CXFp46AMUPZz1lMr_M9tr3_cjee1SHqxrOiVerMDLeyn9xzocZSKwi746Re8vNOtpNCAZjYABs_J0R25IHpvOc1HS8&amp;lt;wbr /&amp;gt;QHGgD5TgOJeS6gX100zdCIGeIlgZnkYj6UvVJWFNhSVhTiPE0=/00000/46016/00&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': ID3 tags are not applicable for International (Germany)&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Browser Opt-Out Implementation ==&lt;br /&gt;
The site in which video content is being measure via Nielsen methodology must provide the means for the user to opt-out of, or opt back into Nielsen Measurement.&lt;br /&gt;
&lt;br /&gt;
For Browser-based applications, opt-out setting is stored via Nielsen cookie. Therefore, it is only necessary that users be made aware of measurement opt-out by incorporating the template below in the user interface.&lt;br /&gt;
&lt;br /&gt;
=== Sample Opt Out Template ===&lt;br /&gt;
Our properties may feature Nielsen’s proprietary measurement software which will allow to contribute to market research, like Nielsen’s TV Ratings. To learn more about this information, see https://www.nielsen.com/digitalprivacy. Nielsen’s software may collect your choices with regards to it.&lt;br /&gt;
&lt;br /&gt;
== Nielsen Privacy Requirements ==&lt;br /&gt;
Privacy protections that Nielsen ensures to have with each App SDK integration are as follows.&lt;br /&gt;
*Disclosure of viewership data collection in EULA / Privacy Policy&lt;br /&gt;
*A link in the EULA/Privacy policy, or in another conspicuous location within the App, to a Nielsen-hosted web page outlining what Nielsen is collecting and how it is being used&lt;br /&gt;
*Method for users to opt-out of Nielsen measurement, any time while using the application&lt;br /&gt;
&lt;br /&gt;
=== Ratings Data Flow ===&lt;br /&gt;
Every view of creditable and watermarked content is measured by Nielsen.&lt;br /&gt;
[[File:RatingsDataFlow.png]]&lt;br /&gt;
&lt;br /&gt;
'''Information NOT Shared'''&lt;br /&gt;
* '''With Nielsen'''&lt;br /&gt;
** User's Identity&lt;br /&gt;
* '''With Data Provider'''&lt;br /&gt;
** Content information&lt;br /&gt;
** Whether user is viewing an ad or video content&lt;br /&gt;
** Player used to play the streaming (audio / video, etc.)&lt;br /&gt;
** Values being de-duped / aggregating for&lt;br /&gt;
&lt;br /&gt;
Nielsen collects only what it needs for audience measurement. Every view of creditable, watermarked content will be measured by Nielsen.&lt;br /&gt;
&lt;br /&gt;
=== Data Collected ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type of Information !! Parameter !! Transmitted to Nielsen? !! Sent to Provider?&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;8&amp;quot; | Nielsen ID3 Watermark&lt;br /&gt;
|-&lt;br /&gt;
| FinalDistributor Timestamp || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| Program Content Timestamp || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| Mobile Breakout Code || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| Commercial Credit Code – Linear or Dynamic || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| Time ShiftedViewing Code || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| Segment Number || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| Segment View Pattern || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;7&amp;quot; | Device/App Info&lt;br /&gt;
|-&lt;br /&gt;
| Device OSVersion || Yes || Yes &lt;br /&gt;
|-&lt;br /&gt;
| Device Model || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| Cache Buster || Yes || Yes &lt;br /&gt;
|-&lt;br /&gt;
| SDKDisabled Flag || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| ServerCode || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| Channel or URL || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;9&amp;quot; | Nielsen Identifiers&lt;br /&gt;
|-&lt;br /&gt;
| Client ID || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| Campaign ID || Yes || Yes &lt;br /&gt;
|-&lt;br /&gt;
| Nielsen Unique Device ID || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| Application ID || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| DeviceGroup (ex. Tablet, Smartphone, Desktop) || Yes || Yes &lt;br /&gt;
|-&lt;br /&gt;
| OS Group (ex. Android, iOS, Windows) || Yes || Yes &lt;br /&gt;
|-&lt;br /&gt;
| SDKVersion || Yes || No&lt;br /&gt;
|-&lt;br /&gt;
| IP Address for DMA, Country Code || Yes || Yes &lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': Data is hashed, and encrypted using AES 128 before transmission to data provider.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Viewability_Data_Collected}}&lt;br /&gt;
&lt;br /&gt;
==== Example ping sent to provider ====&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;https://provider.com/cgi-bin/brandlift.php&amp;lt;/nowiki&amp;gt;?campaign_id=ff12725d724fac7934cf6003f096b4cd&amp;lt;wbr /&amp;gt;&amp;amp;placement_id=a4164b8fba9ee7c873a9c72c7091bb58&amp;lt;wbr /&amp;gt;&amp;amp;creative_id=25280139b61a947e127a52f56c8a2fdd&amp;lt;wbr /&amp;gt;&amp;amp;segment1=9000&amp;lt;wbr /&amp;gt;&amp;amp;segment2=41&amp;lt;wbr /&amp;gt;&amp;amp;segment3=iOS&amp;lt;wbr /&amp;gt;&amp;amp;OSVer=iOS6.1&amp;lt;wbr /&amp;gt;&amp;amp;c9=&amp;lt;wbr /&amp;gt;&amp;amp;devgrp=tablet&amp;lt;wbr /&amp;gt;&amp;amp;h=f5f243fe6d&amp;lt;wbr /&amp;gt;&amp;amp;rnd=1376971827360&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This ping passes the following parameters to the provider:&lt;br /&gt;
* Campaign ID – (campaign, placement, creative)&lt;br /&gt;
* Country Code&lt;br /&gt;
* DMA&lt;br /&gt;
* OS Group (ex. iOS, Android)&lt;br /&gt;
* DeviceOS Version&lt;br /&gt;
* Device Advertiser ID&lt;br /&gt;
* DeviceGroup (ex. Tablet, Smartphone, Desktop)&lt;br /&gt;
* Cache Buster&lt;br /&gt;
&lt;br /&gt;
{{Template:Browser_Privacy_and_Opt-Out}}&lt;br /&gt;
&lt;br /&gt;
=== Opt-Out Implementation ===&lt;br /&gt;
The site must provide the means for the user to opt-out of, or opt back into Nielsen Measurement.&lt;br /&gt;
&lt;br /&gt;
'''Sample Opt Out Template'''&lt;br /&gt;
&lt;br /&gt;
Our properties may feature Nielsen’s proprietary measurement software which will allow to contribute to market research, like Nielsen’s TV Ratings. To learn more about this information, please [http://priv-policy.imrworldwide.com/priv/mobile/us/en/optout.html| click here]. Nielsen’s software may collect your choices with regards to it.&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
See [[Digital Measurement Testing#Testing Browser Implementation|Digital Measurement Testing - Testing Browser Implementation]].&lt;/div&gt;</summary>
		<author><name>AnkitAgrawal</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=DCR_Static_Browser_SDK_(6.0.0)&amp;diff=6974</id>
		<title>DCR Static Browser SDK (6.0.0)</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=DCR_Static_Browser_SDK_(6.0.0)&amp;diff=6974"/>
		<updated>2024-09-03T20:23:47Z</updated>

		<summary type="html">&lt;p&gt;AnkitAgrawal: /* Add Tracking Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|US DCR &amp;amp; DTVR}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
To start using the App SDK, the following items are required:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 30px;&amp;quot; |&lt;br /&gt;
! style=&amp;quot;width: 15%;&amp;quot; | Item&lt;br /&gt;
! Description&lt;br /&gt;
! Source&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|| ☑ || '''App ID (appid)''' || Unique ID assigned to the player/site and configured by product. || Contact Nielsen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Release Notes ==&lt;br /&gt;
The release notes on the Browser SDK can be located here: '''[[Browser SDK Release Notes|Release Notes]]'''&lt;br /&gt;
&lt;br /&gt;
== Implementation Steps ==&lt;br /&gt;
=== Add Tracking Code ===&lt;br /&gt;
The Nielsen DCR Tracking Code must be added to each page.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&amp;lt;script&amp;gt;&lt;br /&gt;
    // Static Queue Snippet&lt;br /&gt;
    !function (e, n) {&lt;br /&gt;
      function t(e) {&lt;br /&gt;
        return &amp;quot;object&amp;quot; == typeof e ? JSON.parse(JSON.stringify(e)) : e&lt;br /&gt;
      }&lt;br /&gt;
      e[n] = e[n] ||&lt;br /&gt;
      {&lt;br /&gt;
        nlsQ: function (o, r, c) {&lt;br /&gt;
          var s = e.document,&lt;br /&gt;
            a = s.createElement(&amp;quot;script&amp;quot;);&lt;br /&gt;
          a.async = 1,&lt;br /&gt;
            a.src = (&amp;quot;http:&amp;quot; === e.location.protocol ? &amp;quot;http:&amp;quot; : &amp;quot;https:&amp;quot;) + &amp;quot;//cdn-gl.imrworldwide.com/conf/&amp;quot; + o + &amp;quot;.js#name=&amp;quot; + r + &amp;quot;&amp;amp;ns=&amp;quot; + n;&lt;br /&gt;
          var i = s.getElementsByTagName(&amp;quot;script&amp;quot;)[0];&lt;br /&gt;
          return i.parentNode.insertBefore(a, i),&lt;br /&gt;
            e[n][r] = e[n][r] || {&lt;br /&gt;
              g: c || {},&lt;br /&gt;
              ggPM: function (o, c, s, a, i) { e[n][r].q = e[n][r].q || []; try { var l = t([o, c, s, a, i]); e[n][r].q.push(l) } catch (e) { console &amp;amp;&amp;amp; console.log &amp;amp;&amp;amp; console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;) } },&lt;br /&gt;
              trackEvent: function (o) { e[n][r].te = e[n][r].te || []; try { var c = t(o); e[n][r].te.push(c) } catch (e) { console &amp;amp;&amp;amp; console.log &amp;amp;&amp;amp; console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;) } }&lt;br /&gt;
            },&lt;br /&gt;
            e[n][r]&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }(window, &amp;quot;NOLBUNDLE&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  // SDK Initialization&lt;br /&gt;
var nSdkInstance = NOLBUNDLE.nlsQ(&amp;quot;PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX&amp;quot;, &amp;quot;nlsnInstance&amp;quot;, {&lt;br /&gt;
    nol_sdkDebug: &amp;quot;debug&amp;quot;&lt;br /&gt;
});&lt;br /&gt;
  &lt;br /&gt;
  // Content Metadata &lt;br /&gt;
  var nielsenMetadata = {&lt;br /&gt;
    type: 'static', &lt;br /&gt;
    assetid: 'HHF887465-9486', // *DYNAMIC METADATA*: unique ID for each article **REQUIRED**&lt;br /&gt;
    section: 'SPORTS', // *DYNAMIC METADATA*: section of site **REQUIRED**&lt;br /&gt;
    segA: 'HDVIDEOS', // *DYNAMIC METADATA*: custom segment&lt;br /&gt;
    segB: '', // *DYNAMIC METADATA*: custom segment&lt;br /&gt;
    segC: ''  // *DYNAMIC METADATA*: custom segment&lt;br /&gt;
    }; &lt;br /&gt;
    &lt;br /&gt;
  // Event 'staticstart' Call&lt;br /&gt;
  nSdkInstance.ggPM(&amp;quot;staticstart&amp;quot;, nielsenMetadata);&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;For DCR static, BSDK cannot be run in an iframe because the blur/focus events of the parent page may not propagate to the iframe. The iframe events typically trigger when the iframe itself is clicked. The BSDK is dependent on the blur/focus events of the browser to detect active viewing of the page. Because the root page events do not propagate to the iframe, this would impact incorrect DCR static crediting.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tracking Code Components ===&lt;br /&gt;
The tracking code includes&lt;br /&gt;
* Static Queue Snippet&lt;br /&gt;
* SDK Initialization&lt;br /&gt;
* Content Metadata&lt;br /&gt;
* staticstart Event&lt;br /&gt;
&lt;br /&gt;
'''Static Queue Snippet'''&lt;br /&gt;
&lt;br /&gt;
The static queue snippet allows the SDK APIs to be called while the actual SDK and configuration file are still being downloaded. As the queue can capture all API calls before the download completes, there is no wait time. Once the SDK is available, the API calls will transition from directing to the queue to the SDK seamlessly.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
    // Static Queue Snippet&lt;br /&gt;
    !function (e, n) {&lt;br /&gt;
      function t(e) {&lt;br /&gt;
        return &amp;quot;object&amp;quot; == typeof e ? JSON.parse(JSON.stringify(e)) : e&lt;br /&gt;
      }&lt;br /&gt;
      e[n] = e[n] ||&lt;br /&gt;
      {&lt;br /&gt;
        nlsQ: function (o, r, c) {&lt;br /&gt;
          var s = e.document,&lt;br /&gt;
            a = s.createElement(&amp;quot;script&amp;quot;);&lt;br /&gt;
          a.async = 1,&lt;br /&gt;
            a.src = (&amp;quot;http:&amp;quot; === e.location.protocol ? &amp;quot;http:&amp;quot; : &amp;quot;https:&amp;quot;) + &amp;quot;//cdn-gl.imrworldwide.com/conf/&amp;quot; + o + &amp;quot;.js#name=&amp;quot; + r + &amp;quot;&amp;amp;ns=&amp;quot; + n;&lt;br /&gt;
          var i = s.getElementsByTagName(&amp;quot;script&amp;quot;)[0];&lt;br /&gt;
          return i.parentNode.insertBefore(a, i),&lt;br /&gt;
            e[n][r] = e[n][r] || {&lt;br /&gt;
              g: c || {},&lt;br /&gt;
              ggPM: function (o, c, s, a, i) { e[n][r].q = e[n][r].q || []; try { var l = t([o, c, s, a, i]); e[n][r].q.push(l) } catch (e) { console &amp;amp;&amp;amp; console.log &amp;amp;&amp;amp; console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;) } },&lt;br /&gt;
              trackEvent: function (o) { e[n][r].te = e[n][r].te || []; try { var c = t(o); e[n][r].te.push(c) } catch (e) { console &amp;amp;&amp;amp; console.log &amp;amp;&amp;amp; console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;) } }&lt;br /&gt;
            },&lt;br /&gt;
            e[n][r]&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }(window, &amp;quot;NOLBUNDLE&amp;quot;);&lt;br /&gt;
  &amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''SDK Initialization'''&lt;br /&gt;
&lt;br /&gt;
While creating an SDK instance, initialize the SDK by calling:&lt;br /&gt;
&lt;br /&gt;
'''Initialization API Call'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;NOLBUNDLE.nlsQ(&amp;quot;PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX&amp;quot;, &amp;quot;&amp;quot;,{nol_sdkDebug: &amp;quot;debug&amp;quot;})&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When the initialization call is made, a unique static config file, &amp;lt;code&amp;gt;&amp;lt;apid&amp;gt;.js&amp;lt;/code&amp;gt;, will be downloaded based on the &amp;lt;code&amp;gt;apid&amp;lt;/code&amp;gt; and cached by the client-side browser(s).&lt;br /&gt;
&lt;br /&gt;
Once the static config file is downloaded, the SDK will be fully downloaded and initialized. All SDK modules are included in one file:&lt;br /&gt;
&amp;quot;nlsSDK600.bundle.min.js&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
'''Content Metadata'''&lt;br /&gt;
&lt;br /&gt;
Metadata can be passed through key-values using the Nielsen reserved keys. The tracking code includes the Nielsen reserved keys and placeholder values.&lt;br /&gt;
&lt;br /&gt;
Pass dynamic metadata for the keys with the &amp;lt;code&amp;gt;&amp;lt;metadataPlaceholder&amp;gt;&amp;lt;/code&amp;gt; value (e.g. &amp;lt;code&amp;gt;section: ''&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
'''staticstart Event'''&lt;br /&gt;
&lt;br /&gt;
There is only one event call required:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;nSdkInstance.ggPM(&amp;quot;staticstart&amp;quot;, nielsenMetadata);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The content metadata object is passed as a parameter when calling 'staticstart' event . To know more about configuring metadata refer [[DCR_Static_Browser_SDK_(6.0.0)#Configure_Metadata|Configure Metadata]].&lt;br /&gt;
&lt;br /&gt;
=== Pass App ID in Initialization Call ===&lt;br /&gt;
Pass the unique App ID in the first parameter of the initialization call, &amp;lt;code&amp;gt;&amp;lt;apid&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Example SDK Initialization'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;var nSdkInstance = NOLBUNDLE.nlsQ(&amp;quot;PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX&amp;quot;, &amp;quot;nlsnInstance&amp;quot;, {nol_sdkDebug: &amp;quot;debug&amp;quot;});&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The initialization call has three parameters:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description !! Values&lt;br /&gt;
|-&lt;br /&gt;
| apid || Unique ID assigned to player/site. || &amp;lt;code&amp;gt;PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| instanceName || Name of SDK instance || Any string value&lt;br /&gt;
|-&lt;br /&gt;
| nol_sdkDebug: &amp;quot;debug&amp;quot; || Enables Nielsen console logging. Only required for testing || &amp;lt;code&amp;gt;{nol_sdkDebug: &amp;quot;debug&amp;quot;}&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Update &amp;lt;code&amp;gt;&amp;lt;apid&amp;gt;&amp;lt;/code&amp;gt; with the AppID provided. Refer to the [[#Going_Live|Going Live]] section to know about updating the AppID to production after testing is completed.&lt;br /&gt;
&lt;br /&gt;
{{Template:Browser_Metadata}}&lt;br /&gt;
&lt;br /&gt;
{{Template:Browser_Privacy_and_Opt-Out}}&lt;br /&gt;
&lt;br /&gt;
== Infinite Scrolling ==&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;onPaginate&amp;lt;/code&amp;gt; will refire the view ping with the existing/original metadata.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;javascript&amp;quot;&amp;gt;nSdkInstance.ggPM(&amp;quot;onPaginate&amp;quot;, scrolloffset);&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
{|&lt;br /&gt;
!width=&amp;quot;23%&amp;quot;| Parameter&lt;br /&gt;
!width=&amp;quot;19%&amp;quot;| Description&lt;br /&gt;
|-&lt;br /&gt;
| event&lt;br /&gt;
| &amp;lt;code&amp;gt;onPaginate&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| scrolloffset&lt;br /&gt;
| The &amp;lt;code&amp;gt;scrolloffset&amp;lt;/code&amp;gt; value should be the y-scroll position:&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== onPaginate ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;onPageinate&amp;lt;/code&amp;gt; is a slightly modified version of &amp;lt;code&amp;gt;staticstart&amp;lt;/code&amp;gt; to enable tracking of user’s focus in pages with continuous scrolling. &amp;lt;code&amp;gt;onPaginate&amp;lt;/code&amp;gt; event provides the same behavior as &amp;lt;code&amp;gt;staticstart&amp;lt;/code&amp;gt; keeping it local to only clients who wish to implement continuous scrolling. (Note: This event &amp;lt;code&amp;gt;onPaginate&amp;lt;/code&amp;gt; will not reset the page duration timer.)&lt;br /&gt;
&lt;br /&gt;
* The maximum number of static View pings allowed per session is ‘1’. This is enforced via the &amp;lt;code&amp;gt;nol_maxPingCount&amp;lt;/code&amp;gt; parameter in the tag and the cadence of impression.&lt;br /&gt;
* When an &amp;lt;code&amp;gt;onPaginate&amp;lt;/code&amp;gt; event is called at the end of section / a focus shift (within the same page), this filter will reset the current ping count to ‘0’ for the static View ping. This change of value will cause a new View ping when the Browser SDK receives the next &amp;lt;code&amp;gt;staticPosition&amp;lt;/code&amp;gt; event (at the section end). This sequence continues through the end of scrolling or till the close of static page session.&lt;br /&gt;
*One of the following must occur before an onPaginate event should be sent : user-initiated action, more than 50% of the content has changed or an ad, or the potential for an ad, is being loaded&lt;br /&gt;
&lt;br /&gt;
[[File:StaticPageEvent35.jpg|center|link=]]&lt;br /&gt;
&lt;br /&gt;
== Going Live ==&lt;br /&gt;
Once the DCR Tracking Code is added, Nielsen will validate the implementation. Following Nielsen testing, users need to make a couple of updates to the initialization call to ensure that the site is being measured properly.&lt;br /&gt;
# '''App ID''': Ensure that correct &amp;lt;apid&amp;gt; is used during initialization&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;'PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# '''Debug Logging''': Disable logging by deleting &amp;lt;code&amp;gt;{nol_sdkDebug: 'DEBUG'}&amp;lt;/code&amp;gt; from initialization call.&lt;br /&gt;
#* '''Example Production Initialization Call''' - Refer to the production initialization call below:&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;var nSdkInstance = NOLBUNDLE.nlsQ(&amp;quot;PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;, &amp;quot;nlsnInstance&amp;quot;);&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>AnkitAgrawal</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=DCR_Video_Browser_SDK&amp;diff=6973</id>
		<title>DCR Video Browser SDK</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=DCR_Video_Browser_SDK&amp;diff=6973"/>
		<updated>2024-09-03T20:22:27Z</updated>

		<summary type="html">&lt;p&gt;AnkitAgrawal: /* Example SDK Configuration */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|US DCR &amp;amp; DTVR}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
Before you start the integration, you will need:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 30px;&amp;quot; |&lt;br /&gt;
! style=&amp;quot;width: 15%;&amp;quot; | Item&lt;br /&gt;
! Description&lt;br /&gt;
! Source&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|| ☑ || '''App ID (appid)''' || Unique ID assigned to the player/site and configured by product. || Contact Nielsen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Release Notes ==&lt;br /&gt;
The release notes on the Browser SDK can be located here: '''[[Browser SDK Release Notes|Release Notes]]'''&lt;br /&gt;
&lt;br /&gt;
== Configure SDK ==&lt;br /&gt;
There are two steps required for configuring the SDK:&lt;br /&gt;
*Add Static Queue Snippet&lt;br /&gt;
*Create SDK Instance&lt;br /&gt;
&lt;br /&gt;
=== Static Queue Snippet ===&lt;br /&gt;
Add the following script tag to the website:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
    // Static Queue Snippet&lt;br /&gt;
    !function (e, n) {&lt;br /&gt;
      function t(e) {&lt;br /&gt;
        return &amp;quot;object&amp;quot; == typeof e ? JSON.parse(JSON.stringify(e)) : e&lt;br /&gt;
      }&lt;br /&gt;
      e[n] = e[n] ||&lt;br /&gt;
      {&lt;br /&gt;
        nlsQ: function (o, r, c) {&lt;br /&gt;
          var s = e.document,&lt;br /&gt;
            a = s.createElement(&amp;quot;script&amp;quot;);&lt;br /&gt;
          a.async = 1,&lt;br /&gt;
            a.src = (&amp;quot;http:&amp;quot; === e.location.protocol ? &amp;quot;http:&amp;quot; : &amp;quot;https:&amp;quot;) + &amp;quot;//cdn-gl.imrworldwide.com/conf/&amp;quot; + o + &amp;quot;.js#name=&amp;quot; + r + &amp;quot;&amp;amp;ns=&amp;quot; + n;&lt;br /&gt;
          var i = s.getElementsByTagName(&amp;quot;script&amp;quot;)[0];&lt;br /&gt;
          return i.parentNode.insertBefore(a, i),&lt;br /&gt;
            e[n][r] = e[n][r] || {&lt;br /&gt;
              g: c || {},&lt;br /&gt;
              ggPM: function (o, c, s, a, i) { e[n][r].q = e[n][r].q || []; try { var l = t([o, c, s, a, i]); e[n][r].q.push(l) } catch (e) { console &amp;amp;&amp;amp; console.log &amp;amp;&amp;amp; console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;) } },&lt;br /&gt;
              trackEvent: function (o) { e[n][r].te = e[n][r].te || []; try { var c = t(o); e[n][r].te.push(c) } catch (e) { console &amp;amp;&amp;amp; console.log &amp;amp;&amp;amp; console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;) } }&lt;br /&gt;
            },&lt;br /&gt;
            e[n][r]&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }(window, &amp;quot;NOLBUNDLE&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
var nSdkInstance = NOLBUNDLE.nlsQ(&amp;quot;XXXXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX&amp;quot;, &amp;quot;nlsnInstance&amp;quot;, {&lt;br /&gt;
  nol_sdkDebug: &amp;quot;debug&amp;quot;,&lt;br /&gt;
  optout: &amp;quot;false&amp;quot;&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The static queue snippet allows the SDK APIs to be called while the actual SDK and configuration file are still being downloaded. As the queue can capture all API calls before the download completes, there is no wait time. Once the SDK is available, the API calls will transition from directing to the queue to the SDK seamlessly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;For DCR static, BSDK cannot be run in an iframe because the blur/focus events of the parent page may not propagate to the iframe. The iframe events typically trigger when the iframe itself is clicked. The BSDK is dependent on the blur/focus events of the browser to detect active viewing of the page. Because the root page events do not propagate to the iframe, this would impact incorrect DCR static crediting.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Create SDK Instance===&lt;br /&gt;
To initialize the SDK, create an SDK instance by making the initialization call:&lt;br /&gt;
&lt;br /&gt;
==== Initialization API Call ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
NOLBUNDLE.nlsQ(&amp;quot;&amp;lt;apid&amp;gt;&amp;quot;, &amp;quot;&amp;lt;instanceName&amp;gt;&amp;quot;,{nol_sdkDebug: &amp;quot;debug&amp;quot;});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
When creating an instance, pass the following values: (&amp;lt;code&amp;gt;nol_sdkDebug&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;optout&amp;lt;/code&amp;gt; are optional)&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter	!! Description	!! Values&lt;br /&gt;
|-&lt;br /&gt;
| apid	|| Unique ID assigned to player/site ||	'PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'&lt;br /&gt;
|-&lt;br /&gt;
|instanceName ||	Name of SDK instance ||	&amp;quot;any string value&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| nol_sdkDebug	|| Enables Nielsen console logging if desired. 	|| &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{nol_sdkDebug: &amp;quot;debug&amp;quot;} &lt;br /&gt;
{nol_sdkDebug: &amp;quot;info&amp;quot;}&lt;br /&gt;
{nol_sdkDebug: &amp;quot;warn&amp;quot;}&lt;br /&gt;
{nol_sdkDebug: &amp;quot;true&amp;quot;}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|optout || Optional: OptOut global parameter. || &amp;lt;code&amp;gt;1/0&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;true/false&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Example SDK Initialization ====&lt;br /&gt;
When the initialization call is made, a unique static configuration file, &amp;lt;apid&amp;gt;.js, will be downloaded based on the apid and will be cached on the user’s browser.&lt;br /&gt;
&lt;br /&gt;
Once the configuration is downloaded, the SDK itself will be downloaded and initialized. All SDK modules are included in one file: “nlsSDK600.bundle.min.js”.&lt;br /&gt;
&lt;br /&gt;
More information on OptOut Parameter under [[DCR Video Browser SDK#Privacy_and_Opt-Out|Privacy and Opt-Out.]]&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
==== Example SDK Initialization with Viewability ====&lt;br /&gt;
If you decide to implement the Nielsen Viewability Module, the SDK will track the viewability of the targeted player/element, log the viewable percentage and record in seconds the time the player/element was in that viewable state.  The only additional information required is the HTML element ID of the element being tracked (which is passed during SDK Initialization), and the volume level (passed as an event).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var nSdkInstance = NOLBUNDLE.nlsQ(&amp;quot;XXXXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX&amp;quot;, &amp;quot;nlsnInstance&amp;quot;, {&lt;br /&gt;
  nol_sdkDebug: &amp;quot;debug&amp;quot;,&lt;br /&gt;
  optout: &amp;quot;false&amp;quot;&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If no &amp;quot;volume&amp;quot; event is passed, a default value of '1' will be used. (IE: 100%).  If the volume level is adjusted, the modified value can be passed to the SDK using the standard ggPM() API along with the new &amp;quot;volume&amp;quot; event.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
nSdkInstance.ggPM(&amp;quot;volume&amp;quot;, &amp;lt;volume level&amp;gt;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Event Name	!! Event #	!! Purpose !! Possible Values !!Example&lt;br /&gt;
|-&lt;br /&gt;
| volume	|| 61  ||ggPM event that will allow clients to pass in the volume levels.	||Supports decimal values in range from 0 - 1||instance.ggPM(&amp;quot;61&amp;quot;, 0); =&amp;gt; muted&lt;br /&gt;
instance.ggPM(&amp;quot;61&amp;quot;, .5) =&amp;gt; not muted&lt;br /&gt;
intance.ggPM(&amp;quot;61&amp;quot;, 1) =&amp;gt; not muted&lt;br /&gt;
|}&lt;br /&gt;
Sample:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
nSdkInstance.ggPM(&amp;quot;volume&amp;quot;, 0); // muted&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example SDK Configuration ===&lt;br /&gt;
&lt;br /&gt;
The configuration should include the Static Queue Snippet and an SDK Instance for an unique App ID as shown in the example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
// Add Static Queue Snippet&lt;br /&gt;
    !function (e, n) {&lt;br /&gt;
      function t(e) {&lt;br /&gt;
        return &amp;quot;object&amp;quot; == typeof e ? JSON.parse(JSON.stringify(e)) : e&lt;br /&gt;
      }&lt;br /&gt;
      e[n] = e[n] ||&lt;br /&gt;
      {&lt;br /&gt;
        nlsQ: function (o, r, c) {&lt;br /&gt;
          var s = e.document,&lt;br /&gt;
            a = s.createElement(&amp;quot;script&amp;quot;);&lt;br /&gt;
          a.async = 1,&lt;br /&gt;
            a.src = (&amp;quot;http:&amp;quot; === e.location.protocol ? &amp;quot;http:&amp;quot; : &amp;quot;https:&amp;quot;) + &amp;quot;//cdn-gl.imrworldwide.com/conf/&amp;quot; + o + &amp;quot;.js#name=&amp;quot; + r + &amp;quot;&amp;amp;ns=&amp;quot; + n;&lt;br /&gt;
          var i = s.getElementsByTagName(&amp;quot;script&amp;quot;)[0];&lt;br /&gt;
          return i.parentNode.insertBefore(a, i),&lt;br /&gt;
            e[n][r] = e[n][r] || {&lt;br /&gt;
              g: c || {},&lt;br /&gt;
              ggPM: function (o, c, s, a, i) { e[n][r].q = e[n][r].q || []; try { var l = t([o, c, s, a, i]); e[n][r].q.push(l) } catch (e) { console &amp;amp;&amp;amp; console.log &amp;amp;&amp;amp; console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;) } },&lt;br /&gt;
              trackEvent: function (o) { e[n][r].te = e[n][r].te || []; try { var c = t(o); e[n][r].te.push(c) } catch (e) { console &amp;amp;&amp;amp; console.log &amp;amp;&amp;amp; console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;) } }&lt;br /&gt;
            },&lt;br /&gt;
            e[n][r]&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }(window, &amp;quot;NOLBUNDLE&amp;quot;);&lt;br /&gt;
 &lt;br /&gt;
// Created SDK Instance&lt;br /&gt;
var nSdkInstance = NOLBUNDLE.nlsQ(&amp;quot;XXXXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX&amp;quot;, &amp;quot;nlsnInstance&amp;quot;, {nol_sdkDebug: &amp;quot;debug&amp;quot;});&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Create Metadata Objects ===&lt;br /&gt;
There are two types of asset metadata:&lt;br /&gt;
*content: identify video&lt;br /&gt;
*ad: identify each ad&lt;br /&gt;
&lt;br /&gt;
The metadata received for each asset is used for classification and reporting.&lt;br /&gt;
&lt;br /&gt;
Metadata can be passed through key-values using the Nielsen reserved keys. User will need to set up content and ad objects with the required Nielsen keys as shown in the sample code below.&lt;br /&gt;
&lt;br /&gt;
==== Content Metadata ====&lt;br /&gt;
Content metadata should remain constant throughout the entirety of an episode/clip including when ads play.&lt;br /&gt;
{{DCR Content Metadata}}&lt;br /&gt;
&lt;br /&gt;
==== Example Content Object ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var contentMetadataObject =&lt;br /&gt;
{  &lt;br /&gt;
  type:           'content',&lt;br /&gt;
  assetid:        'VID-123456',&lt;br /&gt;
  program:        'program name',&lt;br /&gt;
  title:          'episode title with season and episode number',&lt;br /&gt;
  length:         'length in seconds',&lt;br /&gt;
  airdate:        '20210321 09:00:00',&lt;br /&gt;
  isfullepisode:  'y',&lt;br /&gt;
  adloadtype:     '2',&lt;br /&gt;
  segB:           'custom segment B', // optional&lt;br /&gt;
  segC:           'custom segment C', // optional&lt;br /&gt;
  crossId1:       'Standard Episode ID', // optional&lt;br /&gt;
  crossId2:       'Content Originator' //optional&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ad Metadata ===&lt;br /&gt;
The Ad Metadata (if applicable) should be passed for each individual ad.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys	!! Description	!! Values	!! Required&lt;br /&gt;
|-&lt;br /&gt;
| type 	|| type of Ad	||  &amp;lt;code&amp;gt;'preroll'&amp;lt;/code&amp;gt;,  &amp;lt;code&amp;gt;'midroll'&amp;lt;/code&amp;gt;,  &amp;lt;code&amp;gt;'postroll'&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; &amp;lt;code&amp;gt;'ad'&amp;lt;/code&amp;gt;  - If specific type can not be identified.||	✓&lt;br /&gt;
|-&lt;br /&gt;
| assetid ||	unique ID assigned to Ad	|| custom &amp;lt;br&amp;gt;(no [[Special Characters]])	|| ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Example Ad Object ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var adMetadataObject = &lt;br /&gt;
{  &lt;br /&gt;
  type:    'preroll',&lt;br /&gt;
  assetid: 'AD-1'&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt; URL Character Limit: There is a URL character limit of 2K characters due to browser limitations. Exceeding this value could impair data delivery on particular browsers. &amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Call Nielsen APIs ====&lt;br /&gt;
The method for calling events is ggPM().&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
nSdkInstance.ggPM('event', parameter, ...);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Interrupt Scenarios ==&lt;br /&gt;
&lt;br /&gt;
=== Pause Event ===&lt;br /&gt;
The setPlayheadPostion event is used for handling pause. To indicate pause, stop passing the playhead position to the SDK. Once the content resumes, begin sending the playhead again with the correct playhead value.&lt;br /&gt;
&lt;br /&gt;
=== Other Interrupt Scenarios ===&lt;br /&gt;
The following possible browser interruption scenarios must be handled:&lt;br /&gt;
&lt;br /&gt;
* Browser/Tab close&lt;br /&gt;
* Leaving the page to another destination&lt;br /&gt;
* Pressing the stop button&lt;br /&gt;
* Network Loss&lt;br /&gt;
&lt;br /&gt;
There are many cases where the player itself has the ability to detect such situations. If not, these interruption scenarios can be handled through JavaScript. The events that are called will depend on the asset being played (e.g. midroll vs. content).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
window.addEventListener('beforeunload', function(event) &lt;br /&gt;
{&lt;br /&gt;
  // Only inside a midroll indicate &amp;lt;stop&amp;gt; for the ad&lt;br /&gt;
  nSdkInstance.ggPM('stop', playheadPosition);&lt;br /&gt;
  &lt;br /&gt;
  // Indicate &amp;lt;end&amp;gt; and &amp;lt;stop&amp;gt; for the content&lt;br /&gt;
  nSdkInstance.ggPM('end', playheadPosition);&lt;br /&gt;
  nSdkInstance.ggPM('stop', playheadPosition);&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note:''' User may need to add code to support specific browser versions (e.g. older versions of Internet Explorer).&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== SDK Events ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Event !!	Parameter	!! Description&lt;br /&gt;
|-&lt;br /&gt;
| 'loadMetadata'	|| content/ad metadata object	|| Needs to be called at the beginning of each asset&lt;br /&gt;
|-&lt;br /&gt;
| 'setPlayheadPosition'	|| playhead position as integer&amp;lt;br/&amp;gt;&lt;br /&gt;
VOD: || current position in seconds &amp;lt;br/&amp;gt;&lt;br /&gt;
Live: current Unix timestamp (seconds since Jan-1-1970 UTC) &amp;lt;br/&amp;gt;&lt;br /&gt;
Note: 'setPlayheadPosition' has to be called every second&lt;br /&gt;
||&lt;br /&gt;
Pass playhead position every second during playback&lt;br /&gt;
|-&lt;br /&gt;
| 'stop' ||	playhead position in seconds	|| Call when content or ads complete playing and pass playhead position&lt;br /&gt;
|-&lt;br /&gt;
| 'end'	|| playhead position in seconds	|| Call when the current video asset completes playback and pass the playhead position. &amp;lt;br/&amp;gt;&lt;br /&gt;
Example: At the end of the content stream, if the user switches to another piece of content, when the browser is refreshed or closed.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SDK Playhead Event Sequence ==&lt;br /&gt;
The sample event lifecycles can be used as a reference for identifying the order for calling events.&lt;br /&gt;
&lt;br /&gt;
=== Content Playback ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// START OF STREAM&lt;br /&gt;
nSdkInstance.ggPM('loadMetadata', contentMetadataObject); &lt;br /&gt;
 &lt;br /&gt;
// CONTENT PLAYS&lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition);&lt;br /&gt;
//  &lt;br /&gt;
//   pass playhead every second&lt;br /&gt;
//   &lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition);&lt;br /&gt;
&lt;br /&gt;
// END OF STREAM&lt;br /&gt;
nSdkInstance.ggPM('end', playheadPosition);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Content Playback with Ads ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// START OF STREAM&lt;br /&gt;
nSdkInstance.ggPM('loadMetadata', contentMetadataObject); &lt;br /&gt;
 &lt;br /&gt;
// PREROLL&lt;br /&gt;
nSdkInstance.ggPM('loadMetadata', prerollMetadataObject);&lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition);&lt;br /&gt;
//  &lt;br /&gt;
//   pass playhead every second&lt;br /&gt;
//   &lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition);&lt;br /&gt;
nSdkInstance.ggPM('stop', playheadPosition);&lt;br /&gt;
 &lt;br /&gt;
// CONTENT&lt;br /&gt;
nSdkInstance.ggPM('loadMetadata', contentMetadataObject);&lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition);&lt;br /&gt;
//  &lt;br /&gt;
//   pass playhead every second&lt;br /&gt;
//   &lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition);&lt;br /&gt;
nSdkInstance.ggPM('stop', playheadPosition);&lt;br /&gt;
&lt;br /&gt;
// MIDROLL&lt;br /&gt;
nSdkInstance.ggPM('loadMetadata', midrollMetadataObject);&lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition);&lt;br /&gt;
//  &lt;br /&gt;
//   pass playhead every second&lt;br /&gt;
//   &lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition);&lt;br /&gt;
nSdkInstance.ggPM('stop', playheadPosition);&lt;br /&gt;
 &lt;br /&gt;
// CONTENT RESUMES&lt;br /&gt;
nSdkInstance.ggPM('loadMetadata', contentMetadataObject);&lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition);&lt;br /&gt;
//  &lt;br /&gt;
//   pass playhead every second&lt;br /&gt;
//   &lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition);&lt;br /&gt;
&lt;br /&gt;
// END OF STREAM&lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition);&lt;br /&gt;
nSdkInstance.ggPM('end', playheadPosition);&lt;br /&gt;
 &lt;br /&gt;
// POSTROLL&lt;br /&gt;
nSdkInstance.ggPM('loadmetadata', postrollMetadataObject);&lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition);&lt;br /&gt;
//  &lt;br /&gt;
//   pass playhead every second&lt;br /&gt;
//   &lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition);&lt;br /&gt;
nSdkInstance.ggPM('stop', playheadPosition);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
* 'setPlayheadPosition' is used for calculating duration and must be passed every second. The final playhead position must be sent for the current asset being played before calling 'stop', 'end', or 'loadmetadata'.&lt;br /&gt;
&lt;br /&gt;
* For Ad Pods, events must be called for each individual Ad. Each Ad playhead position should begin at ‘0’ when ad starts.&lt;br /&gt;
&lt;br /&gt;
* When content has resumed following an ad break, the playhead position update must continue where previous content segment left off. The playhead position should be passed as a rounded number with no decimals.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Template:Browser_Privacy_and_Opt-Out}}&lt;br /&gt;
&lt;br /&gt;
== Going Live ==&lt;br /&gt;
After the integration has been certified, users will need to make a couple of updates to the initialization call to ensure that player will be measured properly.&lt;br /&gt;
Disable debug logging by deleting {nol_sdkDebug: 'DEBUG'} from initialization call.&lt;br /&gt;
&lt;br /&gt;
'''Example Production Initialization Call'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var nSdkInstance = NOLBUNDLE.nlsQ(&amp;quot;XXXXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX&amp;quot;, &amp;quot;nlsnInstance&amp;quot;, { optout: &amp;quot;false&amp;quot;});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>AnkitAgrawal</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=DTVR_Browser_SDK&amp;diff=6972</id>
		<title>DTVR Browser SDK</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=DTVR_Browser_SDK&amp;diff=6972"/>
		<updated>2024-09-03T20:21:02Z</updated>

		<summary type="html">&lt;p&gt;AnkitAgrawal: /* Example SDK Initialization */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|DCR &amp;amp; DTVR}}   {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
Before you start the integration, you will need:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 30px;&amp;quot; |&lt;br /&gt;
! style=&amp;quot;width: 15%;&amp;quot; | Item&lt;br /&gt;
! Description&lt;br /&gt;
! Source&lt;br /&gt;
|-&lt;br /&gt;
|| ☑ || '''App ID (apid)''' || Unique ID assigned to the player/site and configured by product. || Contact Nielsen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Configure SDK ==&lt;br /&gt;
There are two steps required for configuring your SDK: 1. Add Static Queue Snippet and 2. Create SDK Instance.&lt;br /&gt;
&lt;br /&gt;
=== Add Static Queue Snippet ===&lt;br /&gt;
Add the following script tag to your website:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
    // Static Queue Snippet&lt;br /&gt;
    !function (e, n) {&lt;br /&gt;
      function t(e) {&lt;br /&gt;
        return &amp;quot;object&amp;quot; == typeof e ? JSON.parse(JSON.stringify(e)) : e&lt;br /&gt;
      }&lt;br /&gt;
      e[n] = e[n] ||&lt;br /&gt;
      {&lt;br /&gt;
        nlsQ: function (o, r, c) {&lt;br /&gt;
          var s = e.document,&lt;br /&gt;
            a = s.createElement(&amp;quot;script&amp;quot;);&lt;br /&gt;
          a.async = 1,&lt;br /&gt;
            a.src = (&amp;quot;http:&amp;quot; === e.location.protocol ? &amp;quot;http:&amp;quot; : &amp;quot;https:&amp;quot;) + &amp;quot;//cdn-gl.imrworldwide.com/conf/&amp;quot; + o + &amp;quot;.js#name=&amp;quot; + r + &amp;quot;&amp;amp;ns=&amp;quot; + n;&lt;br /&gt;
          var i = s.getElementsByTagName(&amp;quot;script&amp;quot;)[0];&lt;br /&gt;
          return i.parentNode.insertBefore(a, i),&lt;br /&gt;
            e[n][r] = e[n][r] || {&lt;br /&gt;
              g: c || {},&lt;br /&gt;
              ggPM: function (o, c, s, a, i) { e[n][r].q = e[n][r].q || []; try { var l = t([o, c, s, a, i]); e[n][r].q.push(l) } catch (e) { console &amp;amp;&amp;amp; console.log &amp;amp;&amp;amp; console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;) } },&lt;br /&gt;
              trackEvent: function (o) { e[n][r].te = e[n][r].te || []; try { var c = t(o); e[n][r].te.push(c) } catch (e) { console &amp;amp;&amp;amp; console.log &amp;amp;&amp;amp; console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;) } }&lt;br /&gt;
            },&lt;br /&gt;
            e[n][r]&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }(window, &amp;quot;NOLBUNDLE&amp;quot;);&lt;br /&gt;
  &amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The static queue snippet allows the SDK APIs to be called while the actual SDK and configuration file are still being downloaded. Since the queue is able to capture all API calls before the download completes, there is no wait time. Once the SDK is available, the API calls will transition from directing to the queue to the SDK seamlessly.&lt;br /&gt;
&lt;br /&gt;
=== Create SDK Instance ===&lt;br /&gt;
To initialize the SDK, you will need to create an SDK instance by making the initialization call:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
NOLBUNDLE.nlsQ(&amp;quot;&amp;lt;apid&amp;gt;&amp;quot;, &amp;quot;&amp;lt;instanceName&amp;gt;&amp;quot;,{nol_sdkDebug: &amp;quot;debug&amp;quot;})&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
When creating your instance, you will need to pass three parameter values. The available parameters are listed in the table below:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameters !! Description !! Value !! Required? (Y/N)&lt;br /&gt;
|-&lt;br /&gt;
| apid || UniqueID assigned to player/site. &lt;br /&gt;
|| &amp;quot;XXXXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX&amp;quot; || Yes&lt;br /&gt;
|-&lt;br /&gt;
| instanceName || User-defined string value for describing the player/site. || Client specified || Yes&lt;br /&gt;
|-&lt;br /&gt;
| nol_sdkDebug:&amp;quot;debug&amp;quot; || Enables Debug Mode which allows output to be viewed in console. || &amp;quot;{nol_sdkDebug: &amp;quot;debug&amp;quot;}&amp;quot; || No&lt;br /&gt;
|-&lt;br /&gt;
| containerId || HTML DOM element id of the player container || {&amp;quot;containerId: &amp;quot;player1&amp;quot;} || Yes - if implementing Viewability/Audibility&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SDK Initialization ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var nSdkInstance = NOLBUNDLE.nlsQ(&amp;quot;XXXXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX&amp;quot;, &amp;quot;nlsnInstance&amp;quot;, {nol_sdkDebug: &amp;quot;debug&amp;quot;});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When the initialization call is made, a unique static configuration file, &amp;lt;apid&amp;gt;.js, will be downloaded based on your apid and cached on the user's browser.&lt;br /&gt;
&lt;br /&gt;
Once the configuration is downloaded, the SDK itself will be downloaded and initialized. All SDK modules are included in one file: &amp;quot;nlsSDK600.bundle.min.js&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Example SDK Initialization ===&lt;br /&gt;
Your configuration should include the Static Queue Snippet and an SDK Instance for your unique App ID as shown in the example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
//Add Static Queue Snippet&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
    !function (e, n) {&lt;br /&gt;
      function t(e) {&lt;br /&gt;
        return &amp;quot;object&amp;quot; == typeof e ? JSON.parse(JSON.stringify(e)) : e&lt;br /&gt;
      }&lt;br /&gt;
      e[n] = e[n] ||&lt;br /&gt;
      {&lt;br /&gt;
        nlsQ: function (o, r, c) {&lt;br /&gt;
          var s = e.document,&lt;br /&gt;
            a = s.createElement(&amp;quot;script&amp;quot;);&lt;br /&gt;
          a.async = 1,&lt;br /&gt;
            a.src = (&amp;quot;http:&amp;quot; === e.location.protocol ? &amp;quot;http:&amp;quot; : &amp;quot;https:&amp;quot;) + &amp;quot;//cdn-gl.imrworldwide.com/conf/&amp;quot; + o + &amp;quot;.js#name=&amp;quot; + r + &amp;quot;&amp;amp;ns=&amp;quot; + n;&lt;br /&gt;
          var i = s.getElementsByTagName(&amp;quot;script&amp;quot;)[0];&lt;br /&gt;
          return i.parentNode.insertBefore(a, i),&lt;br /&gt;
            e[n][r] = e[n][r] || {&lt;br /&gt;
              g: c || {},&lt;br /&gt;
              ggPM: function (o, c, s, a, i) { e[n][r].q = e[n][r].q || []; try { var l = t([o, c, s, a, i]); e[n][r].q.push(l) } catch (e) { console &amp;amp;&amp;amp; console.log &amp;amp;&amp;amp; console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;) } },&lt;br /&gt;
              trackEvent: function (o) { e[n][r].te = e[n][r].te || []; try { var c = t(o); e[n][r].te.push(c) } catch (e) { console &amp;amp;&amp;amp; console.log &amp;amp;&amp;amp; console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;) } }&lt;br /&gt;
            },&lt;br /&gt;
            e[n][r]&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }(window, &amp;quot;NOLBUNDLE&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
//Create SDK Instance&lt;br /&gt;
var nSdkInstance = NOLBUNDLE.nlsQ(&amp;quot;XXXXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX&amp;quot;, &amp;quot;nlsnInstance&amp;quot;, {nol_sdkDebug: &amp;quot;debug&amp;quot;});&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== SDK Initialization to measure Viewability &amp;amp; Audibility ==&lt;br /&gt;
To support Viewability and Audibility metrics in the web page the integrator has to provide a tag value of the player view to let Nielsen SDK know that there is a player that needs to be tracked. It’s called the ‘containerId’ and it should be passed in as a string while initializing the Nielsen browser SDK.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NOLBUNDLE.nlsQ(&amp;quot;&amp;lt;apid&amp;gt;&amp;quot;, &amp;quot;&amp;lt;instanceName&amp;gt;&amp;quot;,{containerId: &amp;lt;playerElementID&amp;gt;, nol_sdkDebug: &amp;quot;debug&amp;quot;})&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example SDK Initialization for Viewability &amp;amp; Audibility ===&lt;br /&gt;
Your configuration should include the Static Queue Snippet and an SDK Instance for your unique App ID as shown in the example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
//Add Static Queue Snippet&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
    !function (e, n) {&lt;br /&gt;
      function t(e) {&lt;br /&gt;
        return &amp;quot;object&amp;quot; == typeof e ? JSON.parse(JSON.stringify(e)) : e&lt;br /&gt;
      }&lt;br /&gt;
      e[n] = e[n] ||&lt;br /&gt;
      {&lt;br /&gt;
        nlsQ: function (o, r, c) {&lt;br /&gt;
          var s = e.document,&lt;br /&gt;
            a = s.createElement(&amp;quot;script&amp;quot;);&lt;br /&gt;
          a.async = 1,&lt;br /&gt;
            a.src = (&amp;quot;http:&amp;quot; === e.location.protocol ? &amp;quot;http:&amp;quot; : &amp;quot;https:&amp;quot;) + &amp;quot;//cdn-gl.imrworldwide.com/conf/&amp;quot; + o + &amp;quot;.js#name=&amp;quot; + r + &amp;quot;&amp;amp;ns=&amp;quot; + n;&lt;br /&gt;
          var i = s.getElementsByTagName(&amp;quot;script&amp;quot;)[0];&lt;br /&gt;
          return i.parentNode.insertBefore(a, i),&lt;br /&gt;
            e[n][r] = e[n][r] || {&lt;br /&gt;
              g: c || {},&lt;br /&gt;
              ggPM: function (o, c, s, a, i) { e[n][r].q = e[n][r].q || []; try { var l = t([o, c, s, a, i]); e[n][r].q.push(l) } catch (e) { console &amp;amp;&amp;amp; console.log &amp;amp;&amp;amp; console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;) } },&lt;br /&gt;
              trackEvent: function (o) { e[n][r].te = e[n][r].te || []; try { var c = t(o); e[n][r].te.push(c) } catch (e) { console &amp;amp;&amp;amp; console.log &amp;amp;&amp;amp; console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;) } }&lt;br /&gt;
            },&lt;br /&gt;
            e[n][r]&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }(window, &amp;quot;NOLBUNDLE&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
//Create SDK Instance with containerId&lt;br /&gt;
var nSdkInstance = NOLBUNDLE.nlsQ(&amp;quot;XXXXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX&amp;quot;, &amp;quot;nlsnInstance&amp;quot;, {containerId: &amp;quot;player1&amp;quot;, nol_sdkDebug: &amp;quot;debug&amp;quot;});&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Create Metadata Objects ==&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
There are two types of asset metadata:&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
*content: identify video&lt;br /&gt;
*ad: identify each ad&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
The metadata received for each asset is used for classification and reporting.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
Metadata can be passed through key-values using the Nielsen reserved keys. User will need to set up content and ad objects with the required Nielsen keys as shown in the sample code below.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Content Metadata Object ===&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
Content metadata should remain constant throughout the completion of an episode or live stream.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Key !! Description !!	Values	 !! Required&lt;br /&gt;
|-&lt;br /&gt;
| type ||	type of asset	|| &amp;quot;content&amp;quot;	|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| adModel	|| linear vs dynamic ad model	|| * 1) - Linear – matches TV ad load * 2) Dynamic – Dynamic Ad Insertion (DAI)     || ✓&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
'''Example Content Object'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt; var contentMetadataObject =&lt;br /&gt;
{  &lt;br /&gt;
  type: 'content',&lt;br /&gt;
  adModel: '1'&lt;br /&gt;
};&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ad Metadata Object ===&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
If Ad is not ID3 tagged, then Ad metadata should be passed for each individual Ad, if ads are available during or before the stream begins.&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys	!! Description	!! Values	!! Required&lt;br /&gt;
|-&lt;br /&gt;
| type 	|| type of Ad	||  &amp;lt;code&amp;gt;'preroll'&amp;lt;/code&amp;gt;,  &amp;lt;code&amp;gt;'midroll'&amp;lt;/code&amp;gt;,  &amp;lt;code&amp;gt;'postroll'&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; &amp;lt;code&amp;gt;'ad'&amp;lt;/code&amp;gt;  - If specific type can not be identified.||	✓&lt;br /&gt;
|-&lt;br /&gt;
| assetid || unique ID assigned to ad || custom (no [[Special Characters]]) || ✓&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
'''Example Ad Object'''&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt; var adMetadataObject = &lt;br /&gt;
{  &lt;br /&gt;
  assetid: 'AD-1',&lt;br /&gt;
  type:    'preroll'&lt;br /&gt;
};&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== SDK Events ==&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Event !!	Parameter	!! Description&lt;br /&gt;
|-&lt;br /&gt;
| 'loadMetadata'	|| content/Ad metadata object	|| Needs to be called at the beginning of each asset to pass type and adModel&lt;br /&gt;
|-&lt;br /&gt;
| 'sendID3'	|| Used to send the ID3 tag payload retrieved from the stream || Needs to be called at the beginning of playback&lt;br /&gt;
|-&lt;br /&gt;
| 'setVolume'   || Used to pass in the player volume levels in % || Needs to be called when the player volume changes. This is applicable only for Audibility feature&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Configure and fire API calls ==&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
The syntax for firing events is:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;    nSdkInstance.ggPM(&amp;quot;event&amp;quot;, parameter object);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
Event is passed in parameter 1 and the argument is passed in parameter 2.&lt;br /&gt;
&lt;br /&gt;
=== Configure API calls - loadMetadata ===&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
Use [[loadMetadata (Browser)]] to pass the metadata object. The data must be passed as a JSON string.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;nSdkInstance.ggPM(&amp;quot;loadMetadata&amp;quot;, metadataObject);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Configure API calls - sendID3 ===&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
Use [[sendID3 (Browser)]] to send ID3 payload of the HLS content being played. This will allow the ID3 payload to be sent every time an ID3 packet is received (approximately, once in every 10 seconds).&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;nSdkInstance.ggPM(&amp;quot;sendID3&amp;quot;, ID3_Payload);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
==== Sample ID3 tags ====&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
www.nielsen.com/X100zdCIGeIlgZnkYj6UvQ==/X100zdCIGeIlgZnkYj6UvQ==/AAAB2Jz2_k74GXSzx4npHuI_&amp;lt;wbr /&amp;gt;JwJd3QSUpW30rDkGTcbHEzIMWleCzM-uvNOP9fzJcQMWQLJqzXMCAxParOb5sGijSV9dNM3QiBniJYGZ5GI-lL1fXTTN0IgZ4iWBmeRiPpS9AAAAAAAAAAAAAAAAAAAAAFJWFM5SVhTONNU=/00000/00000/00&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;www.nielsen.com/X100zdCIGeIlgZnkYj6UvQ==/R8WHe7pEBeqBhu8jTeXydg==/AAICoyitYqlxT7n6aZ0oMCGhe&amp;lt;wbr /&amp;gt;Fi4CXFp46AMUPZz1lMr_M9tr3_cjee1SHqxrOiVerMDLeyn9xzocZSKwi746Re8vNOtpNCAZjYABs_J0R25IHpvOc1HS8&amp;lt;wbr /&amp;gt;QHGgD5TgOJeS6gX100zdCIGeIlgZnkYj6UvVJWFNhSVhTiPE0=/00000/46016/00&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;ID3_Payload&amp;lt;/code&amp;gt; is the container to pass the retrieved ID3 tag from the streaming. The player should look for 'PRIV' ID3 tags and send 'owner' field (which typically starts from &amp;quot;www.nielsen.com&amp;quot;) through this API. Refer to [[Browser SDK API Reference#Retrieving ID3 Tags|Browser SDK API Reference - Retrieving ID3 Tags]] for more information.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
Refer to [[Browser SDK API Reference#Retrieving ID3 Tags|Browser SDK API Reference - Retrieving ID3 Tags]] section to know more details.&lt;br /&gt;
&lt;br /&gt;
=== Configure API calls - setVolume ===&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
Use the setVolume(Browser) to send the player volume for Audibility feature. Player volume should be sent at the beginning of stream and whenever volume changes. By default the volumeLevel is set to -1. VolumeLevel is the Audibility percentage (0-100).  If the player is muted, use volumeLevel of 0. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;nSdkInstance.ggPM(&amp;quot;setVolume&amp;quot;, volumeLevel);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&lt;br /&gt;
=== Configure API calls - end ===&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
Call [[end (Browser)]] only at the end of playback, or if the stream is interrupted.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;nSdkInstance.ggPM(&amp;quot;end&amp;quot;, playhead);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== SDK DTVR Event Sequence ==&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
The sample event lifecycle can be used as a reference for identifying the order for calling events.&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
nSdkInstance.ggPM('loadMetadata', contentMetadataObject); &lt;br /&gt;
nSdkInstance.ggPM('sendID3', ID3_Payload); //call sendID3 every 10 seconds and stop calling during any playback interruptions&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Template:Browser_Privacy_and_Opt-Out}}&lt;br /&gt;
&lt;br /&gt;
== Going Live ==&lt;br /&gt;
After the integration has been certified, users will need to make a couple of updates to the initialization call to ensure that player will be measured properly.&lt;br /&gt;
Disable debug logging by deleting {nol_sdkDebug: 'DEBUG'} from initialization call.&lt;br /&gt;
&lt;br /&gt;
'''Example Production Initialization Call'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var nSdkInstance = NOLBUNDLE.nlsQ(&amp;quot;XXXXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX&amp;quot;, &amp;quot;nlsnInstance&amp;quot;, { optout: &amp;quot;false&amp;quot;});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>AnkitAgrawal</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=DTVR_Browser_SDK&amp;diff=6971</id>
		<title>DTVR Browser SDK</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=DTVR_Browser_SDK&amp;diff=6971"/>
		<updated>2024-09-03T20:18:56Z</updated>

		<summary type="html">&lt;p&gt;AnkitAgrawal: /* Add Static Queue Snippet */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|DCR &amp;amp; DTVR}}   {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
Before you start the integration, you will need:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 30px;&amp;quot; |&lt;br /&gt;
! style=&amp;quot;width: 15%;&amp;quot; | Item&lt;br /&gt;
! Description&lt;br /&gt;
! Source&lt;br /&gt;
|-&lt;br /&gt;
|| ☑ || '''App ID (apid)''' || Unique ID assigned to the player/site and configured by product. || Contact Nielsen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Configure SDK ==&lt;br /&gt;
There are two steps required for configuring your SDK: 1. Add Static Queue Snippet and 2. Create SDK Instance.&lt;br /&gt;
&lt;br /&gt;
=== Add Static Queue Snippet ===&lt;br /&gt;
Add the following script tag to your website:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
    // Static Queue Snippet&lt;br /&gt;
    !function (e, n) {&lt;br /&gt;
      function t(e) {&lt;br /&gt;
        return &amp;quot;object&amp;quot; == typeof e ? JSON.parse(JSON.stringify(e)) : e&lt;br /&gt;
      }&lt;br /&gt;
      e[n] = e[n] ||&lt;br /&gt;
      {&lt;br /&gt;
        nlsQ: function (o, r, c) {&lt;br /&gt;
          var s = e.document,&lt;br /&gt;
            a = s.createElement(&amp;quot;script&amp;quot;);&lt;br /&gt;
          a.async = 1,&lt;br /&gt;
            a.src = (&amp;quot;http:&amp;quot; === e.location.protocol ? &amp;quot;http:&amp;quot; : &amp;quot;https:&amp;quot;) + &amp;quot;//cdn-gl.imrworldwide.com/conf/&amp;quot; + o + &amp;quot;.js#name=&amp;quot; + r + &amp;quot;&amp;amp;ns=&amp;quot; + n;&lt;br /&gt;
          var i = s.getElementsByTagName(&amp;quot;script&amp;quot;)[0];&lt;br /&gt;
          return i.parentNode.insertBefore(a, i),&lt;br /&gt;
            e[n][r] = e[n][r] || {&lt;br /&gt;
              g: c || {},&lt;br /&gt;
              ggPM: function (o, c, s, a, i) { e[n][r].q = e[n][r].q || []; try { var l = t([o, c, s, a, i]); e[n][r].q.push(l) } catch (e) { console &amp;amp;&amp;amp; console.log &amp;amp;&amp;amp; console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;) } },&lt;br /&gt;
              trackEvent: function (o) { e[n][r].te = e[n][r].te || []; try { var c = t(o); e[n][r].te.push(c) } catch (e) { console &amp;amp;&amp;amp; console.log &amp;amp;&amp;amp; console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;) } }&lt;br /&gt;
            },&lt;br /&gt;
            e[n][r]&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }(window, &amp;quot;NOLBUNDLE&amp;quot;);&lt;br /&gt;
  &amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The static queue snippet allows the SDK APIs to be called while the actual SDK and configuration file are still being downloaded. Since the queue is able to capture all API calls before the download completes, there is no wait time. Once the SDK is available, the API calls will transition from directing to the queue to the SDK seamlessly.&lt;br /&gt;
&lt;br /&gt;
=== Create SDK Instance ===&lt;br /&gt;
To initialize the SDK, you will need to create an SDK instance by making the initialization call:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
NOLBUNDLE.nlsQ(&amp;quot;&amp;lt;apid&amp;gt;&amp;quot;, &amp;quot;&amp;lt;instanceName&amp;gt;&amp;quot;,{nol_sdkDebug: &amp;quot;debug&amp;quot;})&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
When creating your instance, you will need to pass three parameter values. The available parameters are listed in the table below:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameters !! Description !! Value !! Required? (Y/N)&lt;br /&gt;
|-&lt;br /&gt;
| apid || UniqueID assigned to player/site. &lt;br /&gt;
|| &amp;quot;XXXXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX&amp;quot; || Yes&lt;br /&gt;
|-&lt;br /&gt;
| instanceName || User-defined string value for describing the player/site. || Client specified || Yes&lt;br /&gt;
|-&lt;br /&gt;
| nol_sdkDebug:&amp;quot;debug&amp;quot; || Enables Debug Mode which allows output to be viewed in console. || &amp;quot;{nol_sdkDebug: &amp;quot;debug&amp;quot;}&amp;quot; || No&lt;br /&gt;
|-&lt;br /&gt;
| containerId || HTML DOM element id of the player container || {&amp;quot;containerId: &amp;quot;player1&amp;quot;} || Yes - if implementing Viewability/Audibility&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SDK Initialization ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var nSdkInstance = NOLBUNDLE.nlsQ(&amp;quot;XXXXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX&amp;quot;, &amp;quot;nlsnInstance&amp;quot;, {nol_sdkDebug: &amp;quot;debug&amp;quot;});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When the initialization call is made, a unique static configuration file, &amp;lt;apid&amp;gt;.js, will be downloaded based on your apid and cached on the user's browser.&lt;br /&gt;
&lt;br /&gt;
Once the configuration is downloaded, the SDK itself will be downloaded and initialized. All SDK modules are included in one file: &amp;quot;nlsSDK600.bundle.min.js&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Example SDK Initialization ===&lt;br /&gt;
Your configuration should include the Static Queue Snippet and an SDK Instance for your unique App ID as shown in the example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
//Add Static Queue Snippet&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
    ! function(t, n) {&lt;br /&gt;
        t[n] = t[n] || {&lt;br /&gt;
            nlsQ: function(e, o, c, r, s, i) {&lt;br /&gt;
                return s = t.document,&lt;br /&gt;
                    r = s.createElement(&amp;quot;script&amp;quot;),&lt;br /&gt;
                    r.async = 1,&lt;br /&gt;
                    r.src = (&amp;quot;http:&amp;quot; === t.location.protocol ? &amp;quot;http:&amp;quot; : &amp;quot;https:&amp;quot;) + &amp;quot;//cdn-gl.imrworldwide.com/conf/&amp;quot; + e + &amp;quot;.js#name=&amp;quot; + o + &amp;quot;&amp;amp;ns=&amp;quot; + n,&lt;br /&gt;
                    i = s.getElementsByTagName(&amp;quot;script&amp;quot;)[0],&lt;br /&gt;
                    i.parentNode.insertBefore(r, i),&lt;br /&gt;
                    t[n][o] = t[n][o] || {&lt;br /&gt;
                        g: c || {},&lt;br /&gt;
                        ggPM: function(e, c, r, s, i) {&lt;br /&gt;
                            (t[n][o].q = t[n][o].q || []).push([e, c, r, s, i])&lt;br /&gt;
                        }&lt;br /&gt;
                    }, t[n][o]&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    (window, &amp;quot;NOLBUNDLE&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
//Create SDK Instance&lt;br /&gt;
var nSdkInstance = NOLBUNDLE.nlsQ(&amp;quot;XXXXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX&amp;quot;, &amp;quot;nlsnInstance&amp;quot;, {nol_sdkDebug: &amp;quot;debug&amp;quot;});&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== SDK Initialization to measure Viewability &amp;amp; Audibility ==&lt;br /&gt;
To support Viewability and Audibility metrics in the web page the integrator has to provide a tag value of the player view to let Nielsen SDK know that there is a player that needs to be tracked. It’s called the ‘containerId’ and it should be passed in as a string while initializing the Nielsen browser SDK.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NOLBUNDLE.nlsQ(&amp;quot;&amp;lt;apid&amp;gt;&amp;quot;, &amp;quot;&amp;lt;instanceName&amp;gt;&amp;quot;,{containerId: &amp;lt;playerElementID&amp;gt;, nol_sdkDebug: &amp;quot;debug&amp;quot;})&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example SDK Initialization for Viewability &amp;amp; Audibility ===&lt;br /&gt;
Your configuration should include the Static Queue Snippet and an SDK Instance for your unique App ID as shown in the example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
//Add Static Queue Snippet&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
    ! function(t, n) {&lt;br /&gt;
        t[n] = t[n] || {&lt;br /&gt;
            nlsQ: function(e, o, c, r, s, i) {&lt;br /&gt;
                return s = t.document,&lt;br /&gt;
                    r = s.createElement(&amp;quot;script&amp;quot;),&lt;br /&gt;
                    r.async = 1,&lt;br /&gt;
                    r.src = (&amp;quot;http:&amp;quot; === t.location.protocol ? &amp;quot;http:&amp;quot; : &amp;quot;https:&amp;quot;) + &amp;quot;//cdn-gl.imrworldwide.com/conf/&amp;quot; + e + &amp;quot;.js#name=&amp;quot; + o + &amp;quot;&amp;amp;ns=&amp;quot; + n,&lt;br /&gt;
                    i = s.getElementsByTagName(&amp;quot;script&amp;quot;)[0],&lt;br /&gt;
                    i.parentNode.insertBefore(r, i),&lt;br /&gt;
                    t[n][o] = t[n][o] || {&lt;br /&gt;
                        g: c || {},&lt;br /&gt;
                        ggPM: function(e, c, r, s, i) {&lt;br /&gt;
                            (t[n][o].q = t[n][o].q || []).push([e, c, r, s, i])&lt;br /&gt;
                        }&lt;br /&gt;
                    }, t[n][o]&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    (window, &amp;quot;NOLBUNDLE&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
//Create SDK Instance with containerId&lt;br /&gt;
var nSdkInstance = NOLBUNDLE.nlsQ(&amp;quot;XXXXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX&amp;quot;, &amp;quot;nlsnInstance&amp;quot;, {containerId: &amp;quot;player1&amp;quot;, nol_sdkDebug: &amp;quot;debug&amp;quot;});&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Create Metadata Objects ==&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
There are two types of asset metadata:&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
*content: identify video&lt;br /&gt;
*ad: identify each ad&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
The metadata received for each asset is used for classification and reporting.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
Metadata can be passed through key-values using the Nielsen reserved keys. User will need to set up content and ad objects with the required Nielsen keys as shown in the sample code below.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Content Metadata Object ===&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
Content metadata should remain constant throughout the completion of an episode or live stream.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Key !! Description !!	Values	 !! Required&lt;br /&gt;
|-&lt;br /&gt;
| type ||	type of asset	|| &amp;quot;content&amp;quot;	|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| adModel	|| linear vs dynamic ad model	|| * 1) - Linear – matches TV ad load * 2) Dynamic – Dynamic Ad Insertion (DAI)     || ✓&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
'''Example Content Object'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt; var contentMetadataObject =&lt;br /&gt;
{  &lt;br /&gt;
  type: 'content',&lt;br /&gt;
  adModel: '1'&lt;br /&gt;
};&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ad Metadata Object ===&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
If Ad is not ID3 tagged, then Ad metadata should be passed for each individual Ad, if ads are available during or before the stream begins.&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys	!! Description	!! Values	!! Required&lt;br /&gt;
|-&lt;br /&gt;
| type 	|| type of Ad	||  &amp;lt;code&amp;gt;'preroll'&amp;lt;/code&amp;gt;,  &amp;lt;code&amp;gt;'midroll'&amp;lt;/code&amp;gt;,  &amp;lt;code&amp;gt;'postroll'&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; &amp;lt;code&amp;gt;'ad'&amp;lt;/code&amp;gt;  - If specific type can not be identified.||	✓&lt;br /&gt;
|-&lt;br /&gt;
| assetid || unique ID assigned to ad || custom (no [[Special Characters]]) || ✓&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
'''Example Ad Object'''&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt; var adMetadataObject = &lt;br /&gt;
{  &lt;br /&gt;
  assetid: 'AD-1',&lt;br /&gt;
  type:    'preroll'&lt;br /&gt;
};&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== SDK Events ==&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Event !!	Parameter	!! Description&lt;br /&gt;
|-&lt;br /&gt;
| 'loadMetadata'	|| content/Ad metadata object	|| Needs to be called at the beginning of each asset to pass type and adModel&lt;br /&gt;
|-&lt;br /&gt;
| 'sendID3'	|| Used to send the ID3 tag payload retrieved from the stream || Needs to be called at the beginning of playback&lt;br /&gt;
|-&lt;br /&gt;
| 'setVolume'   || Used to pass in the player volume levels in % || Needs to be called when the player volume changes. This is applicable only for Audibility feature&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Configure and fire API calls ==&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
The syntax for firing events is:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;    nSdkInstance.ggPM(&amp;quot;event&amp;quot;, parameter object);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
Event is passed in parameter 1 and the argument is passed in parameter 2.&lt;br /&gt;
&lt;br /&gt;
=== Configure API calls - loadMetadata ===&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
Use [[loadMetadata (Browser)]] to pass the metadata object. The data must be passed as a JSON string.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;nSdkInstance.ggPM(&amp;quot;loadMetadata&amp;quot;, metadataObject);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Configure API calls - sendID3 ===&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
Use [[sendID3 (Browser)]] to send ID3 payload of the HLS content being played. This will allow the ID3 payload to be sent every time an ID3 packet is received (approximately, once in every 10 seconds).&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;nSdkInstance.ggPM(&amp;quot;sendID3&amp;quot;, ID3_Payload);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
==== Sample ID3 tags ====&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
www.nielsen.com/X100zdCIGeIlgZnkYj6UvQ==/X100zdCIGeIlgZnkYj6UvQ==/AAAB2Jz2_k74GXSzx4npHuI_&amp;lt;wbr /&amp;gt;JwJd3QSUpW30rDkGTcbHEzIMWleCzM-uvNOP9fzJcQMWQLJqzXMCAxParOb5sGijSV9dNM3QiBniJYGZ5GI-lL1fXTTN0IgZ4iWBmeRiPpS9AAAAAAAAAAAAAAAAAAAAAFJWFM5SVhTONNU=/00000/00000/00&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;www.nielsen.com/X100zdCIGeIlgZnkYj6UvQ==/R8WHe7pEBeqBhu8jTeXydg==/AAICoyitYqlxT7n6aZ0oMCGhe&amp;lt;wbr /&amp;gt;Fi4CXFp46AMUPZz1lMr_M9tr3_cjee1SHqxrOiVerMDLeyn9xzocZSKwi746Re8vNOtpNCAZjYABs_J0R25IHpvOc1HS8&amp;lt;wbr /&amp;gt;QHGgD5TgOJeS6gX100zdCIGeIlgZnkYj6UvVJWFNhSVhTiPE0=/00000/46016/00&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;ID3_Payload&amp;lt;/code&amp;gt; is the container to pass the retrieved ID3 tag from the streaming. The player should look for 'PRIV' ID3 tags and send 'owner' field (which typically starts from &amp;quot;www.nielsen.com&amp;quot;) through this API. Refer to [[Browser SDK API Reference#Retrieving ID3 Tags|Browser SDK API Reference - Retrieving ID3 Tags]] for more information.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
Refer to [[Browser SDK API Reference#Retrieving ID3 Tags|Browser SDK API Reference - Retrieving ID3 Tags]] section to know more details.&lt;br /&gt;
&lt;br /&gt;
=== Configure API calls - setVolume ===&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
Use the setVolume(Browser) to send the player volume for Audibility feature. Player volume should be sent at the beginning of stream and whenever volume changes. By default the volumeLevel is set to -1. VolumeLevel is the Audibility percentage (0-100).  If the player is muted, use volumeLevel of 0. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;nSdkInstance.ggPM(&amp;quot;setVolume&amp;quot;, volumeLevel);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&lt;br /&gt;
=== Configure API calls - end ===&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
Call [[end (Browser)]] only at the end of playback, or if the stream is interrupted.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;nSdkInstance.ggPM(&amp;quot;end&amp;quot;, playhead);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== SDK DTVR Event Sequence ==&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
The sample event lifecycle can be used as a reference for identifying the order for calling events.&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
nSdkInstance.ggPM('loadMetadata', contentMetadataObject); &lt;br /&gt;
nSdkInstance.ggPM('sendID3', ID3_Payload); //call sendID3 every 10 seconds and stop calling during any playback interruptions&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Template:Browser_Privacy_and_Opt-Out}}&lt;br /&gt;
&lt;br /&gt;
== Going Live ==&lt;br /&gt;
After the integration has been certified, users will need to make a couple of updates to the initialization call to ensure that player will be measured properly.&lt;br /&gt;
Disable debug logging by deleting {nol_sdkDebug: 'DEBUG'} from initialization call.&lt;br /&gt;
&lt;br /&gt;
'''Example Production Initialization Call'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var nSdkInstance = NOLBUNDLE.nlsQ(&amp;quot;XXXXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX&amp;quot;, &amp;quot;nlsnInstance&amp;quot;, { optout: &amp;quot;false&amp;quot;});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>AnkitAgrawal</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=DCR_Video_Browser_SDK&amp;diff=6970</id>
		<title>DCR Video Browser SDK</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=DCR_Video_Browser_SDK&amp;diff=6970"/>
		<updated>2024-09-03T20:17:47Z</updated>

		<summary type="html">&lt;p&gt;AnkitAgrawal: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|US DCR &amp;amp; DTVR}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
Before you start the integration, you will need:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 30px;&amp;quot; |&lt;br /&gt;
! style=&amp;quot;width: 15%;&amp;quot; | Item&lt;br /&gt;
! Description&lt;br /&gt;
! Source&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|| ☑ || '''App ID (appid)''' || Unique ID assigned to the player/site and configured by product. || Contact Nielsen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Release Notes ==&lt;br /&gt;
The release notes on the Browser SDK can be located here: '''[[Browser SDK Release Notes|Release Notes]]'''&lt;br /&gt;
&lt;br /&gt;
== Configure SDK ==&lt;br /&gt;
There are two steps required for configuring the SDK:&lt;br /&gt;
*Add Static Queue Snippet&lt;br /&gt;
*Create SDK Instance&lt;br /&gt;
&lt;br /&gt;
=== Static Queue Snippet ===&lt;br /&gt;
Add the following script tag to the website:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
    // Static Queue Snippet&lt;br /&gt;
    !function (e, n) {&lt;br /&gt;
      function t(e) {&lt;br /&gt;
        return &amp;quot;object&amp;quot; == typeof e ? JSON.parse(JSON.stringify(e)) : e&lt;br /&gt;
      }&lt;br /&gt;
      e[n] = e[n] ||&lt;br /&gt;
      {&lt;br /&gt;
        nlsQ: function (o, r, c) {&lt;br /&gt;
          var s = e.document,&lt;br /&gt;
            a = s.createElement(&amp;quot;script&amp;quot;);&lt;br /&gt;
          a.async = 1,&lt;br /&gt;
            a.src = (&amp;quot;http:&amp;quot; === e.location.protocol ? &amp;quot;http:&amp;quot; : &amp;quot;https:&amp;quot;) + &amp;quot;//cdn-gl.imrworldwide.com/conf/&amp;quot; + o + &amp;quot;.js#name=&amp;quot; + r + &amp;quot;&amp;amp;ns=&amp;quot; + n;&lt;br /&gt;
          var i = s.getElementsByTagName(&amp;quot;script&amp;quot;)[0];&lt;br /&gt;
          return i.parentNode.insertBefore(a, i),&lt;br /&gt;
            e[n][r] = e[n][r] || {&lt;br /&gt;
              g: c || {},&lt;br /&gt;
              ggPM: function (o, c, s, a, i) { e[n][r].q = e[n][r].q || []; try { var l = t([o, c, s, a, i]); e[n][r].q.push(l) } catch (e) { console &amp;amp;&amp;amp; console.log &amp;amp;&amp;amp; console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;) } },&lt;br /&gt;
              trackEvent: function (o) { e[n][r].te = e[n][r].te || []; try { var c = t(o); e[n][r].te.push(c) } catch (e) { console &amp;amp;&amp;amp; console.log &amp;amp;&amp;amp; console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;) } }&lt;br /&gt;
            },&lt;br /&gt;
            e[n][r]&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }(window, &amp;quot;NOLBUNDLE&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
var nSdkInstance = NOLBUNDLE.nlsQ(&amp;quot;XXXXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX&amp;quot;, &amp;quot;nlsnInstance&amp;quot;, {&lt;br /&gt;
  nol_sdkDebug: &amp;quot;debug&amp;quot;,&lt;br /&gt;
  optout: &amp;quot;false&amp;quot;&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The static queue snippet allows the SDK APIs to be called while the actual SDK and configuration file are still being downloaded. As the queue can capture all API calls before the download completes, there is no wait time. Once the SDK is available, the API calls will transition from directing to the queue to the SDK seamlessly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;For DCR static, BSDK cannot be run in an iframe because the blur/focus events of the parent page may not propagate to the iframe. The iframe events typically trigger when the iframe itself is clicked. The BSDK is dependent on the blur/focus events of the browser to detect active viewing of the page. Because the root page events do not propagate to the iframe, this would impact incorrect DCR static crediting.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Create SDK Instance===&lt;br /&gt;
To initialize the SDK, create an SDK instance by making the initialization call:&lt;br /&gt;
&lt;br /&gt;
==== Initialization API Call ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
NOLBUNDLE.nlsQ(&amp;quot;&amp;lt;apid&amp;gt;&amp;quot;, &amp;quot;&amp;lt;instanceName&amp;gt;&amp;quot;,{nol_sdkDebug: &amp;quot;debug&amp;quot;});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
When creating an instance, pass the following values: (&amp;lt;code&amp;gt;nol_sdkDebug&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;optout&amp;lt;/code&amp;gt; are optional)&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter	!! Description	!! Values&lt;br /&gt;
|-&lt;br /&gt;
| apid	|| Unique ID assigned to player/site ||	'PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'&lt;br /&gt;
|-&lt;br /&gt;
|instanceName ||	Name of SDK instance ||	&amp;quot;any string value&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| nol_sdkDebug	|| Enables Nielsen console logging if desired. 	|| &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{nol_sdkDebug: &amp;quot;debug&amp;quot;} &lt;br /&gt;
{nol_sdkDebug: &amp;quot;info&amp;quot;}&lt;br /&gt;
{nol_sdkDebug: &amp;quot;warn&amp;quot;}&lt;br /&gt;
{nol_sdkDebug: &amp;quot;true&amp;quot;}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|optout || Optional: OptOut global parameter. || &amp;lt;code&amp;gt;1/0&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;true/false&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Example SDK Initialization ====&lt;br /&gt;
When the initialization call is made, a unique static configuration file, &amp;lt;apid&amp;gt;.js, will be downloaded based on the apid and will be cached on the user’s browser.&lt;br /&gt;
&lt;br /&gt;
Once the configuration is downloaded, the SDK itself will be downloaded and initialized. All SDK modules are included in one file: “nlsSDK600.bundle.min.js”.&lt;br /&gt;
&lt;br /&gt;
More information on OptOut Parameter under [[DCR Video Browser SDK#Privacy_and_Opt-Out|Privacy and Opt-Out.]]&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
==== Example SDK Initialization with Viewability ====&lt;br /&gt;
If you decide to implement the Nielsen Viewability Module, the SDK will track the viewability of the targeted player/element, log the viewable percentage and record in seconds the time the player/element was in that viewable state.  The only additional information required is the HTML element ID of the element being tracked (which is passed during SDK Initialization), and the volume level (passed as an event).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var nSdkInstance = NOLBUNDLE.nlsQ(&amp;quot;XXXXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX&amp;quot;, &amp;quot;nlsnInstance&amp;quot;, {&lt;br /&gt;
  nol_sdkDebug: &amp;quot;debug&amp;quot;,&lt;br /&gt;
  optout: &amp;quot;false&amp;quot;&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If no &amp;quot;volume&amp;quot; event is passed, a default value of '1' will be used. (IE: 100%).  If the volume level is adjusted, the modified value can be passed to the SDK using the standard ggPM() API along with the new &amp;quot;volume&amp;quot; event.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
nSdkInstance.ggPM(&amp;quot;volume&amp;quot;, &amp;lt;volume level&amp;gt;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Event Name	!! Event #	!! Purpose !! Possible Values !!Example&lt;br /&gt;
|-&lt;br /&gt;
| volume	|| 61  ||ggPM event that will allow clients to pass in the volume levels.	||Supports decimal values in range from 0 - 1||instance.ggPM(&amp;quot;61&amp;quot;, 0); =&amp;gt; muted&lt;br /&gt;
instance.ggPM(&amp;quot;61&amp;quot;, .5) =&amp;gt; not muted&lt;br /&gt;
intance.ggPM(&amp;quot;61&amp;quot;, 1) =&amp;gt; not muted&lt;br /&gt;
|}&lt;br /&gt;
Sample:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
nSdkInstance.ggPM(&amp;quot;volume&amp;quot;, 0); // muted&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example SDK Configuration ===&lt;br /&gt;
&lt;br /&gt;
The configuration should include the Static Queue Snippet and an SDK Instance for an unique App ID as shown in the example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
// Add Static Queue Snippet&lt;br /&gt;
 !function(t,n)&lt;br /&gt;
{&lt;br /&gt;
  t[n]=t[n]||&lt;br /&gt;
  {&lt;br /&gt;
    nlsQ:function(e,o,c,r,s,i)&lt;br /&gt;
    {&lt;br /&gt;
     return s=t.document,&lt;br /&gt;
     r=s.createElement(&amp;quot;script&amp;quot;),&lt;br /&gt;
     r.async=1,&lt;br /&gt;
     r.src=(&amp;quot;http:&amp;quot;===t.location.protocol?&amp;quot;http:&amp;quot;:&amp;quot;https:&amp;quot;)+&amp;quot;//cdn-gl.imrworldwide.com/conf/&amp;quot;+e+&amp;quot;.js#name=&amp;quot;+o+&amp;quot;&amp;amp;ns=&amp;quot;+n,&lt;br /&gt;
     i=s.getElementsByTagName(&amp;quot;script&amp;quot;)[0],&lt;br /&gt;
     i.parentNode.insertBefore(r,i),&lt;br /&gt;
     t[n][o]=t[n][o]||{g:c||{},&lt;br /&gt;
     ggPM:function(e,c,r,s,i){(t[n][o].q=t[n][o].q||[]).push([e,c,r,s,i])}},t[n][o]&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
(window,&amp;quot;NOLBUNDLE&amp;quot;);&lt;br /&gt;
 &lt;br /&gt;
// Created SDK Instance&lt;br /&gt;
var nSdkInstance = NOLBUNDLE.nlsQ(&amp;quot;XXXXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX&amp;quot;, &amp;quot;nlsnInstance&amp;quot;, {nol_sdkDebug: &amp;quot;debug&amp;quot;});&lt;br /&gt;
&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Create Metadata Objects ===&lt;br /&gt;
There are two types of asset metadata:&lt;br /&gt;
*content: identify video&lt;br /&gt;
*ad: identify each ad&lt;br /&gt;
&lt;br /&gt;
The metadata received for each asset is used for classification and reporting.&lt;br /&gt;
&lt;br /&gt;
Metadata can be passed through key-values using the Nielsen reserved keys. User will need to set up content and ad objects with the required Nielsen keys as shown in the sample code below.&lt;br /&gt;
&lt;br /&gt;
==== Content Metadata ====&lt;br /&gt;
Content metadata should remain constant throughout the entirety of an episode/clip including when ads play.&lt;br /&gt;
{{DCR Content Metadata}}&lt;br /&gt;
&lt;br /&gt;
==== Example Content Object ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var contentMetadataObject =&lt;br /&gt;
{  &lt;br /&gt;
  type:           'content',&lt;br /&gt;
  assetid:        'VID-123456',&lt;br /&gt;
  program:        'program name',&lt;br /&gt;
  title:          'episode title with season and episode number',&lt;br /&gt;
  length:         'length in seconds',&lt;br /&gt;
  airdate:        '20210321 09:00:00',&lt;br /&gt;
  isfullepisode:  'y',&lt;br /&gt;
  adloadtype:     '2',&lt;br /&gt;
  segB:           'custom segment B', // optional&lt;br /&gt;
  segC:           'custom segment C', // optional&lt;br /&gt;
  crossId1:       'Standard Episode ID', // optional&lt;br /&gt;
  crossId2:       'Content Originator' //optional&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ad Metadata ===&lt;br /&gt;
The Ad Metadata (if applicable) should be passed for each individual ad.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys	!! Description	!! Values	!! Required&lt;br /&gt;
|-&lt;br /&gt;
| type 	|| type of Ad	||  &amp;lt;code&amp;gt;'preroll'&amp;lt;/code&amp;gt;,  &amp;lt;code&amp;gt;'midroll'&amp;lt;/code&amp;gt;,  &amp;lt;code&amp;gt;'postroll'&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; &amp;lt;code&amp;gt;'ad'&amp;lt;/code&amp;gt;  - If specific type can not be identified.||	✓&lt;br /&gt;
|-&lt;br /&gt;
| assetid ||	unique ID assigned to Ad	|| custom &amp;lt;br&amp;gt;(no [[Special Characters]])	|| ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Example Ad Object ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var adMetadataObject = &lt;br /&gt;
{  &lt;br /&gt;
  type:    'preroll',&lt;br /&gt;
  assetid: 'AD-1'&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt; URL Character Limit: There is a URL character limit of 2K characters due to browser limitations. Exceeding this value could impair data delivery on particular browsers. &amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Call Nielsen APIs ====&lt;br /&gt;
The method for calling events is ggPM().&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
nSdkInstance.ggPM('event', parameter, ...);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Interrupt Scenarios ==&lt;br /&gt;
&lt;br /&gt;
=== Pause Event ===&lt;br /&gt;
The setPlayheadPostion event is used for handling pause. To indicate pause, stop passing the playhead position to the SDK. Once the content resumes, begin sending the playhead again with the correct playhead value.&lt;br /&gt;
&lt;br /&gt;
=== Other Interrupt Scenarios ===&lt;br /&gt;
The following possible browser interruption scenarios must be handled:&lt;br /&gt;
&lt;br /&gt;
* Browser/Tab close&lt;br /&gt;
* Leaving the page to another destination&lt;br /&gt;
* Pressing the stop button&lt;br /&gt;
* Network Loss&lt;br /&gt;
&lt;br /&gt;
There are many cases where the player itself has the ability to detect such situations. If not, these interruption scenarios can be handled through JavaScript. The events that are called will depend on the asset being played (e.g. midroll vs. content).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
window.addEventListener('beforeunload', function(event) &lt;br /&gt;
{&lt;br /&gt;
  // Only inside a midroll indicate &amp;lt;stop&amp;gt; for the ad&lt;br /&gt;
  nSdkInstance.ggPM('stop', playheadPosition);&lt;br /&gt;
  &lt;br /&gt;
  // Indicate &amp;lt;end&amp;gt; and &amp;lt;stop&amp;gt; for the content&lt;br /&gt;
  nSdkInstance.ggPM('end', playheadPosition);&lt;br /&gt;
  nSdkInstance.ggPM('stop', playheadPosition);&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note:''' User may need to add code to support specific browser versions (e.g. older versions of Internet Explorer).&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== SDK Events ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Event !!	Parameter	!! Description&lt;br /&gt;
|-&lt;br /&gt;
| 'loadMetadata'	|| content/ad metadata object	|| Needs to be called at the beginning of each asset&lt;br /&gt;
|-&lt;br /&gt;
| 'setPlayheadPosition'	|| playhead position as integer&amp;lt;br/&amp;gt;&lt;br /&gt;
VOD: || current position in seconds &amp;lt;br/&amp;gt;&lt;br /&gt;
Live: current Unix timestamp (seconds since Jan-1-1970 UTC) &amp;lt;br/&amp;gt;&lt;br /&gt;
Note: 'setPlayheadPosition' has to be called every second&lt;br /&gt;
||&lt;br /&gt;
Pass playhead position every second during playback&lt;br /&gt;
|-&lt;br /&gt;
| 'stop' ||	playhead position in seconds	|| Call when content or ads complete playing and pass playhead position&lt;br /&gt;
|-&lt;br /&gt;
| 'end'	|| playhead position in seconds	|| Call when the current video asset completes playback and pass the playhead position. &amp;lt;br/&amp;gt;&lt;br /&gt;
Example: At the end of the content stream, if the user switches to another piece of content, when the browser is refreshed or closed.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SDK Playhead Event Sequence ==&lt;br /&gt;
The sample event lifecycles can be used as a reference for identifying the order for calling events.&lt;br /&gt;
&lt;br /&gt;
=== Content Playback ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// START OF STREAM&lt;br /&gt;
nSdkInstance.ggPM('loadMetadata', contentMetadataObject); &lt;br /&gt;
 &lt;br /&gt;
// CONTENT PLAYS&lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition);&lt;br /&gt;
//  &lt;br /&gt;
//   pass playhead every second&lt;br /&gt;
//   &lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition);&lt;br /&gt;
&lt;br /&gt;
// END OF STREAM&lt;br /&gt;
nSdkInstance.ggPM('end', playheadPosition);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Content Playback with Ads ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// START OF STREAM&lt;br /&gt;
nSdkInstance.ggPM('loadMetadata', contentMetadataObject); &lt;br /&gt;
 &lt;br /&gt;
// PREROLL&lt;br /&gt;
nSdkInstance.ggPM('loadMetadata', prerollMetadataObject);&lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition);&lt;br /&gt;
//  &lt;br /&gt;
//   pass playhead every second&lt;br /&gt;
//   &lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition);&lt;br /&gt;
nSdkInstance.ggPM('stop', playheadPosition);&lt;br /&gt;
 &lt;br /&gt;
// CONTENT&lt;br /&gt;
nSdkInstance.ggPM('loadMetadata', contentMetadataObject);&lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition);&lt;br /&gt;
//  &lt;br /&gt;
//   pass playhead every second&lt;br /&gt;
//   &lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition);&lt;br /&gt;
nSdkInstance.ggPM('stop', playheadPosition);&lt;br /&gt;
&lt;br /&gt;
// MIDROLL&lt;br /&gt;
nSdkInstance.ggPM('loadMetadata', midrollMetadataObject);&lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition);&lt;br /&gt;
//  &lt;br /&gt;
//   pass playhead every second&lt;br /&gt;
//   &lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition);&lt;br /&gt;
nSdkInstance.ggPM('stop', playheadPosition);&lt;br /&gt;
 &lt;br /&gt;
// CONTENT RESUMES&lt;br /&gt;
nSdkInstance.ggPM('loadMetadata', contentMetadataObject);&lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition);&lt;br /&gt;
//  &lt;br /&gt;
//   pass playhead every second&lt;br /&gt;
//   &lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition);&lt;br /&gt;
&lt;br /&gt;
// END OF STREAM&lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition);&lt;br /&gt;
nSdkInstance.ggPM('end', playheadPosition);&lt;br /&gt;
 &lt;br /&gt;
// POSTROLL&lt;br /&gt;
nSdkInstance.ggPM('loadmetadata', postrollMetadataObject);&lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition);&lt;br /&gt;
//  &lt;br /&gt;
//   pass playhead every second&lt;br /&gt;
//   &lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition);&lt;br /&gt;
nSdkInstance.ggPM('stop', playheadPosition);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
* 'setPlayheadPosition' is used for calculating duration and must be passed every second. The final playhead position must be sent for the current asset being played before calling 'stop', 'end', or 'loadmetadata'.&lt;br /&gt;
&lt;br /&gt;
* For Ad Pods, events must be called for each individual Ad. Each Ad playhead position should begin at ‘0’ when ad starts.&lt;br /&gt;
&lt;br /&gt;
* When content has resumed following an ad break, the playhead position update must continue where previous content segment left off. The playhead position should be passed as a rounded number with no decimals.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Template:Browser_Privacy_and_Opt-Out}}&lt;br /&gt;
&lt;br /&gt;
== Going Live ==&lt;br /&gt;
After the integration has been certified, users will need to make a couple of updates to the initialization call to ensure that player will be measured properly.&lt;br /&gt;
Disable debug logging by deleting {nol_sdkDebug: 'DEBUG'} from initialization call.&lt;br /&gt;
&lt;br /&gt;
'''Example Production Initialization Call'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var nSdkInstance = NOLBUNDLE.nlsQ(&amp;quot;XXXXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX&amp;quot;, &amp;quot;nlsnInstance&amp;quot;, { optout: &amp;quot;false&amp;quot;});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>AnkitAgrawal</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=DCR_and_DTVR_with_iOS17_or_TVOS17&amp;diff=6868</id>
		<title>DCR and DTVR with iOS17 or TVOS17</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=DCR_and_DTVR_with_iOS17_or_TVOS17&amp;diff=6868"/>
		<updated>2024-07-09T04:31:07Z</updated>

		<summary type="html">&lt;p&gt;AnkitAgrawal: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|DCR &amp;amp; DTVR}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
__NOTOC__&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
Summary: The latest version of Nielsen iOS/TVOS AppSDK (currently 9.4.0.0) has the below-mentioned privacy manifest entries and app tracking/opt-out behavior already included. App developers integrating the SDK will automatically have the required entries added to their app's privacy manifest when compiled with Xcode 15 or greater. '''Nielsen Client Developers do not need to make any additional changes to privacy manifest files at the application level to handle Nielsen tracking behavior.''' &lt;br /&gt;
&lt;br /&gt;
Beginning with iOS/TVOS 17, Apple is adding several requirements for App developers around tracking, use of Identifier For Advertisers (IDFA), and certain system APIs as detailed below:&lt;br /&gt;
===App Privacy Manifest===&lt;br /&gt;
*App privacy manifest files must be updated before submitting apps to the App Store. &lt;br /&gt;
**Declare collection/use of user tracking information - app developers/third-party SDKs will be required to list domains that are used to send messages containing the user's device ID (IDFA).&lt;br /&gt;
***[https://developer.apple.com/documentation/bundleresources/privacy_manifest_files?changes=_4 Apple:Privacy manifest files]&lt;br /&gt;
**Required Reason API - Apple is requiring reasons for apps' usage of certain system APIs that retrieve information about the device or state of some system metrics. &lt;br /&gt;
***[https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api Apple:Describing use of required reason API]&lt;br /&gt;
&lt;br /&gt;
===App Tracking Transparency (ATT) Framework===&lt;br /&gt;
When users select &amp;quot;Ask App Not to Track&amp;quot; from the ATT popup, the operating system will behave differently from previous iOS/tvOS versions:&lt;br /&gt;
&amp;lt;/br&amp;gt;&lt;br /&gt;
*In iOS/tvOS versions lower than 17, when &amp;quot;Ask App Not to Track&amp;quot; was selected, apps were blocked from reading the device's IDFA and measurement would be transmitted with a blank device ID.&lt;br /&gt;
*With iOS/tvOS 17, if the user selects &amp;quot;Ask App Not to Track&amp;quot;, third-party SDKs will not only be blocked from reading the IDFA, the entire app will also be blocked from sending http(s) traffic to domains declared as &amp;quot;tracking domains&amp;quot; in the SDK's privacy manifest file.  This will prevent typical measurement pings from going out and will impact volumetric measurement for your apps.&lt;br /&gt;
&amp;lt;/br&amp;gt;&lt;br /&gt;
A new release of the AppSDK (v9.4) aims to address this requirement through explicit distinction of tracking versus non-tracking traffic through the use of 2 domains as described below:&lt;br /&gt;
*When a user has opted in (Allow Tracking), measurement data pings will continue to be sent to the vtwenty.com (tracking) domain with the available IDFA.&lt;br /&gt;
*When a user has opted out (Ask App Not to Track) or with an unknown status, all the measurement data pings will be sent to the nmrodam.com (non-tracking) domain. These pings will not contain any IDFA tracking.&lt;br /&gt;
NOTE: the domain-changing above refers only Nielsen AppSDK with ad framework support. Non-ad framework flavors of AppSDK are not affected.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''IMPORTANT NOTE:''' Nielsen iOS/TVOS SDK has the privacy manifest entries and app tracking/opt-out behavior already included. App developers integrating the SDK will automatically have the required entries added to their app's privacy manifest when compiled with Xcode 15 or greater. '''Nielsen Client Developers do not need to make any additional changes to privacy manifest files at the application level to handle Nielsen tracking behavior.'''  This functionality is included in Nielsen AppSDK version 9.4.0.0 or greater. With the release of iOS/TVOS 17 in September 2023, Nielsen clients are strongly encouraged to update to AppSDK version 9.4.0.0 (release date: July, 9 2024) or greater as soon as possible to avoid disruption in measurement.&lt;br /&gt;
&lt;br /&gt;
Apple is not currently mandating that SDK developers declare a tracking domain in the SDK-level privacy manifest file, and if one is provided, all traffic from all Nielsen integrations in the app will be blocked for opted-out users. To mitigate this situation, the Nielsen technical team has decided to create 2 versions of the iOS/tvOS AppSDK: one with no tracking domain declared (default) and one with it declared. &lt;br /&gt;
&lt;br /&gt;
The AppSDK 9.4.0.0 build with tracking domain declared will be made available through Nielsen artifactory and/or direct download from Nielsen Engineering Portal. '''Current integrations using Nielsen artifactory distribution will receive notice to update to this version through CocoaPods/Carthage/SPM distributions automatically.''' &lt;br /&gt;
&lt;br /&gt;
If you have any questions about the AppSDK version that has the tracking domain declared, please reach out to your Nielsen Client Engineer.&lt;/div&gt;</summary>
		<author><name>AnkitAgrawal</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=Nielsen_Digital_Measurement_and_iOS17_or_TVOS17&amp;diff=6867</id>
		<title>Nielsen Digital Measurement and iOS17 or TVOS17</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=Nielsen_Digital_Measurement_and_iOS17_or_TVOS17&amp;diff=6867"/>
		<updated>2024-07-09T04:25:52Z</updated>

		<summary type="html">&lt;p&gt;AnkitAgrawal: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|DCR &amp;amp; DTVR}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
__NOTOC__&lt;br /&gt;
== Overview ==&lt;br /&gt;
Beginning with iOS/tvOS 17, Apple is adding several requirements for App developers around tracking, use of Identifier For Advertisers (IDFA), and certain system APIs as detailed below:&lt;br /&gt;
===App Privacy Manifest=== &lt;br /&gt;
*App privacy manifest files must be updated before submitting apps to the App Store. &lt;br /&gt;
**Declare collection/use of user tracking information - app developers/third-party SDKs will be required to list domains that are used to send messages containing the user's device ID (IDFA).&lt;br /&gt;
***[https://developer.apple.com/documentation/bundleresources/privacy_manifest_files?changes=_4 Apple:Privacy manifest files]&lt;br /&gt;
**Required Reason API - Apple is requiring reasons for apps' usage of certain system APIs that retrieve information about the device or state of some system metrics. &lt;br /&gt;
***[https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api Apple:Describing use of required reason API]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Below is the AppSDK  privacy manifest snapshot for AD flavor which showcase tracking domain used to capture the IDFA/AD ID in measurement traffic.&lt;br /&gt;
&lt;br /&gt;
From Privacy accessed API perspective for all SDK flavors , it has declared &lt;br /&gt;
&lt;br /&gt;
* AppSDK does use the User Defaults  to cache the data, needed in kill/relaunch scenarios. The usage is as per the Apple recommendation to read/write information limited to containing app only (CA92.1).&lt;br /&gt;
* AppSDK does use the timestamp API to check the expiry of cached config limited to containing app only(C617.1)&lt;br /&gt;
* AppSDK does observe the sufficient disk space, so it can stop the Sqlite DB insertions if there is an insufficient space for the containing app only(E174.1)&lt;br /&gt;
[[File:NewPrivacyDomain.png|center|thumb|668x668px|AppSDK Privacy Manifest]]&lt;br /&gt;
&lt;br /&gt;
===App Tracking Transparency (ATT) Framework===&lt;br /&gt;
When users select &amp;quot;Ask App Not to Track&amp;quot; from the ATT popup, the operating system will behave differently from previous iOS/tvOS versions:&lt;br /&gt;
&amp;lt;/br&amp;gt;&lt;br /&gt;
*In iOS/tvOS versions lower than 17, when &amp;quot;Ask App Not to Track&amp;quot; was selected, apps were blocked from reading the device's IDFA and measurement would be transmitted with a blank device ID.&lt;br /&gt;
*With iOS/tvOS 17, if the user selects &amp;quot;Ask App Not to Track&amp;quot;, third-party SDKs will not only be blocked from reading the IDFA, the SDKs will also be blocked from sending http(s) traffic to domains declared as &amp;quot;tracking domains&amp;quot; in the SDK's privacy manifest file.  This will prevent typical measurement pings from going out and will impact volumetric measurement for your apps.&lt;br /&gt;
&amp;lt;/br&amp;gt;&lt;br /&gt;
A new release of the AppSDK (v9.4) aims to address this requirement through explicit distinction of tracking versus non-tracking traffic through the use of 2 domains as described below:&lt;br /&gt;
*When a user has opted in (Allow Tracking), measurement data pings will continue to be sent to the vtwenty.com (tracking domain) with the available IDFA.&lt;br /&gt;
*When a user has opted out (Ask App Not to Track) or with an unknown status, all the measurement data pings will be sent to the nmrodam.com (non-tracking domain). These pings will not contain any IDFA tracking.&lt;br /&gt;
&lt;br /&gt;
==Next Steps==&lt;br /&gt;
#Move to the latest Nielsen AppSDK release (v9.4) for builds targeting iOS 17 with Xcode 15. Upgrading to the new build of the Digital SDKs should be straightforward through your build configuration. AppSDKs remain backwards compatible and would not require any further integration changes. Please refer to the Integration guide section for further details.&lt;br /&gt;
#To be decided if the privacy manifest needs to be modified. For coexisting DAR pixel and Digital SDK integrations please reach out to your Nielsen Client Engineer to determine the path forward.&lt;br /&gt;
#Work with your Nielsen Client Engineer once implemented to ensure proper measurement.&lt;/div&gt;</summary>
		<author><name>AnkitAgrawal</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=Nielsen_Digital_Measurement_and_iOS17_or_TVOS17&amp;diff=6866</id>
		<title>Nielsen Digital Measurement and iOS17 or TVOS17</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=Nielsen_Digital_Measurement_and_iOS17_or_TVOS17&amp;diff=6866"/>
		<updated>2024-07-09T04:24:27Z</updated>

		<summary type="html">&lt;p&gt;AnkitAgrawal: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|DCR &amp;amp; DTVR}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
__NOTOC__&lt;br /&gt;
== Overview ==&lt;br /&gt;
Beginning with iOS/tvOS 17, Apple is adding several requirements for App developers around tracking, use of Identifier For Advertisers (IDFA), and certain system APIs as detailed below:&lt;br /&gt;
===App Privacy Manifest=== &lt;br /&gt;
*App privacy manifest files must be updated before submitting apps to the App Store. &lt;br /&gt;
**Declare collection/use of user tracking information - app developers/third-party SDKs will be required to list domains that are used to send messages containing the user's device ID (IDFA).&lt;br /&gt;
***[https://developer.apple.com/documentation/bundleresources/privacy_manifest_files?changes=_4 Apple:Privacy manifest files]&lt;br /&gt;
**Required Reason API - Apple is requiring reasons for apps' usage of certain system APIs that retrieve information about the device or state of some system metrics. &lt;br /&gt;
***[https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api Apple:Describing use of required reason API]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Below is the AppSDK  privacy manifest snapshot for AD flavor which showcase tracking domain used to capture the IDFA/AD ID in measurement traffic.&lt;br /&gt;
&lt;br /&gt;
From Privacy accessed API perspective for all SDK flavors , it has declared &lt;br /&gt;
&lt;br /&gt;
* AppSDK does use the User Defaults  to cache the data, needed in kill/relaunch scenarios. The usage is as per the Apple recommendation to read/write information limited to containing app only (CA92.1).&lt;br /&gt;
* AppSDK does use the timestamp API to check the expiry of cached config limited to containing app only(C617.1)&lt;br /&gt;
* AppSDK does observe the sufficient disk space, so it can stop the Sqlite DB insertions if there is an insufficient space for the containing app only(E174.1)&lt;br /&gt;
[[File:NewPrivacyDomain.png|center|thumb|668x668px|AppSDK Privacy Manifest]]&lt;br /&gt;
&lt;br /&gt;
===App Tracking Transparency (ATT) Framework===&lt;br /&gt;
When users select &amp;quot;Ask App Not to Track&amp;quot; from the ATT popup, the operating system will behave differently from previous iOS/tvOS versions:&lt;br /&gt;
&amp;lt;/br&amp;gt;&lt;br /&gt;
*In iOS/tvOS versions lower than 17, when &amp;quot;Ask App Not to Track&amp;quot; was selected, apps were blocked from reading the device's IDFA and measurement would be transmitted with a blank device ID.&lt;br /&gt;
*With iOS/tvOS 17, if the user selects &amp;quot;Ask App Not to Track&amp;quot;, third-party SDKs will not only be blocked from reading the IDFA, the SDKs will also be blocked from sending http(s) traffic to domains declared as &amp;quot;tracking domains&amp;quot; in the SDK's privacy manifest file.  This will prevent typical measurement pings from going out and will impact volumetric measurement for your apps.&lt;br /&gt;
&amp;lt;/br&amp;gt;&lt;br /&gt;
A new release of the AppSDK (v9.4) aims to address this requirement through explicit distinction of tracking versus non-tracking traffic through the use of 2 domains as described below:&lt;br /&gt;
*When a user has opted in (Allow Tracking), measurement data pings will continue to be sent to the vtwenty.com (tracking domain) with the available IDFA.&lt;br /&gt;
*When a user has opted out (Ask App Not to Track) or with an unknown status, all the measurement data pings will be sent to the nmrodam.com (non-tracking domain). These pings will not contain any IDFA tracking.&lt;br /&gt;
&lt;br /&gt;
==Next Steps==&lt;br /&gt;
#Move to the latest Nielsen AppSDK release (v9.4) for builds targeting iOS 17 with Xcode 15. Upgrading to the new build of the Digital SDKs should be straightforward through your build configuration. AppSDKs remain backwards compatible and would not require any further integration changes. Please refer to the Integration guide section for further details.&lt;br /&gt;
#To be decided if the privacy manifest needs to be modified. For coexisting DAR pixel and Digital SDK integrations please reach out to your Nielsen Client Engineer to determine the path forward.&lt;br /&gt;
#Work with your Nielsen Client Engineer once implemented to ensure proper measurement.&lt;br /&gt;
&lt;br /&gt;
==Technical Details==&lt;br /&gt;
&lt;br /&gt;
Technical details about the upcoming iOS/tvOS AppSDK release for Nielsen client app developers can be found here: [[DCR_and_DTVR_with_iOS17_or_TVOS17]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This page will be updated as more information becomes available.&lt;/div&gt;</summary>
		<author><name>AnkitAgrawal</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=File:NewPrivacyDomain.png&amp;diff=6865</id>
		<title>File:NewPrivacyDomain.png</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=File:NewPrivacyDomain.png&amp;diff=6865"/>
		<updated>2024-07-09T04:22:03Z</updated>

		<summary type="html">&lt;p&gt;AnkitAgrawal: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Updated to vtwenty.com&lt;/div&gt;</summary>
		<author><name>AnkitAgrawal</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=Android_SDK_Release_Notes&amp;diff=6864</id>
		<title>Android SDK Release Notes</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=Android_SDK_Release_Notes&amp;diff=6864"/>
		<updated>2024-07-09T04:15:35Z</updated>

		<summary type="html">&lt;p&gt;AnkitAgrawal: Release 9.4.0.0 changes&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Digital]]&lt;br /&gt;
 __NOTOC__&lt;br /&gt;
&lt;br /&gt;
{{Breadcrumb|}} {{Breadcrumb|Digital Downloads}} {{CurrentBreadcrumb}}&lt;br /&gt;
&lt;br /&gt;
== Release 9.4.0.0 (07-09-2024) ==&lt;br /&gt;
*Support for content tracking and no-tracking domains across sdk flavors and products.&lt;br /&gt;
*Upgraded SDK to use Java 11 and Kotlin 1.8.0.                                  &lt;br /&gt;
*Other bug fixes and enhancements.&lt;br /&gt;
== Release 9.3.0.0 (05-10-2024) ==&lt;br /&gt;
*Support for capturing user opt-out during initialization.&lt;br /&gt;
== Release 9.2.0.0 (9-27-2023) ==&lt;br /&gt;
*DCR Static recognizing metadata with changed assetID for new impressions. &lt;br /&gt;
*Limiting ping retries during https failures. &lt;br /&gt;
*Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 9.1.0.0 (3-31-2023) ==&lt;br /&gt;
*DCR Static duration measurement for AppSDK (currently only AGF)&lt;br /&gt;
*Viewability: allow enabling by product (DCR, DTVR)&lt;br /&gt;
*Other bug fixes and enhancements&lt;br /&gt;
&lt;br /&gt;
== Release 9.0.0.0 (10-07-2022) ==&lt;br /&gt;
* Viewability measurement for DTVR, DCR Content and DCR Ad products. &lt;br /&gt;
* Audibility measurement for DTVR, DCR Content and DCR Ad products.&lt;br /&gt;
* Kotlin-Java interoperability implementation in SDK.&lt;br /&gt;
* Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 8.2.0.0 (03-21-2022) ==&lt;br /&gt;
* Support for EMM AGF AdID-less solution.&lt;br /&gt;
* Enabled SDK to capture network availability changes.&lt;br /&gt;
* Removed the usage of deprecated network classes.&lt;br /&gt;
* Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 8.1.0.0 (06-28-2021) ==&lt;br /&gt;
* Support for SDK build variants - AD/NoAD/NoID.&lt;br /&gt;
* Support to indicate ID used for AD build variant - AD ID vs Android ID.&lt;br /&gt;
* Support to capture Hashed email and UID.&lt;br /&gt;
* Support to collect SDK diagnostic data.&lt;br /&gt;
* Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 8.0.0.0 (10-05-2020) ==&lt;br /&gt;
* FPID and VendorID support.&lt;br /&gt;
* Support for Android apps running on ChromeOS.&lt;br /&gt;
* Support for Xamarin cross platform framework.&lt;br /&gt;
* Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 7.2.0.0 (05-18-2020) ==&lt;br /&gt;
* DTVR AQH and IVD requirements for End and pause timeout.&lt;br /&gt;
* Support for Hybrid app webview measurement. &lt;br /&gt;
* Support for Hybrid app react native webview measurement. &lt;br /&gt;
* Support for React Native measurement.&lt;br /&gt;
* Other bug fixes and enhancements&lt;br /&gt;
&lt;br /&gt;
== Release 7.1.0.0 (12-09-2019) ==&lt;br /&gt;
&lt;br /&gt;
* Application background/foreground state auto-detection (AndroidX)&lt;br /&gt;
* Fixed forward rewind evdata containing negative values&lt;br /&gt;
* Offline viewing measurement enhancements&lt;br /&gt;
* Revisited precedence logic for sfcode parameter&lt;br /&gt;
* Using default value for incorrect adModel parameter&lt;br /&gt;
* Defaulting isLive parameter value on channel change&lt;br /&gt;
* Other fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 7.0.0.0 (09-06-2019) ==&lt;br /&gt;
&lt;br /&gt;
* Support for CDN based config.&lt;br /&gt;
* Support for Market based EMM UAID pings.&lt;br /&gt;
* Changes required for proper DCR Static measurement in multi-instance/multiple appid's case.&lt;br /&gt;
* Fixes for OTT synchronization issues between iOS and Android platforms.&lt;br /&gt;
* Fixes for EV data parameters in few scenarios.&lt;br /&gt;
* Fixes for DCR Static product behaviour in background app refresh and background fetch scenarios.&lt;br /&gt;
* DCR Ad reporting improvements.&lt;br /&gt;
* Fixes and improvements for the SDK console log messages.&lt;br /&gt;
* Other enhancements and fixes.&lt;br /&gt;
&lt;br /&gt;
== Release 6.2.0.0  (02-04-2019) ==&lt;br /&gt;
* Removal of Location Module from SDK Code.&lt;br /&gt;
* Fixed the getOptoutStatus() api, so that client can call it in main thread.&lt;br /&gt;
* Fixed the parsing error happening when clientid/vcid provided as empty in metadata.&lt;br /&gt;
* Align AppSDK for FW detection with BSDK for DCR measurement.&lt;br /&gt;
* Other enhancements and fixes.&lt;br /&gt;
&lt;br /&gt;
== Release 6.1.0.1 (9-13-2018) ==&lt;br /&gt;
*Support added for Video On Demand in TV Ratings&lt;br /&gt;
*Bug fixes and improvements&lt;br /&gt;
&lt;br /&gt;
== Release 6.0.0.4 (5-24-2018) ==&lt;br /&gt;
*If the SDK build target is set to AGF then SDK will send the hello ping to “eu” and “eu-uat” for debug builds. No changes to the non AGF build the default sfcode will continue to be &amp;quot;sdk&amp;quot; and &amp;quot;cert&amp;quot; for debug build.&lt;br /&gt;
*The C1 parameter (NUID) will now be sent as encrypted DeviceID.&lt;br /&gt;
*New SessionID changes. The sessionID will contain 29 length random characters appended by timestamp.&lt;br /&gt;
*Support for multiple SDK instance without any limit.&lt;br /&gt;
*New log feature for CAT tool to retrieve the API level information from client apps. This ping will contain the eventType, parameters, SDK version, appid etc.&lt;br /&gt;
*Removed Viewability for this release.&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.26 (7-31-2017) ==&lt;br /&gt;
*Genre parameter will be a part of DCR pings and the value is reflected as part of c44 parameter.&lt;br /&gt;
*Merged adModel and adLoadType flags&lt;br /&gt;
*Fix for stop event data carried to next session’s duration ping&lt;br /&gt;
*Fix for last playhead call that is not processed (when there is no time-gap between the last playhead and end call)&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.24 (6-2-2017) ==&lt;br /&gt;
*Enhanced support for Digital Audio&lt;br /&gt;
*Ability to pass adloadtype as “linear” or “dynamic”&lt;br /&gt;
*Ability to detect end of content and static material through duration pings&lt;br /&gt;
*Acceptance of empty parameters with a warning message triggered, if a required parameter is missing&lt;br /&gt;
*Acceptance of case-insensitive JSON key values&lt;br /&gt;
*Configurable feature to show Ad view counts in the duration pings&lt;br /&gt;
*Automatic Pause Detection and Debug build detection&lt;br /&gt;
*Change of default ‘type’ from “ad” to “content”&lt;br /&gt;
*Removal of “Static” Launch Ping for Non-Static product implementations&lt;br /&gt;
*Fix for metadata carry over between channels after a channel change&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.18 (1-24-2017) ==&lt;br /&gt;
*Ability to opt-out using “Limit Ad Tracking” feature&lt;br /&gt;
*Improved CPU Performance through encryption process change&lt;br /&gt;
*Opt-Out pages can be served based on user’s language and locale from device&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.14 (12-10-2016) ==&lt;br /&gt;
*Support for Nielsen TV Brand Effect&lt;br /&gt;
*Ability to set CMS parameters at a more global level&lt;br /&gt;
*Collection of additional device information&lt;br /&gt;
*Opt-out pages based on locale and country&lt;br /&gt;
*Opt-out based on the ‘Limit Ad Tracking’ flag&lt;br /&gt;
*Issue a warning in client developer’s console when an ad is being played for more than 5 minutes&lt;br /&gt;
*Reduced load time of Android SDK, caused due to encryption.&lt;br /&gt;
*Limit the duration reported for App launch&lt;br /&gt;
*Modification to accept non-JSON strings&lt;br /&gt;
*Fixed&lt;br /&gt;
**Incorrect DRM placement ID&lt;br /&gt;
**DRM pings sent in bursts in case of time change&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.10 (10-19-2016) ==&lt;br /&gt;
*Fixed an issue where SDK will send a burst of data pings in Android.&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.7 (9-1-2016) ==&lt;br /&gt;
*Support for Android N&lt;br /&gt;
*Usage of stop API call is made optional when switching between content or advertising occurs.&lt;br /&gt;
*General bug fix and performance improvements&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.4 (8-1-2016) ==&lt;br /&gt;
*Support for Pause timeout (from 30 minutes to 5 minutes)&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.3 (7-7-2016) ==&lt;br /&gt;
*Sending event level (button press data) data to census collections.&lt;br /&gt;
*Changes in OTT when switching from mobile to Chromecast&lt;br /&gt;
*General bug fix and performance improvements&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.0.4 (4-25-2016) ==&lt;br /&gt;
*Combined SDK for DCR US and International (Germany)&lt;br /&gt;
*API to signal end of content (end API)&lt;br /&gt;
*Changes to use of stop API&lt;br /&gt;
*Support for OTT measurement&lt;br /&gt;
*Support for Pause timeout&lt;br /&gt;
*Offline viewing&lt;br /&gt;
*Updated API to support JSON object instead of string.&lt;br /&gt;
*Reporting of media URL and bundle ID&lt;br /&gt;
*Updated ping retry logic&lt;br /&gt;
*Changes in OptOut process behavioral&lt;br /&gt;
*Enhanced Debugging and SDK logging&lt;br /&gt;
*Changes to API signature&lt;br /&gt;
*Introduced new API updateOTT to report current OTT status.&lt;br /&gt;
&lt;br /&gt;
== Release 4.0.0.8 (6-9-2015) ==&lt;br /&gt;
*Support for Nielsen DCR product (Digital Content Ratings)&lt;br /&gt;
*All the products should be migrated to the latest SDK.&lt;br /&gt;
*This SDK distribution does not have a native library component or shared object.&lt;br /&gt;
*Support for Nielsen App static measurement&lt;br /&gt;
*Support for Ad measurement&lt;br /&gt;
*Removal of Native C++ code&lt;br /&gt;
*Removed singleton restriction&lt;br /&gt;
*Support for Android 6.0 Marshmallow&lt;br /&gt;
*General bug fix and performance improvements&lt;br /&gt;
&lt;br /&gt;
== Release 1.2.3.8 (1-10-2015) ==&lt;/div&gt;</summary>
		<author><name>AnkitAgrawal</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=TVOS_SDK_Release_Notes&amp;diff=6863</id>
		<title>TVOS SDK Release Notes</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=TVOS_SDK_Release_Notes&amp;diff=6863"/>
		<updated>2024-07-09T04:13:27Z</updated>

		<summary type="html">&lt;p&gt;AnkitAgrawal: Release 9.4.0.0 changes&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Digital]]&lt;br /&gt;
 __NOTOC__&lt;br /&gt;
&lt;br /&gt;
{{Breadcrumb|}} {{Breadcrumb|Digital}} {{CurrentBreadcrumb}}&lt;br /&gt;
&lt;br /&gt;
== Release 9.4.0.0 (07-09-2024) ==&lt;br /&gt;
*Support for privacy manifest with content tracking domain for Ad flavors.&lt;br /&gt;
*Support for content tracking and no-tracking domains across sdk flavors and products.&lt;br /&gt;
*Other bug fixes and enhancements.&lt;br /&gt;
==Release 9.3.0.0 (05-10-2024)==&lt;br /&gt;
*Support for privacy manifest with tracking domain for Ad flavors.&lt;br /&gt;
*Support for capturing user opt-out during initialization.&lt;br /&gt;
*Other bug fixes and enhancements.&lt;br /&gt;
== Release 9.2.0.0 (9-27-2023) ==&lt;br /&gt;
*Support for privacy manifest and required reason API introduced in XCode 15.&lt;br /&gt;
*Digitally signed SDK framework per Apple recommendation&lt;br /&gt;
*DCR Static recognizing metadata with changed assetID for new impressions. &lt;br /&gt;
*Limiting ping retries during https failures. &lt;br /&gt;
*Other bug fixes and enhancements. &lt;br /&gt;
&lt;br /&gt;
== Release 9.1.0.0 (3-31-2023) ==&lt;br /&gt;
*DCR Static duration measurement for AppSDK (currently only AGF).&lt;br /&gt;
*Removed use of iOS keychains, started using NSUserDefaults for persistent storage.&lt;br /&gt;
*Viewability: allow enabling by product (DCR, DTVR).&lt;br /&gt;
*Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 9.0.0.0 (10-07-2022) ==&lt;br /&gt;
* Viewability measurement for DTVR, DCR Content and DCR Ad products.&lt;br /&gt;
* Audibility measurement for DTVR, DCR Content and DCR Ad products.&lt;br /&gt;
* SDK built with XCode 14.&lt;br /&gt;
* Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 8.2.0.0 (03-21-2022) ==&lt;br /&gt;
* Adopting Swift language internally, built on a mixed model (Swift+Objective C).&lt;br /&gt;
* Support for Swift markers to help Swift developers.&lt;br /&gt;
* Removed the usage of deprecated iOS network reachability class.&lt;br /&gt;
* Disabled iCloud backup/synchronization of SDK keychain items.&lt;br /&gt;
* Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 8.1.0.0 (06-28-2021) ==&lt;br /&gt;
* Support for XCFramework build distribution.&lt;br /&gt;
* Support for MacOS Catalyst platform framework.&lt;br /&gt;
* Fixed the device classification for MacOS M1 measurement.&lt;br /&gt;
* Support to capture Hashed email and UID.&lt;br /&gt;
* Support to collect SDK diagnostic data.&lt;br /&gt;
* Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 8.0.0.0 (10-05-2020) ==&lt;br /&gt;
* iOS 14 App Transparency Framework support.&lt;br /&gt;
* FPID and VendorID support.&lt;br /&gt;
* Fixed the device classification for iPADOS measurement.&lt;br /&gt;
* Support for Xamarin cross platform framework.&lt;br /&gt;
* Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 7.2.0.0 (05-18-2020) ==&lt;br /&gt;
* DTVR AQH and IVD requirements for End and pause timeout.&lt;br /&gt;
* Support for Hybrid app webview measurement. &lt;br /&gt;
* Support for Hybrid app react native webview measurement. &lt;br /&gt;
* Support for React Native measurement.&lt;br /&gt;
* Other bug fixes and enhancements&lt;br /&gt;
&lt;br /&gt;
== Release 7.1.0.0 (12-09-2019) ==&lt;br /&gt;
* Removed usage of deprecated class UIWebView&lt;br /&gt;
* Offline viewing measurement enhancements&lt;br /&gt;
* Fixed deadlock on SDK shutdown&lt;br /&gt;
* Revisited precedence logic for sfcode parameter&lt;br /&gt;
* Fix for DCR individual ad pings parameters after channel change&lt;br /&gt;
* Using default value for incorrect adModel parameter&lt;br /&gt;
* Defaulting isLive parameter value on channel change&lt;br /&gt;
* Other fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Release 7.0.0.0 (09-06-2019) ==&lt;br /&gt;
* Support for CDN based config.&lt;br /&gt;
* Support for Market based EMM UAID pings.&lt;br /&gt;
* Changes required for proper DCR Static measurement in multi-instance/multiple appid's case.&lt;br /&gt;
* Fixes for OTT synchronization issues between iOS and Android platforms.&lt;br /&gt;
* Fixes for EV data parameters in few scenarios.&lt;br /&gt;
* Fixes for DCR Static product behaviour in background app refresh and background fetch scenarios.&lt;br /&gt;
* DCR Ad reporting improvements.&lt;br /&gt;
* Fixes and improvements for the SDK console log messages.&lt;br /&gt;
* Other enhancements and fixes.&lt;br /&gt;
&lt;br /&gt;
== Release 6.2.0.0 (02-04-2019) == &lt;br /&gt;
* Introduced Dynamic framework for SDK.&lt;br /&gt;
* Removal of Location Module from SDK Code.&lt;br /&gt;
* Increased SDK log file size for Debug mode.&lt;br /&gt;
* Removed OTT Airplay/mirroring detection that caused crashes in AVAudioSession class.&lt;br /&gt;
* DCR performance improvements.&lt;br /&gt;
* Fixed the parsing error happening when clientid/vcid provided as empty in metadata.&lt;br /&gt;
* Align AppSDK for FW detection with BSDK for DCR measurement.&lt;br /&gt;
* Other Bug Fixes/Enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 6.1.0.1 (9-13-2018) ==&lt;br /&gt;
*Nielsen SDK support for Xcode 10 and tvOS 12&lt;br /&gt;
&lt;br /&gt;
== Release 6.0.0.4 (5-24-2018) ==&lt;br /&gt;
*If the SDK build target is set to AGF then SDK will send the hello ping to “eu” and “eu-uat” for debug builds. No changes to the non AGF build the default sfcode will continue to be &amp;quot;sdk&amp;quot; and &amp;quot;cert&amp;quot; for debug build.&lt;br /&gt;
*The C1 parameter (NUID) will now be sent as encrypted DeviceID.&lt;br /&gt;
*New SessionID changes. The sessionID will contain 29 length random characters appended by timestamp.&lt;br /&gt;
*Support for multiple SDK instance without any limit.&lt;br /&gt;
*New log feature for CAT tool to retrieve the API level information from client apps. This ping will contain the eventType, parameters, SDK version, appid etc.&lt;br /&gt;
*Removed Viewability for this release.&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.17 (1-23-2017) ==&lt;br /&gt;
*Added &amp;quot;seconds&amp;quot; place to the launch ping&lt;br /&gt;
*Ability to opt-out using &amp;quot;Limit Ad Tracking&amp;quot; feature&lt;br /&gt;
*Improved CPU Performance while apps are running in background&lt;br /&gt;
*Opt-Out pages can be served based on user’s language and locale from device&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.12 (12-14-2016) ==&lt;br /&gt;
*Support for Nielsen TV Brand Effect&lt;br /&gt;
*Ability to set CMS parameters at a more global level&lt;br /&gt;
*Opt-out pages based on locale and country&lt;br /&gt;
*Opt-out policy based on the &amp;quot;Limit Ad Tracking&amp;quot; flag&lt;br /&gt;
*Collection of additional device information&lt;br /&gt;
*Issue a warning in client developer’s console when ad is played for more than 5 minutes&lt;br /&gt;
*Removed the requirement for “type” parameter&lt;br /&gt;
*Limit the duration reported for App launch&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.7 (9-13-2016) ==&lt;br /&gt;
*General bug fix and performance improvements&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.5 (7-12-2016) ==&lt;br /&gt;
*Includes a sample TVOS application used to assist during integration.&lt;br /&gt;
*Support for TVML based optout pages&lt;br /&gt;
*General bug fix and performance improvements&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.0.7 (6-15-2016) ==&lt;br /&gt;
*Combined SDK for DCR US and International (Germany)&lt;br /&gt;
*API to signal end of content (end API)&lt;br /&gt;
*Support for Pause timeout&lt;br /&gt;
*Updated API to support JSON object instead of string.&lt;br /&gt;
*Reporting of media URL and bundle ID&lt;br /&gt;
*Updated ping retry logic&lt;br /&gt;
*Changes in OptOut process behavioral&lt;br /&gt;
*Enhanced Debugging and SDK logging&lt;br /&gt;
*Changes to API signature&lt;/div&gt;</summary>
		<author><name>AnkitAgrawal</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=iOS_SDK_Release_Notes&amp;diff=6862</id>
		<title>iOS SDK Release Notes</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=iOS_SDK_Release_Notes&amp;diff=6862"/>
		<updated>2024-07-09T04:12:04Z</updated>

		<summary type="html">&lt;p&gt;AnkitAgrawal: /* Release 9.4.0.0 (07-09-2024) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Digital]]&lt;br /&gt;
 __NOTOC__&lt;br /&gt;
&lt;br /&gt;
{{Breadcrumb|}} {{Breadcrumb|Digital Downloads}} {{CurrentBreadcrumb}}&lt;br /&gt;
&lt;br /&gt;
== Release 9.4.0.0 (07-09-2024) ==&lt;br /&gt;
*Support for privacy manifest with content tracking domain for Ad flavors.&lt;br /&gt;
*Support for content tracking and no-tracking domains across sdk flavors and products.&lt;br /&gt;
*Other bug fixes and enhancements.&lt;br /&gt;
== Release 9.3.0.0 (05-10-2024) ==&lt;br /&gt;
*Support for privacy manifest with tracking domain for Ad flavors.&lt;br /&gt;
*Support for capturing user opt-out during initialization.&lt;br /&gt;
*Other bug fixes and enhancements.&lt;br /&gt;
== Release 9.2.0.0 (09-27-2023) ==&lt;br /&gt;
*Support for privacy manifest and required reason API introduced in XCode 15.&lt;br /&gt;
*Digitally signed SDK framework per Apple recommendation&lt;br /&gt;
*DCR Static recognizing metadata with changed assetID for new impressions. &lt;br /&gt;
*Limiting ping retries during https failures. &lt;br /&gt;
*Other bug fixes and enhancements. &lt;br /&gt;
&lt;br /&gt;
== Release 9.1.0.0 (03-31-2023) ==&lt;br /&gt;
*DCR Static duration measurement for AppSDK (currently only AGF).&lt;br /&gt;
*Removed use of iOS keychains, started using NSUserDefaults for persistent storage.&lt;br /&gt;
*Viewability: allow enabling by product (DCR, DTVR).&lt;br /&gt;
*Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 9.0.0.0 (10-07-2022) ==&lt;br /&gt;
* Viewability measurement for DTVR, DCR Content and DCR Ad products.&lt;br /&gt;
* Audibility measurement for DTVR, DCR Content and DCR Ad products.&lt;br /&gt;
* SDK built with XCode 14.&lt;br /&gt;
* Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 8.2.0.0 (03-21-2022) ==&lt;br /&gt;
* Adopting Swift language internally, built on a mixed model (Swift+Objective C).&lt;br /&gt;
* Support for Swift markers to help Swift developers.&lt;br /&gt;
* Removed the usage of deprecated iOS network reachability class.&lt;br /&gt;
* Disabled iCloud backup/synchronization of SDK keychain items.&lt;br /&gt;
* Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 8.1.0.0 (06-28-2021) ==&lt;br /&gt;
* Support for XCFramework build distribution.&lt;br /&gt;
* Support for MacOS Catalyst platform framework.&lt;br /&gt;
* Fixed the device classification for MacOS M1 measurement.&lt;br /&gt;
* Support to capture Hashed email and UID.&lt;br /&gt;
* Support to collect SDK diagnostic data.&lt;br /&gt;
* Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 8.0.0.0 (10-05-2020) ==&lt;br /&gt;
* iOS 14 App Transparency Framework support.&lt;br /&gt;
* FPID and VendorID support.&lt;br /&gt;
* Fixed the device classification for iPADOS measurement.&lt;br /&gt;
* Support for Xamarin cross platform framework.&lt;br /&gt;
* Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 7.2.0.0 (05-18-2020) ==&lt;br /&gt;
* DTVR AQH and IVD requirements for End and pause timeout.&lt;br /&gt;
* Support for Hybrid app webview measurement. &lt;br /&gt;
* Support for Hybrid app react native webview measurement. &lt;br /&gt;
* Support for React Native measurement.&lt;br /&gt;
* Other bug fixes and enhancements&lt;br /&gt;
&lt;br /&gt;
== Release 7.1.0.0 (12-09-2019) ==&lt;br /&gt;
* Removed usage of deprecated class UIWebView&lt;br /&gt;
* Offline viewing measurement enhancements&lt;br /&gt;
* Fixed deadlock on SDK shutdown&lt;br /&gt;
* Revisited precedence logic for sfcode parameter&lt;br /&gt;
* Fix for DCR individual ad pings parameters after channel change&lt;br /&gt;
* Using default value for incorrect adModel parameter&lt;br /&gt;
* Defaulting isLive parameter value on channel change&lt;br /&gt;
* Other fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 7.0.0.0 (09-06-2019) ==&lt;br /&gt;
* Support for CDN based config.&lt;br /&gt;
* Support for Market based EMM UAID pings.&lt;br /&gt;
* Changes required for proper DCR Static measurement in multi-instance/multiple appid's case.&lt;br /&gt;
* Fixes for OTT synchronization issues between iOS and Android platforms.&lt;br /&gt;
* Fixes for EV data parameters in few scenarios.&lt;br /&gt;
* Fixes for DCR Static product behaviour in background app refresh and background fetch scenarios.&lt;br /&gt;
* DCR Ad reporting improvements.&lt;br /&gt;
* Fixes and improvements for the SDK console log messages.&lt;br /&gt;
* Other enhancements and fixes.&lt;br /&gt;
&lt;br /&gt;
== Release 6.2.0.0 (02-04-2019) == &lt;br /&gt;
* Introduced Dynamic framework for SDK.&lt;br /&gt;
* Removal of Location Module from SDK Code.&lt;br /&gt;
* Increased SDK log file size for Debug mode.&lt;br /&gt;
* Removed OTT Airplay/mirroring detection that caused crashes in AVAudioSession class.&lt;br /&gt;
* DCR performance improvements.&lt;br /&gt;
* Fixed the parsing error happening when clientid/vcid provided as empty in metadata.&lt;br /&gt;
* Align AppSDK for FW detection with BSDK for DCR measurement.&lt;br /&gt;
* Other Bug Fixes/Enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 6.1.0.1 (9-13-2018) ==&lt;br /&gt;
*Support added for Video On Demand in TV Ratings&lt;br /&gt;
*Support for Xcode 10 and iOS 12&lt;br /&gt;
&lt;br /&gt;
== Release 6.0.0.4 (5-24-2018) ==&lt;br /&gt;
*If the SDK build target is set to AGF then SDK will send the hello ping to “eu” and “eu-uat” for debug builds. No changes to the non AGF build the default sfcode will continue to be &amp;quot;sdk&amp;quot; and &amp;quot;cert&amp;quot; for debug build.&lt;br /&gt;
*The C1 parameter (NUID) will now be sent as encrypted DeviceID.&lt;br /&gt;
*New SessionID changes. The sessionID will contain 29 length random characters appended by timestamp.&lt;br /&gt;
*Support for multiple SDK instance without any limit.&lt;br /&gt;
*New log feature for CAT tool to retrieve the API level information from client apps. This ping will contain the eventType, parameters, SDK version, appid etc.&lt;br /&gt;
*Removed Viewability for this release.&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.29 (7-31-2017) ==&lt;br /&gt;
*Genre parameter will be a part of DCR pings and the value will be reflected as part of c44 parameter.&lt;br /&gt;
*Merged adModel and adLoadType flags&lt;br /&gt;
*Fix for stop event data carried to next session’s duration ping&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.25 (5-31-2017) ==&lt;br /&gt;
*Enhanced support for Digital Audio&lt;br /&gt;
*Ability to pass adloadtype as “linear” or “dynamic”&lt;br /&gt;
*Ability to detect end of content and static material through duration pings&lt;br /&gt;
*Acceptance of empty parameters with a warning message triggered, if a required parameter is missing&lt;br /&gt;
*Acceptance of case-insensitive JSON key values&lt;br /&gt;
*Configurable feature to show Ad view counts in the duration pings&lt;br /&gt;
*Automatic Pause Detection and Debug build detection&lt;br /&gt;
*Change of default ‘type’ from “ad” to “content”&lt;br /&gt;
*Removal of “Static” Launch Ping for Non-Static product implementations&lt;br /&gt;
*Fix for App crash when multiple threads are accessing the SQLite&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.23 (5-5-2017) ==&lt;br /&gt;
*Ability to pass adloadtype as “linear” or “dynamic”&lt;br /&gt;
*Ability to detect end of content and static material through duration pings&lt;br /&gt;
*Acceptance of empty parameters with a warning message triggered, if a required parameter is missing&lt;br /&gt;
*Acceptance of case-insensitive JSON key values&lt;br /&gt;
*Configurable feature to show Ad view counts in the duration pings&lt;br /&gt;
*Automatic Pause Detection and Debug build detection&lt;br /&gt;
*Change of default ‘type’ from “ad” to “content”&lt;br /&gt;
*Removal of “Static” Launch Ping for Non-Static product implementations&lt;br /&gt;
*Fix for App crash when multiple threads are accessing the SQLite&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.19 (4-3-2017) ==&lt;br /&gt;
*Fix for muting background music apps&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.18 (2-3-2017) ==&lt;br /&gt;
*Minor bug fixes and performance improvement&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.17 (1-23-2017) ==&lt;br /&gt;
*Added “seconds” place to the launch ping&lt;br /&gt;
*Ability to opt-out using “Limit Ad Tracking” feature&lt;br /&gt;
*Improved CPU Performance while apps are running in background&lt;br /&gt;
*Opt-Out pages can be served based on user’s language and locale from device&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.12 (12-14-2016) ==&lt;br /&gt;
*Support for Nielsen TV Brand Effect&lt;br /&gt;
*Ability to set CMS parameters at a more global level&lt;br /&gt;
*Opt-out pages based on locale and country&lt;br /&gt;
*Opt-out policy based on the ‘Limit Ad Tracking’ flag&lt;br /&gt;
*Collection of additional device information&lt;br /&gt;
*Issue a warning in client developer’s console when ad is played for more than 5 minutes&lt;br /&gt;
*Removed the requirement for “type” parameter&lt;br /&gt;
*Limit the duration reported for App launch&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.9 (10-18-2016) ==&lt;br /&gt;
*Fixed Linker error duplicate symbols for Reachability notification in iOS.&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.7 (9-13-2016) ==&lt;br /&gt;
*Support for iOS 10&lt;br /&gt;
*Usage of stop API call is made optional when switching between content or advertising occurs.&lt;br /&gt;
*General bug fix and performance improvements&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.5 (7-12-2016) ==&lt;br /&gt;
*Sending event level (button press data) data to census collections.&lt;br /&gt;
*Support for Pause timeout (from 30 minutes to 5 minutes)&lt;br /&gt;
*Changes in OTT when switching from mobile to Chromecast&lt;br /&gt;
*Self-error Reporting for iOS SDK&lt;br /&gt;
*General bug fix and performance improvements&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.0.5 (4-25-2016) ==&lt;br /&gt;
*Combined SDK for DCR US and International (Germany)&lt;br /&gt;
*API to signal end of content (end API)&lt;br /&gt;
*Changes to use of stop API&lt;br /&gt;
*Support for OTT measurement&lt;br /&gt;
*Support for Pause timeout&lt;br /&gt;
*Offline viewing&lt;br /&gt;
*Updated API to support JSON object instead of string.&lt;br /&gt;
*Reporting of media URL and bundle ID&lt;br /&gt;
*Updated ping retry logic&lt;br /&gt;
*Changes in OptOut process behavioral&lt;br /&gt;
*Enhanced Debugging and SDK logging&lt;br /&gt;
*Changes to API signature&lt;br /&gt;
*Introduced new API updateOTT to report current OTT status.&lt;br /&gt;
&lt;br /&gt;
== Release 4.0.0.8 (6-9-2015) ==&lt;br /&gt;
*Support for Nielsen DCR product (Digital Content Ratings)&lt;br /&gt;
**All the products should be migrated to the latest SDK.&lt;br /&gt;
**This SDK distribution does not have a native library component or shared object.&lt;br /&gt;
*Support for Nielsen App static measurement&lt;br /&gt;
*Support for Ad measurement&lt;br /&gt;
*Removal of Native C++ code&lt;br /&gt;
*Removed singleton restriction&lt;br /&gt;
*Support for iOS 9 and iOS 9 PIP mode&lt;br /&gt;
*General bug fix and performance improvements&lt;br /&gt;
&lt;br /&gt;
== Release 3.2.1.26 (1-10-2015) ==&lt;/div&gt;</summary>
		<author><name>AnkitAgrawal</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=Digital_Measurement_Video_webOS&amp;diff=6722</id>
		<title>Digital Measurement Video webOS</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=Digital_Measurement_Video_webOS&amp;diff=6722"/>
		<updated>2024-06-10T19:00:10Z</updated>

		<summary type="html">&lt;p&gt;AnkitAgrawal: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|DCR &amp;amp; DTVR}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
__NOTOC__&lt;br /&gt;
== Introduction ==&lt;br /&gt;
The following document will highlight the steps needed to run Browser SDK (BSDK) on LG Smart TVs that are currently running webOS TV 23 on Chromium 94 web engine&lt;br /&gt;
&lt;br /&gt;
The tutorial should be used in combination with the documentation at [https://webostv.developer.lge.com/develop/getting-started/build-your-first-web-app webOS TV Developer] to build an app and verify that the BSDK properly measures  the video and static content. In the tutorial we will be using a [https://webostv.developer.lge.com/develop/getting-started/web-app-types#hosted-web-app hosted web app] which will host the content on the web server. We will also use the [https://webostv.developer.lge.com/develop/tools/simulator-introduction webOS TV Simulator] for app development.&lt;br /&gt;
&lt;br /&gt;
== Step 1: Install the webOS TV CLI ==&lt;br /&gt;
&lt;br /&gt;
Navigate [https://webostv.developer.lge.com/develop/tools/simulator-installation here] and install the webOS TV CLI&lt;br /&gt;
&lt;br /&gt;
== Step 2: Install the webOS TV Simulator ==&lt;br /&gt;
&lt;br /&gt;
Navigate [https://webostv.developer.lge.com/develop/tools/simulator-installation here] and install the webOS TV Simulator&lt;br /&gt;
&lt;br /&gt;
== Step 3: Create App ==&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
# We will begin creating the app by navigating [https://webostv.developer.lge.com/develop/getting-started/web-app-types#hosted-web-app here] and following the installation steps:&lt;br /&gt;
# Run &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt; ares-generate -t hosted_webapp nlsn-bsdk-webOS &amp;lt;/syntaxhighlight&amp;gt; to generate the app and accept all defaults&lt;br /&gt;
# Open  the generated folder in a text editor or IDE and and create a new folder called app&lt;br /&gt;
# Add the following into a video.html file and make sure to update App ID with Nielsen provided App ID while creating the SDK instance&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add the following script tag to the website:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;en&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
    &amp;lt;meta charset=&amp;quot;UTF-8&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;meta http-equiv=&amp;quot;X-UA-Compatible&amp;quot; content=&amp;quot;IE=edge&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;viewport&amp;quot; content=&amp;quot;width=device-width, initial-scale=1.0&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;DCR Video webOS Sample&amp;lt;/title&amp;gt;&lt;br /&gt;
    &amp;lt;script&amp;gt;&lt;br /&gt;
        // Static Queue Snippet&lt;br /&gt;
        !function (e, n) {&lt;br /&gt;
            function t(e) {&lt;br /&gt;
                return &amp;quot;object&amp;quot; == typeof e ? JSON.parse(JSON.stringify(e)) : e&lt;br /&gt;
            }&lt;br /&gt;
            e[n] = e[n] ||&lt;br /&gt;
            {&lt;br /&gt;
                nlsQ: function (o, r, c) {&lt;br /&gt;
                    var s = e.document,&lt;br /&gt;
                        a = s.createElement(&amp;quot;script&amp;quot;);&lt;br /&gt;
                    a.async = 1,&lt;br /&gt;
                        a.src = (&amp;quot;http:&amp;quot; === e.location.protocol ? &amp;quot;http:&amp;quot; : &amp;quot;https:&amp;quot;) + &amp;quot;//cdn-gl.imrworldwide.com/conf/&amp;quot; + o + &amp;quot;.js#name=&amp;quot; + r + &amp;quot;&amp;amp;ns=&amp;quot; + n;&lt;br /&gt;
                    var i = s.getElementsByTagName(&amp;quot;script&amp;quot;)[0];&lt;br /&gt;
                    return i.parentNode.insertBefore(a, i),&lt;br /&gt;
                        e[n][r] = e[n][r] || {&lt;br /&gt;
                            g: c || {},&lt;br /&gt;
                            ggPM: function (o, c, s, a, i) { e[n][r].q = e[n][r].q || []; try { var l = t([o, c, s, a, i]); e[n][r].q.push(l) } catch (e) { console &amp;amp;&amp;amp; console.log &amp;amp;&amp;amp; console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;) } },&lt;br /&gt;
                            trackEvent: function (o) { e[n][r].te = e[n][r].te || []; try { var c = t(o); e[n][r].te.push(c) } catch (e) { console &amp;amp;&amp;amp; console.log &amp;amp;&amp;amp; console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;) } }&lt;br /&gt;
                        },&lt;br /&gt;
                        e[n][r]&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
}(window, &amp;quot;NOLBUNDLE&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        // INSERT CLIENT APP ID&lt;br /&gt;
        var nSdkInstance = NOLBUNDLE.nlsQ(&amp;quot;PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;, &amp;quot;videoSdkInstance&amp;quot;, {&lt;br /&gt;
            nol_sdkDebug: &amp;quot;debug&amp;quot;,&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        var contentMetadata = {&lt;br /&gt;
            type: 'content',&lt;br /&gt;
            assetid: 'VID-123456',&lt;br /&gt;
            program: 'program name',&lt;br /&gt;
            title: 'episode title with season and episode number',&lt;br /&gt;
            length: 'length in seconds',&lt;br /&gt;
            airdate: '20210321 09:00:00',&lt;br /&gt;
            isfullepisode: 'y',&lt;br /&gt;
            adloadtype: '2'&lt;br /&gt;
        };&lt;br /&gt;
    &amp;lt;/script&amp;gt;&lt;br /&gt;
    &amp;lt;style&amp;gt;&lt;br /&gt;
        body {&lt;br /&gt;
            background-color: white;&lt;br /&gt;
        }&lt;br /&gt;
    &amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
    &amp;lt;h1&amp;gt;DCR Video webOS Sample App&amp;lt;/h1&amp;gt;&lt;br /&gt;
    &amp;lt;div&amp;gt;&lt;br /&gt;
      &amp;lt;video controls src=&amp;quot;https://archive.org/download/BigBuckBunny_124/Content/big_buck_bunny_720p_surround.mp4&amp;quot;&lt;br /&gt;
        poster=&amp;quot;https://peach.blender.org/wp-content/uploads/title_anouncement.jpg?x11217&amp;quot; width=&amp;quot;620&amp;quot;&amp;gt;&lt;br /&gt;
             Sorry, your browser doesn't support embedded videos,&lt;br /&gt;
             but don't worry, you can &amp;lt;a&lt;br /&gt;
     href=&amp;quot;https://archive.org/details/BigBuckBunny_124&amp;quot;&amp;gt;download it&amp;lt;/a&amp;gt;&lt;br /&gt;
        and watch it with your favorite video player!&lt;br /&gt;
      &amp;lt;/video&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;/main&amp;gt;&lt;br /&gt;
    &amp;lt;script&amp;gt;&lt;br /&gt;
        var media = document.querySelector('video');&lt;br /&gt;
        var playheadPosition = 0;&lt;br /&gt;
        var metadataLoaded = false;&lt;br /&gt;
&lt;br /&gt;
        // Loadmetadata&lt;br /&gt;
        // Load contentMetadata object&lt;br /&gt;
        media.addEventListener('loadedmetadata', (event) =&amp;gt; {&lt;br /&gt;
            // Call SDK loadmetadata event&lt;br /&gt;
            if (!metadataLoaded) {&lt;br /&gt;
                nSdkInstance.ggPM(&amp;quot;loadmetadata&amp;quot;, contentMetadata);&lt;br /&gt;
                metadataLoaded = true;&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        media.addEventListener('play', (event) =&amp;gt; {&lt;br /&gt;
            // Call SDK play event&lt;br /&gt;
            if (!metadataLoaded) {&lt;br /&gt;
                nSdkInstance.ggPM(&amp;quot;loadmetadata&amp;quot;, contentMetadata);&lt;br /&gt;
                metadataLoaded = true;&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        // Player paused&lt;br /&gt;
        media.addEventListener('pause', function (e) {&lt;br /&gt;
            nSdkInstance.ggPM(&amp;quot;pause&amp;quot;, playheadPosition);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        // Set playhead position&lt;br /&gt;
        media.addEventListener('timeupdate', function (e) {&lt;br /&gt;
            var currTime = Math.floor(media.currentTime);&lt;br /&gt;
            if (playheadPosition &amp;lt; currTime) {&lt;br /&gt;
                playheadPosition = currTime;&lt;br /&gt;
                nSdkInstance.ggPM(&amp;quot;setplayheadposition&amp;quot;, playheadPosition);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        // End&lt;br /&gt;
        media.addEventListener('ended', function (e) {&lt;br /&gt;
            nSdkInstance.ggPM(&amp;quot;end&amp;quot;, playheadPosition);&lt;br /&gt;
            metadataLoaded = false;&lt;br /&gt;
            playheadPosition = 0;&lt;br /&gt;
        });&lt;br /&gt;
    &amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Click [https://gitlab.com/nielsen-media/digital/shared/sdk/browser-sdk/misc/bsdk-client-documentation/-/wikis/DCR-Video-Quick-Start here] for more information on DCR Video implementation.&lt;br /&gt;
&lt;br /&gt;
  3. Navigate to &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt; index.html &amp;lt;/syntaxhighlight&amp;gt; at the root of the directory and update the &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt; location.href &amp;lt;/syntaxhighlight&amp;gt; url to point to &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt; http://{{LOCAL_SERVER_URL}}/app/video.html &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That is all that we need to run the app on the webOS TV Simulator. Please make sure to update the App ID for SDK initialization to view proper crediting&lt;br /&gt;
&lt;br /&gt;
== Step 4: Open up webOS TV Simulator ==&lt;br /&gt;
&lt;br /&gt;
Open up the webOS TV Simulator &amp;gt; navigate to File &amp;gt; Launch App &amp;gt; open the folder containing the app created in the previous step &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:WEBOS 1.png||600px|center|]]&lt;br /&gt;
&lt;br /&gt;
== Step 5: Debug app ==&lt;br /&gt;
Click on the Inspect button on the remote to open up developer tools &amp;gt; navigate to the Console tab &amp;gt; check for BSDK initialization and measurement.&lt;br /&gt;
[[File:LGwebos 2.png||600px|center|]]&lt;br /&gt;
&lt;br /&gt;
Note - Debug Logging: Disable logging by deleting &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt; {nol_sdkDebug: 'debug'} &amp;lt;/syntaxhighlight&amp;gt; from initialization call.&lt;br /&gt;
&lt;br /&gt;
== Remote events ==&lt;br /&gt;
Build out the app further by including [https://webostv.developer.lge.com/develop/guides/magic-remote remote events] and attaching the player events to corresponding &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt; keycode: &amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
var media = document.querySelector('video');&lt;br /&gt;
window.addEventListener(&amp;quot;keydown&amp;quot;, function (e) {&lt;br /&gt;
    switch (e.keyCode) {&lt;br /&gt;
        case 415: // Play&lt;br /&gt;
            media.play(); // play video&lt;br /&gt;
            nSdkInstance.ggPM(&amp;quot;play&amp;quot;, contentMetadata); // SDK call&lt;br /&gt;
            break;&lt;br /&gt;
        case 19: // Pause&lt;br /&gt;
            media.pause(); // play video&lt;br /&gt;
            nSdkInstance.ggPM(&amp;quot;pause&amp;quot;, playheadPosition); // SDK call&lt;br /&gt;
            break;&lt;br /&gt;
        case 461: // Back&lt;br /&gt;
            nSdkInstance.ggPM(&amp;quot;stop&amp;quot;, playheadPosition); // SDK call&lt;br /&gt;
            break;&lt;br /&gt;
        default:&lt;br /&gt;
            break;&lt;br /&gt;
    }&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Next steps ==&lt;br /&gt;
&lt;br /&gt;
For further testing on webOS TV apps on the TV, refer to this [https://webostv.developer.lge.com/develop/getting-started/developer-mode-app guide]. If there are any questions or concerns then please reach out to BSDK team. Reference the following guides for product specific information:&lt;br /&gt;
&lt;br /&gt;
* [[DCR_Video_Browser_SDK|DCR Video]]&lt;br /&gt;
* [[DCR_Static_Browser_SDK_(6.0.0)|DCR Static]]&lt;br /&gt;
* [[DTVR_Browser_SDK|DTVR]]&lt;/div&gt;</summary>
		<author><name>AnkitAgrawal</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=Digital_Measurement_Video_TizenTv&amp;diff=6721</id>
		<title>Digital Measurement Video TizenTv</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=Digital_Measurement_Video_TizenTv&amp;diff=6721"/>
		<updated>2024-06-10T18:47:33Z</updated>

		<summary type="html">&lt;p&gt;AnkitAgrawal: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|DCR &amp;amp; DTVR}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
__NOTOC__&lt;br /&gt;
== Introduction ==&lt;br /&gt;
The following document will highlight the steps needed to run Browser SDK (BSDK) on Samsung Smart TV using TIzen Studio for app development.&lt;br /&gt;
The tutorial should be used in conjunction with the documentation at [https://docs.tizen.org/application/web/get-started/tv/first-samsung-tv-app/ Create Your First Samsung Smart TV Web Application] to build an app with BSDK integration for content measurement. In this tutorial we will create a native app and highlight the different permissions required to run the BSDK.&lt;br /&gt;
&lt;br /&gt;
== Step 1: Install Tizen Studio ==&lt;br /&gt;
&lt;br /&gt;
Navigate [https://developer.tizen.org/development/tizen-studio/download here] and install Tizen Studio.&lt;br /&gt;
During installation make sure to install the '''TV Extensions package''' from the Package Manager.&lt;br /&gt;
&lt;br /&gt;
== Step 2: Generate Security Profile ==&lt;br /&gt;
&lt;br /&gt;
Navigate [https://docs.tizen.org/application/tizen-studio/common-tools/certificate-registration here] and generate the security profile in order to run applications.&lt;br /&gt;
&lt;br /&gt;
== Step 3: Create Basic Project ==&lt;br /&gt;
&lt;br /&gt;
Follow the [https://docs.tizen.org/application/web/get-started/tv/first-samsung-tv-app/ step-by-step guide] and create the Basic Project template. &lt;br /&gt;
Replace the code in the&amp;lt;syntaxhighlight&amp;gt;index.html&amp;lt;/syntaxhighlight&amp;gt;file with the code snippet below and update the App ID with a Nielsen provided App ID during SDK initialization.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;en&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
    &amp;lt;meta charset=&amp;quot;UTF-8&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta http-equiv=&amp;quot;X-UA-Compatible&amp;quot; content=&amp;quot;IE=edge&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;viewport&amp;quot; content=&amp;quot;width=device-width, initial-scale=1.0&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;DCR Video Tizen Sample&amp;lt;/title&amp;gt;&lt;br /&gt;
    &amp;lt;script&amp;gt;&lt;br /&gt;
        // Static Queue Snippet&lt;br /&gt;
        !function (e, n) {&lt;br /&gt;
            function t(e) {&lt;br /&gt;
                return &amp;quot;object&amp;quot; == typeof e ? JSON.parse(JSON.stringify(e)) : e&lt;br /&gt;
            }&lt;br /&gt;
            e[n] = e[n] ||&lt;br /&gt;
            {&lt;br /&gt;
                nlsQ: function (o, r, c) {&lt;br /&gt;
                    var s = e.document,&lt;br /&gt;
                        a = s.createElement(&amp;quot;script&amp;quot;);&lt;br /&gt;
                    a.async = 1,&lt;br /&gt;
                        a.src = (&amp;quot;http:&amp;quot; === e.location.protocol ? &amp;quot;http:&amp;quot; : &amp;quot;https:&amp;quot;) + &amp;quot;//cdn-gl.imrworldwide.com/conf/&amp;quot; + o + &amp;quot;.js#name=&amp;quot; + r + &amp;quot;&amp;amp;ns=&amp;quot; + n;&lt;br /&gt;
                    var i = s.getElementsByTagName(&amp;quot;script&amp;quot;)[0];&lt;br /&gt;
                    return i.parentNode.insertBefore(a, i),&lt;br /&gt;
                        e[n][r] = e[n][r] || {&lt;br /&gt;
                            g: c || {},&lt;br /&gt;
                            ggPM: function (o, c, s, a, i) { e[n][r].q = e[n][r].q || []; try { var l = t([o, c, s, a, i]); e[n][r].q.push(l) } catch (e) { console &amp;amp;&amp;amp; console.log &amp;amp;&amp;amp; console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;) } },&lt;br /&gt;
                            trackEvent: function (o) { e[n][r].te = e[n][r].te || []; try { var c = t(o); e[n][r].te.push(c) } catch (e) { console &amp;amp;&amp;amp; console.log &amp;amp;&amp;amp; console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;) } }&lt;br /&gt;
                        },&lt;br /&gt;
                        e[n][r]&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }(window, &amp;quot;NOLBUNDLE&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        // Replace (PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX) with CLIENT APP ID&lt;br /&gt;
        var nSdkInstance = NOLBUNDLE.nlsQ(&amp;quot;PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;, &amp;quot;videoSdkInstance&amp;quot;, {&lt;br /&gt;
            nol_sdkDebug: &amp;quot;debug&amp;quot;,&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        var contentMetadata = {&lt;br /&gt;
            type: 'content',&lt;br /&gt;
            assetid: 'VID-123456',&lt;br /&gt;
            program: 'program name',&lt;br /&gt;
            title: 'episode title with season and episode number',&lt;br /&gt;
            length: 'length in seconds',&lt;br /&gt;
            airdate: '20210321 09:00:00',&lt;br /&gt;
            isfullepisode: 'y',&lt;br /&gt;
            adloadtype: '2'&lt;br /&gt;
        };&lt;br /&gt;
    &amp;lt;/script&amp;gt;&lt;br /&gt;
    &amp;lt;style&amp;gt;&lt;br /&gt;
        body {&lt;br /&gt;
            background-color: white;&lt;br /&gt;
        }&lt;br /&gt;
    &amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
    &amp;lt;h1&amp;gt;DCR Video Tizen Sample App&amp;lt;/h1&amp;gt;&lt;br /&gt;
    &amp;lt;div&amp;gt;&lt;br /&gt;
      &amp;lt;video controls src=&amp;quot;https://archive.org/download/BigBuckBunny_124/Content/big_buck_bunny_720p_surround.mp4&amp;quot;&lt;br /&gt;
        poster=&amp;quot;https://peach.blender.org/wp-content/uploads/title_anouncement.jpg?x11217&amp;quot; width=&amp;quot;620&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
        Sorry, your browser doesn't support embedded videos,&lt;br /&gt;
        but don't worry, you can &amp;lt;a href=&amp;quot;https://archive.org/details/BigBuckBunny_124&amp;quot;&amp;gt;download it&amp;lt;/a&amp;gt;&lt;br /&gt;
        and watch it with your favorite video player!&lt;br /&gt;
      &amp;lt;/video&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;/main&amp;gt;&lt;br /&gt;
    &amp;lt;script&amp;gt;&lt;br /&gt;
        var media = document.querySelector('video');&lt;br /&gt;
        var playheadPosition = 0;&lt;br /&gt;
        var metadataLoaded = false;&lt;br /&gt;
&lt;br /&gt;
        // Loadmetadata&lt;br /&gt;
        // Load contentMetadata object&lt;br /&gt;
        media.addEventListener('loadedmetadata', (event) =&amp;gt; {&lt;br /&gt;
            // Call SDK loadmetadata event&lt;br /&gt;
            if (!metadataLoaded) {&lt;br /&gt;
                nSdkInstance.ggPM(&amp;quot;loadmetadata&amp;quot;, contentMetadata);&lt;br /&gt;
                metadataLoaded = true;&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        media.addEventListener('play', (event) =&amp;gt; {&lt;br /&gt;
            // Call SDK play event&lt;br /&gt;
            if (!metadataLoaded) {&lt;br /&gt;
                nSdkInstance.ggPM(&amp;quot;loadmetadata&amp;quot;, contentMetadata);&lt;br /&gt;
                metadataLoaded = true;&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        // Player paused&lt;br /&gt;
        media.addEventListener('pause', function (e) {&lt;br /&gt;
            nSdkInstance.ggPM(&amp;quot;pause&amp;quot;, playheadPosition);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        // Set playhead position&lt;br /&gt;
        media.addEventListener('timeupdate', function (e) {&lt;br /&gt;
            var currTime = Math.floor(media.currentTime);&lt;br /&gt;
            if (playheadPosition &amp;lt; currTime) {&lt;br /&gt;
                playheadPosition = currTime;&lt;br /&gt;
                nSdkInstance.ggPM(&amp;quot;setplayheadposition&amp;quot;, playheadPosition);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        // End&lt;br /&gt;
        media.addEventListener('ended', function (e) {&lt;br /&gt;
            nSdkInstance.ggPM(&amp;quot;end&amp;quot;, playheadPosition);&lt;br /&gt;
            metadataLoaded = false;&lt;br /&gt;
            playheadPosition = 0;&lt;br /&gt;
        });&lt;br /&gt;
    &amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Step 4: Run Project==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;Right click on the project &amp;gt; Run As &amp;gt; Tizen Web Simulator Application (Samsung TV)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Tizen 1 Step4.png||600px|center|]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Extra configurations must be done to run and debug the application on a Target Device, please reference the following [[TizenTv_Debugging|guide]] for more information&lt;br /&gt;
&lt;br /&gt;
== Step 5: Debug App==&lt;br /&gt;
Right click anywhere in the Simulator to open the Web Inspector &amp;gt; navigate to the Console tab &amp;gt; check for BSDK initialization and content measurement.&lt;br /&gt;
[[File:Tizen 1 Step5.png||600px|center|]]&lt;br /&gt;
&lt;br /&gt;
Debug Logging: Disable logging by deleting &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;{nol_sdkDebug: 'debug'}&amp;lt;/syntaxhighlight&amp;gt; from initialization call&lt;br /&gt;
&lt;br /&gt;
== Remote control events ==&lt;br /&gt;
Build out the app further by including [https://developer.samsung.com/smarttv/develop/guides/user-interaction/remote-control.html remote control events] and attaching the player events to corresponding &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;keyCode &amp;lt;/syntaxhighlight&amp;gt; or using Tizen registered keys:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
var media = document.querySelector('video');&lt;br /&gt;
window.addEventListener(&amp;quot;keydown&amp;quot;, function (e) {&lt;br /&gt;
    switch (e.keyCode) {&lt;br /&gt;
        case 10252: // MediaPlayPause&lt;br /&gt;
            if(!media.paused) {&lt;br /&gt;
                media.pause(); // pause video&lt;br /&gt;
                nSdkInstance.ggPM(&amp;quot;pause&amp;quot;, playheadPosition); // SDK call&lt;br /&gt;
                break;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            media.play(); // play video&lt;br /&gt;
            nSdkInstance.ggPM(&amp;quot;play&amp;quot;, contentMetadata); // SDK call&lt;br /&gt;
            break;&lt;br /&gt;
        case 10009: // Back&lt;br /&gt;
            nSdkInstance.ggPM(&amp;quot;stop&amp;quot;, playheadPosition); // SDK call&lt;br /&gt;
            break;&lt;br /&gt;
        ...&lt;br /&gt;
        default:&lt;br /&gt;
            break;&lt;br /&gt;
    }&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Next steps ==&lt;br /&gt;
&lt;br /&gt;
For further testing Samsung Tizen TV apps, refer to this [https://docs.tizen.org/application/web/tutorials/process/run-debug-app/ guide]. If there are any questions or concerns then please reach out to the BSDK team. Reference the following guides for product specific information:&lt;br /&gt;
&lt;br /&gt;
* [[DCR_Video_Browser_SDK|DCR Video]]&lt;br /&gt;
* [[DCR_Static_Browser_SDK_(6.0.0)|DCR Static]]&lt;br /&gt;
* [[DTVR_Browser_SDK|DTVR]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
For further technical details or a sample application, please contact your Technical Account Manager (TAM).&lt;/div&gt;</summary>
		<author><name>AnkitAgrawal</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=Digital_Measurement_Video_TizenTv&amp;diff=6720</id>
		<title>Digital Measurement Video TizenTv</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=Digital_Measurement_Video_TizenTv&amp;diff=6720"/>
		<updated>2024-06-10T18:47:17Z</updated>

		<summary type="html">&lt;p&gt;AnkitAgrawal: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|DCR &amp;amp; DTVR}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
__NOTOC__&lt;br /&gt;
== Introduction ==&lt;br /&gt;
The following document will highlight the steps needed to run Browser SDK (BSDK) on Samsung Smart TV using TIzen Studio for app development.&lt;br /&gt;
The tutorial should be used in conjunction with the documentation at [https://docs.tizen.org/application/web/get-started/tv/first-samsung-tv-app/ Create Your First Samsung Smart TV Web Application] to build an app with BSDK integration for content measurement. In this tutorial we will create a native app and highlight the different permissions required to run the BSDK.&lt;br /&gt;
&lt;br /&gt;
== Step 1: Install Tizen Studio ==&lt;br /&gt;
&lt;br /&gt;
Navigate [https://developer.tizen.org/development/tizen-studio/download here] and install Tizen Studio.&lt;br /&gt;
During installation make sure to install the '''TV Extension's package''' from the Package Manager.&lt;br /&gt;
&lt;br /&gt;
== Step 2: Generate Security Profile ==&lt;br /&gt;
&lt;br /&gt;
Navigate [https://docs.tizen.org/application/tizen-studio/common-tools/certificate-registration here] and generate the security profile in order to run applications.&lt;br /&gt;
&lt;br /&gt;
== Step 3: Create Basic Project ==&lt;br /&gt;
&lt;br /&gt;
Follow the [https://docs.tizen.org/application/web/get-started/tv/first-samsung-tv-app/ step-by-step guide] and create the Basic Project template. &lt;br /&gt;
Replace the code in the&amp;lt;syntaxhighlight&amp;gt;index.html&amp;lt;/syntaxhighlight&amp;gt;file with the code snippet below and update the App ID with a Nielsen provided App ID during SDK initialization.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;en&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
    &amp;lt;meta charset=&amp;quot;UTF-8&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta http-equiv=&amp;quot;X-UA-Compatible&amp;quot; content=&amp;quot;IE=edge&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;viewport&amp;quot; content=&amp;quot;width=device-width, initial-scale=1.0&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;DCR Video Tizen Sample&amp;lt;/title&amp;gt;&lt;br /&gt;
    &amp;lt;script&amp;gt;&lt;br /&gt;
        // Static Queue Snippet&lt;br /&gt;
        !function (e, n) {&lt;br /&gt;
            function t(e) {&lt;br /&gt;
                return &amp;quot;object&amp;quot; == typeof e ? JSON.parse(JSON.stringify(e)) : e&lt;br /&gt;
            }&lt;br /&gt;
            e[n] = e[n] ||&lt;br /&gt;
            {&lt;br /&gt;
                nlsQ: function (o, r, c) {&lt;br /&gt;
                    var s = e.document,&lt;br /&gt;
                        a = s.createElement(&amp;quot;script&amp;quot;);&lt;br /&gt;
                    a.async = 1,&lt;br /&gt;
                        a.src = (&amp;quot;http:&amp;quot; === e.location.protocol ? &amp;quot;http:&amp;quot; : &amp;quot;https:&amp;quot;) + &amp;quot;//cdn-gl.imrworldwide.com/conf/&amp;quot; + o + &amp;quot;.js#name=&amp;quot; + r + &amp;quot;&amp;amp;ns=&amp;quot; + n;&lt;br /&gt;
                    var i = s.getElementsByTagName(&amp;quot;script&amp;quot;)[0];&lt;br /&gt;
                    return i.parentNode.insertBefore(a, i),&lt;br /&gt;
                        e[n][r] = e[n][r] || {&lt;br /&gt;
                            g: c || {},&lt;br /&gt;
                            ggPM: function (o, c, s, a, i) { e[n][r].q = e[n][r].q || []; try { var l = t([o, c, s, a, i]); e[n][r].q.push(l) } catch (e) { console &amp;amp;&amp;amp; console.log &amp;amp;&amp;amp; console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;) } },&lt;br /&gt;
                            trackEvent: function (o) { e[n][r].te = e[n][r].te || []; try { var c = t(o); e[n][r].te.push(c) } catch (e) { console &amp;amp;&amp;amp; console.log &amp;amp;&amp;amp; console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;) } }&lt;br /&gt;
                        },&lt;br /&gt;
                        e[n][r]&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }(window, &amp;quot;NOLBUNDLE&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        // Replace (PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX) with CLIENT APP ID&lt;br /&gt;
        var nSdkInstance = NOLBUNDLE.nlsQ(&amp;quot;PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;, &amp;quot;videoSdkInstance&amp;quot;, {&lt;br /&gt;
            nol_sdkDebug: &amp;quot;debug&amp;quot;,&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        var contentMetadata = {&lt;br /&gt;
            type: 'content',&lt;br /&gt;
            assetid: 'VID-123456',&lt;br /&gt;
            program: 'program name',&lt;br /&gt;
            title: 'episode title with season and episode number',&lt;br /&gt;
            length: 'length in seconds',&lt;br /&gt;
            airdate: '20210321 09:00:00',&lt;br /&gt;
            isfullepisode: 'y',&lt;br /&gt;
            adloadtype: '2'&lt;br /&gt;
        };&lt;br /&gt;
    &amp;lt;/script&amp;gt;&lt;br /&gt;
    &amp;lt;style&amp;gt;&lt;br /&gt;
        body {&lt;br /&gt;
            background-color: white;&lt;br /&gt;
        }&lt;br /&gt;
    &amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
    &amp;lt;h1&amp;gt;DCR Video Tizen Sample App&amp;lt;/h1&amp;gt;&lt;br /&gt;
    &amp;lt;div&amp;gt;&lt;br /&gt;
      &amp;lt;video controls src=&amp;quot;https://archive.org/download/BigBuckBunny_124/Content/big_buck_bunny_720p_surround.mp4&amp;quot;&lt;br /&gt;
        poster=&amp;quot;https://peach.blender.org/wp-content/uploads/title_anouncement.jpg?x11217&amp;quot; width=&amp;quot;620&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
        Sorry, your browser doesn't support embedded videos,&lt;br /&gt;
        but don't worry, you can &amp;lt;a href=&amp;quot;https://archive.org/details/BigBuckBunny_124&amp;quot;&amp;gt;download it&amp;lt;/a&amp;gt;&lt;br /&gt;
        and watch it with your favorite video player!&lt;br /&gt;
      &amp;lt;/video&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;/main&amp;gt;&lt;br /&gt;
    &amp;lt;script&amp;gt;&lt;br /&gt;
        var media = document.querySelector('video');&lt;br /&gt;
        var playheadPosition = 0;&lt;br /&gt;
        var metadataLoaded = false;&lt;br /&gt;
&lt;br /&gt;
        // Loadmetadata&lt;br /&gt;
        // Load contentMetadata object&lt;br /&gt;
        media.addEventListener('loadedmetadata', (event) =&amp;gt; {&lt;br /&gt;
            // Call SDK loadmetadata event&lt;br /&gt;
            if (!metadataLoaded) {&lt;br /&gt;
                nSdkInstance.ggPM(&amp;quot;loadmetadata&amp;quot;, contentMetadata);&lt;br /&gt;
                metadataLoaded = true;&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        media.addEventListener('play', (event) =&amp;gt; {&lt;br /&gt;
            // Call SDK play event&lt;br /&gt;
            if (!metadataLoaded) {&lt;br /&gt;
                nSdkInstance.ggPM(&amp;quot;loadmetadata&amp;quot;, contentMetadata);&lt;br /&gt;
                metadataLoaded = true;&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        // Player paused&lt;br /&gt;
        media.addEventListener('pause', function (e) {&lt;br /&gt;
            nSdkInstance.ggPM(&amp;quot;pause&amp;quot;, playheadPosition);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        // Set playhead position&lt;br /&gt;
        media.addEventListener('timeupdate', function (e) {&lt;br /&gt;
            var currTime = Math.floor(media.currentTime);&lt;br /&gt;
            if (playheadPosition &amp;lt; currTime) {&lt;br /&gt;
                playheadPosition = currTime;&lt;br /&gt;
                nSdkInstance.ggPM(&amp;quot;setplayheadposition&amp;quot;, playheadPosition);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        // End&lt;br /&gt;
        media.addEventListener('ended', function (e) {&lt;br /&gt;
            nSdkInstance.ggPM(&amp;quot;end&amp;quot;, playheadPosition);&lt;br /&gt;
            metadataLoaded = false;&lt;br /&gt;
            playheadPosition = 0;&lt;br /&gt;
        });&lt;br /&gt;
    &amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Step 4: Run Project==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;Right click on the project &amp;gt; Run As &amp;gt; Tizen Web Simulator Application (Samsung TV)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Tizen 1 Step4.png||600px|center|]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Extra configurations must be done to run and debug the application on a Target Device, please reference the following [[TizenTv_Debugging|guide]] for more information&lt;br /&gt;
&lt;br /&gt;
== Step 5: Debug App==&lt;br /&gt;
Right click anywhere in the Simulator to open the Web Inspector &amp;gt; navigate to the Console tab &amp;gt; check for BSDK initialization and content measurement.&lt;br /&gt;
[[File:Tizen 1 Step5.png||600px|center|]]&lt;br /&gt;
&lt;br /&gt;
Debug Logging: Disable logging by deleting &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;{nol_sdkDebug: 'debug'}&amp;lt;/syntaxhighlight&amp;gt; from initialization call&lt;br /&gt;
&lt;br /&gt;
== Remote control events ==&lt;br /&gt;
Build out the app further by including [https://developer.samsung.com/smarttv/develop/guides/user-interaction/remote-control.html remote control events] and attaching the player events to corresponding &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;keyCode &amp;lt;/syntaxhighlight&amp;gt; or using Tizen registered keys:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
var media = document.querySelector('video');&lt;br /&gt;
window.addEventListener(&amp;quot;keydown&amp;quot;, function (e) {&lt;br /&gt;
    switch (e.keyCode) {&lt;br /&gt;
        case 10252: // MediaPlayPause&lt;br /&gt;
            if(!media.paused) {&lt;br /&gt;
                media.pause(); // pause video&lt;br /&gt;
                nSdkInstance.ggPM(&amp;quot;pause&amp;quot;, playheadPosition); // SDK call&lt;br /&gt;
                break;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            media.play(); // play video&lt;br /&gt;
            nSdkInstance.ggPM(&amp;quot;play&amp;quot;, contentMetadata); // SDK call&lt;br /&gt;
            break;&lt;br /&gt;
        case 10009: // Back&lt;br /&gt;
            nSdkInstance.ggPM(&amp;quot;stop&amp;quot;, playheadPosition); // SDK call&lt;br /&gt;
            break;&lt;br /&gt;
        ...&lt;br /&gt;
        default:&lt;br /&gt;
            break;&lt;br /&gt;
    }&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Next steps ==&lt;br /&gt;
&lt;br /&gt;
For further testing Samsung Tizen TV apps, refer to this [https://docs.tizen.org/application/web/tutorials/process/run-debug-app/ guide]. If there are any questions or concerns then please reach out to the BSDK team. Reference the following guides for product specific information:&lt;br /&gt;
&lt;br /&gt;
* [[DCR_Video_Browser_SDK|DCR Video]]&lt;br /&gt;
* [[DCR_Static_Browser_SDK_(6.0.0)|DCR Static]]&lt;br /&gt;
* [[DTVR_Browser_SDK|DTVR]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
For further technical details or a sample application, please contact your Technical Account Manager (TAM).&lt;/div&gt;</summary>
		<author><name>AnkitAgrawal</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=Digital_Measurement_Video_TizenTv&amp;diff=6719</id>
		<title>Digital Measurement Video TizenTv</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=Digital_Measurement_Video_TizenTv&amp;diff=6719"/>
		<updated>2024-06-10T18:46:55Z</updated>

		<summary type="html">&lt;p&gt;AnkitAgrawal: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|DCR &amp;amp; DTVR}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
__NOTOC__&lt;br /&gt;
== Introduction ==&lt;br /&gt;
The following document will highlight the steps needed to run Browser SDK (BSDK) on Samsung Smart TV using TIzen Studio for app development.&lt;br /&gt;
The tutorial should be used in conjunction with the documentation at [https://docs.tizen.org/application/web/get-started/tv/first-samsung-tv-app/ Create Your First Samsung Smart TV Web Application] to build an app with BSDK integration for content measurement. In this tutorial we will create a native app and highlight the different permissions required to run the BSDK.&lt;br /&gt;
&lt;br /&gt;
== Step 1: Install Tizen Studio ==&lt;br /&gt;
&lt;br /&gt;
Navigate [https://developer.tizen.org/development/tizen-studio/download here] and install Tizen Studio.&lt;br /&gt;
During installation make sure to install the '''TV Extensions package''' from the Package Manager.&lt;br /&gt;
&lt;br /&gt;
== Step 2: Generate Security Profile ==&lt;br /&gt;
&lt;br /&gt;
Navigate [https://docs.tizen.org/application/tizen-studio/common-tools/certificate-registration here] and generate the security profile in order to run applications.&lt;br /&gt;
&lt;br /&gt;
== Step 3: Create Basic Project ==&lt;br /&gt;
&lt;br /&gt;
Follow the [https://docs.tizen.org/application/web/get-started/tv/first-samsung-tv-app/ step-by-step guide] and create the Basic Project template. &lt;br /&gt;
Replace the code in the&amp;lt;syntaxhighlight&amp;gt;index.html&amp;lt;/syntaxhighlight&amp;gt;file with the code snippet below and update the App ID with a Nielsen provided App ID during SDK initialization.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;en&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
    &amp;lt;meta charset=&amp;quot;UTF-8&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta http-equiv=&amp;quot;X-UA-Compatible&amp;quot; content=&amp;quot;IE=edge&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;viewport&amp;quot; content=&amp;quot;width=device-width, initial-scale=1.0&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;DCR Video Tizen Sample&amp;lt;/title&amp;gt;&lt;br /&gt;
    &amp;lt;script&amp;gt;&lt;br /&gt;
        // Static Queue Snippet&lt;br /&gt;
        !function (e, n) {&lt;br /&gt;
            function t(e) {&lt;br /&gt;
                return &amp;quot;object&amp;quot; == typeof e ? JSON.parse(JSON.stringify(e)) : e&lt;br /&gt;
            }&lt;br /&gt;
            e[n] = e[n] ||&lt;br /&gt;
            {&lt;br /&gt;
                nlsQ: function (o, r, c) {&lt;br /&gt;
                    var s = e.document,&lt;br /&gt;
                        a = s.createElement(&amp;quot;script&amp;quot;);&lt;br /&gt;
                    a.async = 1,&lt;br /&gt;
                        a.src = (&amp;quot;http:&amp;quot; === e.location.protocol ? &amp;quot;http:&amp;quot; : &amp;quot;https:&amp;quot;) + &amp;quot;//cdn-gl.imrworldwide.com/conf/&amp;quot; + o + &amp;quot;.js#name=&amp;quot; + r + &amp;quot;&amp;amp;ns=&amp;quot; + n;&lt;br /&gt;
                    var i = s.getElementsByTagName(&amp;quot;script&amp;quot;)[0];&lt;br /&gt;
                    return i.parentNode.insertBefore(a, i),&lt;br /&gt;
                        e[n][r] = e[n][r] || {&lt;br /&gt;
                            g: c || {},&lt;br /&gt;
                            ggPM: function (o, c, s, a, i) { e[n][r].q = e[n][r].q || []; try { var l = t([o, c, s, a, i]); e[n][r].q.push(l) } catch (e) { console &amp;amp;&amp;amp; console.log &amp;amp;&amp;amp; console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;) } },&lt;br /&gt;
                            trackEvent: function (o) { e[n][r].te = e[n][r].te || []; try { var c = t(o); e[n][r].te.push(c) } catch (e) { console &amp;amp;&amp;amp; console.log &amp;amp;&amp;amp; console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;) } }&lt;br /&gt;
                        },&lt;br /&gt;
                        e[n][r]&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }(window, &amp;quot;NOLBUNDLE&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        // Replace (PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX) with CLIENT APP ID&lt;br /&gt;
        var nSdkInstance = NOLBUNDLE.nlsQ(&amp;quot;PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;, &amp;quot;videoSdkInstance&amp;quot;, {&lt;br /&gt;
            nol_sdkDebug: &amp;quot;debug&amp;quot;,&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        var contentMetadata = {&lt;br /&gt;
            type: 'content',&lt;br /&gt;
            assetid: 'VID-123456',&lt;br /&gt;
            program: 'program name',&lt;br /&gt;
            title: 'episode title with season and episode number',&lt;br /&gt;
            length: 'length in seconds',&lt;br /&gt;
            airdate: '20210321 09:00:00',&lt;br /&gt;
            isfullepisode: 'y',&lt;br /&gt;
            adloadtype: '2'&lt;br /&gt;
        };&lt;br /&gt;
    &amp;lt;/script&amp;gt;&lt;br /&gt;
    &amp;lt;style&amp;gt;&lt;br /&gt;
        body {&lt;br /&gt;
            background-color: white;&lt;br /&gt;
        }&lt;br /&gt;
    &amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
    &amp;lt;h1&amp;gt;DCR Video Tizen Sample App&amp;lt;/h1&amp;gt;&lt;br /&gt;
    &amp;lt;div&amp;gt;&lt;br /&gt;
      &amp;lt;video controls src=&amp;quot;https://archive.org/download/BigBuckBunny_124/Content/big_buck_bunny_720p_surround.mp4&amp;quot;&lt;br /&gt;
        poster=&amp;quot;https://peach.blender.org/wp-content/uploads/title_anouncement.jpg?x11217&amp;quot; width=&amp;quot;620&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
        Sorry, your browser doesn't support embedded videos,&lt;br /&gt;
        but don't worry, you can &amp;lt;a href=&amp;quot;https://archive.org/details/BigBuckBunny_124&amp;quot;&amp;gt;download it&amp;lt;/a&amp;gt;&lt;br /&gt;
        and watch it with your favorite video player!&lt;br /&gt;
      &amp;lt;/video&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;/main&amp;gt;&lt;br /&gt;
    &amp;lt;script&amp;gt;&lt;br /&gt;
        var media = document.querySelector('video');&lt;br /&gt;
        var playheadPosition = 0;&lt;br /&gt;
        var metadataLoaded = false;&lt;br /&gt;
&lt;br /&gt;
        // Loadmetadata&lt;br /&gt;
        // Load contentMetadata object&lt;br /&gt;
        media.addEventListener('loadedmetadata', (event) =&amp;gt; {&lt;br /&gt;
            // Call SDK loadmetadata event&lt;br /&gt;
            if (!metadataLoaded) {&lt;br /&gt;
                nSdkInstance.ggPM(&amp;quot;loadmetadata&amp;quot;, contentMetadata);&lt;br /&gt;
                metadataLoaded = true;&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        media.addEventListener('play', (event) =&amp;gt; {&lt;br /&gt;
            // Call SDK play event&lt;br /&gt;
            if (!metadataLoaded) {&lt;br /&gt;
                nSdkInstance.ggPM(&amp;quot;loadmetadata&amp;quot;, contentMetadata);&lt;br /&gt;
                metadataLoaded = true;&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        // Player paused&lt;br /&gt;
        media.addEventListener('pause', function (e) {&lt;br /&gt;
            nSdkInstance.ggPM(&amp;quot;pause&amp;quot;, playheadPosition);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        // Set playhead position&lt;br /&gt;
        media.addEventListener('timeupdate', function (e) {&lt;br /&gt;
            var currTime = Math.floor(media.currentTime);&lt;br /&gt;
            if (playheadPosition &amp;lt; currTime) {&lt;br /&gt;
                playheadPosition = currTime;&lt;br /&gt;
                nSdkInstance.ggPM(&amp;quot;setplayheadposition&amp;quot;, playheadPosition);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        // End&lt;br /&gt;
        media.addEventListener('ended', function (e) {&lt;br /&gt;
            nSdkInstance.ggPM(&amp;quot;end&amp;quot;, playheadPosition);&lt;br /&gt;
            metadataLoaded = false;&lt;br /&gt;
            playheadPosition = 0;&lt;br /&gt;
        });&lt;br /&gt;
    &amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Step 4: Run Project==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;Right click on the project &amp;gt; Run As &amp;gt; Tizen Web Simulator Application (Samsung TV)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Tizen 1 Step4.png||600px|center|]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Extra configurations must be done to run and debug the application on a Target Device, please reference the following [[TizenTv_Debugging|guide]] for more information&lt;br /&gt;
&lt;br /&gt;
== Step 5: Debug App==&lt;br /&gt;
Right click anywhere in the Simulator to open the Web Inspector &amp;gt; navigate to the Console tab &amp;gt; check for BSDK initialization and content measurement.&lt;br /&gt;
[[File:Tizen 1 Step5.png||600px|center|]]&lt;br /&gt;
&lt;br /&gt;
Debug Logging: Disable logging by deleting &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;{nol_sdkDebug: 'debug'}&amp;lt;/syntaxhighlight&amp;gt; from initialization call&lt;br /&gt;
&lt;br /&gt;
== Remote control events ==&lt;br /&gt;
Build out the app further by including [https://developer.samsung.com/smarttv/develop/guides/user-interaction/remote-control.html remote control events] and attaching the player events to corresponding &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;keyCode &amp;lt;/syntaxhighlight&amp;gt; or using Tizen registered keys:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
var media = document.querySelector('video');&lt;br /&gt;
window.addEventListener(&amp;quot;keydown&amp;quot;, function (e) {&lt;br /&gt;
    switch (e.keyCode) {&lt;br /&gt;
        case 10252: // MediaPlayPause&lt;br /&gt;
            if(!media.paused) {&lt;br /&gt;
                media.pause(); // pause video&lt;br /&gt;
                nSdkInstance.ggPM(&amp;quot;pause&amp;quot;, playheadPosition); // SDK call&lt;br /&gt;
                break;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            media.play(); // play video&lt;br /&gt;
            nSdkInstance.ggPM(&amp;quot;play&amp;quot;, contentMetadata); // SDK call&lt;br /&gt;
            break;&lt;br /&gt;
        case 10009: // Back&lt;br /&gt;
            nSdkInstance.ggPM(&amp;quot;stop&amp;quot;, playheadPosition); // SDK call&lt;br /&gt;
            break;&lt;br /&gt;
        ...&lt;br /&gt;
        default:&lt;br /&gt;
            break;&lt;br /&gt;
    }&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Next steps ==&lt;br /&gt;
&lt;br /&gt;
For further testing Samsung Tizen TV apps, refer to this [https://docs.tizen.org/application/web/tutorials/process/run-debug-app/ guide]. If there are any questions or concerns then please reach out to the BSDK team. Reference the following guides for product specific information:&lt;br /&gt;
&lt;br /&gt;
* [[DCR_Video_Browser_SDK|DCR Video]]&lt;br /&gt;
* [[DCR_Static_Browser_SDK_(6.0.0)|DCR Static]]&lt;br /&gt;
* [[DTVR_Browser_SDK|DTVR]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
For further technical details or a sample application, please contact your Technical Account Manager (TAM).&lt;/div&gt;</summary>
		<author><name>AnkitAgrawal</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=Digital_Measurement_Video_TizenTv&amp;diff=6718</id>
		<title>Digital Measurement Video TizenTv</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=Digital_Measurement_Video_TizenTv&amp;diff=6718"/>
		<updated>2024-06-10T18:46:27Z</updated>

		<summary type="html">&lt;p&gt;AnkitAgrawal: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|DCR &amp;amp; DTVR}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
__NOTOC__&lt;br /&gt;
== Introduction ==&lt;br /&gt;
The following document will highlight the steps needed to run Browser SDK (BSDK) on Samsung Smart TV using TIzen Studio for app development.&lt;br /&gt;
The tutorial should be used in conjunction with the documentation at [https://docs.tizen.org/application/web/get-started/tv/first-samsung-tv-app/ Create Your First Samsung Smart TV Web Application] to build an app with BSDK integration for content measurement. In this tutorial we will create a native app and highlight the different permissions required to run the BSDK.&lt;br /&gt;
&lt;br /&gt;
== Step 1: Install Tizen Studio ==&lt;br /&gt;
&lt;br /&gt;
Navigate [https://developer.tizen.org/development/tizen-studio/download here] and install Tizen Studio.&lt;br /&gt;
During installation make sure to install the '''TV Extension package''' from the Package Manager.&lt;br /&gt;
&lt;br /&gt;
== Step 2: Generate Security Profile ==&lt;br /&gt;
&lt;br /&gt;
Navigate [https://docs.tizen.org/application/tizen-studio/common-tools/certificate-registration here] and generate the security profile in order to run applications.&lt;br /&gt;
&lt;br /&gt;
== Step 3: Create Basic Project ==&lt;br /&gt;
&lt;br /&gt;
Follow the [https://docs.tizen.org/application/web/get-started/tv/first-samsung-tv-app/ step-by-step guide] and create the Basic Project template. &lt;br /&gt;
Replace the code in the&amp;lt;syntaxhighlight&amp;gt;index.html&amp;lt;/syntaxhighlight&amp;gt;file with the code snippet below and update the App ID with a Nielsen provided App ID during SDK initialization.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;en&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
    &amp;lt;meta charset=&amp;quot;UTF-8&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta http-equiv=&amp;quot;X-UA-Compatible&amp;quot; content=&amp;quot;IE=edge&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;viewport&amp;quot; content=&amp;quot;width=device-width, initial-scale=1.0&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;DCR Video Tizen Sample&amp;lt;/title&amp;gt;&lt;br /&gt;
    &amp;lt;script&amp;gt;&lt;br /&gt;
        // Static Queue Snippet&lt;br /&gt;
        !function (e, n) {&lt;br /&gt;
            function t(e) {&lt;br /&gt;
                return &amp;quot;object&amp;quot; == typeof e ? JSON.parse(JSON.stringify(e)) : e&lt;br /&gt;
            }&lt;br /&gt;
            e[n] = e[n] ||&lt;br /&gt;
            {&lt;br /&gt;
                nlsQ: function (o, r, c) {&lt;br /&gt;
                    var s = e.document,&lt;br /&gt;
                        a = s.createElement(&amp;quot;script&amp;quot;);&lt;br /&gt;
                    a.async = 1,&lt;br /&gt;
                        a.src = (&amp;quot;http:&amp;quot; === e.location.protocol ? &amp;quot;http:&amp;quot; : &amp;quot;https:&amp;quot;) + &amp;quot;//cdn-gl.imrworldwide.com/conf/&amp;quot; + o + &amp;quot;.js#name=&amp;quot; + r + &amp;quot;&amp;amp;ns=&amp;quot; + n;&lt;br /&gt;
                    var i = s.getElementsByTagName(&amp;quot;script&amp;quot;)[0];&lt;br /&gt;
                    return i.parentNode.insertBefore(a, i),&lt;br /&gt;
                        e[n][r] = e[n][r] || {&lt;br /&gt;
                            g: c || {},&lt;br /&gt;
                            ggPM: function (o, c, s, a, i) { e[n][r].q = e[n][r].q || []; try { var l = t([o, c, s, a, i]); e[n][r].q.push(l) } catch (e) { console &amp;amp;&amp;amp; console.log &amp;amp;&amp;amp; console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;) } },&lt;br /&gt;
                            trackEvent: function (o) { e[n][r].te = e[n][r].te || []; try { var c = t(o); e[n][r].te.push(c) } catch (e) { console &amp;amp;&amp;amp; console.log &amp;amp;&amp;amp; console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;) } }&lt;br /&gt;
                        },&lt;br /&gt;
                        e[n][r]&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }(window, &amp;quot;NOLBUNDLE&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        // Replace (PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX) with CLIENT APP ID&lt;br /&gt;
        var nSdkInstance = NOLBUNDLE.nlsQ(&amp;quot;PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;, &amp;quot;videoSdkInstance&amp;quot;, {&lt;br /&gt;
            nol_sdkDebug: &amp;quot;debug&amp;quot;,&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        var contentMetadata = {&lt;br /&gt;
            type: 'content',&lt;br /&gt;
            assetid: 'VID-123456',&lt;br /&gt;
            program: 'program name',&lt;br /&gt;
            title: 'episode title with season and episode number',&lt;br /&gt;
            length: 'length in seconds',&lt;br /&gt;
            airdate: '20210321 09:00:00',&lt;br /&gt;
            isfullepisode: 'y',&lt;br /&gt;
            adloadtype: '2'&lt;br /&gt;
        };&lt;br /&gt;
    &amp;lt;/script&amp;gt;&lt;br /&gt;
    &amp;lt;style&amp;gt;&lt;br /&gt;
        body {&lt;br /&gt;
            background-color: white;&lt;br /&gt;
        }&lt;br /&gt;
    &amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
    &amp;lt;h1&amp;gt;DCR Video Tizen Sample App&amp;lt;/h1&amp;gt;&lt;br /&gt;
    &amp;lt;div&amp;gt;&lt;br /&gt;
      &amp;lt;video controls src=&amp;quot;https://archive.org/download/BigBuckBunny_124/Content/big_buck_bunny_720p_surround.mp4&amp;quot;&lt;br /&gt;
        poster=&amp;quot;https://peach.blender.org/wp-content/uploads/title_anouncement.jpg?x11217&amp;quot; width=&amp;quot;620&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
        Sorry, your browser doesn't support embedded videos,&lt;br /&gt;
        but don't worry, you can &amp;lt;a href=&amp;quot;https://archive.org/details/BigBuckBunny_124&amp;quot;&amp;gt;download it&amp;lt;/a&amp;gt;&lt;br /&gt;
        and watch it with your favorite video player!&lt;br /&gt;
      &amp;lt;/video&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;/main&amp;gt;&lt;br /&gt;
    &amp;lt;script&amp;gt;&lt;br /&gt;
        var media = document.querySelector('video');&lt;br /&gt;
        var playheadPosition = 0;&lt;br /&gt;
        var metadataLoaded = false;&lt;br /&gt;
&lt;br /&gt;
        // Loadmetadata&lt;br /&gt;
        // Load contentMetadata object&lt;br /&gt;
        media.addEventListener('loadedmetadata', (event) =&amp;gt; {&lt;br /&gt;
            // Call SDK loadmetadata event&lt;br /&gt;
            if (!metadataLoaded) {&lt;br /&gt;
                nSdkInstance.ggPM(&amp;quot;loadmetadata&amp;quot;, contentMetadata);&lt;br /&gt;
                metadataLoaded = true;&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        media.addEventListener('play', (event) =&amp;gt; {&lt;br /&gt;
            // Call SDK play event&lt;br /&gt;
            if (!metadataLoaded) {&lt;br /&gt;
                nSdkInstance.ggPM(&amp;quot;loadmetadata&amp;quot;, contentMetadata);&lt;br /&gt;
                metadataLoaded = true;&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        // Player paused&lt;br /&gt;
        media.addEventListener('pause', function (e) {&lt;br /&gt;
            nSdkInstance.ggPM(&amp;quot;pause&amp;quot;, playheadPosition);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        // Set playhead position&lt;br /&gt;
        media.addEventListener('timeupdate', function (e) {&lt;br /&gt;
            var currTime = Math.floor(media.currentTime);&lt;br /&gt;
            if (playheadPosition &amp;lt; currTime) {&lt;br /&gt;
                playheadPosition = currTime;&lt;br /&gt;
                nSdkInstance.ggPM(&amp;quot;setplayheadposition&amp;quot;, playheadPosition);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        // End&lt;br /&gt;
        media.addEventListener('ended', function (e) {&lt;br /&gt;
            nSdkInstance.ggPM(&amp;quot;end&amp;quot;, playheadPosition);&lt;br /&gt;
            metadataLoaded = false;&lt;br /&gt;
            playheadPosition = 0;&lt;br /&gt;
        });&lt;br /&gt;
    &amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Step 4: Run Project==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;Right click on the project &amp;gt; Run As &amp;gt; Tizen Web Simulator Application (Samsung TV)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Tizen 1 Step4.png||600px|center|]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Extra configurations must be done to run and debug the application on a Target Device, please reference the following [[TizenTv_Debugging|guide]] for more information&lt;br /&gt;
&lt;br /&gt;
== Step 5: Debug App==&lt;br /&gt;
Right click anywhere in the Simulator to open the Web Inspector &amp;gt; navigate to the Console tab &amp;gt; check for BSDK initialization and content measurement.&lt;br /&gt;
[[File:Tizen 1 Step5.png||600px|center|]]&lt;br /&gt;
&lt;br /&gt;
Debug Logging: Disable logging by deleting &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;{nol_sdkDebug: 'debug'}&amp;lt;/syntaxhighlight&amp;gt; from initialization call&lt;br /&gt;
&lt;br /&gt;
== Remote control events ==&lt;br /&gt;
Build out the app further by including [https://developer.samsung.com/smarttv/develop/guides/user-interaction/remote-control.html remote control events] and attaching the player events to corresponding &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;keyCode &amp;lt;/syntaxhighlight&amp;gt; or using Tizen registered keys:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
var media = document.querySelector('video');&lt;br /&gt;
window.addEventListener(&amp;quot;keydown&amp;quot;, function (e) {&lt;br /&gt;
    switch (e.keyCode) {&lt;br /&gt;
        case 10252: // MediaPlayPause&lt;br /&gt;
            if(!media.paused) {&lt;br /&gt;
                media.pause(); // pause video&lt;br /&gt;
                nSdkInstance.ggPM(&amp;quot;pause&amp;quot;, playheadPosition); // SDK call&lt;br /&gt;
                break;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            media.play(); // play video&lt;br /&gt;
            nSdkInstance.ggPM(&amp;quot;play&amp;quot;, contentMetadata); // SDK call&lt;br /&gt;
            break;&lt;br /&gt;
        case 10009: // Back&lt;br /&gt;
            nSdkInstance.ggPM(&amp;quot;stop&amp;quot;, playheadPosition); // SDK call&lt;br /&gt;
            break;&lt;br /&gt;
        ...&lt;br /&gt;
        default:&lt;br /&gt;
            break;&lt;br /&gt;
    }&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Next steps ==&lt;br /&gt;
&lt;br /&gt;
For further testing Samsung Tizen TV apps, refer to this [https://docs.tizen.org/application/web/tutorials/process/run-debug-app/ guide]. If there are any questions or concerns then please reach out to the BSDK team. Reference the following guides for product specific information:&lt;br /&gt;
&lt;br /&gt;
* [[DCR_Video_Browser_SDK|DCR Video]]&lt;br /&gt;
* [[DCR_Static_Browser_SDK_(6.0.0)|DCR Static]]&lt;br /&gt;
* [[DTVR_Browser_SDK|DTVR]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
For further technical details or a sample application, please contact your Technical Account Manager (TAM).&lt;/div&gt;</summary>
		<author><name>AnkitAgrawal</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=Digital_Measurement_Video_TizenTv&amp;diff=6717</id>
		<title>Digital Measurement Video TizenTv</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=Digital_Measurement_Video_TizenTv&amp;diff=6717"/>
		<updated>2024-06-10T18:45:17Z</updated>

		<summary type="html">&lt;p&gt;AnkitAgrawal: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|DCR &amp;amp; DTVR}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
__NOTOC__&lt;br /&gt;
== Introduction ==&lt;br /&gt;
The following document will highlight the steps needed to run Browser SDK (BSDK) on Samsung Smart TV using TIzen Studio for app development.&lt;br /&gt;
The tutorial should be used in conjunction with the documentation at [https://docs.tizen.org/application/web/get-started/tv/first-samsung-tv-app/ Create Your First Samsung Smart TV Web Application] to build an app with BSDK integration for content measurement. In this tutorial we will create a native app and highlight the different permissions required to run the BSDK.&lt;br /&gt;
&lt;br /&gt;
== Step 1: Install Tizen Studio ==&lt;br /&gt;
&lt;br /&gt;
Navigate [https://developer.tizen.org/development/tizen-studio/download here] and install Tizen Studio.&lt;br /&gt;
During installation make sure to install the '''TV Extension's package''' from the Package Manager.&lt;br /&gt;
&lt;br /&gt;
== Step 2: Generate Security Profile ==&lt;br /&gt;
&lt;br /&gt;
Navigate [https://docs.tizen.org/application/tizen-studio/common-tools/certificate-registration here] and generate the security profile in order to run applications.&lt;br /&gt;
&lt;br /&gt;
== Step 3: Create Basic Project ==&lt;br /&gt;
&lt;br /&gt;
Follow the [https://docs.tizen.org/application/web/get-started/tv/first-samsung-tv-app/ step-by-step guide] and create the Basic Project template. &lt;br /&gt;
Replace the code in the&amp;lt;syntaxhighlight&amp;gt;index.html&amp;lt;/syntaxhighlight&amp;gt;file with the code snippet below and update the App ID with a Nielsen provided App ID during SDK initialization.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;en&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
    &amp;lt;meta charset=&amp;quot;UTF-8&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta http-equiv=&amp;quot;X-UA-Compatible&amp;quot; content=&amp;quot;IE=edge&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;meta name=&amp;quot;viewport&amp;quot; content=&amp;quot;width=device-width, initial-scale=1.0&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;DCR Video Tizen Sample&amp;lt;/title&amp;gt;&lt;br /&gt;
    &amp;lt;script&amp;gt;&lt;br /&gt;
        // Static Queue Snippet&lt;br /&gt;
        !function (e, n) {&lt;br /&gt;
            function t(e) {&lt;br /&gt;
                return &amp;quot;object&amp;quot; == typeof e ? JSON.parse(JSON.stringify(e)) : e&lt;br /&gt;
            }&lt;br /&gt;
            e[n] = e[n] ||&lt;br /&gt;
            {&lt;br /&gt;
                nlsQ: function (o, r, c) {&lt;br /&gt;
                    var s = e.document,&lt;br /&gt;
                        a = s.createElement(&amp;quot;script&amp;quot;);&lt;br /&gt;
                    a.async = 1,&lt;br /&gt;
                        a.src = (&amp;quot;http:&amp;quot; === e.location.protocol ? &amp;quot;http:&amp;quot; : &amp;quot;https:&amp;quot;) + &amp;quot;//cdn-gl.imrworldwide.com/conf/&amp;quot; + o + &amp;quot;.js#name=&amp;quot; + r + &amp;quot;&amp;amp;ns=&amp;quot; + n;&lt;br /&gt;
                    var i = s.getElementsByTagName(&amp;quot;script&amp;quot;)[0];&lt;br /&gt;
                    return i.parentNode.insertBefore(a, i),&lt;br /&gt;
                        e[n][r] = e[n][r] || {&lt;br /&gt;
                            g: c || {},&lt;br /&gt;
                            ggPM: function (o, c, s, a, i) { e[n][r].q = e[n][r].q || []; try { var l = t([o, c, s, a, i]); e[n][r].q.push(l) } catch (e) { console &amp;amp;&amp;amp; console.log &amp;amp;&amp;amp; console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;) } },&lt;br /&gt;
                            trackEvent: function (o) { e[n][r].te = e[n][r].te || []; try { var c = t(o); e[n][r].te.push(c) } catch (e) { console &amp;amp;&amp;amp; console.log &amp;amp;&amp;amp; console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;) } }&lt;br /&gt;
                        },&lt;br /&gt;
                        e[n][r]&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }(window, &amp;quot;NOLBUNDLE&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        // Replace (PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX) with CLIENT APP ID&lt;br /&gt;
        var nSdkInstance = NOLBUNDLE.nlsQ(&amp;quot;PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;, &amp;quot;videoSdkInstance&amp;quot;, {&lt;br /&gt;
            nol_sdkDebug: &amp;quot;debug&amp;quot;,&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        var contentMetadata = {&lt;br /&gt;
            type: 'content',&lt;br /&gt;
            assetid: 'VID-123456',&lt;br /&gt;
            program: 'program name',&lt;br /&gt;
            title: 'episode title with season and episode number',&lt;br /&gt;
            length: 'length in seconds',&lt;br /&gt;
            airdate: '20210321 09:00:00',&lt;br /&gt;
            isfullepisode: 'y',&lt;br /&gt;
            adloadtype: '2'&lt;br /&gt;
        };&lt;br /&gt;
    &amp;lt;/script&amp;gt;&lt;br /&gt;
    &amp;lt;style&amp;gt;&lt;br /&gt;
        body {&lt;br /&gt;
            background-color: white;&lt;br /&gt;
        }&lt;br /&gt;
    &amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
    &amp;lt;h1&amp;gt;DCR Video Tizen Sample App&amp;lt;/h1&amp;gt;&lt;br /&gt;
    &amp;lt;div&amp;gt;&lt;br /&gt;
      &amp;lt;video controls src=&amp;quot;https://archive.org/download/BigBuckBunny_124/Content/big_buck_bunny_720p_surround.mp4&amp;quot;&lt;br /&gt;
        poster=&amp;quot;https://peach.blender.org/wp-content/uploads/title_anouncement.jpg?x11217&amp;quot; width=&amp;quot;620&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
        Sorry, your browser doesn't support embedded videos,&lt;br /&gt;
        but don't worry, you can &amp;lt;a href=&amp;quot;https://archive.org/details/BigBuckBunny_124&amp;quot;&amp;gt;download it&amp;lt;/a&amp;gt;&lt;br /&gt;
        and watch it with your favorite video player!&lt;br /&gt;
      &amp;lt;/video&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;/main&amp;gt;&lt;br /&gt;
    &amp;lt;script&amp;gt;&lt;br /&gt;
        var media = document.querySelector('video');&lt;br /&gt;
        var playheadPosition = 0;&lt;br /&gt;
        var metadataLoaded = false;&lt;br /&gt;
&lt;br /&gt;
        // Loadmetadata&lt;br /&gt;
        // Load contentMetadata object&lt;br /&gt;
        media.addEventListener('loadedmetadata', (event) =&amp;gt; {&lt;br /&gt;
            // Call SDK loadmetadata event&lt;br /&gt;
            if (!metadataLoaded) {&lt;br /&gt;
                nSdkInstance.ggPM(&amp;quot;loadmetadata&amp;quot;, contentMetadata);&lt;br /&gt;
                metadataLoaded = true;&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        media.addEventListener('play', (event) =&amp;gt; {&lt;br /&gt;
            // Call SDK play event&lt;br /&gt;
            if (!metadataLoaded) {&lt;br /&gt;
                nSdkInstance.ggPM(&amp;quot;loadmetadata&amp;quot;, contentMetadata);&lt;br /&gt;
                metadataLoaded = true;&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        // Player paused&lt;br /&gt;
        media.addEventListener('pause', function (e) {&lt;br /&gt;
            nSdkInstance.ggPM(&amp;quot;pause&amp;quot;, playheadPosition);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        // Set playhead position&lt;br /&gt;
        media.addEventListener('timeupdate', function (e) {&lt;br /&gt;
            var currTime = Math.floor(media.currentTime);&lt;br /&gt;
            if (playheadPosition &amp;lt; currTime) {&lt;br /&gt;
                playheadPosition = currTime;&lt;br /&gt;
                nSdkInstance.ggPM(&amp;quot;setplayheadposition&amp;quot;, playheadPosition);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        // End&lt;br /&gt;
        media.addEventListener('ended', function (e) {&lt;br /&gt;
            nSdkInstance.ggPM(&amp;quot;end&amp;quot;, playheadPosition);&lt;br /&gt;
            metadataLoaded = false;&lt;br /&gt;
            playheadPosition = 0;&lt;br /&gt;
        });&lt;br /&gt;
    &amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Step 4: Run Project==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;Right click on the project &amp;gt; Run As &amp;gt; Tizen Web Simulator Application (Samsung TV)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Tizen 1 Step4.png||600px|center|]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Extra configurations must be done to run and debug the application on a Target Device, please reference the following [[TizenTv_Debugging|guide]] for more information&lt;br /&gt;
&lt;br /&gt;
== Step 5: Debug App==&lt;br /&gt;
Right click anywhere in the Simulator to open the Web Inspector &amp;gt; navigate to the Console tab &amp;gt; check for BSDK initialization and content measurement.&lt;br /&gt;
[[File:Tizen 1 Step5.png||600px|center|]]&lt;br /&gt;
&lt;br /&gt;
Debug Logging: Disable logging by deleting &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;{nol_sdkDebug: 'debug'}&amp;lt;/syntaxhighlight&amp;gt; from initialization call&lt;br /&gt;
&lt;br /&gt;
== Remote control events ==&lt;br /&gt;
Build out the app further by including [https://developer.samsung.com/smarttv/develop/guides/user-interaction/remote-control.html remote control events] and attaching the player events to corresponding &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;keyCode &amp;lt;/syntaxhighlight&amp;gt; or using Tizen registered keys:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
var media = document.querySelector('video');&lt;br /&gt;
window.addEventListener(&amp;quot;keydown&amp;quot;, function (e) {&lt;br /&gt;
    switch (e.keyCode) {&lt;br /&gt;
        case 10252: // MediaPlayPause&lt;br /&gt;
            if(!media.paused) {&lt;br /&gt;
                media.pause(); // pause video&lt;br /&gt;
                nSdkInstance.ggPM(&amp;quot;pause&amp;quot;, playheadPosition); // SDK call&lt;br /&gt;
                break;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            media.play(); // play video&lt;br /&gt;
            nSdkInstance.ggPM(&amp;quot;play&amp;quot;, contentMetadata); // SDK call&lt;br /&gt;
            break;&lt;br /&gt;
        case 10009: // Back&lt;br /&gt;
            nSdkInstance.ggPM(&amp;quot;stop&amp;quot;, playheadPosition); // SDK call&lt;br /&gt;
            break;&lt;br /&gt;
        ...&lt;br /&gt;
        default:&lt;br /&gt;
            break;&lt;br /&gt;
    }&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Next steps ==&lt;br /&gt;
&lt;br /&gt;
For further testing Samsung Tizen TV apps, refer to this [https://docs.tizen.org/application/web/tutorials/process/run-debug-app/ guide]. If there are any questions or concerns then please reach out to the BSDK team. Reference the following guides for product specific information:&lt;br /&gt;
&lt;br /&gt;
* [[DCR_Video_Browser_SDK|DCR Video]]&lt;br /&gt;
* [[DCR_Static_Browser_SDK_(6.0.0)|DCR Static]]&lt;br /&gt;
* [[DTVR_Browser_SDK|DTVR]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
For further technical details or a sample application, please contact your Technical Account Manager (TAM).&lt;/div&gt;</summary>
		<author><name>AnkitAgrawal</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=TVOS_SDK_Release_Notes&amp;diff=6657</id>
		<title>TVOS SDK Release Notes</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=TVOS_SDK_Release_Notes&amp;diff=6657"/>
		<updated>2024-05-27T12:35:03Z</updated>

		<summary type="html">&lt;p&gt;AnkitAgrawal: Updated TVOS notes&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Digital]]&lt;br /&gt;
 __NOTOC__&lt;br /&gt;
&lt;br /&gt;
{{Breadcrumb|}} {{Breadcrumb|Digital}} {{CurrentBreadcrumb}}&lt;br /&gt;
==Release 9.3.0.0 (05-10-2024)==&lt;br /&gt;
*Support for privacy manifest with tracking domain for Ad flavors.&lt;br /&gt;
*Support for capturing user opt-out during initialization.&lt;br /&gt;
*Other bug fixes and enhancements.&lt;br /&gt;
== Release 9.2.0.0 (9-27-2023) ==&lt;br /&gt;
*Support for privacy manifest and required reason API introduced in XCode 15.&lt;br /&gt;
*Digitally signed SDK framework per Apple recommendation&lt;br /&gt;
*DCR Static recognizing metadata with changed assetID for new impressions. &lt;br /&gt;
*Limiting ping retries during https failures. &lt;br /&gt;
*Other bug fixes and enhancements. &lt;br /&gt;
&lt;br /&gt;
== Release 9.1.0.0 (3-31-2023) ==&lt;br /&gt;
*DCR Static duration measurement for AppSDK (currently only AGF).&lt;br /&gt;
*Removed use of iOS keychains, started using NSUserDefaults for persistent storage.&lt;br /&gt;
*Viewability: allow enabling by product (DCR, DTVR).&lt;br /&gt;
*Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 9.0.0.0 (10-07-2022) ==&lt;br /&gt;
* Viewability measurement for DTVR, DCR Content and DCR Ad products.&lt;br /&gt;
* Audibility measurement for DTVR, DCR Content and DCR Ad products.&lt;br /&gt;
* SDK built with XCode 14.&lt;br /&gt;
* Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 8.2.0.0 (03-21-2022) ==&lt;br /&gt;
* Adopting Swift language internally, built on a mixed model (Swift+Objective C).&lt;br /&gt;
* Support for Swift markers to help Swift developers.&lt;br /&gt;
* Removed the usage of deprecated iOS network reachability class.&lt;br /&gt;
* Disabled iCloud backup/synchronization of SDK keychain items.&lt;br /&gt;
* Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 8.1.0.0 (06-28-2021) ==&lt;br /&gt;
* Support for XCFramework build distribution.&lt;br /&gt;
* Support for MacOS Catalyst platform framework.&lt;br /&gt;
* Fixed the device classification for MacOS M1 measurement.&lt;br /&gt;
* Support to capture Hashed email and UID.&lt;br /&gt;
* Support to collect SDK diagnostic data.&lt;br /&gt;
* Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 8.0.0.0 (10-05-2020) ==&lt;br /&gt;
* iOS 14 App Transparency Framework support.&lt;br /&gt;
* FPID and VendorID support.&lt;br /&gt;
* Fixed the device classification for iPADOS measurement.&lt;br /&gt;
* Support for Xamarin cross platform framework.&lt;br /&gt;
* Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 7.2.0.0 (05-18-2020) ==&lt;br /&gt;
* DTVR AQH and IVD requirements for End and pause timeout.&lt;br /&gt;
* Support for Hybrid app webview measurement. &lt;br /&gt;
* Support for Hybrid app react native webview measurement. &lt;br /&gt;
* Support for React Native measurement.&lt;br /&gt;
* Other bug fixes and enhancements&lt;br /&gt;
&lt;br /&gt;
== Release 7.1.0.0 (12-09-2019) ==&lt;br /&gt;
* Removed usage of deprecated class UIWebView&lt;br /&gt;
* Offline viewing measurement enhancements&lt;br /&gt;
* Fixed deadlock on SDK shutdown&lt;br /&gt;
* Revisited precedence logic for sfcode parameter&lt;br /&gt;
* Fix for DCR individual ad pings parameters after channel change&lt;br /&gt;
* Using default value for incorrect adModel parameter&lt;br /&gt;
* Defaulting isLive parameter value on channel change&lt;br /&gt;
* Other fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Release 7.0.0.0 (09-06-2019) ==&lt;br /&gt;
* Support for CDN based config.&lt;br /&gt;
* Support for Market based EMM UAID pings.&lt;br /&gt;
* Changes required for proper DCR Static measurement in multi-instance/multiple appid's case.&lt;br /&gt;
* Fixes for OTT synchronization issues between iOS and Android platforms.&lt;br /&gt;
* Fixes for EV data parameters in few scenarios.&lt;br /&gt;
* Fixes for DCR Static product behaviour in background app refresh and background fetch scenarios.&lt;br /&gt;
* DCR Ad reporting improvements.&lt;br /&gt;
* Fixes and improvements for the SDK console log messages.&lt;br /&gt;
* Other enhancements and fixes.&lt;br /&gt;
&lt;br /&gt;
== Release 6.2.0.0 (02-04-2019) == &lt;br /&gt;
* Introduced Dynamic framework for SDK.&lt;br /&gt;
* Removal of Location Module from SDK Code.&lt;br /&gt;
* Increased SDK log file size for Debug mode.&lt;br /&gt;
* Removed OTT Airplay/mirroring detection that caused crashes in AVAudioSession class.&lt;br /&gt;
* DCR performance improvements.&lt;br /&gt;
* Fixed the parsing error happening when clientid/vcid provided as empty in metadata.&lt;br /&gt;
* Align AppSDK for FW detection with BSDK for DCR measurement.&lt;br /&gt;
* Other Bug Fixes/Enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 6.1.0.1 (9-13-2018) ==&lt;br /&gt;
*Nielsen SDK support for Xcode 10 and tvOS 12&lt;br /&gt;
&lt;br /&gt;
== Release 6.0.0.4 (5-24-2018) ==&lt;br /&gt;
*If the SDK build target is set to AGF then SDK will send the hello ping to “eu” and “eu-uat” for debug builds. No changes to the non AGF build the default sfcode will continue to be &amp;quot;sdk&amp;quot; and &amp;quot;cert&amp;quot; for debug build.&lt;br /&gt;
*The C1 parameter (NUID) will now be sent as encrypted DeviceID.&lt;br /&gt;
*New SessionID changes. The sessionID will contain 29 length random characters appended by timestamp.&lt;br /&gt;
*Support for multiple SDK instance without any limit.&lt;br /&gt;
*New log feature for CAT tool to retrieve the API level information from client apps. This ping will contain the eventType, parameters, SDK version, appid etc.&lt;br /&gt;
*Removed Viewability for this release.&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.17 (1-23-2017) ==&lt;br /&gt;
*Added &amp;quot;seconds&amp;quot; place to the launch ping&lt;br /&gt;
*Ability to opt-out using &amp;quot;Limit Ad Tracking&amp;quot; feature&lt;br /&gt;
*Improved CPU Performance while apps are running in background&lt;br /&gt;
*Opt-Out pages can be served based on user’s language and locale from device&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.12 (12-14-2016) ==&lt;br /&gt;
*Support for Nielsen TV Brand Effect&lt;br /&gt;
*Ability to set CMS parameters at a more global level&lt;br /&gt;
*Opt-out pages based on locale and country&lt;br /&gt;
*Opt-out policy based on the &amp;quot;Limit Ad Tracking&amp;quot; flag&lt;br /&gt;
*Collection of additional device information&lt;br /&gt;
*Issue a warning in client developer’s console when ad is played for more than 5 minutes&lt;br /&gt;
*Removed the requirement for “type” parameter&lt;br /&gt;
*Limit the duration reported for App launch&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.7 (9-13-2016) ==&lt;br /&gt;
*General bug fix and performance improvements&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.5 (7-12-2016) ==&lt;br /&gt;
*Includes a sample TVOS application used to assist during integration.&lt;br /&gt;
*Support for TVML based optout pages&lt;br /&gt;
*General bug fix and performance improvements&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.0.7 (6-15-2016) ==&lt;br /&gt;
*Combined SDK for DCR US and International (Germany)&lt;br /&gt;
*API to signal end of content (end API)&lt;br /&gt;
*Support for Pause timeout&lt;br /&gt;
*Updated API to support JSON object instead of string.&lt;br /&gt;
*Reporting of media URL and bundle ID&lt;br /&gt;
*Updated ping retry logic&lt;br /&gt;
*Changes in OptOut process behavioral&lt;br /&gt;
*Enhanced Debugging and SDK logging&lt;br /&gt;
*Changes to API signature&lt;/div&gt;</summary>
		<author><name>AnkitAgrawal</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=TVOS_SDK_Release_Notes&amp;diff=6656</id>
		<title>TVOS SDK Release Notes</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=TVOS_SDK_Release_Notes&amp;diff=6656"/>
		<updated>2024-05-27T12:34:08Z</updated>

		<summary type="html">&lt;p&gt;AnkitAgrawal: Updated TVOS notes&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Digital]]&lt;br /&gt;
 __NOTOC__&lt;br /&gt;
&lt;br /&gt;
{{Breadcrumb|}} {{Breadcrumb|Digital}} {{CurrentBreadcrumb}}&lt;br /&gt;
==Release 9.3.0.0 (05-10-2024)==&lt;br /&gt;
*Support for privacy manifest with tracking domain for Ad flavors.&lt;br /&gt;
*Support for capturing user opt-out during initialization.&lt;br /&gt;
*Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
*&lt;br /&gt;
== Release 9.2.0.0 (9-27-2023) ==&lt;br /&gt;
*Support for privacy manifest and required reason API introduced in XCode 15.&lt;br /&gt;
*Digitally signed SDK framework per Apple recommendation&lt;br /&gt;
*DCR Static recognizing metadata with changed assetID for new impressions. &lt;br /&gt;
*Limiting ping retries during https failures. &lt;br /&gt;
*Other bug fixes and enhancements. &lt;br /&gt;
&lt;br /&gt;
== Release 9.1.0.0 (3-31-2023) ==&lt;br /&gt;
*DCR Static duration measurement for AppSDK (currently only AGF).&lt;br /&gt;
*Removed use of iOS keychains, started using NSUserDefaults for persistent storage.&lt;br /&gt;
*Viewability: allow enabling by product (DCR, DTVR).&lt;br /&gt;
*Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 9.0.0.0 (10-07-2022) ==&lt;br /&gt;
* Viewability measurement for DTVR, DCR Content and DCR Ad products.&lt;br /&gt;
* Audibility measurement for DTVR, DCR Content and DCR Ad products.&lt;br /&gt;
* SDK built with XCode 14.&lt;br /&gt;
* Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 8.2.0.0 (03-21-2022) ==&lt;br /&gt;
* Adopting Swift language internally, built on a mixed model (Swift+Objective C).&lt;br /&gt;
* Support for Swift markers to help Swift developers.&lt;br /&gt;
* Removed the usage of deprecated iOS network reachability class.&lt;br /&gt;
* Disabled iCloud backup/synchronization of SDK keychain items.&lt;br /&gt;
* Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 8.1.0.0 (06-28-2021) ==&lt;br /&gt;
* Support for XCFramework build distribution.&lt;br /&gt;
* Support for MacOS Catalyst platform framework.&lt;br /&gt;
* Fixed the device classification for MacOS M1 measurement.&lt;br /&gt;
* Support to capture Hashed email and UID.&lt;br /&gt;
* Support to collect SDK diagnostic data.&lt;br /&gt;
* Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 8.0.0.0 (10-05-2020) ==&lt;br /&gt;
* iOS 14 App Transparency Framework support.&lt;br /&gt;
* FPID and VendorID support.&lt;br /&gt;
* Fixed the device classification for iPADOS measurement.&lt;br /&gt;
* Support for Xamarin cross platform framework.&lt;br /&gt;
* Other bug fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 7.2.0.0 (05-18-2020) ==&lt;br /&gt;
* DTVR AQH and IVD requirements for End and pause timeout.&lt;br /&gt;
* Support for Hybrid app webview measurement. &lt;br /&gt;
* Support for Hybrid app react native webview measurement. &lt;br /&gt;
* Support for React Native measurement.&lt;br /&gt;
* Other bug fixes and enhancements&lt;br /&gt;
&lt;br /&gt;
== Release 7.1.0.0 (12-09-2019) ==&lt;br /&gt;
* Removed usage of deprecated class UIWebView&lt;br /&gt;
* Offline viewing measurement enhancements&lt;br /&gt;
* Fixed deadlock on SDK shutdown&lt;br /&gt;
* Revisited precedence logic for sfcode parameter&lt;br /&gt;
* Fix for DCR individual ad pings parameters after channel change&lt;br /&gt;
* Using default value for incorrect adModel parameter&lt;br /&gt;
* Defaulting isLive parameter value on channel change&lt;br /&gt;
* Other fixes and enhancements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Release 7.0.0.0 (09-06-2019) ==&lt;br /&gt;
* Support for CDN based config.&lt;br /&gt;
* Support for Market based EMM UAID pings.&lt;br /&gt;
* Changes required for proper DCR Static measurement in multi-instance/multiple appid's case.&lt;br /&gt;
* Fixes for OTT synchronization issues between iOS and Android platforms.&lt;br /&gt;
* Fixes for EV data parameters in few scenarios.&lt;br /&gt;
* Fixes for DCR Static product behaviour in background app refresh and background fetch scenarios.&lt;br /&gt;
* DCR Ad reporting improvements.&lt;br /&gt;
* Fixes and improvements for the SDK console log messages.&lt;br /&gt;
* Other enhancements and fixes.&lt;br /&gt;
&lt;br /&gt;
== Release 6.2.0.0 (02-04-2019) == &lt;br /&gt;
* Introduced Dynamic framework for SDK.&lt;br /&gt;
* Removal of Location Module from SDK Code.&lt;br /&gt;
* Increased SDK log file size for Debug mode.&lt;br /&gt;
* Removed OTT Airplay/mirroring detection that caused crashes in AVAudioSession class.&lt;br /&gt;
* DCR performance improvements.&lt;br /&gt;
* Fixed the parsing error happening when clientid/vcid provided as empty in metadata.&lt;br /&gt;
* Align AppSDK for FW detection with BSDK for DCR measurement.&lt;br /&gt;
* Other Bug Fixes/Enhancements.&lt;br /&gt;
&lt;br /&gt;
== Release 6.1.0.1 (9-13-2018) ==&lt;br /&gt;
*Nielsen SDK support for Xcode 10 and tvOS 12&lt;br /&gt;
&lt;br /&gt;
== Release 6.0.0.4 (5-24-2018) ==&lt;br /&gt;
*If the SDK build target is set to AGF then SDK will send the hello ping to “eu” and “eu-uat” for debug builds. No changes to the non AGF build the default sfcode will continue to be &amp;quot;sdk&amp;quot; and &amp;quot;cert&amp;quot; for debug build.&lt;br /&gt;
*The C1 parameter (NUID) will now be sent as encrypted DeviceID.&lt;br /&gt;
*New SessionID changes. The sessionID will contain 29 length random characters appended by timestamp.&lt;br /&gt;
*Support for multiple SDK instance without any limit.&lt;br /&gt;
*New log feature for CAT tool to retrieve the API level information from client apps. This ping will contain the eventType, parameters, SDK version, appid etc.&lt;br /&gt;
*Removed Viewability for this release.&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.17 (1-23-2017) ==&lt;br /&gt;
*Added &amp;quot;seconds&amp;quot; place to the launch ping&lt;br /&gt;
*Ability to opt-out using &amp;quot;Limit Ad Tracking&amp;quot; feature&lt;br /&gt;
*Improved CPU Performance while apps are running in background&lt;br /&gt;
*Opt-Out pages can be served based on user’s language and locale from device&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.12 (12-14-2016) ==&lt;br /&gt;
*Support for Nielsen TV Brand Effect&lt;br /&gt;
*Ability to set CMS parameters at a more global level&lt;br /&gt;
*Opt-out pages based on locale and country&lt;br /&gt;
*Opt-out policy based on the &amp;quot;Limit Ad Tracking&amp;quot; flag&lt;br /&gt;
*Collection of additional device information&lt;br /&gt;
*Issue a warning in client developer’s console when ad is played for more than 5 minutes&lt;br /&gt;
*Removed the requirement for “type” parameter&lt;br /&gt;
*Limit the duration reported for App launch&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.7 (9-13-2016) ==&lt;br /&gt;
*General bug fix and performance improvements&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.1.5 (7-12-2016) ==&lt;br /&gt;
*Includes a sample TVOS application used to assist during integration.&lt;br /&gt;
*Support for TVML based optout pages&lt;br /&gt;
*General bug fix and performance improvements&lt;br /&gt;
&lt;br /&gt;
== Release 5.1.0.7 (6-15-2016) ==&lt;br /&gt;
*Combined SDK for DCR US and International (Germany)&lt;br /&gt;
*API to signal end of content (end API)&lt;br /&gt;
*Support for Pause timeout&lt;br /&gt;
*Updated API to support JSON object instead of string.&lt;br /&gt;
*Reporting of media URL and bundle ID&lt;br /&gt;
*Updated ping retry logic&lt;br /&gt;
*Changes in OptOut process behavioral&lt;br /&gt;
*Enhanced Debugging and SDK logging&lt;br /&gt;
*Changes to API signature&lt;/div&gt;</summary>
		<author><name>AnkitAgrawal</name></author>
	</entry>
</feed>