<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://nielsentest.mywikis.net/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=NickParrucci</id>
	<title>Engineering Client Portal - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://nielsentest.mywikis.net/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=NickParrucci"/>
	<link rel="alternate" type="text/html" href="https://nielsentest.mywikis.net/wiki/Special:Contributions/NickParrucci"/>
	<updated>2026-04-07T00:32:05Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.39.5</generator>
	<entry>
		<id>https://nielsentest.mywikis.net/w/index.php?title=TV&amp;diff=6580</id>
		<title>TV</title>
		<link rel="alternate" type="text/html" href="https://nielsentest.mywikis.net/w/index.php?title=TV&amp;diff=6580"/>
		<updated>2024-01-31T21:18:58Z</updated>

		<summary type="html">&lt;p&gt;NickParrucci: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:TV]]&lt;br /&gt;
{{Banner|Encoder Support}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
 {{Alert|'''Download:''' '''https://nielsendownloads.digitalengsdk.com/tv/REMINDER_Spring_2019_DST.pdf Reminder: Daylight Savings Time (DST) changes November 3]''' &amp;lt;br&amp;gt; '''See also:''' '''[https://nielsendownloads-blue.digitalengsdk.com/tv/Quick_Reference_Guide_Spring_2019_DST.pdf Daylight Savings Time Quick Reference Guide Spring 2019]''' }}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--  --&amp;gt;&lt;br /&gt;
{{Alert|&lt;br /&gt;
'''Nielsen Encoder Installation and Configuration Policy 2022 Now Available:'''&amp;lt;br&amp;gt;&lt;br /&gt;
'''Official release notification:  [https://nielsendownloads.digitalengsdk.com/tv/Encoding/Encoder+Policy+2022+-+04-01-22.pdf Nielsen Encoder Installation and Configuration Policy 2022]&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 50px;&amp;quot; |&lt;br /&gt;
! Certified Vendors&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;1&amp;quot; | &lt;br /&gt;
| '''[[Nielsen Encoder Certified Vendors]]'''&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;1&amp;quot; | &lt;br /&gt;
| '''[[Nielsen Decoder Certified Vendors]]'''&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;1&amp;quot; | &lt;br /&gt;
| '''[[PCM-to-ID3 Certified Vendors]]'''&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 50px;&amp;quot; |&lt;br /&gt;
! Reference &amp;amp; Policy Supplements&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;1&amp;quot; | {{SmallIcon|PDFIcon.png}}&lt;br /&gt;
| '''[https://nielsendownloads.digitalengsdk.com/tv/Encoding/Encoder+Policy+2022+-+04-01-22.pdf Nielsen Encoder Installation and Configuration Policy 2022]'''&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;1&amp;quot; | {{SmallIcon|PDFIcon.png}}&lt;br /&gt;
| '''[https://nielsendownloads-blue.digitalengsdk.com/tv/Encoding/Internet_Distribution_Policy_Rev_A.pdf Internet Distribution Policy]'''&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;1&amp;quot; | {{SmallIcon|PDFIcon.png}}&lt;br /&gt;
| '''[https://nielsendownloads.digitalengsdk.com/tv/Encoding/Nielsen+Encoder+Solutions+2023.pdf Nielsen Encoder Solutions 2023]'''&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;1&amp;quot; | {{SmallIcon|PDFIcon.png}}&lt;br /&gt;
| '''[https://nielsendownloads-blue.digitalengsdk.com/tv/Encoding/MVPD%20provided%20Direct%20Feeds%20with%20Unique%20Commercial%20Content.pdf MVPD provided Direct Feeds with Unique Commercial Content]'''&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;1&amp;quot; | {{SmallIcon|PDFIcon.png}}&lt;br /&gt;
| '''[https://nielsendownloads-blue.digitalengsdk.com/tv/Encoder%20Alert%20Distribution%20List%20Instructions_Final.pdf Nielsen Encoder Alert Distribution List - Instructions]'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{CategoryIcon|EncodingIcon.png|TV Audio Encoding}}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 75px;&amp;quot; |&lt;br /&gt;
! style=&amp;quot;width: 35%;&amp;quot; | Software&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; | OS &lt;br /&gt;
! Download &lt;br /&gt;
|-&lt;br /&gt;
| {{SmallIcon|CircuitIcon.png}}&lt;br /&gt;
| '''[[NWE-3GA]]''' || {{OSIcon|WindowsIcon.png}} || &lt;br /&gt;
{{TVDownloadRequestLink|name=NWE-3GA NWE-3G Software package Rev 2.3.0.9 (New)|dlid=73aeefb5972bb1f556aa5093c14b981d223bec8e}}&lt;br /&gt;
{{TVDownloadRequestLink|name=NWE-3GA NWE-3G Software package Rev.2.2.0.1|dlid=53fa2674bebc1a010c50b747ff969a61e4094b43}}&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| {{SmallIcon|RackIcon.png}}&lt;br /&gt;
| '''[[NWE-TS]]'''&lt;br /&gt;
|| {{OSIcon|FirmwareIcon.png}} || &lt;br /&gt;
{{TVDownloadRequestLink|name=NWE-TS Firmware 4.6.10|dlid=31e04631784a2438fc41c81f34a49c33cd513ec6}} &amp;lt;small&amp;gt;''('''New!''' - June 17th, 2019)''&amp;lt;/small&amp;gt;&lt;br /&gt;
{{TVDownloadRequestLink|name=NWE-TS Firmware 4.5.1|dlid=5126ebc2699eda28002ba6e2e84fb8a1031827f5}}&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| {{SmallIcon|RackIcon.png}}&lt;br /&gt;
| '''[[Multi-Channel Encoder]]'''&lt;br /&gt;
|| {{OSIcon|FirmwareIcon.png}} || &lt;br /&gt;
*[[Encoder Downloads| Multi-Channel Encoder v1.2.4]]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| {{SmallIcon|VODIcon.png}}&lt;br /&gt;
| '''[[VOD Content Encoder]]'''&lt;br /&gt;
|| {{OSIcon|WindowsIcon.png}} || &lt;br /&gt;
*[[Encoder Downloads| VOD Content Encoder]]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| {{SmallIcon|VODIcon.png}}&lt;br /&gt;
| '''[[VOD in TV Ratings]]'''  ''&amp;lt;small&amp;gt;(formerly RTVOD)&amp;lt;/small&amp;gt;''&lt;br /&gt;
|| {{OSIcon|WindowsIcon.png}} || &lt;br /&gt;
*[[Encoder Downloads| VOD in TV Ratings]] ''&amp;lt;small&amp;gt;(formerly RTVOD)&amp;lt;/small&amp;gt;''&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| {{SmallIcon|ComputerWaveIcon.png}}&lt;br /&gt;
| '''[[SpoTTrac®]]'''&lt;br /&gt;
|| {{OSIcon|FirmwareIcon.png}} || &lt;br /&gt;
*[[Encoder Downloads| SpoTTrac Firmware]]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| {{SmallIcon|EncoderGrayIcon.png}}&lt;br /&gt;
| '''[[NAVE II]]'''&lt;br /&gt;
|| {{OSIcon|WindowsIcon.png}} || &lt;br /&gt;
*NAVE II Firmware v38&lt;br /&gt;
*NAVE II Manager&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| {{SmallIcon|EncoderGrayIcon.png}}&lt;br /&gt;
| '''[[NAVE IIC]]'''&lt;br /&gt;
|| {{OSIcon|WindowsIcon.png}} || &lt;br /&gt;
*NAVE IIC Firmware v3.4.15&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{CategoryIcon|ID3Icon.png|ID3 Transcoding}}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 75px;&amp;quot; |&lt;br /&gt;
! style=&amp;quot;width: 35%;&amp;quot; | Software&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; | OS &lt;br /&gt;
! Download &lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|rowspan=&amp;quot;3&amp;quot;| {{SmallIcon|ID3XcodeIcon.png}}&lt;br /&gt;
|rowspan=&amp;quot;3&amp;quot;| '''[[ID3 Transcoders]]'''&lt;br /&gt;
''&amp;lt;small&amp;gt;(Click for Documentation, Software Updates, and Test Streams)&amp;lt;/small&amp;gt;''&lt;br /&gt;
|| {{OSIcon|WindowsIcon.png}} || &lt;br /&gt;
{{TVDownloadRequestLink|name=PCM-to-ID3 SDK (Windows) v2.3.2|dlid=ac5b0e72a84b1a6e86da1a8fe0a89e24083468eb}}&lt;br /&gt;
{{TVDownloadRequestLink|name=PCM-to-ID3 SDK (Windows Visual Studio 2013) v2.3|dlid=533cee44e69c6859e56acd9cbb38334d6b215c00}}&lt;br /&gt;
|-&lt;br /&gt;
|| {{OSIcon|LinuxIcon.png}} || &lt;br /&gt;
{{TVDownloadRequestLink|name=PCM-to-ID3 SDK (Linux x64 GLIBC 2.12) v2.3.2|dlid=c499535f6ce9a0326a408b167079e01a0596e141}}&lt;br /&gt;
{{TVDownloadRequestLink|name=PCM-to-ID3 SDK (Linux x64 GLIBC 2.17) v2.3.2|dlid=b353e404994a1d26726b196960efe40c30427571}}&lt;br /&gt;
{{TVDownloadRequestLink|name=PCM-to-ID3 SDK (Linux x86 GLIBC 2.17) v2.3.2|dlid=f82dfbde6f5f68ccf677b63e32fc83e68fa82cd6}}&lt;br /&gt;
|-&lt;br /&gt;
|| {{OSIcon|macOSIcon.png}} || &lt;br /&gt;
{{TVDownloadRequestLink|name=PCM-to-ID3 SDK (MacOS) v2.3|dlid=3a9d04be165f39ac956278c8292cd1b87ce34b62}}&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|rowspan=&amp;quot;1&amp;quot;| {{SmallIcon|ID3DashIcon.png}}&lt;br /&gt;
|rowspan=&amp;quot;1&amp;quot;| '''[[ID3 in MPEG-DASH]]'''&lt;br /&gt;
''&amp;lt;small&amp;gt;(Click for Documentation, and Sample Audio Files)&amp;lt;/small&amp;gt;''&lt;br /&gt;
|| {{OSIcon|StaticIcon.png}} || &lt;br /&gt;
*[https://nielsendownloads-blue.digitalengsdk.com/tv/ID3%20Transcoding/ID3%20in%20MPEG-DASH/bbb-MPEG-DASH.zip Big Buck Bunny MPEG-DASH Nielsen Tagged]&lt;br /&gt;
*[https://nielsendownloads-blue.digitalengsdk.com/tv/ID3%20Transcoding/ID3%20in%20MPEG-DASH/nielsenconsumer-MPEG-DASH.zip Nielsen Consumer MPEG-DASH Nielsen Tagged]&lt;br /&gt;
*[https://nielsendownloads-blue.digitalengsdk.com/tv/ID3%20Transcoding/ID3%20in%20MPEG-DASH/nielsenxplatform-MPEG-DASH.zip Nielsen Cross Platform MPEG-DASH Nielsen Tagged]&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|rowspan=&amp;quot;3&amp;quot;| {{SmallIcon|ID3ValidateIcon.png}} &lt;br /&gt;
|rowspan=&amp;quot;3&amp;quot;| '''[[PCM-to-ID3 Validator]]'''&lt;br /&gt;
''&amp;lt;small&amp;gt;(Click for Documentation, and Downloads)&amp;lt;/small&amp;gt;''&lt;br /&gt;
|| {{OSIcon|WindowsIcon.png}} || &lt;br /&gt;
{{TVDownloadRequestLink|name=PCM-to-ID3 Validator (Windows) v1.8|dlid=67d34c64d1ed349c1ad92ac47adf62c877f47fcb}}&lt;br /&gt;
|-&lt;br /&gt;
|| {{OSIcon|LinuxIcon.png}} || &lt;br /&gt;
{{TVDownloadRequestLink|name=PCM-to-ID3 Validator (CentOS) v1.7|dlid=dd6b62c76995aa7e1702c60e02076348ceaf573b}}&lt;br /&gt;
|-&lt;br /&gt;
|| {{OSIcon|macOSIcon.png}} || &lt;br /&gt;
{{TVDownloadRequestLink|name=PCM-to-ID3 Validator (MacOS) v1.7|dlid=3afc5a7ec29593e2eb47daa9746b6d16cbd785e1}}&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|rowspan=&amp;quot;3&amp;quot;| {{SmallIcon|ID3ValidateIcon.png}} &lt;br /&gt;
|rowspan=&amp;quot;3&amp;quot;| '''[[PCM-to-ID3 Validator SDK]]'''&lt;br /&gt;
''&amp;lt;small&amp;gt;(Click for Documentation, and Downloads)&amp;lt;/small&amp;gt;''&lt;br /&gt;
|| {{OSIcon|WindowsIcon.png}} || &lt;br /&gt;
{{TVDownloadRequestLink|name=PCM-to-ID3 Validator SDK (Windows) v1.8|dlid=78a936556ebc5caf57d2fc4d09de3a272ace9fea}}&lt;br /&gt;
|-&lt;br /&gt;
|| {{OSIcon|LinuxIcon.png}} || &lt;br /&gt;
{{TVDownloadRequestLink|name=PCM-to-ID3 Validator SDK (CentOS) v1.7|dlid=ccb9af4ef45cfcf7aa4406ca63ab3b7c6efdad11}}&lt;br /&gt;
|-&lt;br /&gt;
|| {{OSIcon|macOSIcon.png}} || &lt;br /&gt;
{{TVDownloadRequestLink|name=PCM-to-ID3 Validator SDK (MacOS) v1.7|dlid=05e99551d28ef4a65eab6168ad2872648346aab2}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{CategoryIcon|DiagnosisToolsIcon.png|Diagnostic Tools}}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 75px;&amp;quot; |&lt;br /&gt;
! style=&amp;quot;width: 35%;&amp;quot; | Software&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; | OS &lt;br /&gt;
! Download &lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| {{SmallIcon|NACATIcon.png}} &lt;br /&gt;
|| '''[[Nielsen Audio Code Analysis Tool 2|Nielsen Audio Code Analysis Tool 2 (NACAT2)]]''' &lt;br /&gt;
|| {{OSIcon|WindowsIcon.png}} || &lt;br /&gt;
{{TVDownloadRequestLink|name=NACAT2 1.4|dlid=83d58832e663a21841b32f771cc2781ae5b5b572}}&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| {{SmallIcon|NACATIcon.png}} &lt;br /&gt;
|| '''[[Nielsen Audio Code Analysis Tool|Nielsen Audio Code Analysis Tool (NACAT)]]''' &lt;br /&gt;
|| {{OSIcon|WindowsIcon.png}} || &lt;br /&gt;
{{TVDownloadRequestLink|name=NACAT installer (Windows) v4.3|dlid=212d5eb338cf66cd20f3846347bc3c8c6b2dfbc4}}&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| {{SmallIcon|NDICEIcon.png}}&lt;br /&gt;
|| '''[[Nielsen Digital Code Extractor]]'''&lt;br /&gt;
|| {{OSIcon|WindowsIcon.png}} || &lt;br /&gt;
{{TVDownloadRequestLink|name=Nielsen Digital Code Extractor Installer|dlid=c0eb8eb1802bd08956f6e215473ef1881274a6df}} &amp;lt;BR&amp;gt; (See special installation instructions in [[Nielsen Digital Code Extractor|guide]])&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|rowspan=&amp;quot;3&amp;quot;| {{SmallIcon|SDKIcon.png}} &lt;br /&gt;
|rowspan=&amp;quot;3&amp;quot;| '''[[Decoder SDK Monitor]]'''&lt;br /&gt;
|| {{OSIcon|WindowsIcon.png}} || &lt;br /&gt;
{{TVDownloadRequestLink|name=Decoder SDK Monitor (Windows vs2017) v1.4|dlid=b3ae411765cfa2b878c3f50c0824e61d81a58fbb}}&lt;br /&gt;
|-&lt;br /&gt;
|| {{OSIcon|WindowsIcon.png}} || &lt;br /&gt;
{{TVDownloadRequestLink|name=Decoder SDK Monitor (Windows vs2015) v1.4|dlid=68d1fd697862e663a7aa2efc46377f053c983a5a}}&lt;br /&gt;
|-&lt;br /&gt;
|| {{OSIcon|LinuxIcon.png}} || &lt;br /&gt;
{{TVDownloadRequestLink|name=Decoder SDK Monitor (CentOS) v1.4|dlid=c978921ba90736bf7f2c82287a0a97af89109bec}}&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| {{SmallIcon|NDICEIcon.png}}&lt;br /&gt;
|| '''[[Nielsen Monitor Application]]'''&lt;br /&gt;
|| {{OSIcon|WindowsIcon.png}} || &lt;br /&gt;
{{TVDownloadRequestLink|name=Nielsen Monitor Application (Windows) v1.4|dlid=6ddf77a8f67dff67b4cbad1fee630ee80318b5bf}}&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| {{SmallIcon|NDICEIcon.png}}&lt;br /&gt;
|| '''[[Nielsen Monitor Application]]|TEST for Nick REMOVE before prod'''&lt;br /&gt;
|| {{OSIcon|WindowsIcon.png}} || &lt;br /&gt;
{{TVDownloadRequestLink|name=testfile|dlid=cf62886426e702be71f6e8dd25c1d7d35a920876}}&lt;br /&gt;
&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>NickParrucci</name></author>
	</entry>
	<entry>
		<id>https://nielsentest.mywikis.net/w/index.php?title=Main_Page&amp;diff=6576</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://nielsentest.mywikis.net/w/index.php?title=Main_Page&amp;diff=6576"/>
		<updated>2024-01-17T16:04:53Z</updated>

		<summary type="html">&lt;p&gt;NickParrucci: Reverted edits by NickParrucci (talk) to last revision by Admin&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Banner|Engineering Portal}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;small-4 large-4 columns&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&amp;gt;{{NavigationBox|AudioIcon.png|Radio}}&amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;small-4 large-4 columns&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&amp;gt;{{NavigationBox|EncoderIcon.png|TV}}&amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;small-4 large-4 columns&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&amp;gt;{{NavigationBox|DigitalIcon.png|Digital}}&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>NickParrucci</name></author>
	</entry>
	<entry>
		<id>https://nielsentest.mywikis.net/w/index.php?title=Main_Page&amp;diff=6575</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://nielsentest.mywikis.net/w/index.php?title=Main_Page&amp;diff=6575"/>
		<updated>2024-01-17T16:04:37Z</updated>

		<summary type="html">&lt;p&gt;NickParrucci: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Banner|Engineering Portal}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;small-4 large-4 columns&amp;quot;&amp;gt;{{NavigationBox|AudioIcon.png|Radio}}&amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;small-4 large-4 columns&amp;quot;&amp;gt;{{NavigationBox|EncoderIcon.png|TV}}&amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;small-4 large-4 columns&amp;quot;&amp;gt;{{NavigationBox|DigitalIcon.png|Digital}}&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>NickParrucci</name></author>
	</entry>
	<entry>
		<id>https://nielsentest.mywikis.net/w/index.php?title=Main_Page&amp;diff=6574</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://nielsentest.mywikis.net/w/index.php?title=Main_Page&amp;diff=6574"/>
		<updated>2024-01-17T16:02:17Z</updated>

		<summary type="html">&lt;p&gt;NickParrucci: Reverted edits by NickParrucci (talk) to last revision by Admin&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Banner|Engineering Portal}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;small-4 large-4 columns&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&amp;gt;{{NavigationBox|AudioIcon.png|Radio}}&amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;small-4 large-4 columns&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&amp;gt;{{NavigationBox|EncoderIcon.png|TV}}&amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;small-4 large-4 columns&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&amp;gt;{{NavigationBox|DigitalIcon.png|Digital}}&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>NickParrucci</name></author>
	</entry>
	<entry>
		<id>https://nielsentest.mywikis.net/w/index.php?title=Main_Page&amp;diff=6573</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://nielsentest.mywikis.net/w/index.php?title=Main_Page&amp;diff=6573"/>
		<updated>2024-01-17T16:02:02Z</updated>

		<summary type="html">&lt;p&gt;NickParrucci: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Banner|Engineering Portal}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;div&amp;gt;{{NavigationBox|AudioIcon.png|Radio}}&amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div&amp;gt;{{NavigationBox|EncoderIcon.png|TV}}&amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div&amp;gt;{{NavigationBox|DigitalIcon.png|Digital}}&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>NickParrucci</name></author>
	</entry>
	<entry>
		<id>https://nielsentest.mywikis.net/w/index.php?title=Template:NavigationBox&amp;diff=6572</id>
		<title>Template:NavigationBox</title>
		<link rel="alternate" type="text/html" href="https://nielsentest.mywikis.net/w/index.php?title=Template:NavigationBox&amp;diff=6572"/>
		<updated>2024-01-17T15:56:46Z</updated>

		<summary type="html">&lt;p&gt;NickParrucci: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Image:{{{icon|{{{1}}}}}}|center|200px|link={{{title|{{{2}}}}}}|{{{title|{{{2}}}}}}|class=iconImage]]&lt;br /&gt;
&amp;lt;span class=&amp;quot;iconText&amp;quot;&amp;gt;[[{{{2}}}]]&amp;lt;/span&amp;gt;&lt;/div&gt;</summary>
		<author><name>NickParrucci</name></author>
	</entry>
	<entry>
		<id>https://nielsentest.mywikis.net/w/index.php?title=Main_Page&amp;diff=6571</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://nielsentest.mywikis.net/w/index.php?title=Main_Page&amp;diff=6571"/>
		<updated>2024-01-16T14:16:38Z</updated>

		<summary type="html">&lt;p&gt;NickParrucci: Reverted edits by NickParrucci (talk) to last revision by Admin&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Banner|Engineering Portal}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;small-4 large-4 columns&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&amp;gt;{{NavigationBox|AudioIcon.png|Radio}}&amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;small-4 large-4 columns&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&amp;gt;{{NavigationBox|EncoderIcon.png|TV}}&amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;small-4 large-4 columns&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&amp;gt;{{NavigationBox|DigitalIcon.png|Digital}}&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>NickParrucci</name></author>
	</entry>
	<entry>
		<id>https://nielsentest.mywikis.net/w/index.php?title=Main_Page&amp;diff=6570</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://nielsentest.mywikis.net/w/index.php?title=Main_Page&amp;diff=6570"/>
		<updated>2024-01-16T14:15:02Z</updated>

		<summary type="html">&lt;p&gt;NickParrucci: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Banner|Engineering Portal}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;small-4 large-4 columns&amp;quot; style=&amp;quot;margin: auto;&amp;quot;&amp;gt;{{NavigationBox|AudioIcon.png|Radio}}&amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;small-4 large-4 columns&amp;quot; style=&amp;quot;margin: auto;&amp;quot;&amp;gt;{{NavigationBox|EncoderIcon.png|TV}}&amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;small-4 large-4 columns&amp;quot; style=&amp;quot;margin: auto;&amp;quot;&amp;gt;{{NavigationBox|DigitalIcon.png|Digital}}&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>NickParrucci</name></author>
	</entry>
	<entry>
		<id>https://nielsentest.mywikis.net/w/index.php?title=Main_Page&amp;diff=6569</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://nielsentest.mywikis.net/w/index.php?title=Main_Page&amp;diff=6569"/>
		<updated>2024-01-16T14:12:36Z</updated>

		<summary type="html">&lt;p&gt;NickParrucci: Reverted edits by NickParrucci (talk) to last revision by Admin&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Banner|Engineering Portal}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;small-4 large-4 columns&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&amp;gt;{{NavigationBox|AudioIcon.png|Radio}}&amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;small-4 large-4 columns&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&amp;gt;{{NavigationBox|EncoderIcon.png|TV}}&amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;small-4 large-4 columns&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&amp;gt;{{NavigationBox|DigitalIcon.png|Digital}}&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>NickParrucci</name></author>
	</entry>
	<entry>
		<id>https://nielsentest.mywikis.net/w/index.php?title=Main_Page&amp;diff=6568</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://nielsentest.mywikis.net/w/index.php?title=Main_Page&amp;diff=6568"/>
		<updated>2024-01-16T14:12:01Z</updated>

		<summary type="html">&lt;p&gt;NickParrucci: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Banner|Engineering Portal}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;small-4 large-4 columns&amp;quot;&amp;gt;{{NavigationBox|AudioIcon.png|Radio}}&amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;small-4 large-4 columns&amp;quot;&amp;gt;{{NavigationBox|EncoderIcon.png|TV}}&amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;small-4 large-4 columns&amp;quot;&amp;gt;{{NavigationBox|DigitalIcon.png|Digital}}&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>NickParrucci</name></author>
	</entry>
	<entry>
		<id>https://nielsentest.mywikis.net/w/index.php?title=Template:DCR_Content_Metadata&amp;diff=6564</id>
		<title>Template:DCR Content Metadata</title>
		<link rel="alternate" type="text/html" href="https://nielsentest.mywikis.net/w/index.php?title=Template:DCR_Content_Metadata&amp;diff=6564"/>
		<updated>2023-10-25T19:40:20Z</updated>

		<summary type="html">&lt;p&gt;NickParrucci: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
! '''Keys''' !! '''Description''' !! '''Values''' !! '''Required'''!!'''Provider'''&lt;br /&gt;
|-&lt;br /&gt;
| type || Type of asset ||For Video use: &amp;lt;code&amp;gt;content&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt; For Static or text &amp;lt;code&amp;gt;static&amp;lt;/code&amp;gt; || Yes || Nielsen&lt;br /&gt;
|-style=&amp;quot;background-color:#e9f9fa;&amp;quot;&lt;br /&gt;
| assetid || Unique ID assigned to asset &amp;lt;br&amp;gt; Note: Refrain from using the following special characters [[Special_Characters|(Special Characters)]]. || Examples: &amp;lt;br&amp;gt; &amp;lt;code&amp;gt;BBT345a234 &amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; &amp;lt;code&amp;gt;CBSs5e234F2021&amp;lt;/code&amp;gt;  || Yes || Client &lt;br /&gt;
|-&lt;br /&gt;
| program ||Complete program or movie title &amp;lt;br&amp;gt; (no abbreviations or shorthand) &amp;lt;br&amp;gt; Note: there is a 25 character limit.  ||&amp;lt;code&amp;gt; The Big Bang Theory&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; &amp;lt;code&amp;gt; TheBigBangTheory&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt;&amp;lt;code&amp;gt; The Dark Knight&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt;&amp;lt;code&amp;gt; TheDarkKnight&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; || Yes || Client &lt;br /&gt;
|-style=&amp;quot;background-color:#e9f9fa;&amp;quot;&lt;br /&gt;
| title ||Episode title with season and episode number (40 character limit) &amp;lt;br&amp;gt; (Formats accepted: S01E03, S1E3, S1 E3). || Examples: &amp;lt;br&amp;gt; &amp;lt;code&amp;gt;The Pants Alternative S03E18&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; &amp;lt;code&amp;gt;The Pants Alternative S3E18&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; &amp;lt;code&amp;gt;The Pants Alternative S3 E18&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; Can also accept: &amp;lt;code&amp;gt; S3E18&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; Not Valid: &amp;lt;code&amp;gt; 318 &amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt; 0318 &amp;lt;/code&amp;gt;|| Yes || Client &lt;br /&gt;
|-&lt;br /&gt;
| crossId1 || Gracenote TMS ID (If available) should be passed for all telecasted content for clients using the Gracenote solution for proper matching purposes. &amp;lt;br&amp;gt;Note: The TMS ID will be a 14 character string. Normally leading with 2 alpha characerts ('EP', 'MV', 'SH' or 'SP'), followed by 12 numbers.&lt;br /&gt;
|| The TMS ID will be a 14 character string. &amp;lt;br&amp;gt; Normally being with  'EV,' 'EP', 'SH', 'SP', or 'MV' &amp;lt;br&amp;gt; Followed by 12 numbers after the initial two letter prefix. &amp;lt;br&amp;gt; &amp;lt;br&amp;gt; The Giant Morning Show: &amp;lt;code&amp;gt;SH009311820022&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; The Pants Alternative Episode : &amp;lt;code&amp;gt;EP009311820061&amp;lt;/code&amp;gt; || Optional || Nielsen&lt;br /&gt;
|-style=&amp;quot;background-color:#e9f9fa;&amp;quot;&lt;br /&gt;
| crossId2 || Populated by content distributor to contribute viewing from that distributor to the given content originator. || Custom&amp;lt;br&amp;gt;For a full list of acceptable values, please contact your Nielsen reprentative. || Yes, for distributors || Nielsen&lt;br /&gt;
|-&lt;br /&gt;
| length || Length of content in seconds&amp;lt;br&amp;gt;Note: Integers and decimal values are acceptable for the length parameter. || Examples:&lt;br /&gt;
&amp;lt;small&amp;gt;For standard VOD content - &amp;lt;code&amp;gt;300&amp;lt;/code&amp;gt; to represent 5 minutes, &amp;lt;code&amp;gt;1320&amp;lt;/code&amp;gt; to represent 22 minutes, etc.&lt;br /&gt;
&amp;lt;br&amp;gt;If DAI live stream of a discrete program (Live Event/Sporting Event), pass length of content. See example for standard VOD content above.&lt;br /&gt;
&amp;lt;br&amp;gt;If unknown DAI live steam, pass a value of &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;.&amp;lt;/small&amp;gt; &lt;br /&gt;
|| Yes || Client &lt;br /&gt;
|-style=&amp;quot;background-color:#e9f9fa;&amp;quot;&lt;br /&gt;
| airdate ||Original broadcast or release date for the program &amp;lt;br&amp;gt;For USA, date should be EST &amp;lt;br&amp;gt; Outside USA, date should be local time.&amp;lt;br&amp;gt;If not applicable or available, original broadcast or release date for the Program. || Acceptable Formats:&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;YYYY-MM-DDTHH:MI:SS&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;YYYY-MM-DDHH:MI:SS&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;YYYY-MM-DDTHH:MI:SS+xx:xx&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;YYYY-MM-DDTHH:MI:SS-xx:xx&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;YYYYMMDDHH:MI:SS&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;YYYYMMDD HH:MI:SS&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;MM-DD-YYYY&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;MM/DD/YYYY&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;YYYYMMDD&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; || Yes || Client &lt;br /&gt;
|-&lt;br /&gt;
| isfullepisode || Full episode flag to identify differences between long form content. || &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;- full episode, &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt;- non full episode(clip,teaser,promo,etc.)&lt;br /&gt;
&amp;lt;small&amp;gt;Also accept: &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;lf&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;yes&amp;lt;/code&amp;gt;- longform&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;sf&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;no&amp;lt;/code&amp;gt;- shortform&lt;br /&gt;
|| Yes || Nielsen&lt;br /&gt;
|-style=&amp;quot;background-color:#e9f9fa;&amp;quot;&lt;br /&gt;
| adloadtype || &amp;lt;big&amp;gt;&amp;lt;small&amp;gt;Type of ad load: &lt;br /&gt;
&amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; Linear – matches TV ad load&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;2&amp;lt;/code&amp;gt; Dynamic – Dynamic Ad Insertion (DAI)&amp;lt;/small&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
|| &amp;lt;code&amp;gt;2&amp;lt;/code&amp;gt; - DCR measures content with dynamic ads || Yes || Nielsen&lt;br /&gt;
|-&lt;br /&gt;
| segB || One of two custom segment for the clients granular reporting within a brand. || Examples:&amp;lt;br&amp;gt;Genre - &amp;lt;code&amp;gt;horror&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;comedy&amp;lt;/code&amp;gt;, etc.&amp;lt;br&amp;gt;Timeslot - &amp;lt;code&amp;gt;primetime&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;daytime&amp;lt;/code&amp;gt;, etc.&amp;lt;br&amp;gt;News type - &amp;lt;code&amp;gt;breakingnews&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;weather&amp;lt;/code&amp;gt;, etc. || Optional || Client &lt;br /&gt;
|-style=&amp;quot;background-color:#e9f9fa;&amp;quot;&lt;br /&gt;
| segC || One of two custom segment for the clients granular reporting within a brand. || Examples:&amp;lt;br&amp;gt;Genre - &amp;lt;code&amp;gt;horror&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;comedy&amp;lt;/code&amp;gt;, etc.&amp;lt;br&amp;gt;Timeslot - &amp;lt;code&amp;gt;primetime&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;daytime&amp;lt;/code&amp;gt;, etc.&amp;lt;br&amp;gt;News type - &amp;lt;code&amp;gt;breakingnews&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;weather&amp;lt;/code&amp;gt;, etc. || Optional || Client &lt;br /&gt;
|}&lt;br /&gt;
Custom segments (segB and segC) can be used to aggregate video and/or static content within a single Brand to receive more granular reports within a brand.&lt;br /&gt;
&lt;br /&gt;
Examples regarding usage of segments within SDK:&lt;br /&gt;
* All comedy clips and stories for a Brand rolled into a &amp;quot;Comedy&amp;quot; segment&lt;br /&gt;
* genre grouping content by Comedy vs. Drama&lt;br /&gt;
* group related Text + Video content - i.e. for a show that has a lot of - static pages associated with it&lt;br /&gt;
* packaging based on how clients sell inventory&lt;br /&gt;
* grouping related types of content either by genre, category or platform.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;/div&gt;</summary>
		<author><name>NickParrucci</name></author>
	</entry>
	<entry>
		<id>https://nielsentest.mywikis.net/w/index.php?title=File:LGwebos_2.png&amp;diff=6563</id>
		<title>File:LGwebos 2.png</title>
		<link rel="alternate" type="text/html" href="https://nielsentest.mywikis.net/w/index.php?title=File:LGwebos_2.png&amp;diff=6563"/>
		<updated>2023-10-25T18:31:00Z</updated>

		<summary type="html">&lt;p&gt;NickParrucci: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;webos with logs&lt;/div&gt;</summary>
		<author><name>NickParrucci</name></author>
	</entry>
	<entry>
		<id>https://nielsentest.mywikis.net/w/index.php?title=File:WEBOS_1.png&amp;diff=6562</id>
		<title>File:WEBOS 1.png</title>
		<link rel="alternate" type="text/html" href="https://nielsentest.mywikis.net/w/index.php?title=File:WEBOS_1.png&amp;diff=6562"/>
		<updated>2023-10-25T18:30:04Z</updated>

		<summary type="html">&lt;p&gt;NickParrucci: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;webos screen&lt;/div&gt;</summary>
		<author><name>NickParrucci</name></author>
	</entry>
	<entry>
		<id>https://nielsentest.mywikis.net/w/index.php?title=webOS&amp;diff=6561</id>
		<title>webOS</title>
		<link rel="alternate" type="text/html" href="https://nielsentest.mywikis.net/w/index.php?title=webOS&amp;diff=6561"/>
		<updated>2023-10-25T18:27:32Z</updated>

		<summary type="html">&lt;p&gt;NickParrucci: Created page with &amp;quot;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|DCR &amp;amp; DTVR}}  {{CurrentBreadcrumb}} Category:Digital  __NOTOC__ == Introduction == The following document will highligh...&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;
&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;
* [https://engineeringportal.nielsen.com/docs/DCR_Video_Browser_SDK DCR Video]&lt;br /&gt;
* [https://engineeringportal.nielsen.com/docs/DCR_Static_Browser_SDK_(6.0.0) DCR Static]&lt;br /&gt;
* [https://engineeringportal.nielsen.com/docs/DTVR_Browser_SDK DTVR]&lt;/div&gt;</summary>
		<author><name>NickParrucci</name></author>
	</entry>
	<entry>
		<id>https://nielsentest.mywikis.net/w/index.php?title=DCR_and_DTVR_with_iOS17_or_TVOS17&amp;diff=6542</id>
		<title>DCR and DTVR with iOS17 or TVOS17</title>
		<link rel="alternate" type="text/html" href="https://nielsentest.mywikis.net/w/index.php?title=DCR_and_DTVR_with_iOS17_or_TVOS17&amp;diff=6542"/>
		<updated>2023-09-29T12:11:23Z</updated>

		<summary type="html">&lt;p&gt;NickParrucci: /* SDK Versions and Behavior */&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.2.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.2) 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 imrworldwide.com 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 non-tracking domain nmrodam.com. 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.2.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.2.0.0 (release date: September, 27 2023) 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.2.0.0 build with no 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;br /&gt;
&lt;br /&gt;
== SDK Versions and Behavior ==&lt;br /&gt;
NOTE: only AppSDK with ad support is included below, since other flavors are not concerned with IDFA/DeviceID&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|- style=&amp;quot;font-weight:bold; text-align:center;&amp;quot;&lt;br /&gt;
! Client app Xcode version &lt;br /&gt;
! iOS/TVOS Version&lt;br /&gt;
! AppSDK Version&lt;br /&gt;
! ATT Status&lt;br /&gt;
! Opt-out Status&lt;br /&gt;
! Tracking declared in privacy manifest (SDK or app level)&lt;br /&gt;
! Tracking Domain provided in privacy manifest (SDK or app level)&lt;br /&gt;
! Ping/Message Behavior&lt;br /&gt;
|-&lt;br /&gt;
| 14 &lt;br /&gt;
| any &lt;br /&gt;
| any&lt;br /&gt;
| &amp;quot;Allow Tracking&amp;quot;&lt;br /&gt;
| false&lt;br /&gt;
| n/a&lt;br /&gt;
| n/a&lt;br /&gt;
| All pings allowed, with DeviceID&lt;br /&gt;
|-&lt;br /&gt;
| 14 &lt;br /&gt;
| any &lt;br /&gt;
| any&lt;br /&gt;
| &amp;quot;Ask App Not to Track&amp;quot;&lt;br /&gt;
| true&lt;br /&gt;
| n/a&lt;br /&gt;
| n/a&lt;br /&gt;
| All pings allowed, blank DeviceID&lt;br /&gt;
|-&lt;br /&gt;
| 15 &lt;br /&gt;
| 16.x and below &lt;br /&gt;
| any&lt;br /&gt;
| &amp;quot;Allow Tracking&amp;quot;&lt;br /&gt;
| false&lt;br /&gt;
| no&lt;br /&gt;
| no&lt;br /&gt;
| All pings allowed, with DeviceID&lt;br /&gt;
|-&lt;br /&gt;
| 15 &lt;br /&gt;
| 16.x and below &lt;br /&gt;
| any&lt;br /&gt;
| &amp;quot;Ask App Not to Track&amp;quot;&lt;br /&gt;
| true&lt;br /&gt;
| no&lt;br /&gt;
| no&lt;br /&gt;
| All pings allowed, blank DeviceID&lt;br /&gt;
|-&lt;br /&gt;
| 15 &lt;br /&gt;
| 17 or greater &lt;br /&gt;
| 9.1.x.x and below&lt;br /&gt;
| &amp;quot;Ask App Not to Track&amp;quot;&lt;br /&gt;
| true&lt;br /&gt;
| no&lt;br /&gt;
| no&lt;br /&gt;
| All pings allowed, blank DeviceID&lt;br /&gt;
|-&lt;br /&gt;
| 15 &lt;br /&gt;
| 17 or greater &lt;br /&gt;
| 9.1.x.x and below&lt;br /&gt;
| &amp;quot;Allow Tracking&amp;quot;&lt;br /&gt;
| false&lt;br /&gt;
| no&lt;br /&gt;
| no&lt;br /&gt;
| All pings allowed, with DeviceID&lt;br /&gt;
|-&lt;br /&gt;
| 15 &lt;br /&gt;
| 17 or greater &lt;br /&gt;
| 9.2.0.0 and below&lt;br /&gt;
| &amp;quot;Ask App Not to Track&amp;quot;&lt;br /&gt;
| true&lt;br /&gt;
| yes (App level)&lt;br /&gt;
| yes - imrworldwide.com&lt;br /&gt;
| All pings allowed, blank DeviceID, SDK pings will use non-tracking domain nmrodram.com&lt;br /&gt;
|-&lt;br /&gt;
| 15 &lt;br /&gt;
| 17 or greater &lt;br /&gt;
| 9.2.0.0 and greater&lt;br /&gt;
| &amp;quot;Allow Tracking&amp;quot;&lt;br /&gt;
| false&lt;br /&gt;
| yes - (SDK level)&lt;br /&gt;
| yes - imrworldwide.com&lt;br /&gt;
| All pings allowed, with DeviceID&lt;br /&gt;
|-&lt;br /&gt;
| 15 &lt;br /&gt;
| 17 or greater &lt;br /&gt;
| 9.2.0.0 and greater&lt;br /&gt;
| &amp;quot;Ask App Not to Track&amp;quot;&lt;br /&gt;
| true&lt;br /&gt;
| yes - (SDK level)&lt;br /&gt;
| yes - imrworldwide.com&lt;br /&gt;
| All pings allowed, blank DeviceID, SDK pings will use non-tracking domain nmrodram.com, all the app traffic from non-sdk integrations going to tracking domain imrworldwide.com, will be blocked&lt;/div&gt;</summary>
		<author><name>NickParrucci</name></author>
	</entry>
	<entry>
		<id>https://nielsentest.mywikis.net/w/index.php?title=TVOS_SDK_Release_Notes&amp;diff=6532</id>
		<title>TVOS SDK Release Notes</title>
		<link rel="alternate" type="text/html" href="https://nielsentest.mywikis.net/w/index.php?title=TVOS_SDK_Release_Notes&amp;diff=6532"/>
		<updated>2023-09-27T18:11:48Z</updated>

		<summary type="html">&lt;p&gt;NickParrucci: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
 __NOTOC__ &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>NickParrucci</name></author>
	</entry>
	<entry>
		<id>https://nielsentest.mywikis.net/w/index.php?title=iOS_SDK_Release_Notes&amp;diff=6531</id>
		<title>iOS SDK Release Notes</title>
		<link rel="alternate" type="text/html" href="https://nielsentest.mywikis.net/w/index.php?title=iOS_SDK_Release_Notes&amp;diff=6531"/>
		<updated>2023-09-27T18:10:47Z</updated>

		<summary type="html">&lt;p&gt;NickParrucci: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital Downloads}} {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
 __NOTOC__ &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;
== 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>NickParrucci</name></author>
	</entry>
	<entry>
		<id>https://nielsentest.mywikis.net/w/index.php?title=Android_SDK_Release_Notes&amp;diff=6530</id>
		<title>Android SDK Release Notes</title>
		<link rel="alternate" type="text/html" href="https://nielsentest.mywikis.net/w/index.php?title=Android_SDK_Release_Notes&amp;diff=6530"/>
		<updated>2023-09-27T18:09:58Z</updated>

		<summary type="html">&lt;p&gt;NickParrucci: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital Downloads}} {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
 __NOTOC__ &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>NickParrucci</name></author>
	</entry>
	<entry>
		<id>https://nielsentest.mywikis.net/w/index.php?title=DCR_Video_iOS14_Migration&amp;diff=6526</id>
		<title>DCR Video iOS14 Migration</title>
		<link rel="alternate" type="text/html" href="https://nielsentest.mywikis.net/w/index.php?title=DCR_Video_iOS14_Migration&amp;diff=6526"/>
		<updated>2023-09-22T18:39:26Z</updated>

		<summary type="html">&lt;p&gt;NickParrucci: &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;
__NOTOC__&lt;br /&gt;
== Overview ==&lt;br /&gt;
NOTE: this page is for historical reference. In addition to dealing with App Tracking Transparency, developers should also be aware of changes related to iOS 17 detailed here: [[Nielsen_Digital_Measurement_and_iOS17_or_TVOS17]]&lt;br /&gt;
&lt;br /&gt;
Apple recently released a new policy on consent requirements for its mobile advertising tool, Identifier for Advertisers (IDFA). With this new policy, (App Tracking Setting) users can choose whether an IDFA may be used by mobile applications. iOS 14 was released on Sept 16th.&lt;br /&gt;
&lt;br /&gt;
==  What does this mean for measurement? ==&lt;br /&gt;
Apple added a new Framework called “The App Tracking Transparency Framework”. This is now required to control whether the Ad Framework will return the IDFA.  If our app requests the IDFA, but advertisingTrackingEnabled=No, then we will get: &amp;lt;code&amp;gt; IDFA = 00000000 -0000-0000-0000-000000000000&amp;lt;/code&amp;gt;. If a client is using our APP SDK v7 and below, running on a device with iOS14 installed, as this is a new framework, our SDK will never be able to retrieve the IDFA.&lt;br /&gt;
&lt;br /&gt;
Version 8 of our App SDK will come in two versions.  One that is enabled to work with the App Tracking Transparency Framework, and another version that does not use the Ad Framework.  A Table outlining the various iOS versions and Nielsen AppSDK versions is located later in this document.&lt;br /&gt;
&lt;br /&gt;
== Transparency Framework ==&lt;br /&gt;
Apple was going to force all publishers to check if &amp;lt;code&amp;gt;ATTrackingManager. AuthorizationStatus&amp;lt;/code&amp;gt; was equal to authorized.  Now however, since they are not forcing publishers to ask the user, as long as the &amp;lt;code&amp;gt;ATTrackingManager.AuthorizationStatus&amp;lt;/code&amp;gt; is equal to undefined, or authorized, you are allowed to grab the IDFA value.  The change they made was to allow us to use undefined as a valid state.&lt;br /&gt;
To display the App Tracking Transparency authorization request for accessing the IDFA, update your info.plist to add the &amp;lt;code&amp;gt;NSUserTrackingUsageDescription&amp;lt;/code&amp;gt; key with a custom message describing your usage.&lt;br /&gt;
&lt;br /&gt;
== SDK Versions and Behavior ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|- style=&amp;quot;font-weight:bold; text-align:center;&amp;quot;&lt;br /&gt;
! OS&lt;br /&gt;
! SDK Flavor/Version&lt;br /&gt;
! LAT/Tracking&lt;br /&gt;
! Opt-out Status&lt;br /&gt;
! Opt-out URL&lt;br /&gt;
! Integration Changes&lt;br /&gt;
|-&lt;br /&gt;
| iOS/tvOS 13 and below&lt;br /&gt;
| Appsdk &amp;lt; 7.2&lt;br /&gt;
| LAT works fine&lt;br /&gt;
| As per LAT&lt;br /&gt;
| LAT URL&lt;br /&gt;
| No Changes&lt;br /&gt;
|-&lt;br /&gt;
| iOS/tvOS 13 and below&lt;br /&gt;
| Appsdk without ad framework &amp;lt; 7.2&lt;br /&gt;
| NA (Not Applicable)&lt;br /&gt;
| User choice opt-out/in&lt;br /&gt;
| User choice opt-out/in url&lt;br /&gt;
| No Changes&lt;br /&gt;
|-&lt;br /&gt;
| iOS/tvOS 13 and below&lt;br /&gt;
| AppSDK 8.0&lt;br /&gt;
| LAT works fine&lt;br /&gt;
| As per LAT&lt;br /&gt;
| LAT URL&lt;br /&gt;
| No Changes&lt;br /&gt;
|-&lt;br /&gt;
| iOS/tvOS 13 or 14&lt;br /&gt;
| Appsdk 8.0 without Ad Framework&lt;br /&gt;
| NA (Not Applicable)&lt;br /&gt;
| User choice opt-out/in&lt;br /&gt;
| User choice opt-out/in url&lt;br /&gt;
| No Changes&lt;br /&gt;
|-&lt;br /&gt;
| iOS/tvOS 14&lt;br /&gt;
| Appsdk &amp;lt; 7.2&lt;br /&gt;
| No support for new Apple tracking API&lt;br /&gt;
| Opt-out will be marked as true&lt;br /&gt;
| LAT URL&lt;br /&gt;
| style=&amp;quot;font-weight:bold;&amp;quot; | Yes, Clients to upgrade to SDK 8.0&lt;br /&gt;
|-&lt;br /&gt;
| iOS/tvOS 14&lt;br /&gt;
| AppSDK 8.0&lt;br /&gt;
| Client has implemented the Consent pop-up.&lt;br /&gt;
| As per LAT&lt;br /&gt;
| LAT URL&lt;br /&gt;
| style=&amp;quot;font-weight:bold;&amp;quot; | Yes, Clients to implement pop-up and app store verbiage&lt;br /&gt;
|-&lt;br /&gt;
| iOS/tvOS 14.0 - 14.4&amp;lt;br /&amp;gt;APPLE is not enforcing App Transparency Layer (pop-up)&lt;br /&gt;
| AppSDK 8.0&lt;br /&gt;
| Apple not mandating consent pop-up.&lt;br /&gt;
| As per LAT&lt;br /&gt;
| LAT URL&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| iOS/tvOS 14.5+&amp;lt;br /&amp;gt;APPLE is enforcing App Transparency Layer (pop-up)&lt;br /&gt;
| AppSDK 8.0&lt;br /&gt;
| Client has not implemented the consent pop-up.&lt;br /&gt;
| As per LAT&lt;br /&gt;
| LAT URL&lt;br /&gt;
| style=&amp;quot;font-weight:bold;&amp;quot; | Yes, Clients to implement pop-up and app store verbiage&lt;br /&gt;
|-&lt;br /&gt;
| iOS/tvOS 14&lt;br /&gt;
| Appsdk 8.0 without Ad Framework&lt;br /&gt;
| style=&amp;quot;font-weight:bold;&amp;quot; | Clients denied the Ad Framework SDK&lt;br /&gt;
| User choice opt-out/in&lt;br /&gt;
| User choice opt-out/in url&lt;br /&gt;
| style=&amp;quot;font-weight:bold;&amp;quot; | Yes, Clients implement webview to pass user choice to the sdk. No changes for AGF no ad framework clients.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Privacy and Opt-Out ==&lt;br /&gt;
&lt;br /&gt;
=== OS-level Opt-out ===&lt;br /&gt;
The Nielsen SDK automatically leverages the iOS's '''Limit Ad Tracking''' or '''AppTracking''' setting.&lt;br /&gt;
&lt;br /&gt;
* If the User's device is running &amp;lt; iOS 13.x, the Nielsen SDK will check the status of '''Limit Ad Tracking''' (Located under Privacy &amp;gt;&amp;gt; Advertising). If this is enabled, the user will be opted out of demographic measurement.&lt;br /&gt;
* iOS14 modifies the way Apple manages the collection of a User's Opt-In status through '''AppTracking'''. Starting with Version 8.x+, the Nielsen App SDK will check the iOS version during initialization. If the device is running iOS12 or iOS13, the Limit Ad Tracking setting is requested. If iOS14.x +, then AppTracking is utilized.&lt;br /&gt;
If using the Nielsen SDK V7 on a device running iOS14, the value returned will always be isAdvertisingTrackingEnabled = true opting out the user from demographic measurement.&lt;br /&gt;
Apple started requiring publishers to secure consent from the user in iOS14.5+. This means the AppTracking Setting must equal approved before the User is Opted in.&lt;br /&gt;
* '''Limit Ad Tracking''' is managed using the isAdvertisingTrackingEnabled value.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;background-color:#F3F3F3;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Value Returned in iOS12 / iOS13 using Nielsen SDK &amp;lt; V7.x&lt;br /&gt;
! style=&amp;quot;color:#222;&amp;quot; | Opt in/out Status&lt;br /&gt;
|- style=&amp;quot;background-color:#D9EAD3; color:#222;&amp;quot;&lt;br /&gt;
| isAdvertisingTrackingEnabled = false&lt;br /&gt;
| User will be included in demographic measurement.&lt;br /&gt;
|- style=&amp;quot;background-color:#FCF0E4; color:#222;&amp;quot;&lt;br /&gt;
| isAdvertisingTrackingEnabled = true&lt;br /&gt;
| User will NOT be included in demographic measurement.&lt;br /&gt;
|}&lt;br /&gt;
* '''AppTracking''' is managed using the [https://developer.apple.com/documentation/apptrackingtransparency AppTrackingTransparency framework]. If the value returned when checked is:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;background-color:#EAECF0;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Value Returned is iOS14 using Nielsen SDK &amp;gt; V8.x&lt;br /&gt;
! style=&amp;quot;color:#222;&amp;quot; | Opt in/out Status&lt;br /&gt;
|- style=&amp;quot;background-color:#D9EAD3; color:#222;&amp;quot;&lt;br /&gt;
| ATTrackingManager.AuthorizationStatus.authorized&lt;br /&gt;
| User will be included in demographic measurement.&lt;br /&gt;
|- style=&amp;quot;background-color:#FCF0E4; color:#222;&amp;quot;&lt;br /&gt;
| ATTrackingManager.AuthorizationStatus.notDeterminded&amp;lt;br /&amp;gt;ATTrackingManager.AuthorizationStatus.denied&amp;lt;br /&amp;gt;ATTrackingManager.AuthorizationStatus.restricted&lt;br /&gt;
| User will NOT be included in demographic measurement.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The user is opted out of demographic measurement if the OS-level Limit Ad Tracking setting is enabled, or AppTracking value equals denied or restricted. As a publisher, you cannot override this setting.&lt;br /&gt;
&lt;br /&gt;
== User Choice ==&lt;br /&gt;
The User Choice method can be used without the Ad Framework, or in situations where the publisher does not wish to use the [https://developer.apple.com/documentation/apptrackingtransparency App Tracking Transparency Framework].&lt;/div&gt;</summary>
		<author><name>NickParrucci</name></author>
	</entry>
	<entry>
		<id>https://nielsentest.mywikis.net/w/index.php?title=Nielsen_Digital_Measurement_and_iOS17_or_TVOS17&amp;diff=6525</id>
		<title>Nielsen Digital Measurement and iOS17 or TVOS17</title>
		<link rel="alternate" type="text/html" href="https://nielsentest.mywikis.net/w/index.php?title=Nielsen_Digital_Measurement_and_iOS17_or_TVOS17&amp;diff=6525"/>
		<updated>2023-09-22T18:36:44Z</updated>

		<summary type="html">&lt;p&gt;NickParrucci: &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;
===&amp;lt;span style=&amp;quot;color: #ff0000;&amp;quot;&amp;gt;Please note: this page will be updated as more information becomes available from Apple&amp;lt;/span&amp;gt;===&lt;br /&gt;
&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;
===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.2) 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 imrworldwide.com 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 non-tracking domain nmrodam.com. 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 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>NickParrucci</name></author>
	</entry>
	<entry>
		<id>https://nielsentest.mywikis.net/w/index.php?title=DCR_and_DTVR_with_iOS17_or_TVOS17&amp;diff=6524</id>
		<title>DCR and DTVR with iOS17 or TVOS17</title>
		<link rel="alternate" type="text/html" href="https://nielsentest.mywikis.net/w/index.php?title=DCR_and_DTVR_with_iOS17_or_TVOS17&amp;diff=6524"/>
		<updated>2023-09-22T18:33:25Z</updated>

		<summary type="html">&lt;p&gt;NickParrucci: Created page with &amp;quot;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|DCR &amp;amp; DTVR}}  {{CurrentBreadcrumb}} Category:Digital  __NOTOC__  == Overview == Summary: The latest version of Nielsen...&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;
&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.2.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.2) 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 imrworldwide.com 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 non-tracking domain nmrodam.com. 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.2.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.2.0.0 (release date: September, 27 2023) 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.2.0.0 build with no 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;br /&gt;
&lt;br /&gt;
== SDK Versions and Behavior ==&lt;br /&gt;
NOTE: only AppSDK with ad support is included below, since other flavors are not concerned with IDFA/DeviceID&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|- style=&amp;quot;font-weight:bold; text-align:center;&amp;quot;&lt;br /&gt;
! Client app Xcode version &lt;br /&gt;
! iOS/TVOS Version&lt;br /&gt;
! AppSDK Version&lt;br /&gt;
! ATT Status&lt;br /&gt;
! Opt-out Status&lt;br /&gt;
! Tracking declared in privacy manifest (SDK or app level)&lt;br /&gt;
! Tracking Domain provided in privacy manifest (SDK or app level)&lt;br /&gt;
! Ping/Message Behavior&lt;br /&gt;
|-&lt;br /&gt;
| 14 &lt;br /&gt;
| any &lt;br /&gt;
| any&lt;br /&gt;
| &amp;quot;Allow Tracking&amp;quot;&lt;br /&gt;
| false&lt;br /&gt;
| n/a&lt;br /&gt;
| n/a&lt;br /&gt;
| All pings allowed, with DeviceID&lt;br /&gt;
|-&lt;br /&gt;
| 14 &lt;br /&gt;
| any &lt;br /&gt;
| any&lt;br /&gt;
| &amp;quot;Ask App Not to Track&amp;quot;&lt;br /&gt;
| true&lt;br /&gt;
| n/a&lt;br /&gt;
| n/a&lt;br /&gt;
| All pings allowed, blank DeviceID&lt;br /&gt;
|-&lt;br /&gt;
| 15 &lt;br /&gt;
| 16.x and below &lt;br /&gt;
| any&lt;br /&gt;
| &amp;quot;Allow Tracking&amp;quot;&lt;br /&gt;
| false&lt;br /&gt;
| no&lt;br /&gt;
| no&lt;br /&gt;
| All pings allowed, with DeviceID&lt;br /&gt;
|-&lt;br /&gt;
| 15 &lt;br /&gt;
| 16.x and below &lt;br /&gt;
| any&lt;br /&gt;
| &amp;quot;Ask App Not to Track&amp;quot;&lt;br /&gt;
| true&lt;br /&gt;
| no&lt;br /&gt;
| no&lt;br /&gt;
| All pings allowed, blank DeviceID&lt;br /&gt;
|-&lt;br /&gt;
| 15 &lt;br /&gt;
| 17 or greater &lt;br /&gt;
| 9.1.x.x and below&lt;br /&gt;
| &amp;quot;Allow Tracking&amp;quot;&lt;br /&gt;
| false&lt;br /&gt;
| no&lt;br /&gt;
| no&lt;br /&gt;
| All pings allowed, with DeviceID&lt;br /&gt;
|-&lt;br /&gt;
| 15 &lt;br /&gt;
| 17 or greater &lt;br /&gt;
| 9.1.x.x and below&lt;br /&gt;
| &amp;quot;Ask App Not to Track&amp;quot;&lt;br /&gt;
| true&lt;br /&gt;
| no&lt;br /&gt;
| no&lt;br /&gt;
| All pings allowed, blank DeviceID&lt;br /&gt;
|-&lt;br /&gt;
| 15 &lt;br /&gt;
| 17 or greater &lt;br /&gt;
| 9.1.x.x and below&lt;br /&gt;
| &amp;quot;Allow Tracking&amp;quot;&lt;br /&gt;
| false&lt;br /&gt;
| no&lt;br /&gt;
| no&lt;br /&gt;
| All pings allowed, with DeviceID&lt;br /&gt;
|-&lt;br /&gt;
| 15 &lt;br /&gt;
| 17 or greater &lt;br /&gt;
| 9.2.0.0 and below&lt;br /&gt;
| &amp;quot;Ask App Not to Track&amp;quot;&lt;br /&gt;
| true&lt;br /&gt;
| yes (App level)&lt;br /&gt;
| yes - imrworldwide.com&lt;br /&gt;
| All pings allowed, blank DeviceID, SDK pings will use non-tracking domain nmrodram.com&lt;br /&gt;
|-&lt;br /&gt;
| 15 &lt;br /&gt;
| 17 or greater &lt;br /&gt;
| 9.2.0.0 and greater&lt;br /&gt;
| &amp;quot;Allow Tracking&amp;quot;&lt;br /&gt;
| false&lt;br /&gt;
| yes - (SDK level)&lt;br /&gt;
| yes - imrworldwide.com&lt;br /&gt;
| All pings allowed, with DeviceID&lt;br /&gt;
|-&lt;br /&gt;
| 15 &lt;br /&gt;
| 17 or greater &lt;br /&gt;
| 9.2.0.0 and greater&lt;br /&gt;
| &amp;quot;Ask App Not to Track&amp;quot;&lt;br /&gt;
| true&lt;br /&gt;
| yes - (SDK level)&lt;br /&gt;
| yes - imrworldwide.com&lt;br /&gt;
| All pings allowed, blank DeviceID, SDK pings will use non-tracking domain nmrodram.com, all the app traffic from non-sdk integrations going to tracking domain imrworldwide.com, will be blocked&lt;/div&gt;</summary>
		<author><name>NickParrucci</name></author>
	</entry>
	<entry>
		<id>https://nielsentest.mywikis.net/w/index.php?title=Nielsen_Digital_Measurement_and_iOS17_or_TVOS17&amp;diff=6523</id>
		<title>Nielsen Digital Measurement and iOS17 or TVOS17</title>
		<link rel="alternate" type="text/html" href="https://nielsentest.mywikis.net/w/index.php?title=Nielsen_Digital_Measurement_and_iOS17_or_TVOS17&amp;diff=6523"/>
		<updated>2023-09-13T15:55:06Z</updated>

		<summary type="html">&lt;p&gt;NickParrucci: /* Integration Guide */&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;
===&amp;lt;span style=&amp;quot;color: #ff0000;&amp;quot;&amp;gt;Please note: this page will be updated as more information becomes available from Apple&amp;lt;/span&amp;gt;===&lt;br /&gt;
&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;
===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.2) 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 imrworldwide.com 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 non-tracking domain nmrodam.com. 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 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;
Technical details about the upcoming iOS/tvOS AppSDK release for Nielsen client app developers will be coming soon.&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>NickParrucci</name></author>
	</entry>
	<entry>
		<id>https://nielsentest.mywikis.net/w/index.php?title=Nielsen_Digital_Measurement_and_iOS17_or_TVOS17&amp;diff=6512</id>
		<title>Nielsen Digital Measurement and iOS17 or TVOS17</title>
		<link rel="alternate" type="text/html" href="https://nielsentest.mywikis.net/w/index.php?title=Nielsen_Digital_Measurement_and_iOS17_or_TVOS17&amp;diff=6512"/>
		<updated>2023-09-06T18:17:21Z</updated>

		<summary type="html">&lt;p&gt;NickParrucci: /* Next Steps */&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;
===&amp;lt;span style=&amp;quot;color: #ff0000;&amp;quot;&amp;gt;Please note: this page will be updated as more information becomes available from Apple&amp;lt;/span&amp;gt;===&lt;br /&gt;
&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;
===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.2) 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 imrworldwide.com 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 non-tracking domain nmrodam.com. 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 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;
==Integration Guide==&lt;br /&gt;
Technical details about the upcoming iOS/tvOS AppSDK release for Nielsen client app developers will be coming soon.&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>NickParrucci</name></author>
	</entry>
	<entry>
		<id>https://nielsentest.mywikis.net/w/index.php?title=Nielsen_Digital_Measurement_and_iOS17_or_TVOS17&amp;diff=6511</id>
		<title>Nielsen Digital Measurement and iOS17 or TVOS17</title>
		<link rel="alternate" type="text/html" href="https://nielsentest.mywikis.net/w/index.php?title=Nielsen_Digital_Measurement_and_iOS17_or_TVOS17&amp;diff=6511"/>
		<updated>2023-09-06T18:15:42Z</updated>

		<summary type="html">&lt;p&gt;NickParrucci: Created page with &amp;quot;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|DCR &amp;amp; DTVR}}  {{CurrentBreadcrumb}} Category:Digital  __NOTOC__ ===&amp;lt;span style=&amp;quot;color: #ff0000;&amp;quot;&amp;gt;Please note: this page...&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;
&lt;br /&gt;
__NOTOC__&lt;br /&gt;
===&amp;lt;span style=&amp;quot;color: #ff0000;&amp;quot;&amp;gt;Please note: this page will be updated as more information becomes available from Apple&amp;lt;/span&amp;gt;===&lt;br /&gt;
&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;
===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.2) 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 imrworldwide.com 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 non-tracking domain nmrodam.com. 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 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;
==Integration Guide==&lt;br /&gt;
Technical details about the upcoming iOS/tvOS AppSDK release for Nielsen client app developers will be coming soon.&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>NickParrucci</name></author>
	</entry>
	<entry>
		<id>https://nielsentest.mywikis.net/w/index.php?title=DCR_Chromecast_browser_SDK&amp;diff=6510</id>
		<title>DCR Chromecast browser SDK</title>
		<link rel="alternate" type="text/html" href="https://nielsentest.mywikis.net/w/index.php?title=DCR_Chromecast_browser_SDK&amp;diff=6510"/>
		<updated>2023-09-05T18:27:10Z</updated>

		<summary type="html">&lt;p&gt;NickParrucci: /* SENDER side */&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;
== 1. General Cast architecture ==&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
[[File:GeneralCastArch.png||600px|center|]]&lt;br /&gt;
See https://developers.google.com/cast/docs/developers&lt;br /&gt;
&lt;br /&gt;
=== Sender App ===&lt;br /&gt;
is a user controlled JavaScript/HTML5 application which can run on browsers in mobile or desktop devices.&lt;br /&gt;
&lt;br /&gt;
=== Receiver App ===&lt;br /&gt;
is an HTML5/JavaScript application placed at a custom URL that handles communication between the Sender app and the Chromecast device.&lt;br /&gt;
&lt;br /&gt;
== 2. Cast scenarios ==&lt;br /&gt;
&lt;br /&gt;
=== 2.1 Pure casting scenario === &lt;br /&gt;
In the Pure casting scenario the video plays on the Chromecast device, while playback stops on the sender app &amp;lt;br /&amp;gt;&lt;br /&gt;
The sender app should not pass any Nielsen API calls once the pure casting scenario starts. All Nielsen API calls are handled by the receiver app.&lt;br /&gt;
[[File:NielsenChromecastCast.png|600px|center]]&lt;br /&gt;
&lt;br /&gt;
=== 2.2 Chromecast mirroring scenario ===&lt;br /&gt;
In the Chromecast mirroring scenario the video plays on both the sender and receiver apps.  &amp;lt;br /&amp;gt; &lt;br /&gt;
[[File:NielsenChromecastMirror.png|600px|center]]&lt;br /&gt;
&lt;br /&gt;
== 3.Sender App JavaScript - Nielsen Browser SDK implementation ==&lt;br /&gt;
&lt;br /&gt;
=== 3.1 General ===&lt;br /&gt;
By adding the below cast-specific API calls alongside the standard implementation of the Nielsen Browser SDK, a sender app can pass appropriate cast-specific metadata.&lt;br /&gt;
&lt;br /&gt;
=== 3.2 API calls ===&lt;br /&gt;
&lt;br /&gt;
==== 3.2.1 updateOTT ====&lt;br /&gt;
The below call should be made to the Browser SDK whenever the player switches from not casting to casting and vice versa.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
nolSDKInstance.ggPM('updateOTT',contentMetadataObject);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
Use the updateOTT method to notify the casting BrowserSDK instance whether the remote OTT device (like Google ChromeCast, Roku, Amazon FireTV, etc.) is connected or disconnected (indicated by &amp;quot;ottStatus&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
When the OTT device is connected, call updateOTT with &amp;quot;ottStatus&amp;quot;: &amp;quot;1&amp;quot; as well as a set of OTT device related parameters in the contentMetadataObject.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
var contentMetadataObject ={&lt;br /&gt;
        type: &amp;quot;content&amp;quot;,&lt;br /&gt;
        ottStatus: &amp;quot;1&amp;quot;,&lt;br /&gt;
        ottType: &amp;quot;casting&amp;quot;,&lt;br /&gt;
        ottDevice: &amp;quot;chromecast&amp;quot;,&lt;br /&gt;
        ottDeviceName: &amp;quot;Google Chromecast&amp;quot;,&lt;br /&gt;
        ottDeviceID: nolSDKInstance.getId(),&lt;br /&gt;
        ottDeviceManufacturer: &amp;quot;Google&amp;quot;,&lt;br /&gt;
        ottDeviceModel: &amp;quot;ChromeCastModel&amp;quot;,&lt;br /&gt;
        ottDeviceVersion: &amp;quot;1.0.0&amp;quot; &lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When the OTT device is disconnected, call updateOTT with “ottStatus”: “0”.&lt;br /&gt;
&lt;br /&gt;
==== 3.2.2 getOptOutStatus() and sessionId ====&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
Assign the below mediaInfo metadata parameters in the target load so that they may be passed to the receiver at the beginning of the casting session.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
mediaInfo.metadata.kGCKMetadataNlsKeyDeviceID = nolSDKInstance.sessionId; //Session Id&lt;br /&gt;
mediaInfo.metadata.kGCKMetadataNlsKeyOptout   = nolSDKInstance.getOptOutStatus(); //OptOut status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
Below is a sample code snippet on how the sender browser app should retrieve and relay the information from sender to receiver app.&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
        var mediaInfo = new chrome.cast.media.MediaInfo(&lt;br /&gt;
         this.mediaContents[mediaIndex]['sources'][0], 'video/mp4');&lt;br /&gt;
&lt;br /&gt;
        mediaInfo.metadata = new chrome.cast.media.GenericMediaMetadata();&lt;br /&gt;
        mediaInfo.metadata.metadataType = chrome.cast.media.MetadataType.GENERIC;&lt;br /&gt;
        mediaInfo.metadata.title = this.mediaContents[mediaIndex]['title'];&lt;br /&gt;
        mediaInfo.metadata.length = this.currentMediaDuration;&lt;br /&gt;
        mediaInfo.metadata.images = [&lt;br /&gt;
            {'url': MEDIA_SOURCE_ROOT + this.mediaContents[mediaIndex]['thumb']}];&lt;br /&gt;
&lt;br /&gt;
        /*Adding custom parameters in metadata to be passed to receiver*/&lt;br /&gt;
        mediaInfo.metadata.kGCKMetadataNlsKeyDeviceID = nolSDKInstance.sessionId; //Session Id&lt;br /&gt;
        mediaInfo.metadata.kGCKMetadataNlsKeyOptout   = nolSDKInstance.getOptOutStatus(); //OptOut status&lt;br /&gt;
&lt;br /&gt;
        var request = new chrome.cast.media.LoadRequest(mediaInfo);&lt;br /&gt;
          castSession.loadMedia(request).then(&lt;br /&gt;
           this.playerHandler.loaded.bind(this.playerHandler),&lt;br /&gt;
           function (errorCode) {&lt;br /&gt;
             this.playerState = PLAYER_STATE.ERROR;&lt;br /&gt;
             console.log('Remote media load error: ' +&lt;br /&gt;
               CastPlayer.getErrorMessage(errorCode));&lt;br /&gt;
          }.bind(this));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 4. Summary - Sequence of API calls  ==&lt;br /&gt;
Below is the sequence of API calls from the beginning to the end of casting.&lt;br /&gt;
&lt;br /&gt;
=== SENDER side ===&lt;br /&gt;
1) If the video is playing only on the Sender App, the standard Nielsen Browser SDK API calls should be invoked.&amp;lt;br /&amp;gt; &lt;br /&gt;
2) Once a user presses the cast icon and if the video is playing already, call browser sdk '''end()''' api. &amp;lt;br /&amp;gt;&lt;br /&gt;
3) Inform the Browser SDK about the Chromecast's status (connected or disconnected) by calling '''updateOTT()''' and passing metadata object. &amp;lt;br /&amp;gt; &lt;br /&gt;
4) Retrieve the OptOutStatus and sessionId.&amp;lt;br /&amp;gt;&lt;br /&gt;
5) Pass the optOutStatus and sessionId into the MediaInfo metadata object.&amp;lt;br /&amp;gt; &lt;br /&gt;
6) When the Start casting (the video should be stopped on the sender device).&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== RECEIVER side === &lt;br /&gt;
Playback has started at ChromeCast device (TV).&amp;lt;br /&amp;gt;&lt;br /&gt;
7) Retrieve the MediaInfo metadata sent by the sender device. &amp;lt;br /&amp;gt;&lt;br /&gt;
8) [https://engineeringportal.nielsen.com/docs/DCR_Video_Browser_SDK#Initialization_API_Call Instantiate] the Browser SDK. &amp;lt;br /&amp;gt;&lt;br /&gt;
9) Pass content/ad metadata by calling '''loadMetaData()'''. &amp;lt;br /&amp;gt;&lt;br /&gt;
10) Send '''updateOTT''' event to BSDK receiver instance, to relay the sender OTT metadata ( kGCKMetadataNlsKeyDeviceID and kGCKMetadataNlsKeyOptout) received from sender app.&amp;lt;br /&amp;gt;&lt;br /&gt;
11) Pass content/ad playheads every second by calling '''setPlayheadPosition()'''. &amp;lt;br /&amp;gt;&lt;br /&gt;
12) Based on the user's interactions or the playlist state, call '''stop()''' (once paused) or '''end()''' (once the content or casting has ended).&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== SENDER side ===&lt;br /&gt;
Casting has ended and playback resumes on the sender device.&amp;lt;br /&amp;gt;&lt;br /&gt;
13) Start a new session by calling content/ad '''loadMetaData()'''.&amp;lt;br /&amp;gt;&lt;br /&gt;
14) Continue sending API calls as usual.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Below is a sample code snippet on how the receiver app should retrieve the ottMetadata received from sender apps and relay the information  to receiver BSDK instance.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
sampleplayer.CastPlayer.prototype.onLoad_ = function(event) {&lt;br /&gt;
var senderMetadata = event.data.media.metadata,&lt;br /&gt;
sessionId = senderMetadata.kGCKMetadataNlsKeyDeviceID,&lt;br /&gt;
optout = senderMetadata.kGCKMetadataNlsKeyOptout;&lt;br /&gt;
  this.cancelDeferredPlay_('new media is loaded');&lt;br /&gt;
  this.load(new cast.receiver.MediaManager.LoadInfo( (event.data),  event.senderId));&lt;br /&gt;
	var contentMetadata = {&lt;br /&gt;
         	   &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;,&lt;br /&gt;
          	  &amp;quot;dataSrc&amp;quot;: &amp;quot;cms&amp;quot;,&lt;br /&gt;
           	 &amp;quot;assetid&amp;quot;: &amp;quot;vid-123&amp;quot;,&lt;br /&gt;
          	  &amp;quot;assetName&amp;quot;: &amp;quot;Test video&amp;quot;,&lt;br /&gt;
           	 &amp;quot;program&amp;quot;: &amp;quot;Test program&amp;quot;,&lt;br /&gt;
          	  &amp;quot;title&amp;quot;: &amp;quot;Clickbaby&amp;quot;,&lt;br /&gt;
          	  &amp;quot;length&amp;quot;:”60”,&lt;br /&gt;
          	  &amp;quot;segA&amp;quot;: &amp;quot;CustomSegmentValueA&amp;quot;,&lt;br /&gt;
          	  &amp;quot;segB&amp;quot;: &amp;quot;CustomSegmentValueB&amp;quot;,&lt;br /&gt;
          	  &amp;quot;segC&amp;quot;: &amp;quot;CustomSegmentValueC&amp;quot;&lt;br /&gt;
	};&lt;br /&gt;
      window.nolSDKInstance.ggPM('loadMetadata', contentMetadata);&lt;br /&gt;
	   var ottMetadataObject ={&lt;br /&gt;
			ottStatus: &amp;quot;1&amp;quot;,&lt;br /&gt;
			ottType: &amp;quot;casting&amp;quot;,&lt;br /&gt;
			ottDevice: &amp;quot;chromecast&amp;quot;,&lt;br /&gt;
			ottDeviceName: &amp;quot;Google Chromecast&amp;quot;,&lt;br /&gt;
			ottDeviceID: nolSDKInstance.getId(),&lt;br /&gt;
			ottDeviceManufacturer: &amp;quot;Google&amp;quot;,&lt;br /&gt;
			ottDeviceModel: &amp;quot;ChromeCastModel&amp;quot;,&lt;br /&gt;
			ottDeviceVersion: &amp;quot;1.0.0&amp;quot;, &lt;br /&gt;
			kGCKMetadataNlsKeyOptout : optout,&lt;br /&gt;
		    kGCKMetadataNlsKeyDeviceID : sessionId	&lt;br /&gt;
		  };&lt;br /&gt;
window.nolSDKInstance.ggPM('updateOTT', ottMetadataObject);};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
Chromecast Developer Documentation: &amp;lt;https://developers.google.com/cast/docs/developers&amp;gt; &amp;lt;br /&amp;gt;&lt;br /&gt;
Browser SDK API Reference: &amp;lt;https://engineeringportal.nielsen.com/docs/Browser_SDK_API_Reference&amp;gt; &amp;lt;br /&amp;gt;&lt;/div&gt;</summary>
		<author><name>NickParrucci</name></author>
	</entry>
	<entry>
		<id>https://nielsentest.mywikis.net/w/index.php?title=DTVR_Browser_SDK&amp;diff=6509</id>
		<title>DTVR Browser SDK</title>
		<link rel="alternate" type="text/html" href="https://nielsentest.mywikis.net/w/index.php?title=DTVR_Browser_SDK&amp;diff=6509"/>
		<updated>2023-08-25T20:36:34Z</updated>

		<summary type="html">&lt;p&gt;NickParrucci: /* Configure API calls - setVolume */&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;
    ! 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;
&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>NickParrucci</name></author>
	</entry>
	<entry>
		<id>https://nielsentest.mywikis.net/w/index.php?title=Digital_Measurement_Metadata&amp;diff=6504</id>
		<title>Digital Measurement Metadata</title>
		<link rel="alternate" type="text/html" href="https://nielsentest.mywikis.net/w/index.php?title=Digital_Measurement_Metadata&amp;diff=6504"/>
		<updated>2023-08-21T18:07:16Z</updated>

		<summary type="html">&lt;p&gt;NickParrucci: /* Example Content Object */&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;
__NOTOC__&lt;br /&gt;
= Digital Metadata =&lt;br /&gt;
Digital Metadata can passed through key-values using the Nielsen reserved keys. The keys and values are listed by product below. &lt;br /&gt;
&lt;br /&gt;
== Digital Content Ratings (DCR) Metadata ==&lt;br /&gt;
=== Video Metadata ===&lt;br /&gt;
{{DCR Content Metadata}}&lt;br /&gt;
&lt;br /&gt;
==== Example Video Metadata 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:        'The Big Bang Theory',&lt;br /&gt;
  title:          'The Pants Alternative S03E18',  //no abbreviations or shorthand&lt;br /&gt;
  length:         '1320',   //lengths in seconds&lt;br /&gt;
  airdate:        '2021-03-21T12:00:00Z',&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;
&lt;br /&gt;
=== Static Metadata ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Key !! Description !! Data Type !! Value !! Required?&lt;br /&gt;
|-&lt;br /&gt;
| type || asset type || fixed || &amp;lt;code&amp;gt;'static'&amp;lt;/code&amp;gt; || Yes&lt;br /&gt;
|-&lt;br /&gt;
| assetid || Unique ID for each article || dynamic || custom &amp;lt;br&amp;gt;(no [[Special Characters]]) || Yes&lt;br /&gt;
|-&lt;br /&gt;
| section || section of each site (e.g. section value should be first level in page URL: website.com/section). Limit to 25 unique values || dynamic || custom &amp;lt;br&amp;gt;(no [[Special Characters]]) || Yes&lt;br /&gt;
|-&lt;br /&gt;
| segA || custom segment for reporting: Limit to 25 unique values across custom segments (segA + segB + segC) || dynamic || custom || No&lt;br /&gt;
|-&lt;br /&gt;
| segB || custom segment for reporting: Limit to 25 unique values across custom segments (segA + segB + segC) || dynamic || custom || No&lt;br /&gt;
|-&lt;br /&gt;
| segC || custom segment for reporting: Limit to 25 unique values across custom segments (segA + segB + segC) || dynamic || custom || No&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The values passed through the Nielsen keys will determine the breakouts that are seen in reporting. The custom segments (A, B &amp;amp; C) will roll into the sub-brand. To not use custom segments A, B and C, do not pass any value in these keys.&lt;br /&gt;
&lt;br /&gt;
==== Example Static Metadata 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: '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: 'HD Videos', // *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;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Digital TV Ratings (DTVR) Metadata ==&lt;br /&gt;
=== Content Metadata ===&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;
| 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;
====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;
  adModel: '1'&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Custom Variables Extension ====&lt;br /&gt;
If you are looking for additional reporting options, reach out to us. We have a [[Custom Variables Extension]] and can work with you to obtain your desired reporting.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Key&lt;br /&gt;
! Description&lt;br /&gt;
! style=&amp;quot;width: 14%;&amp;quot; | Values&lt;br /&gt;
! style=&amp;quot;width: 12%;&amp;quot; | Required for Audio/Video?&lt;br /&gt;
! style=&amp;quot;width: 12%;&amp;quot; | Required for Static (page)?&lt;br /&gt;
! Reported for&lt;br /&gt;
|-&lt;br /&gt;
| clientid || Brand value is automatically populated through the App ID provided. The value passed here will override the default value. (e.g. Multiple brands in App) || custom || Optional || Optional || Audio / Video and Static Measurement&lt;br /&gt;
|-&lt;br /&gt;
| subbrand || VCID value is automatically populated through the App ID provided. This value passed here will override the default value. (e.g. Multiple Sub-brands in App) || custom || Optional || Optional || Audio / Video and Static Measurement&lt;br /&gt;
|-&lt;br /&gt;
| type ||&lt;br /&gt;
Type of measurement:&lt;br /&gt;
*audio / video – &amp;quot;content&amp;quot;&lt;br /&gt;
*page – &amp;quot;static&amp;quot;&lt;br /&gt;
*ad – &amp;quot;preroll&amp;quot;, &amp;quot;midroll&amp;quot; or &amp;quot;postroll&amp;quot;&lt;br /&gt;
|| &amp;quot;content&amp;quot;, &amp;quot;static&amp;quot; || Mandatory || Mandatory || &lt;br /&gt;
|-&lt;br /&gt;
| assetid || ID assigned to content. '''Must be unique and consistent''' across all content at the episode level, as well as across platforms (e.g. iOS and Android use the same ID). || custom&amp;lt;br&amp;gt;(no [[Special Characters]]) || Mandatory || Not Required || &lt;br /&gt;
|-&lt;br /&gt;
| section || Section of site || custom || Not Required || Mandatory || &lt;br /&gt;
|-&lt;br /&gt;
| isfullepisode || Full episode flag ||&lt;br /&gt;
*&amp;quot;y&amp;quot; or &amp;quot;lf&amp;quot; - full episode&lt;br /&gt;
*&amp;quot;n&amp;quot; or &amp;quot;sf&amp;quot; - short form&lt;br /&gt;
|| Mandatory || Not Required ||&lt;br /&gt;
|-&lt;br /&gt;
| program || Program name || custom || Mandatory || Not Required || Audio / Video Measurement&lt;br /&gt;
|-&lt;br /&gt;
| title || Episode title || custom || Mandatory || Not Required || Audio / Video Measurement&lt;br /&gt;
|-&lt;br /&gt;
| length || Length of content in seconds for VOD. 0 may be used for Live content if the exact content length is not known.  || custom || Mandatory || Not Required ||&lt;br /&gt;
|-&lt;br /&gt;
| segA || Segment A (this is not available for audio / video Measurement reporting as the episode title is reported) || custom || Not Required || Not Required || Static Measurement&lt;br /&gt;
|-&lt;br /&gt;
| segB || Segment B || custom || Not Required || Not Required || Audio / Video and Static Measurement&lt;br /&gt;
|-&lt;br /&gt;
| segC || Segment C || custom || Not Required || Not Required || Audio / Video and Static Measurement&lt;br /&gt;
|-&lt;br /&gt;
| crossId1 || Standard episode ID. Gracenote/TMS ID should be used when available. Must be unique per episode. || custom || Optional || Not Required ||&lt;br /&gt;
|-&lt;br /&gt;
| crossId2 || Content originator (required only for distributors) || custom || Optional || Not Required ||&lt;br /&gt;
|-&lt;br /&gt;
| airdate || Original (local) air date and time (Eastern Time for US) || YYYYMMDD HH24:MI:SS || Mandatory || Not Required ||&lt;br /&gt;
|-&lt;br /&gt;
| pipmode ||&lt;br /&gt;
Current state of picture-in-picture (PIP) mode on device.&lt;br /&gt;
*&amp;quot;true&amp;quot; if audio / video measurement is displayed in PIP mode&lt;br /&gt;
*&amp;quot;false&amp;quot; if audio / video measurement is displayed in regular mode&lt;br /&gt;
|| &amp;quot;true&amp;quot;, &amp;quot;false&amp;quot; || Optional || Not Required || Audio / Video Measurement&lt;br /&gt;
|-&lt;br /&gt;
| adloadtype ||&lt;br /&gt;
Type of ad load:&lt;br /&gt;
#Linear - matches TV ad load&lt;br /&gt;
#Dynamic - Dynamic Ad Insertion (DAI)&lt;br /&gt;
|| &amp;quot;1&amp;quot; - Linear&lt;br /&gt;
&amp;quot;2&amp;quot; - Dynamic&lt;br /&gt;
|| Mandatory for DCR || Not Required || DCR &lt;br /&gt;
|-&lt;br /&gt;
| adModel ||&lt;br /&gt;
Type of ad model:&lt;br /&gt;
#Linear - matches TV ad load&lt;br /&gt;
#Dynamic - Dynamic Ad Insertion (DAI)&lt;br /&gt;
|| &amp;quot;1&amp;quot; - Linear&lt;br /&gt;
&amp;quot;2&amp;quot; - Dynamic&lt;br /&gt;
|| Mandatory for DTVR || Not Required || DTVR&lt;br /&gt;
|-&lt;br /&gt;
| progen || Genre (required only for non-TV originated content). See [[DCR OTT Genre List]] for acceptable values. || e.g. DD for Daytime Drama || Required for non-TV content || Not Required&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
'''clientid &amp;amp; subbrand (vcid)'''&lt;br /&gt;
By default, clientid and subbrand are setup in Nielsen backend configuration to capture brand and sub-brand information. The fields get populated from backend for a registered client appid. But if an app contains multiple brands and sub-brands and client is willing to give credit to another brand or sub-brand then :&lt;br /&gt;
*Client app developer can override the clientid and subbrand (brand and sub-brand info.) in [[loadMetadata]] call to get a proper measurement for a desired brand and sub-brand.&lt;br /&gt;
**If no clientid and subbrand are specified in CMS of a content and an ad, default values reported in the Configuration will be reported.&lt;br /&gt;
**If clientid and subbrand are specified in CMS of the content or ad, the most recent clientid and subbrand will be reported in subsequent pings. To report with a different clientid and subbrand, include the new values for the keys in their subsequent [[loadMetadata]] call.&lt;br /&gt;
'''Picture-in-picture (PIP) mode'''&lt;br /&gt;
Once the app detects PIP mode, call [[loadMetadata]] with the same set of assetids, values and with one additional parameter &amp;quot;pipmode&amp;quot;: &amp;quot;true&amp;quot;. Once PIP mode is disabled in the device, call [[loadMetadata]] again with &amp;quot;pipmode&amp;quot;:&amp;quot;false&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==== Custom Variables Extension ====&lt;br /&gt;
Contact Nielsen Technical Account Manager (TAM) to configure any custom variables, as needed for implementing the application.&lt;br /&gt;
&lt;br /&gt;
See [[Custom Variables Extension]] for more information.&lt;br /&gt;
&lt;br /&gt;
==== Advertisement Metadata ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Key !! Description !! Values !! Required for Audio / Video? !! Required for Static (page)&lt;br /&gt;
|-&lt;br /&gt;
| type || Type of ad || &amp;quot;preroll&amp;quot;&lt;br /&gt;
&amp;quot;midroll&amp;quot;&lt;br /&gt;
&amp;quot;postroll&amp;quot; &lt;br /&gt;
|| Mandatory || Not Required&lt;br /&gt;
|-&lt;br /&gt;
| assetid || An ID assigned to the advertisement. Can be an internal ID, an ID provided by the ad server, or a randomly generated ID. Must be unique across all ads || custom || Mandatory || Not Required&lt;br /&gt;
|-&lt;br /&gt;
| title || Title of the advertisement || &amp;quot;MyAdName&amp;quot; || Mandatory || Not Required&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Passing Metadata ===&lt;br /&gt;
The required metadata can be passed as key values through the loadMetadata method. The sample code below shows a metadata objects for various assets.&lt;br /&gt;
'''Audio / Video Measurement Asset'''&lt;br /&gt;
Type should be &amp;quot;content&amp;quot;&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;assetName&amp;quot;: &amp;quot;myassetName&amp;quot;,&lt;br /&gt;
       &amp;quot;length&amp;quot;: &amp;quot;300.0&amp;quot;,&lt;br /&gt;
       &amp;quot;title&amp;quot;: &amp;quot;myTitle&amp;quot;,&lt;br /&gt;
       &amp;quot;program&amp;quot;: &amp;quot;myProgram&amp;quot;,&lt;br /&gt;
       &amp;quot;censuscategory&amp;quot;: &amp;quot;myCensusCategory&amp;quot;,&lt;br /&gt;
       &amp;quot;assetid&amp;quot;: &amp;quot;myAssetId&amp;quot;,&lt;br /&gt;
       &amp;quot;channelName&amp;quot;: &amp;quot;myChannel&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;segmentB&amp;quot;,&lt;br /&gt;
       &amp;quot;segC&amp;quot;: &amp;quot;segmentC&amp;quot;,&lt;br /&gt;
       &amp;quot;isfullepisode&amp;quot;:&amp;quot;y&amp;quot;,&lt;br /&gt;
       &amp;quot;crossId1&amp;quot;: &amp;quot;Reference11&amp;quot;,&lt;br /&gt;
       &amp;quot;crossId2&amp;quot;: &amp;quot;Reference22&amp;quot;,&lt;br /&gt;
       &amp;quot;airdate&amp;quot;: &amp;quot;20161013 20:00:00&amp;quot;&lt;br /&gt;
    }&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Static (Page) Measurement Asset'''&lt;br /&gt;
Type should be &amp;quot;static&amp;quot;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;    {&lt;br /&gt;
       &amp;quot;type&amp;quot;: &amp;quot;static&amp;quot;,&lt;br /&gt;
       &amp;quot;assetid&amp;quot;: &amp;quot;static123&amp;quot;,&lt;br /&gt;
       &amp;quot;section&amp;quot;: &amp;quot;siteSection&amp;quot;,&lt;br /&gt;
       &amp;quot;segA&amp;quot;: &amp;quot;segmentA&amp;quot;,&lt;br /&gt;
       &amp;quot;segB&amp;quot;: &amp;quot;segmentB&amp;quot;,&lt;br /&gt;
       &amp;quot;segC&amp;quot;: &amp;quot;segmentC&amp;quot;&lt;br /&gt;
    }&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''For any of the ad types'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;    {&lt;br /&gt;
        &amp;quot;type&amp;quot;: &amp;quot;midroll&amp;quot;,&lt;br /&gt;
        &amp;quot;length&amp;quot;: &amp;quot;30.0&amp;quot;,&lt;br /&gt;
        &amp;quot;assetid&amp;quot;: &amp;quot;myMidrollAssetId&amp;quot;,&lt;br /&gt;
        &amp;quot;adloadtype&amp;quot;: &amp;quot;2&amp;quot;,&lt;br /&gt;
        &amp;quot;tv&amp;quot;: &amp;quot;true&amp;quot;,&lt;br /&gt;
        &amp;quot;dataSrc&amp;quot;: &amp;quot;cms&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 &amp;lt;code&amp;gt;loadMetadata&amp;lt;/code&amp;gt; and playhead position through &amp;lt;code&amp;gt;setPlayheadPosition&amp;lt;/code&amp;gt;.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''loadMetadata'''&lt;br /&gt;
The object can then be passed when calling [[loadMetadata]].&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;    loadMetadata(jsonMetadataObject);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;/div&gt;</summary>
		<author><name>NickParrucci</name></author>
	</entry>
	<entry>
		<id>https://nielsentest.mywikis.net/w/index.php?title=Digital_Measurement_Metadata&amp;diff=6503</id>
		<title>Digital Measurement Metadata</title>
		<link rel="alternate" type="text/html" href="https://nielsentest.mywikis.net/w/index.php?title=Digital_Measurement_Metadata&amp;diff=6503"/>
		<updated>2023-08-21T18:06:55Z</updated>

		<summary type="html">&lt;p&gt;NickParrucci: &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;
__NOTOC__&lt;br /&gt;
= Digital Metadata =&lt;br /&gt;
Digital Metadata can passed through key-values using the Nielsen reserved keys. The keys and values are listed by product below. &lt;br /&gt;
&lt;br /&gt;
== Digital Content Ratings (DCR) Metadata ==&lt;br /&gt;
=== Video Metadata ===&lt;br /&gt;
{{DCR Content Metadata}}&lt;br /&gt;
&lt;br /&gt;
==== Example Video Metadata 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:        'The Big Bang Theory',&lt;br /&gt;
  title:          'The Pants Alternative S03E18',  //no abbreviations or shorthand&lt;br /&gt;
  length:         '1320',   //lengths in seconds&lt;br /&gt;
  airdate:        '2021-03-21T12:00:00Z',&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;
&lt;br /&gt;
=== Static Metadata ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Key !! Description !! Data Type !! Value !! Required?&lt;br /&gt;
|-&lt;br /&gt;
| type || asset type || fixed || &amp;lt;code&amp;gt;'static'&amp;lt;/code&amp;gt; || Yes&lt;br /&gt;
|-&lt;br /&gt;
| assetid || Unique ID for each article || dynamic || custom &amp;lt;br&amp;gt;(no [[Special Characters]]) || Yes&lt;br /&gt;
|-&lt;br /&gt;
| section || section of each site (e.g. section value should be first level in page URL: website.com/section). Limit to 25 unique values || dynamic || custom &amp;lt;br&amp;gt;(no [[Special Characters]]) || Yes&lt;br /&gt;
|-&lt;br /&gt;
| segA || custom segment for reporting: Limit to 25 unique values across custom segments (segA + segB + segC) || dynamic || custom || No&lt;br /&gt;
|-&lt;br /&gt;
| segB || custom segment for reporting: Limit to 25 unique values across custom segments (segA + segB + segC) || dynamic || custom || No&lt;br /&gt;
|-&lt;br /&gt;
| segC || custom segment for reporting: Limit to 25 unique values across custom segments (segA + segB + segC) || dynamic || custom || No&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The values passed through the Nielsen keys will determine the breakouts that are seen in reporting. The custom segments (A, B &amp;amp; C) will roll into the sub-brand. To not use custom segments A, B and C, do not pass any value in these keys.&lt;br /&gt;
&lt;br /&gt;
==== Example Static Metadata 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: '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: 'HD Videos', // *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;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Digital TV Ratings (DTVR) Metadata ==&lt;br /&gt;
=== Content Metadata ===&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;
| 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;
====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;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==== Custom Variables Extension ====&lt;br /&gt;
If you are looking for additional reporting options, reach out to us. We have a [[Custom Variables Extension]] and can work with you to obtain your desired reporting.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Key&lt;br /&gt;
! Description&lt;br /&gt;
! style=&amp;quot;width: 14%;&amp;quot; | Values&lt;br /&gt;
! style=&amp;quot;width: 12%;&amp;quot; | Required for Audio/Video?&lt;br /&gt;
! style=&amp;quot;width: 12%;&amp;quot; | Required for Static (page)?&lt;br /&gt;
! Reported for&lt;br /&gt;
|-&lt;br /&gt;
| clientid || Brand value is automatically populated through the App ID provided. The value passed here will override the default value. (e.g. Multiple brands in App) || custom || Optional || Optional || Audio / Video and Static Measurement&lt;br /&gt;
|-&lt;br /&gt;
| subbrand || VCID value is automatically populated through the App ID provided. This value passed here will override the default value. (e.g. Multiple Sub-brands in App) || custom || Optional || Optional || Audio / Video and Static Measurement&lt;br /&gt;
|-&lt;br /&gt;
| type ||&lt;br /&gt;
Type of measurement:&lt;br /&gt;
*audio / video – &amp;quot;content&amp;quot;&lt;br /&gt;
*page – &amp;quot;static&amp;quot;&lt;br /&gt;
*ad – &amp;quot;preroll&amp;quot;, &amp;quot;midroll&amp;quot; or &amp;quot;postroll&amp;quot;&lt;br /&gt;
|| &amp;quot;content&amp;quot;, &amp;quot;static&amp;quot; || Mandatory || Mandatory || &lt;br /&gt;
|-&lt;br /&gt;
| assetid || ID assigned to content. '''Must be unique and consistent''' across all content at the episode level, as well as across platforms (e.g. iOS and Android use the same ID). || custom&amp;lt;br&amp;gt;(no [[Special Characters]]) || Mandatory || Not Required || &lt;br /&gt;
|-&lt;br /&gt;
| section || Section of site || custom || Not Required || Mandatory || &lt;br /&gt;
|-&lt;br /&gt;
| isfullepisode || Full episode flag ||&lt;br /&gt;
*&amp;quot;y&amp;quot; or &amp;quot;lf&amp;quot; - full episode&lt;br /&gt;
*&amp;quot;n&amp;quot; or &amp;quot;sf&amp;quot; - short form&lt;br /&gt;
|| Mandatory || Not Required ||&lt;br /&gt;
|-&lt;br /&gt;
| program || Program name || custom || Mandatory || Not Required || Audio / Video Measurement&lt;br /&gt;
|-&lt;br /&gt;
| title || Episode title || custom || Mandatory || Not Required || Audio / Video Measurement&lt;br /&gt;
|-&lt;br /&gt;
| length || Length of content in seconds for VOD. 0 may be used for Live content if the exact content length is not known.  || custom || Mandatory || Not Required ||&lt;br /&gt;
|-&lt;br /&gt;
| segA || Segment A (this is not available for audio / video Measurement reporting as the episode title is reported) || custom || Not Required || Not Required || Static Measurement&lt;br /&gt;
|-&lt;br /&gt;
| segB || Segment B || custom || Not Required || Not Required || Audio / Video and Static Measurement&lt;br /&gt;
|-&lt;br /&gt;
| segC || Segment C || custom || Not Required || Not Required || Audio / Video and Static Measurement&lt;br /&gt;
|-&lt;br /&gt;
| crossId1 || Standard episode ID. Gracenote/TMS ID should be used when available. Must be unique per episode. || custom || Optional || Not Required ||&lt;br /&gt;
|-&lt;br /&gt;
| crossId2 || Content originator (required only for distributors) || custom || Optional || Not Required ||&lt;br /&gt;
|-&lt;br /&gt;
| airdate || Original (local) air date and time (Eastern Time for US) || YYYYMMDD HH24:MI:SS || Mandatory || Not Required ||&lt;br /&gt;
|-&lt;br /&gt;
| pipmode ||&lt;br /&gt;
Current state of picture-in-picture (PIP) mode on device.&lt;br /&gt;
*&amp;quot;true&amp;quot; if audio / video measurement is displayed in PIP mode&lt;br /&gt;
*&amp;quot;false&amp;quot; if audio / video measurement is displayed in regular mode&lt;br /&gt;
|| &amp;quot;true&amp;quot;, &amp;quot;false&amp;quot; || Optional || Not Required || Audio / Video Measurement&lt;br /&gt;
|-&lt;br /&gt;
| adloadtype ||&lt;br /&gt;
Type of ad load:&lt;br /&gt;
#Linear - matches TV ad load&lt;br /&gt;
#Dynamic - Dynamic Ad Insertion (DAI)&lt;br /&gt;
|| &amp;quot;1&amp;quot; - Linear&lt;br /&gt;
&amp;quot;2&amp;quot; - Dynamic&lt;br /&gt;
|| Mandatory for DCR || Not Required || DCR &lt;br /&gt;
|-&lt;br /&gt;
| adModel ||&lt;br /&gt;
Type of ad model:&lt;br /&gt;
#Linear - matches TV ad load&lt;br /&gt;
#Dynamic - Dynamic Ad Insertion (DAI)&lt;br /&gt;
|| &amp;quot;1&amp;quot; - Linear&lt;br /&gt;
&amp;quot;2&amp;quot; - Dynamic&lt;br /&gt;
|| Mandatory for DTVR || Not Required || DTVR&lt;br /&gt;
|-&lt;br /&gt;
| progen || Genre (required only for non-TV originated content). See [[DCR OTT Genre List]] for acceptable values. || e.g. DD for Daytime Drama || Required for non-TV content || Not Required&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
'''clientid &amp;amp; subbrand (vcid)'''&lt;br /&gt;
By default, clientid and subbrand are setup in Nielsen backend configuration to capture brand and sub-brand information. The fields get populated from backend for a registered client appid. But if an app contains multiple brands and sub-brands and client is willing to give credit to another brand or sub-brand then :&lt;br /&gt;
*Client app developer can override the clientid and subbrand (brand and sub-brand info.) in [[loadMetadata]] call to get a proper measurement for a desired brand and sub-brand.&lt;br /&gt;
**If no clientid and subbrand are specified in CMS of a content and an ad, default values reported in the Configuration will be reported.&lt;br /&gt;
**If clientid and subbrand are specified in CMS of the content or ad, the most recent clientid and subbrand will be reported in subsequent pings. To report with a different clientid and subbrand, include the new values for the keys in their subsequent [[loadMetadata]] call.&lt;br /&gt;
'''Picture-in-picture (PIP) mode'''&lt;br /&gt;
Once the app detects PIP mode, call [[loadMetadata]] with the same set of assetids, values and with one additional parameter &amp;quot;pipmode&amp;quot;: &amp;quot;true&amp;quot;. Once PIP mode is disabled in the device, call [[loadMetadata]] again with &amp;quot;pipmode&amp;quot;:&amp;quot;false&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==== Custom Variables Extension ====&lt;br /&gt;
Contact Nielsen Technical Account Manager (TAM) to configure any custom variables, as needed for implementing the application.&lt;br /&gt;
&lt;br /&gt;
See [[Custom Variables Extension]] for more information.&lt;br /&gt;
&lt;br /&gt;
==== Advertisement Metadata ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Key !! Description !! Values !! Required for Audio / Video? !! Required for Static (page)&lt;br /&gt;
|-&lt;br /&gt;
| type || Type of ad || &amp;quot;preroll&amp;quot;&lt;br /&gt;
&amp;quot;midroll&amp;quot;&lt;br /&gt;
&amp;quot;postroll&amp;quot; &lt;br /&gt;
|| Mandatory || Not Required&lt;br /&gt;
|-&lt;br /&gt;
| assetid || An ID assigned to the advertisement. Can be an internal ID, an ID provided by the ad server, or a randomly generated ID. Must be unique across all ads || custom || Mandatory || Not Required&lt;br /&gt;
|-&lt;br /&gt;
| title || Title of the advertisement || &amp;quot;MyAdName&amp;quot; || Mandatory || Not Required&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Passing Metadata ===&lt;br /&gt;
The required metadata can be passed as key values through the loadMetadata method. The sample code below shows a metadata objects for various assets.&lt;br /&gt;
'''Audio / Video Measurement Asset'''&lt;br /&gt;
Type should be &amp;quot;content&amp;quot;&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;assetName&amp;quot;: &amp;quot;myassetName&amp;quot;,&lt;br /&gt;
       &amp;quot;length&amp;quot;: &amp;quot;300.0&amp;quot;,&lt;br /&gt;
       &amp;quot;title&amp;quot;: &amp;quot;myTitle&amp;quot;,&lt;br /&gt;
       &amp;quot;program&amp;quot;: &amp;quot;myProgram&amp;quot;,&lt;br /&gt;
       &amp;quot;censuscategory&amp;quot;: &amp;quot;myCensusCategory&amp;quot;,&lt;br /&gt;
       &amp;quot;assetid&amp;quot;: &amp;quot;myAssetId&amp;quot;,&lt;br /&gt;
       &amp;quot;channelName&amp;quot;: &amp;quot;myChannel&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;segmentB&amp;quot;,&lt;br /&gt;
       &amp;quot;segC&amp;quot;: &amp;quot;segmentC&amp;quot;,&lt;br /&gt;
       &amp;quot;isfullepisode&amp;quot;:&amp;quot;y&amp;quot;,&lt;br /&gt;
       &amp;quot;crossId1&amp;quot;: &amp;quot;Reference11&amp;quot;,&lt;br /&gt;
       &amp;quot;crossId2&amp;quot;: &amp;quot;Reference22&amp;quot;,&lt;br /&gt;
       &amp;quot;airdate&amp;quot;: &amp;quot;20161013 20:00:00&amp;quot;&lt;br /&gt;
    }&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Static (Page) Measurement Asset'''&lt;br /&gt;
Type should be &amp;quot;static&amp;quot;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;    {&lt;br /&gt;
       &amp;quot;type&amp;quot;: &amp;quot;static&amp;quot;,&lt;br /&gt;
       &amp;quot;assetid&amp;quot;: &amp;quot;static123&amp;quot;,&lt;br /&gt;
       &amp;quot;section&amp;quot;: &amp;quot;siteSection&amp;quot;,&lt;br /&gt;
       &amp;quot;segA&amp;quot;: &amp;quot;segmentA&amp;quot;,&lt;br /&gt;
       &amp;quot;segB&amp;quot;: &amp;quot;segmentB&amp;quot;,&lt;br /&gt;
       &amp;quot;segC&amp;quot;: &amp;quot;segmentC&amp;quot;&lt;br /&gt;
    }&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''For any of the ad types'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;    {&lt;br /&gt;
        &amp;quot;type&amp;quot;: &amp;quot;midroll&amp;quot;,&lt;br /&gt;
        &amp;quot;length&amp;quot;: &amp;quot;30.0&amp;quot;,&lt;br /&gt;
        &amp;quot;assetid&amp;quot;: &amp;quot;myMidrollAssetId&amp;quot;,&lt;br /&gt;
        &amp;quot;adloadtype&amp;quot;: &amp;quot;2&amp;quot;,&lt;br /&gt;
        &amp;quot;tv&amp;quot;: &amp;quot;true&amp;quot;,&lt;br /&gt;
        &amp;quot;dataSrc&amp;quot;: &amp;quot;cms&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 &amp;lt;code&amp;gt;loadMetadata&amp;lt;/code&amp;gt; and playhead position through &amp;lt;code&amp;gt;setPlayheadPosition&amp;lt;/code&amp;gt;.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''loadMetadata'''&lt;br /&gt;
The object can then be passed when calling [[loadMetadata]].&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;    loadMetadata(jsonMetadataObject);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;/div&gt;</summary>
		<author><name>NickParrucci</name></author>
	</entry>
	<entry>
		<id>https://nielsentest.mywikis.net/w/index.php?title=Digital_Measurement_iOS_Cocoapods_Guide&amp;diff=6502</id>
		<title>Digital Measurement iOS Cocoapods Guide</title>
		<link rel="alternate" type="text/html" href="https://nielsentest.mywikis.net/w/index.php?title=Digital_Measurement_iOS_Cocoapods_Guide&amp;diff=6502"/>
		<updated>2023-08-16T14:49:43Z</updated>

		<summary type="html">&lt;p&gt;NickParrucci: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|Digital Downloads}} {{Breadcrumb|Digital Measurement iOS Artifactory Guide}} {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
__NOTOC__&lt;br /&gt;
= How to install Nielsen SDK using CocoaPods =&lt;br /&gt;
CocoaPods is a dependency manager for Swift and Objective-C Cocoa projects. It has over 30 thousand libraries and is used in over 1.9 million apps. The Nielsen SDK now uses this distribution framework for improved version management and provides a Static and Dynamic Framework.&lt;br /&gt;
&lt;br /&gt;
== Initial Configuration ==&lt;br /&gt;
The Nielsen SDK integration requires Cocoapods.  &lt;br /&gt;
* The XCFramework which requires Cocoapods Version 1.10.1 or higher.&lt;br /&gt;
* The Dynamic Framework which requires Cocoapods Version 1.6.1 or higher.&lt;br /&gt;
* The Static Framework requires Cocoapods version 1.4.0. or higher.&lt;br /&gt;
&lt;br /&gt;
The full installation guide for this framework is provided on the [https://guides.cocoapods.org/using/getting-started.html Getting Started] page, and how to set up the Podfile is mentioned in [https://guides.cocoapods.org/using/using-cocoapods.html Using Cocoapods] page.&lt;br /&gt;
&lt;br /&gt;
== Repository Credentials ==&lt;br /&gt;
The first step is to add the credentials received from Nielsen into your .netrc file.&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;
== Verify version of Cocoapods ==&lt;br /&gt;
First verify that Cocoapods is installed.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=Javascript&amp;gt;&lt;br /&gt;
pod --version&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
If it is not, then install.&amp;lt;br &amp;gt;&lt;br /&gt;
===== Install via gem =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=Javascript&amp;gt;&lt;br /&gt;
sudo gem install cocoapods&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===== Install using homebrew ===== &lt;br /&gt;
&amp;lt;syntaxhighlight lang=Javascript&amp;gt;&lt;br /&gt;
brew install cocoapods&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
== Add Cocoapod repository ==&lt;br /&gt;
=== XCFramework (Cocoapods 1.10.1+) ===&lt;br /&gt;
If using '''XCFramework''' (preferred approach), from the command line, type the following:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=Javascript&amp;gt;&lt;br /&gt;
pod repo add NielsenAppSDK https://github.com/NielsenDigitalSDK/nielsenappsdk-ios-specs-dynamic.git&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Make sure you run the pod init command in your **project's directory.**&lt;br /&gt;
&amp;lt;syntaxhighlight lang=Javascript&amp;gt;&lt;br /&gt;
pod init&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;You now need to slightly modify the PodFile that was created in this directory.  From the command line, you can use vi or vim to edit. &amp;lt;br&amp;gt; The following must be in the PodFile:&lt;br /&gt;
==== Podfile ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=Javascript&amp;gt;&lt;br /&gt;
platform :ios, '14.0'&lt;br /&gt;
source 'https://github.com/NielsenDigitalSDK/nielsenappsdk-ios-specs-dynamic.git'&lt;br /&gt;
source 'https://github.com/CocoaPods/Specs.git'&lt;br /&gt;
&lt;br /&gt;
target 'YourProjectsNameHere' do&lt;br /&gt;
 use_frameworks!&lt;br /&gt;
    #Pods for ApplicationTarget&lt;br /&gt;
    pod 'NielsenAppSDK-XC'&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': If you migrate from the iOS dynamic framework to the XCFramework, just add -XC suffix for the pod in the podfile. E.g. NielsenAppSDK should be replaced with NielsenAppSDK-XC. The same Github repo is used for both dynamic and XCFramework.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': Although official CocoaPods source is implicit but once you specify NielsenAppSDK source, then CocoaPods source will need to be included in PodFile if you are using some other third party pods along with NielsenAppSDK. Further details are mentioned here https://guides.cocoapods.org/syntax/podfile.html#source&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note on TVOS''': Nielsen AppSDK clients with applications on TVOS platform should take into account that TVOS slices are now part of the same XCFramework with iOS slices, so the XCFramework name is the same for both iOS and TVOS. But the TVOS framework imported in the application still has TVOS in its name. This is needed to reduce the number of changes in the existing apps. The code below should be added into the podfiles for TVOS XCFramework users:&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=Javascript&amp;gt;&lt;br /&gt;
# modify XCFramework configuration files to update NielsenAppApi.framework -&amp;gt; NielsenTVAppApi.framework&lt;br /&gt;
post_install do |installer|&lt;br /&gt;
  installer.pods_project.targets.each do |target|&lt;br /&gt;
    if target.name == 'Pods-NielsenVideoPlayerTVOSPodsXC'&lt;br /&gt;
      # update Pods-NielsenVideoPlayerTVOSPodsXC.debug.xcconfig file&lt;br /&gt;
      # update Pods-NielsenVideoPlayerTVOSPodsXC.release.xcconfig file&lt;br /&gt;
      target.build_configurations.each do |config|&lt;br /&gt;
          xcconfig_path = config.base_configuration_reference.real_path&lt;br /&gt;
          puts &amp;quot;post_install: Found #{File.basename(xcconfig_path)}&amp;quot;&lt;br /&gt;
          xcconfig = File.read(xcconfig_path)&lt;br /&gt;
          new_xcconfig = xcconfig.sub('-framework &amp;quot;NielsenAppApi&amp;quot;', '-framework &amp;quot;NielsenTVAppApi&amp;quot;')&lt;br /&gt;
          File.open(xcconfig_path, &amp;quot;w&amp;quot;) { |file| file &amp;lt;&amp;lt; new_xcconfig }&lt;br /&gt;
          puts &amp;quot;post_install: Updated #{File.basename(xcconfig_path)} file with a value: NielsenTVAppApi.framework&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
      # update Pods-NielsenVideoPlayerTVOSPodsXC-frameworks.sh file&lt;br /&gt;
      frameworksh_path = &amp;quot;Pods/Target Support Files/#{target.name}/#{target.name}-frameworks.sh&amp;quot;&lt;br /&gt;
      if File.exist?(frameworksh_path)&lt;br /&gt;
        puts &amp;quot;post_install: Found #{File.basename(frameworksh_path)}&amp;quot;&lt;br /&gt;
        text = File.read(frameworksh_path)&lt;br /&gt;
        new_contents = text.gsub('NielsenAppApi.framework', 'NielsenTVAppApi.framework')&lt;br /&gt;
        File.open(frameworksh_path, &amp;quot;w&amp;quot;) {|file| file.puts new_contents}&lt;br /&gt;
        puts &amp;quot;post_install: Updated #{File.basename(frameworksh_path)} file with a value: NielsenTVAppApi.framework&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;If you migrate from the TVOS dynamic framework to the XCFramework, please note that TVOS slices are now part of the same XCFramework with iOS slices. So in addition to appending of the -XC suffix to the pod name in the podfile please remove TVOS. E.g. the naming for the pod NielsenTVOSAppSDK should be changed to NielsenAppSDK-XC.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Dynamic Framework (Cocoapods 1.6.1+) ===&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': We highly recommend to migrate to XCFramework for all our clients.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
If using '''Dynamic Framework''', from the command line, type the following:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=Javascript&amp;gt;&lt;br /&gt;
pod repo add NielsenAppSDK https://github.com/NielsenDigitalSDK/nielsenappsdk-ios-specs-dynamic.git&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Make sure you run the pod init command in your **project's directory.**&lt;br /&gt;
&amp;lt;syntaxhighlight lang=Javascript&amp;gt;&lt;br /&gt;
pod init&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;You now need to slightly modify the PodFile that was created in this directory.  From the command line, you can use vi or vim to edit. &amp;lt;br&amp;gt; The following must be in the PodFile:&lt;br /&gt;
==== Podfile ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=Javascript&amp;gt;&lt;br /&gt;
platform :ios, '11.0'&lt;br /&gt;
source 'https://github.com/NielsenDigitalSDK/nielsenappsdk-ios-specs-dynamic.git'&lt;br /&gt;
&lt;br /&gt;
target 'YourProjectsNameHere' do&lt;br /&gt;
 use_frameworks!&lt;br /&gt;
    #Pods for ApplicationTarget&lt;br /&gt;
    pod 'NielsenAppSDK'&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': If you are building an application on a Mac with Apple M1 chip, please add the following fix to end of the podfile&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=Javascript&amp;gt;&lt;br /&gt;
post_install do |installer|&lt;br /&gt;
  installer.pods_project.build_configurations.each do |config|&lt;br /&gt;
    config.build_settings[&amp;quot;EXCLUDED_ARCHS[sdk=iphonesimulator*]&amp;quot;] = &amp;quot;arm64&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== For Static Framework (Cocoapods 1.4+) ===&lt;br /&gt;
From the command line, type the following:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=Javascript&amp;gt;&lt;br /&gt;
pod repo add NielsenAppSDK https://github.com/nielsendigitalsdk/nielsenappsdk-ios-specs.git&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Make sure you run the pod init command in your **project's directory.**&lt;br /&gt;
&amp;lt;syntaxhighlight lang=Javascript&amp;gt;&lt;br /&gt;
pod init&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;You now need to slightly modify the PodFile that was created in this directory.  From the command line, you can use vi or vim to edit. &amp;lt;br&amp;gt; The following must be in the PodFile:&lt;br /&gt;
==== Podfile ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=Javascript&amp;gt;&lt;br /&gt;
platform :ios, '11.0'&lt;br /&gt;
source 'https://github.com/NielsenDigitalSDK/nielsenappsdk-ios-specs.git'&lt;br /&gt;
&lt;br /&gt;
target 'YourProjectsNameHere' do&lt;br /&gt;
    #Pods for ApplicationTarget&lt;br /&gt;
    pod 'NielsenAppSDK'&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': If you are building an application on a Mac with Apple M1 chip, please add the following fix to end of the podfile&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=Javascript&amp;gt;&lt;br /&gt;
post_install do |installer|&lt;br /&gt;
  installer.pods_project.build_configurations.each do |config|&lt;br /&gt;
    config.build_settings[&amp;quot;EXCLUDED_ARCHS[sdk=iphonesimulator*]&amp;quot;] = &amp;quot;arm64&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''NOTE: You can have multiple pods within the Podfile''&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
To select a specific version of the Nielsen SDK, just append the build number.  For example, this line is requesting XCFramework build 8.1.0.0:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=javascript&amp;gt;&lt;br /&gt;
pod 'NielsenAppSDK-XC','8.1.0.0'&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&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.&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
=== For Cocoapods Versions &amp;lt; 1.6.0 ===&lt;br /&gt;
&lt;br /&gt;
If you are using a version of Cocoapods that is less than 1.6.0, you have a Swift Project and your pod has '''use_frameworks!''' please use the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=javascript&amp;gt;&lt;br /&gt;
# Uncomment the next line to define a global platform for your project&lt;br /&gt;
platform :ios, '8.0'&lt;br /&gt;
source 'https://github.com/NielsenDigitalSDK/nielsenappsdk-ios-specs.git'&lt;br /&gt;
&lt;br /&gt;
target 'YourProjectsNameHere' do&lt;br /&gt;
  # Comment the next line if you're not using Swift and don't want to use dynamic frameworks&lt;br /&gt;
use_frameworks!&lt;br /&gt;
    #Pods for ApplicationTarget&lt;br /&gt;
    pod 'NielsenAppSDK'&lt;br /&gt;
&lt;br /&gt;
static_frameworks = ['NielsenAppSDK']&lt;br /&gt;
# make all the other frameworks into static frameworks by overriding the static_framework? function to return true&lt;br /&gt;
pre_install do |installer|&lt;br /&gt;
    installer.pod_targets.each do |pod|&lt;br /&gt;
        if static_frameworks.include?(pod.name)&lt;br /&gt;
            puts &amp;quot;Overriding the static_framework? method for #{pod.name}&amp;quot;&lt;br /&gt;
            def pod.static_framework?;&lt;br /&gt;
            true&lt;br /&gt;
            end&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Execute Install ==&lt;br /&gt;
Once that has been edited, you can now execute the install:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=Swift&amp;gt;&lt;br /&gt;
pod install&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cocoapods will automatically create a new file with extension “.xcworkspace”. From this moment, that file should be used for using the target project instead of previous one with extension “.xcodeproj”. Inside of this workspace you will see “Pods” target which will include ready to use NielsenAppApi framework.&lt;br /&gt;
&lt;br /&gt;
Open the file with the extension of &amp;lt;code&amp;gt;.xcworkspace&amp;lt;/code&amp;gt; file using Xcode.&lt;br /&gt;
&lt;br /&gt;
== Execute Update ==&lt;br /&gt;
When you want to retrieve latest Nielsen SDK version then please use pod update [Nielsen App Flavor Name]:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=Swift&amp;gt;&lt;br /&gt;
pod update NielsenAppSDK-XC&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In case if you set specific version of the Nielsen SDK in your PodFile then you'll also need to update that specific version to latest version in your PodFile before executing pod update command:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=Swift&amp;gt;&lt;br /&gt;
pod 'NielsenAppSDK-XC','9.0.0.0'&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
== Build Notes ==&lt;br /&gt;
Please note that the Nielsen dynamic framework contains slices for devices and simulators.  When building your project it is recommended that Simulator slices are removed before sending the app to the AppStore.   An example of the shell script that should be added as a Run Script phase in the application is attached&lt;br /&gt;
&amp;lt;syntaxhighlight lang=Swift&amp;gt;&lt;br /&gt;
APP_PATH=&amp;quot;${TARGET_BUILD_DIR}/${WRAPPER_NAME}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# This script loops through the frameworks embedded in the application and&lt;br /&gt;
# removes unused architectures.&lt;br /&gt;
find &amp;quot;$APP_PATH&amp;quot; -name '*.framework' -type d | while read -r FRAMEWORK&lt;br /&gt;
do&lt;br /&gt;
FRAMEWORK_EXECUTABLE_NAME=$(defaults read &amp;quot;$FRAMEWORK/Info.plist&amp;quot; CFBundleExecutable)&lt;br /&gt;
FRAMEWORK_EXECUTABLE_PATH=&amp;quot;$FRAMEWORK/$FRAMEWORK_EXECUTABLE_NAME&amp;quot;&lt;br /&gt;
echo &amp;quot;Executable is $FRAMEWORK_EXECUTABLE_PATH&amp;quot;&lt;br /&gt;
&lt;br /&gt;
EXTRACTED_ARCHS=()&lt;br /&gt;
&lt;br /&gt;
for ARCH in $ARCHS&lt;br /&gt;
do&lt;br /&gt;
echo &amp;quot;Extracting $ARCH from $FRAMEWORK_EXECUTABLE_NAME&amp;quot;&lt;br /&gt;
lipo -extract &amp;quot;$ARCH&amp;quot; &amp;quot;$FRAMEWORK_EXECUTABLE_PATH&amp;quot; -o &amp;quot;$FRAMEWORK_EXECUTABLE_PATH-$ARCH&amp;quot;&lt;br /&gt;
EXTRACTED_ARCHS+=(&amp;quot;$FRAMEWORK_EXECUTABLE_PATH-$ARCH&amp;quot;)&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Merging extracted architectures: ${ARCHS}&amp;quot;&lt;br /&gt;
lipo -o &amp;quot;$FRAMEWORK_EXECUTABLE_PATH-merged&amp;quot; -create &amp;quot;${EXTRACTED_ARCHS[@]}&amp;quot;&lt;br /&gt;
rm &amp;quot;${EXTRACTED_ARCHS[@]}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Replacing original executable with thinned version&amp;quot;&lt;br /&gt;
rm &amp;quot;$FRAMEWORK_EXECUTABLE_PATH&amp;quot;&lt;br /&gt;
mv &amp;quot;$FRAMEWORK_EXECUTABLE_PATH-merged&amp;quot; &amp;quot;$FRAMEWORK_EXECUTABLE_PATH&amp;quot;&lt;br /&gt;
&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pod Versions ==&lt;br /&gt;
The following Pod versions are now available: (For 'kids' apps, please use the NoId framework (EG: NielsenNoIdAppSDK-XC).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': Nielsen SDK builds for tvOS are no longer distributed as separated packages. XCFramework allows to combine iOS and tvOS platforms in a single package. Please use the corresponding XCFramework while migrating from static or dynamic framework for tvOS. E.g. NielsenTVOSAppSDK -&amp;gt; NielsenAppSDK-XC.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width: 30%;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#efefef;&amp;quot;&lt;br /&gt;
! App Flavor Name&lt;br /&gt;
|-&lt;br /&gt;
| NielsenAppSDK-XC&lt;br /&gt;
|-&lt;br /&gt;
| NielsenNoAdAppSDK-XC&lt;br /&gt;
|-&lt;br /&gt;
| NielsenNoIdAppSDK-XC&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
We highly recommend to migrate to XCFramework for all our clients. For clients who still have reasons to keep using the old framework packages in the application and do not migrate to XCFramework we distribute &amp;quot;fat&amp;quot; frameworks both static and dynamic for the release 8.1.0.0. Anyway, our plan to stop distributing &amp;quot;fat&amp;quot; frameworks for future releases and to distribute the Nielsen iOS SDK as an XCFramework only.&lt;br /&gt;
&lt;br /&gt;
The following Pod versions are available: (For 'kids' apps, please use the NoId framework (EG: NielsenNoIdAppSDK, NielsenNoIdTVOSAppSDK) &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width: 30%;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#efefef;&amp;quot;&lt;br /&gt;
! App Flavor Name&lt;br /&gt;
|-&lt;br /&gt;
| NielsenAppSDK&lt;br /&gt;
|-&lt;br /&gt;
| NielsenNoAdAppSDK&lt;br /&gt;
|-&lt;br /&gt;
| NielsenNoAdTVOSAppSDK&lt;br /&gt;
|-&lt;br /&gt;
| NielsenNoIdAppSDK &lt;br /&gt;
|-&lt;br /&gt;
| NielsenNoIdTVOSAppSDK &lt;br /&gt;
|-&lt;br /&gt;
| NielsenTVOSAppSDK&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Regional Builds ===&lt;br /&gt;
(For 'kids' apps, please use the NoId framework (EG: NielsenAGFNoIdAppSDK-XC, NielsenAGFNoIdTVOSAppSDK-XC) &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width: 30%;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#efefef;&amp;quot;&lt;br /&gt;
! App Flavor Name&lt;br /&gt;
|-&lt;br /&gt;
| NielsenAGFAppSDK-XC&lt;br /&gt;
|-&lt;br /&gt;
| NielsenAGFNoAdAppSDK-XC&lt;br /&gt;
|-&lt;br /&gt;
| NielsenAGFNoIdAppSDK-XC&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Fat frameworks are still available for the release 8.1.0.0.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width: 30%;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#efefef;&amp;quot;&lt;br /&gt;
! App Flavor Name&lt;br /&gt;
|-&lt;br /&gt;
| NielsenAGFAppSDK&lt;br /&gt;
|-&lt;br /&gt;
| NielsenAGFNoAdAppSDK&lt;br /&gt;
|-&lt;br /&gt;
| NielsenAGFNoAdTVOSAppSDK&lt;br /&gt;
|-&lt;br /&gt;
| NielsenAGFNoIdAppSDK&lt;br /&gt;
|-&lt;br /&gt;
| NielsenAGFNoIdTVOSAppSDK&lt;br /&gt;
|-&lt;br /&gt;
| NielsenAGFTVOSAppSDK&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Appsdk 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 iOS 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;ai.8.1.0.0_abc&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Pod Cache Cleanup  ===&lt;br /&gt;
If you find any trouble while installing or updating latest Nielsen SDK version then you may need to clean up the pod cache by executing following commands:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=Swift&amp;gt;&lt;br /&gt;
rm -rf ~/Library/Caches/CocoaPods&lt;br /&gt;
rm -rf Pods&lt;br /&gt;
rm -rf ~/Library/Developer/Xcode/DerivedData/*&lt;br /&gt;
pod deintegrate&lt;br /&gt;
pod setup&lt;br /&gt;
pod install&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Xcode 14 Bitcode Changes ===&lt;br /&gt;
Starting from Xcode 14, bitcode is no longer required for iOS, watchOS and tvOS applications, and the App Store no longer accepts bitcode submissions from Xcode 14. So if bitcode is enabled to Yes then following error may come while integrating through Cocoapods:&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Xcode setting ENABLE_BITCODE: obtain an updated library from the vendor, or disable bitcode for this target&amp;quot;  &lt;br /&gt;
&lt;br /&gt;
To Fix:&lt;br /&gt;
Target -&amp;gt; Build Settings -&amp;gt; Build Options -&amp;gt; set Enable Bitcode to No. &lt;br /&gt;
&lt;br /&gt;
[[File:NielsenSamplePlayer.png|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
=== Additional Resources ===&lt;br /&gt;
&lt;br /&gt;
For more information on [https://guides.cocoapods.org/using/getting-started.html CocoaPods] or How to set up the Profile in the [https://guides.cocoapods.org/using/using-cocoapods.html Using Cocoapods] page.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>NickParrucci</name></author>
	</entry>
	<entry>
		<id>https://nielsentest.mywikis.net/w/index.php?title=File:NielsenChromecastMirror.png&amp;diff=6472</id>
		<title>File:NielsenChromecastMirror.png</title>
		<link rel="alternate" type="text/html" href="https://nielsentest.mywikis.net/w/index.php?title=File:NielsenChromecastMirror.png&amp;diff=6472"/>
		<updated>2023-07-31T19:09:00Z</updated>

		<summary type="html">&lt;p&gt;NickParrucci: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;mirroring diagram&lt;/div&gt;</summary>
		<author><name>NickParrucci</name></author>
	</entry>
	<entry>
		<id>https://nielsentest.mywikis.net/w/index.php?title=File:NielsenChromecastCast.png&amp;diff=6471</id>
		<title>File:NielsenChromecastCast.png</title>
		<link rel="alternate" type="text/html" href="https://nielsentest.mywikis.net/w/index.php?title=File:NielsenChromecastCast.png&amp;diff=6471"/>
		<updated>2023-07-31T19:08:24Z</updated>

		<summary type="html">&lt;p&gt;NickParrucci: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;cast diagram&lt;/div&gt;</summary>
		<author><name>NickParrucci</name></author>
	</entry>
	<entry>
		<id>https://nielsentest.mywikis.net/w/index.php?title=DCR_Chromecast_browser_SDK&amp;diff=6470</id>
		<title>DCR Chromecast browser SDK</title>
		<link rel="alternate" type="text/html" href="https://nielsentest.mywikis.net/w/index.php?title=DCR_Chromecast_browser_SDK&amp;diff=6470"/>
		<updated>2023-07-31T19:07:19Z</updated>

		<summary type="html">&lt;p&gt;NickParrucci: Created page with &amp;quot;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|DCR &amp;amp; DTVR}}  {{CurrentBreadcrumb}} Category:Digital  == 1. General Cast architecture == &amp;lt;br /&amp;gt; File:GeneralCastArch....&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;
&lt;br /&gt;
== 1. General Cast architecture ==&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
[[File:GeneralCastArch.png||600px|center|]]&lt;br /&gt;
See https://developers.google.com/cast/docs/developers&lt;br /&gt;
&lt;br /&gt;
=== Sender App ===&lt;br /&gt;
is a user controlled JavaScript/HTML5 application which can run on browsers in mobile or desktop devices.&lt;br /&gt;
&lt;br /&gt;
=== Receiver App ===&lt;br /&gt;
is an HTML5/JavaScript application placed at a custom URL that handles communication between the Sender app and the Chromecast device.&lt;br /&gt;
&lt;br /&gt;
== 2. Cast scenarios ==&lt;br /&gt;
&lt;br /&gt;
=== 2.1 Pure casting scenario === &lt;br /&gt;
In the Pure casting scenario the video plays on the Chromecast device, while playback stops on the sender app &amp;lt;br /&amp;gt;&lt;br /&gt;
The sender app should not pass any Nielsen API calls once the pure casting scenario starts. All Nielsen API calls are handled by the receiver app.&lt;br /&gt;
[[File:NielsenChromecastCast.png|600px|center]]&lt;br /&gt;
&lt;br /&gt;
=== 2.2 Chromecast mirroring scenario ===&lt;br /&gt;
In the Chromecast mirroring scenario the video plays on both the sender and receiver apps.  &amp;lt;br /&amp;gt; &lt;br /&gt;
[[File:NielsenChromecastMirror.png|600px|center]]&lt;br /&gt;
&lt;br /&gt;
== 3.Sender App JavaScript - Nielsen Browser SDK implementation ==&lt;br /&gt;
&lt;br /&gt;
=== 3.1 General ===&lt;br /&gt;
By adding the below cast-specific API calls alongside the standard implementation of the Nielsen Browser SDK, a sender app can pass appropriate cast-specific metadata.&lt;br /&gt;
&lt;br /&gt;
=== 3.2 API calls ===&lt;br /&gt;
&lt;br /&gt;
==== 3.2.1 updateOTT ====&lt;br /&gt;
The below call should be made to the Browser SDK whenever the player switches from not casting to casting and vice versa.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
nolSDKInstance.ggPM('updateOTT',contentMetadataObject);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
Use the updateOTT method to notify the casting BrowserSDK instance whether the remote OTT device (like Google ChromeCast, Roku, Amazon FireTV, etc.) is connected or disconnected (indicated by &amp;quot;ottStatus&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
When the OTT device is connected, call updateOTT with &amp;quot;ottStatus&amp;quot;: &amp;quot;1&amp;quot; as well as a set of OTT device related parameters in the contentMetadataObject.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
var contentMetadataObject ={&lt;br /&gt;
        type: &amp;quot;content&amp;quot;,&lt;br /&gt;
        ottStatus: &amp;quot;1&amp;quot;,&lt;br /&gt;
        ottType: &amp;quot;casting&amp;quot;,&lt;br /&gt;
        ottDevice: &amp;quot;chromecast&amp;quot;,&lt;br /&gt;
        ottDeviceName: &amp;quot;Google Chromecast&amp;quot;,&lt;br /&gt;
        ottDeviceID: nolSDKInstance.getId(),&lt;br /&gt;
        ottDeviceManufacturer: &amp;quot;Google&amp;quot;,&lt;br /&gt;
        ottDeviceModel: &amp;quot;ChromeCastModel&amp;quot;,&lt;br /&gt;
        ottDeviceVersion: &amp;quot;1.0.0&amp;quot; &lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When the OTT device is disconnected, call updateOTT with “ottStatus”: “0”.&lt;br /&gt;
&lt;br /&gt;
==== 3.2.2 getOptOutStatus() and sessionId ====&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
Assign the below mediaInfo metadata parameters in the target load so that they may be passed to the receiver at the beginning of the casting session.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
mediaInfo.metadata.kGCKMetadataNlsKeyDeviceID = nolSDKInstance.sessionId; //Session Id&lt;br /&gt;
mediaInfo.metadata.kGCKMetadataNlsKeyOptout   = nolSDKInstance.getOptOutStatus(); //OptOut status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
Below is a sample code snippet on how the sender browser app should retrieve and relay the information from sender to receiver app.&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
        var mediaInfo = new chrome.cast.media.MediaInfo(&lt;br /&gt;
         this.mediaContents[mediaIndex]['sources'][0], 'video/mp4');&lt;br /&gt;
&lt;br /&gt;
        mediaInfo.metadata = new chrome.cast.media.GenericMediaMetadata();&lt;br /&gt;
        mediaInfo.metadata.metadataType = chrome.cast.media.MetadataType.GENERIC;&lt;br /&gt;
        mediaInfo.metadata.title = this.mediaContents[mediaIndex]['title'];&lt;br /&gt;
        mediaInfo.metadata.length = this.currentMediaDuration;&lt;br /&gt;
        mediaInfo.metadata.images = [&lt;br /&gt;
            {'url': MEDIA_SOURCE_ROOT + this.mediaContents[mediaIndex]['thumb']}];&lt;br /&gt;
&lt;br /&gt;
        /*Adding custom parameters in metadata to be passed to receiver*/&lt;br /&gt;
        mediaInfo.metadata.kGCKMetadataNlsKeyDeviceID = nolSDKInstance.sessionId; //Session Id&lt;br /&gt;
        mediaInfo.metadata.kGCKMetadataNlsKeyOptout   = nolSDKInstance.getOptOutStatus(); //OptOut status&lt;br /&gt;
&lt;br /&gt;
        var request = new chrome.cast.media.LoadRequest(mediaInfo);&lt;br /&gt;
          castSession.loadMedia(request).then(&lt;br /&gt;
           this.playerHandler.loaded.bind(this.playerHandler),&lt;br /&gt;
           function (errorCode) {&lt;br /&gt;
             this.playerState = PLAYER_STATE.ERROR;&lt;br /&gt;
             console.log('Remote media load error: ' +&lt;br /&gt;
               CastPlayer.getErrorMessage(errorCode));&lt;br /&gt;
          }.bind(this));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 4. Summary - Sequence of API calls  ==&lt;br /&gt;
Below is the sequence of API calls from the beginning to the end of casting.&lt;br /&gt;
&lt;br /&gt;
=== SENDER side ===&lt;br /&gt;
1) If the video is playing only on the Sender App, the standard Nielsen Browser SDK API calls should be invoked.&amp;lt;br /&amp;gt; &lt;br /&gt;
2) Once a user presses the cast icon and if the video is playing already, call browser sdk '''end()''' api. &amp;lt;br /&amp;gt;&lt;br /&gt;
3) Inform the Browser SDK about the Chromecast's status (connected or disconnected) by calling '''updateOTT()''' and passing metadata object. &amp;lt;br /&amp;gt; &lt;br /&gt;
4) Retrieve the OptOutStatus and sessionId.&amp;lt;br /&amp;gt;&lt;br /&gt;
5) Pass the optOutStatus and sessionId into the MediaInfo metadata object.&amp;lt;br /&amp;gt; &lt;br /&gt;
6) When the Start casting (the video should be stopped on the sender device).&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== RECEIVER side === &lt;br /&gt;
Playback has started at ChromeCast device (TV).&amp;lt;br /&amp;gt;&lt;br /&gt;
7) Retrieve the MediaInfo metadata sent by the sender device. &amp;lt;br /&amp;gt;&lt;br /&gt;
8) [https://engineeringportal.nielsen.com/docs/DCR_Video_Browser_SDK#Initialization_API_Call Instantiate] the Browser SDK. &amp;lt;br /&amp;gt;&lt;br /&gt;
9) Pass content/ad metadata by calling '''loadMetaData()'''. &amp;lt;br /&amp;gt;&lt;br /&gt;
10) Send '''updateOTT''' event to BSDK receiver instance, to relay the sender OTT metadata ( kGCKMetadataNlsKeyDeviceID and kGCKMetadataNlsKeyOptout) received from sender app.&amp;lt;br /&amp;gt;&lt;br /&gt;
11) Pass content/ad playheads every second by calling '''setPlayheadPosition()'''. &amp;lt;br /&amp;gt;&lt;br /&gt;
12) Based on the user's interactions or the playlist state, call '''stop()''' (once paused) or '''end()''' (once the content or casting has ended).&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== SENDER side ===&lt;br /&gt;
Casting has ended and playback resumes on the sender device.&amp;lt;br /&amp;gt;&lt;br /&gt;
13) Start a new session by calling content/ad '''loadMetaData()'''.&amp;lt;br /&amp;gt;&lt;br /&gt;
14) Continue sending API calls as usual.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Below is a sample code snippet on how the receiver app should retrieve the ottMetadata received from sender apps and relay the information  to receiver BSDK instance.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
sampleplayer.CastPlayer.prototype.onLoad_ = function(event) {&lt;br /&gt;
var senderMetadata = event.data.media.metadata,&lt;br /&gt;
sessionId = senderMetadata.kGCKMetadataNlsKeyDeviceID,&lt;br /&gt;
optout = senderMetadata.kGCKMetadataNlsKeyOptout;&lt;br /&gt;
  this.cancelDeferredPlay_('new media is loaded');&lt;br /&gt;
  this.load(new cast.receiver.MediaManager.LoadInfo( (event.data),  event.senderId));&lt;br /&gt;
	var contentMetadata = {&lt;br /&gt;
         	   &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;,&lt;br /&gt;
          	  &amp;quot;dataSrc&amp;quot;: &amp;quot;cms&amp;quot;,&lt;br /&gt;
           	 &amp;quot;assetid&amp;quot;: &amp;quot;vid-123&amp;quot;,&lt;br /&gt;
          	  &amp;quot;assetName&amp;quot;: &amp;quot;Test video&amp;quot;,&lt;br /&gt;
           	 &amp;quot;program&amp;quot;: &amp;quot;Test program&amp;quot;,&lt;br /&gt;
          	  &amp;quot;title&amp;quot;: &amp;quot;Clickbaby&amp;quot;,&lt;br /&gt;
          	  &amp;quot;length&amp;quot;:”60”,&lt;br /&gt;
          	  &amp;quot;segA&amp;quot;: &amp;quot;CustomSegmentValueA&amp;quot;,&lt;br /&gt;
          	  &amp;quot;segB&amp;quot;: &amp;quot;CustomSegmentValueB&amp;quot;,&lt;br /&gt;
          	  &amp;quot;segC&amp;quot;: &amp;quot;CustomSegmentValueC&amp;quot;&lt;br /&gt;
	};&lt;br /&gt;
      window.nolSDKInstance.ggPM(15, contentMetadata);&lt;br /&gt;
	   var ottMetadataObject ={&lt;br /&gt;
			ottStatus: &amp;quot;1&amp;quot;,&lt;br /&gt;
			ottType: &amp;quot;casting&amp;quot;,&lt;br /&gt;
			ottDevice: &amp;quot;chromecast&amp;quot;,&lt;br /&gt;
			ottDeviceName: &amp;quot;Google Chromecast&amp;quot;,&lt;br /&gt;
			ottDeviceID: nolSDKInstance.getId(),&lt;br /&gt;
			ottDeviceManufacturer: &amp;quot;Google&amp;quot;,&lt;br /&gt;
			ottDeviceModel: &amp;quot;ChromeCastModel&amp;quot;,&lt;br /&gt;
			ottDeviceVersion: &amp;quot;1.0.0&amp;quot;, &lt;br /&gt;
			kGCKMetadataNlsKeyOptout : optout,&lt;br /&gt;
		    kGCKMetadataNlsKeyDeviceID : sessionId	&lt;br /&gt;
		  };&lt;br /&gt;
window.nolSDKInstance.ggPM('updateOTT', ottMetadataObject);};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
Chromecast Developer Documentation: &amp;lt;https://developers.google.com/cast/docs/developers&amp;gt; &amp;lt;br /&amp;gt;&lt;br /&gt;
Browser SDK API Reference: &amp;lt;https://engineeringportal.nielsen.com/docs/Browser_SDK_API_Reference&amp;gt; &amp;lt;br /&amp;gt;&lt;/div&gt;</summary>
		<author><name>NickParrucci</name></author>
	</entry>
	<entry>
		<id>https://nielsentest.mywikis.net/w/index.php?title=File:GeneralCastArch.png&amp;diff=6469</id>
		<title>File:GeneralCastArch.png</title>
		<link rel="alternate" type="text/html" href="https://nielsentest.mywikis.net/w/index.php?title=File:GeneralCastArch.png&amp;diff=6469"/>
		<updated>2023-07-31T19:07:04Z</updated>

		<summary type="html">&lt;p&gt;NickParrucci: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;architechture diagram&lt;/div&gt;</summary>
		<author><name>NickParrucci</name></author>
	</entry>
	<entry>
		<id>https://nielsentest.mywikis.net/w/index.php?title=iOS_Step_By_Step&amp;diff=6468</id>
		<title>iOS Step By Step</title>
		<link rel="alternate" type="text/html" href="https://nielsentest.mywikis.net/w/index.php?title=iOS_Step_By_Step&amp;diff=6468"/>
		<updated>2023-07-27T13:30:19Z</updated>

		<summary type="html">&lt;p&gt;NickParrucci: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
__NOTOC__&lt;br /&gt;
&lt;br /&gt;
Provided below are step-by-step quick start guides for implementing Nielsen iOS SDK for DCR Static, DCR Video, and DTVR products. Click each section to get started. &lt;br /&gt;
&lt;br /&gt;
== &amp;amp;rarr; iOS DCR Static ==&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivision&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide DCR Static &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivision&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== iOS DCR Static Introduction ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisiona-&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide Intro &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisiona-&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Digital Content Ratings (DCR) Static product provides content consumption measurement in client mobile apps and webpages. This measurement includes insight into the total time a user spent on a webpage, how they navigated through the page via links, and many other data points.&lt;br /&gt;
This tutorial provides the steps to implement the DCR Static product in a sample iOS app. It includes:&lt;br /&gt;
&lt;br /&gt;
*SDK Initialization Call&lt;br /&gt;
*DCR Static Metadata: information about the sections being tracked&lt;br /&gt;
&lt;br /&gt;
By the end of this guide you will have the needed steps to integrate Nielsen's AppSDK in the background of your app.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== iOS DCR Static Step 1 - Obtain AppID ===&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisiona1&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 1 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisiona1&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To begin using the iOS SDK (AppSDK) you will need to obtain an Application ID (AppId)&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! !! Item !! Description !! Source&lt;br /&gt;
|-&lt;br /&gt;
|&amp;amp;#9989; || App ID (appid) || Unique ID assigned to the player/site and configured by product || Contact your Nielsen TAM&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The appid is a 37 character unique ID assigned to the player/site and configured by product and is required when creating a new instance of the AppSDK in the app.&lt;br /&gt;
&amp;lt;/br&amp;gt;Example: '''PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== iOS DCR Static Step 2 - SDK Initialization ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionc&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 2 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionc&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== How to obtain the NielsenAppApi.Framework ====&lt;br /&gt;
The Nielsen AppSDK can either be downloaded directly or can be integrated directly within an application through the use of CocoaPods. We recommend using the CocoaPods-based integration whenever possible to ensure you maintain the most recent changes and enhancements to the Nielsen libraries.&lt;br /&gt;
* [[Digital_Measurement_iOS_Artifactory_Guide|Select to obtain CocoaPods implementation guide]]&lt;br /&gt;
* [[Special:Downloads|Select to Download Directly]]&lt;br /&gt;
&lt;br /&gt;
==== Configuring Xcode Development Environment ====&lt;br /&gt;
Starting with SDK version 6.0.0.0, the Nielsen App SDK is compatible with Apple iOS versions 8.0 and above.  In addition, when using the dynamic framework,  all the required frameworks are linked automatically as the are needed.  More details can be found here: https://stackoverflow.com/questions/24902787/dont-we-need-to-link-framework-to-xcode-project-anymore&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': All communications between the SDK and the Census (Collection Facility) use HTTPS.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Download Framework ====&lt;br /&gt;
The first step is to download and copy the [[Special:Downloads|NielsenAppApi.framework]] bundle to the app project directory. (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
==== Add Framework ====&lt;br /&gt;
In the General tab for app configuration add NielsenAppApi.framework in the list of Embedded Binaries.  (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
==== Add Path ====&lt;br /&gt;
Add path to the NielsenAppApi.framework in the Framework Search Paths build setting.  (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
==== Import Framework ====&lt;br /&gt;
Add NielsenAppApi.framework module in the source file of your app:&lt;br /&gt;
&lt;br /&gt;
==== Using Swift ====&lt;br /&gt;
Add the following:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
import NielsenAppApi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using Objective-C ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang =&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
@import NielsenAppApi;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sample SDK Initialization Code ===&lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Swift  = &lt;br /&gt;
Swift 4.0 Example:&lt;br /&gt;
&amp;lt;code&amp;gt;NielsenInit.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
import Foundation&lt;br /&gt;
import NielsenAppApi&lt;br /&gt;
&lt;br /&gt;
class NielsenInit : NSObject {&lt;br /&gt;
    class func createNielsenApi(delegate: NielsenAppApiDelegate) -&amp;gt; NielsenAppApi?{&lt;br /&gt;
        &lt;br /&gt;
        let appInformation:[String: String] = [&lt;br /&gt;
            &amp;quot;appid&amp;quot;: &amp;quot;PDA7D5EE6-B1B8-4123-9277-2A788XXXXXXX&amp;quot;,&lt;br /&gt;
            &amp;quot;sfcode&amp;quot;: &amp;quot;dcr&amp;quot;,&lt;br /&gt;
            &amp;quot;nol_devDebug&amp;quot;: &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
        ]       &lt;br /&gt;
        return NielsenAppApi(appInfo:appInformation, delegate:delegate)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sample code using AVPlayer.&lt;br /&gt;
&amp;lt;code&amp;gt;LandingVC.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
import UIKit&lt;br /&gt;
import NielsenAppApi&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class LandingVC: UIViewController, NielsenAppApiDelegate {&lt;br /&gt;
    &lt;br /&gt;
    var nielsenMain : NielsenAppApi!&lt;br /&gt;
    var sdkMethods : SDKMethods!&lt;br /&gt;
    var data : [String : Any]!&lt;br /&gt;
&lt;br /&gt;
class ViewController: UIViewController, NielsenAppApiDelegate, AVPlayerViewControllerDelegate  {&lt;br /&gt;
&lt;br /&gt;
// your code//    &lt;br /&gt;
&lt;br /&gt;
  override func viewDidLoad() {&lt;br /&gt;
        super.viewDidLoad()&lt;br /&gt;
        //Getting the instance of NielsenApi&lt;br /&gt;
        self.nielsenApi = NielsenInit.createNielsenApi(delegate: self)&lt;br /&gt;
            }&lt;br /&gt;
  }&lt;br /&gt;
    override func viewDidAppear(_ animated: Bool) {      &lt;br /&gt;
        self.data = sdkMethods.loadStaticMaster()     // This is just an example of populating the metadata&lt;br /&gt;
        self.nielsenMain.loadMetadata(self.data)&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Objective C = &lt;br /&gt;
Initialize the Nielsen App object within the viewDidLoad view controller delegate method using initWithAppInfo:delegate:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;If App SDK is initialized using init or new methods, it will ignore the API calls resulting in no measurement. The SDK will not return any errors.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;    &lt;br /&gt;
#import &amp;quot;NielsenInit.h&amp;quot;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenEventTracker.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@implementation NielsenInit&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppApi *)createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate&lt;br /&gt;
{    &lt;br /&gt;
    //Initialising the NielsenEventTracker class by passing app information which returns the instance of NielsenEventTracker.&lt;br /&gt;
    &lt;br /&gt;
    NSDictionary *appInformation = @{ @&amp;quot;appid&amp;quot;: @&amp;quot;PDA7D5EE6-B1B8-4123-9277-2A788XXXXXXX&amp;quot;,&lt;br /&gt;
                            @&amp;quot;appversion&amp;quot;: @&amp;quot;1.0&amp;quot;,&lt;br /&gt;
                            @&amp;quot;sfcode&amp;quot;: @&amp;quot;dcr&amp;quot;,&lt;br /&gt;
                            @&amp;quot;nol_devDebug&amp;quot;: @&amp;quot;DEBUG&amp;quot;, };&lt;br /&gt;
    &lt;br /&gt;
    return [[NielsenAppApi alloc] initWithAppInfo:appInformation delegate:delegate];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following would be the &amp;lt;code&amp;gt;NielsenInit.h&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;Foundation/Foundation.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@class NielsenAppApi;&lt;br /&gt;
@protocol NielsenAppApiDelegate;&lt;br /&gt;
&lt;br /&gt;
@interface NielsenInit : NSObject&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppApi *)createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Sample Code:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
@implementation ViewController&lt;br /&gt;
&lt;br /&gt;
- (void)viewDidLoad {&lt;br /&gt;
    [super viewDidLoad];&lt;br /&gt;
        &lt;br /&gt;
    //Getting the instance of Nielsen SDK&lt;br /&gt;
    nielsenApi = [NielsenInit createNielsenAppApiWithDelegate:nil];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== iOS DCR Static Step 3 - Create/Load DCR Static Metadata Object ===&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisiond&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 3 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisiond&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Configure Metadata ====&lt;br /&gt;
Map the Nielsen keys to variables so that the content metadata is dynamically updated.&lt;br /&gt;
&lt;br /&gt;
The Nielsen reserved keys are:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Key !! Description !! Data Type !! Value !! Required?&lt;br /&gt;
|-&lt;br /&gt;
| type || asset type || fixed || &amp;lt;code&amp;gt;'static'&amp;lt;/code&amp;gt; || Yes&lt;br /&gt;
|-&lt;br /&gt;
| assetid || Unique ID for each article || dynamic || custom &amp;lt;br&amp;gt;(no [[Special Characters]]) || No&lt;br /&gt;
|-&lt;br /&gt;
| section || section of each site (e.g. section value should be first level in page URL: website.com/section). Limit to 25 unique values || dynamic || custom || Yes&lt;br /&gt;
|-&lt;br /&gt;
| segA || custom segment for reporting: Limit to 25 unique values across custom segments (segA + segB + segC) || dynamic || custom || No&lt;br /&gt;
|-&lt;br /&gt;
| segB || custom segment for reporting: Limit to 25 unique values across custom segments (segA + segB + segC) || dynamic || custom || No&lt;br /&gt;
|-&lt;br /&gt;
| segC || custom segment for reporting: Limit to 25 unique values across custom segments (segA + segB + segC) || dynamic || custom || No&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The values passed through the Nielsen keys will determine the breakouts that are seen in reporting. The custom segments (A, B &amp;amp; C) will roll into the sub-brand. To not use custom segments A, B and C, do not pass any value in these keys.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Configure API calls - loadMetadata ====&lt;br /&gt;
Use [[loadMetadata]] to pass 'content' [[Digital Measurement Metadata]]. The CMS data must be passed as a JSON object.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;    loadMetadata(JSONObject jsonMetadata);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Note: The [[loadMetadata]] call must have (&amp;quot;type&amp;quot;: &amp;quot;static&amp;quot;). &amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Call [[loadMetadata]] with JSON metadata as below.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;    new JSONObject()&lt;br /&gt;
        .put(&amp;quot;type&amp;quot;, &amp;quot;static&amp;quot;)&lt;br /&gt;
        .put(&amp;quot;section&amp;quot;, &amp;quot;siteSection&amp;quot;)&lt;br /&gt;
        .put(&amp;quot;assetid&amp;quot;, &amp;quot;vid345-67483&amp;quot;)&lt;br /&gt;
        .put(&amp;quot;segA&amp;quot;, &amp;quot;segmentA&amp;quot;)&lt;br /&gt;
        .put(&amp;quot;segB&amp;quot;, &amp;quot;segmentB&amp;quot;)&lt;br /&gt;
        .put(&amp;quot;segC&amp;quot;,&amp;quot;segmentC&amp;quot;)&lt;br /&gt;
    }&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As soon as this loadMetadata call is made, AppSDK will record a view event and start tracking the section/page time spent (AppSDK 9.1 and above).&lt;br /&gt;
&lt;br /&gt;
==== DCR Static Duration Measurement per Section/Page/Asset ====&lt;br /&gt;
If your Nielsen AppID is enabled for DCR Static duration measurement, a view event will be recorded and a timer will be started for each screen/page. Duration will be measured until a new page is loaded or the app is moved to the background. The event which triggers recognition of page view and timer start is the loadMetadata API call with a metadata object of type 'static'. Once a page is viewed and the timer has started, duration will be measured until a new page has loaded ''with associated loadMetadata call having a different '''section name''' from the previous page''. If a new loadMetadata call is made with the same '''section name''', it will be ignored - no new view will be recorded. If it is desired to have a new view event even though the metadata contains the same '''section name''' (example: single-page apps having several assedIDs but common section name), staticEnd API can be called between page views. For the purposes of this overview, staticend will not be used. See [[DCR_Static_iOS_SDK|this page]] for more information. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Keep Going ===&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisiong&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisiong&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Congratulations, you've successfully integrated the iOS SDK in your app!&lt;br /&gt;
&lt;br /&gt;
You can add static loadMetadata calls for more sections/pages in your app to see what happens when transitioning between sections.&lt;br /&gt;
&lt;br /&gt;
View your application's debug logs and search for the term (AppSDK) to see messages emitted by Nielsen AppSDK.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Next Steps ===&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisioni&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisioni&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now that you've integrated DCR Static for the AppSDK, what's next?&lt;br /&gt;
&lt;br /&gt;
====Going Live====&lt;br /&gt;
&lt;br /&gt;
In addition to the basic steps above, before going live developers need to handle app background/foreground events, make certain privacy disclosures, and allow users to opt out of Nielsen measurement. More details can be found [[DCR_Static_iOS_SDK|here]], along with a more comprehensive reference for implementing DCR Static measurement with AppSDK.&lt;br /&gt;
&lt;br /&gt;
Once the DCR Tracking Code is added, Nielsen will validate the implementation. Following Nielsen testing, developers need to make a few updates to the initialization call to ensure that the app is being measured properly.&lt;br /&gt;
&lt;br /&gt;
#'''App ID''': Ensure that correct  is used during initialization '''PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'''&lt;br /&gt;
#'''Debug Logging''': Disable logging by changing initialization call to use @&amp;quot;nol_devDebug&amp;quot;:@&amp;quot;INFO&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== &amp;amp;rarr; iOS DCR Video ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivision1&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide DCR Video &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivision1&amp;quot;&amp;gt;&lt;br /&gt;
==== iOS DCR Video Introduction ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv2-&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide Intro &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv2-&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Digital Content Ratings (DCR) Video product provides content consumption measurement in client mobile apps and webpages. This measurement includes insight into the total time a user spent watching the tracked content, video player events, and much more.&lt;br /&gt;
This example provides the steps to implement the DCR Video product in a sample iOS app. It includes:&lt;br /&gt;
&lt;br /&gt;
*SDK Initialization&lt;br /&gt;
*DCR Video Metadata: information about the content being tracked&lt;br /&gt;
*DCR Video Events/API calls&lt;br /&gt;
&lt;br /&gt;
By the end of this guide you will have the needed steps to integrate Nielsen's AppSDK in the background of your app.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== iOS DCR Video Step 1 - Obtain AppID ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv3&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 1 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv3&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To begin using the iOS AppSDK, you will need to obtain an Application ID (AppId)&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! !! Item !! Description !! Source&lt;br /&gt;
|-&lt;br /&gt;
|&amp;amp;#9989; || App ID (appid) || Unique ID assigned to the player/site and configured by product || Contact your Nielsen Representative&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The appid is a 37 character unique ID assigned to the player/site and configured by product and is required when creating a new instance of the AppSDK in the app.&lt;br /&gt;
&amp;lt;/br&amp;gt;Example: '''PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== iOS DCR Video Step 2 - SDK Initialization ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionc&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 2 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionc&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== How to obtain the NielsenAppApi.Framework =====&lt;br /&gt;
The Nielsen AppSDK can either be downloaded directly or can be integrated directly within an application through the use of CocoaPods. We recommend using the CocoaPods-based integration whenever possible to ensure you maintain the most recent changes and enhancements to the Nielsen libraries.&lt;br /&gt;
* [[Digital_Measurement_iOS_Artifactory_Guide|Select to obtain CocoaPods implementation guide]]&lt;br /&gt;
* [[Special:Downloads|Select to Download Directly]]&lt;br /&gt;
&lt;br /&gt;
===== Configuring Xcode Development Environment =====&lt;br /&gt;
Starting with SDK version 6.0.0.0, the Nielsen App SDK is compatible with Apple iOS versions 8.0 and above.  In addition, when using the dynamic framework,  all the required frameworks are linked automatically as the are needed.  More details can be found here: https://stackoverflow.com/questions/24902787/dont-we-need-to-link-framework-to-xcode-project-anymore&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': All communications between the SDK and the Census (Collection Facility) use HTTPS.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======= Download Framework =======&lt;br /&gt;
The first step is to download and copy the [[Special:Downloads|NielsenAppApi.framework]] bundle to the app project directory. (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
======= Add Framework =======&lt;br /&gt;
In the General tab for app configuration add NielsenAppApi.framework in the list of Embedded Binaries.  (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
======= Add Path =======&lt;br /&gt;
Add path to the NielsenAppApi.framework in the Framework Search Paths build setting.  (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
======= Import Framework =======&lt;br /&gt;
Add NielsenAppApi.framework module in the source file of your app:&lt;br /&gt;
&lt;br /&gt;
======= Using Swift =======&lt;br /&gt;
Add the following:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
import NielsenAppApi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======= Using Objective-C =======&lt;br /&gt;
&amp;lt;syntaxhighlight lang =&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
@import NielsenAppApi;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======= SDK Initialization =======&lt;br /&gt;
&lt;br /&gt;
The following table contains the list of arguments that can be passed via the AppInfo JSON schema.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter / Argument !! Description !! Source !! Required? !! Example&lt;br /&gt;
|--style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
| appid || Unique Nielsen ID for the application. The ID is a GUID data type. If you did not receive your App ID, let us know and we will provide you. || Nielsen-specified || Yes || PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&lt;br /&gt;
|--style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
| nol_devDebug || Enables Nielsen console logging. Only required for testing &amp;lt;br&amp;gt;&lt;br /&gt;
|| Nielsen-specified || Optional || DEBUG&lt;br /&gt;
|}&lt;br /&gt;
==== Debug flag for development environment ====&lt;br /&gt;
Player application developers / integrators can use Debug flag to check whether an App SDK API call made is successful. To activate the Debug flag,&lt;br /&gt;
Pass the argument &amp;lt;code&amp;gt;@&amp;quot;nol_devDebug&amp;quot;:@&amp;quot;DEBUG&amp;quot;&amp;lt;/code&amp;gt;, in the JSON string . &lt;br /&gt;
&lt;br /&gt;
Once the flag is active, it logs each API call made and the data passed. The log created by this flag is minimal.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': DO NOT activate the Debug flag in a production environment.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Swift Example ===&lt;br /&gt;
==== Sample SDK Initialization Code ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;NielsenInit.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class NielsenInit: NSObject {&lt;br /&gt;
    class func createNielsenAppApi(delegate: NielsenAppApiDelegate) -&amp;gt; NielsenAppApi?{&lt;br /&gt;
    let appInformation:[String: String] = [&lt;br /&gt;
           &amp;quot;appid&amp;quot;: &amp;quot;PE392366B-F2C1-4BC4-AB62-A7DAFDCXXXX&amp;quot;,&lt;br /&gt;
           &amp;quot;nol_devDebug&amp;quot;: &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
        ]&lt;br /&gt;
        return NielsenAppApi(appInfo:appInformation, delegate:delegate)}}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;ViewController.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class ViewController: UIViewController, NielsenAppApiDelegate, AVPictureInPictureControllerDelegate, CLLocationManagerDelegate  {&lt;br /&gt;
&lt;br /&gt;
    let avPlayerViewController = AVPlayerViewController()&lt;br /&gt;
    var avPlayer:AVPlayer?&lt;br /&gt;
    var nielsenAppApi: NielsenAppApi!&lt;br /&gt;
&lt;br /&gt;
  override func viewDidLoad() {&lt;br /&gt;
        super.viewDidLoad()&lt;br /&gt;
        self.nielsenAppApi = NielsenInit.createNielsenAppApi(delegate: self)&lt;br /&gt;
        NSLog(&amp;quot;Nielsen SDK initialized&amp;quot;)&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Objective C ===&lt;br /&gt;
==== Sample SDK Initialization Code ====&lt;br /&gt;
Initialize the Nielsen App object within the viewDidLoad view controller delegate method using initWithAppInfo:delegate:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;If App SDK is initialized using init or new methods, it will ignore the API calls resulting in no measurement. The SDK will not return any errors.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;quot;NlsAppApiFactory.h&amp;quot;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenAppApi.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@implementation NlsAppApiFactory&lt;br /&gt;
+ (NielsenAppApi *)createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
{&lt;br /&gt;
    NSDictionary *appInformation = @{&lt;br /&gt;
                                     @&amp;quot;appid&amp;quot;: &amp;quot;PE392366B-F2C1-4BC4-AB62-A7DAFDC51XXX&amp;quot;,&lt;br /&gt;
                                     @&amp;quot;nol_devDebug&amp;quot;: @&amp;quot;DEBUG&amp;quot;&lt;br /&gt;
                                     };&lt;br /&gt;
    return [[NielsenAppApi alloc] initWithAppInfo:appInformation delegate:delegate];&lt;br /&gt;
}&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following would be the &amp;lt;code&amp;gt;NlsAppApiFactory.h&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;Foundation/Foundation.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@class NielsenAppApi;&lt;br /&gt;
@protocol NielsenAppApiDeligate;&lt;br /&gt;
@interface NlsAppApiFactory : NSObject&lt;br /&gt;
+ (NielsenAppAPI *) createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
@end&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
The following might be in the &amp;lt;code&amp;gt;Viewcontroller.m&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
@implementation ViewController&lt;br /&gt;
&lt;br /&gt;
- (void)viewDidLoad {&lt;br /&gt;
    [super viewDidLoad];&lt;br /&gt;
    &lt;br /&gt;
    //Setting background image&lt;br /&gt;
    UIImage *backgroundImage = [UIImage imageNamed:@&amp;quot;new_ios_bg.png&amp;quot;];&lt;br /&gt;
    UIImageView *backgroundImageView=[[UIImageView alloc]initWithFrame:self.view.frame];&lt;br /&gt;
    backgroundImageView.image=backgroundImage;&lt;br /&gt;
    [self.view insertSubview:backgroundImageView atIndex:0];&lt;br /&gt;
    &lt;br /&gt;
    //Mark: In NielsenInit class we are initialising the Nielsen SDK.&lt;br /&gt;
    &lt;br /&gt;
    //Getting the instance of Nielsen SDK&lt;br /&gt;
    nielsenApi = [NielsenInit createNielsenAppApiWithDelegate:nil];&lt;br /&gt;
}&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== iOS DCR Video Step 3 - Create DCR Video Content Metadata Object ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv5&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 3 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv5&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Configure Metadata =====&lt;br /&gt;
The SDK methods handle 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 Nielsen Key names (e.g. appid, program) 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;br&amp;gt;&lt;br /&gt;
===== Create channelName Metadata =====&lt;br /&gt;
channelName 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;
|--style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
! Key !! Description !!	Values	 !! Required&lt;br /&gt;
|--style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
| channelName	|| Any string representing the channel/stream	|| custom	|| ✓&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== Create Content Metadata =====&lt;br /&gt;
Content metadata should remain constant throughout the entirety of an episode/clip including when ads play.&lt;br /&gt;
&amp;lt;blockquote&amp;gt; program and title metadata values should be passed to SDK as UTF-8 strings. &amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;height: 45em; overflow-y:auto;&amp;quot;&amp;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'''!!'''Provider'''&lt;br /&gt;
|-&lt;br /&gt;
| type || Type of asset ||For Video use: &amp;lt;code&amp;gt;content&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt; For Static or text &amp;lt;code&amp;gt;static&amp;lt;/code&amp;gt; || Yes || Nielsen&lt;br /&gt;
|-style=&amp;quot;background-color:#e9f9fa;&amp;quot;&lt;br /&gt;
| assetid || Unique ID assigned to asset &amp;lt;br&amp;gt; Note: Refrain from using the following special characters [[Special_Characters|(Special Characters)]]. || Examples: &amp;lt;br&amp;gt; &amp;lt;code&amp;gt;BBT345a234 &amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; &amp;lt;code&amp;gt;CBSs5e234F2021&amp;lt;/code&amp;gt;  || Yes || Client &lt;br /&gt;
|-&lt;br /&gt;
| program ||Complete program or movie title &amp;lt;br&amp;gt; (no abbreviations or shorthand) &amp;lt;br&amp;gt; Note: there is a 25 character limit.  ||&amp;lt;code&amp;gt; The Big Bang Theory&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; &amp;lt;code&amp;gt; TheBigBangTheory&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt;&amp;lt;code&amp;gt; The Dark Knight&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt;&amp;lt;code&amp;gt; TheDarkKnight&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; || Yes || Client &lt;br /&gt;
|-style=&amp;quot;background-color:#e9f9fa;&amp;quot;&lt;br /&gt;
| title ||Episode title with season and episode number (40 character limit) &amp;lt;br&amp;gt; (Formats accepted: S01E03, S1E3, S1 E3). || Examples: &amp;lt;br&amp;gt; &amp;lt;code&amp;gt;The Pants Alternative S03E18&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; &amp;lt;code&amp;gt;The Pants Alternative S3E18&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; &amp;lt;code&amp;gt;The Pants Alternative S3 E18&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; Can also accept: &amp;lt;code&amp;gt; S3E18&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; Not Valid: &amp;lt;code&amp;gt; 318 &amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt; 0318 &amp;lt;/code&amp;gt;|| Yes || Client &lt;br /&gt;
|-&lt;br /&gt;
| crossId1 || Gracenote TMS ID (If available) should be passed for all telecasted content for clients using the Gracenote solution for proper matching purposes. &amp;lt;br&amp;gt;Note: The TMS ID will be a 14 character string. Normally leading with 2 alpha characerts ('EP', 'MV', 'SH' or 'SP'), followed by 12 numbers.&lt;br /&gt;
|| The TMS ID will be a 14 character string. &amp;lt;br&amp;gt; Normally being with  'EV,' 'EP', 'SH', 'SP', or 'MV' &amp;lt;br&amp;gt; Followed by 12 numbers after the initial two letter prefix. &amp;lt;br&amp;gt; &amp;lt;br&amp;gt; The Giant Morning Show: &amp;lt;code&amp;gt;SH009311820022&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; The Pants Alternative Episode : &amp;lt;code&amp;gt;EP009311820061&amp;lt;/code&amp;gt; || Optional || Nielsen&lt;br /&gt;
|-style=&amp;quot;background-color:#e9f9fa;&amp;quot;&lt;br /&gt;
| crossId2 || Populated by content distributor to contribute viewing from that distributor to the given content originator. || For a full list of acceptable values, please contact your Nielsen reprentative. || Yes, for distributors || Nielsen&lt;br /&gt;
|-&lt;br /&gt;
| length || Length of content in seconds&amp;lt;br&amp;gt;Note: Integers and decimals are acceptable values are acceptable for the length parameter. || Examples:&lt;br /&gt;
&amp;lt;small&amp;gt;For standard VOD content - &amp;lt;code&amp;gt;300&amp;lt;/code&amp;gt; to represent 5 minutes, &amp;lt;code&amp;gt;1320&amp;lt;/code&amp;gt; to represent 22 minutes, etc.&lt;br /&gt;
&amp;lt;br&amp;gt;If DAI live stream of a discrete program (Live Event/Sporting Event), pass length of content. See example for standard VOD content above.&lt;br /&gt;
&amp;lt;br&amp;gt;If unknown DAI live steam, pass a value of &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;.&amp;lt;/small&amp;gt; &lt;br /&gt;
|| Yes || Client &lt;br /&gt;
|-style=&amp;quot;background-color:#e9f9fa;&amp;quot;&lt;br /&gt;
| airdate ||Original broadcast or release date for the program &amp;lt;br&amp;gt;For USA, date should be EST &amp;lt;br&amp;gt; Outside USA, date should be local time.&amp;lt;br&amp;gt;If not applicable or available, original broadcast or release date for the Program. || Acceptable Formats:&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;YYYY-MM-DDTHH:MI:SS&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;YYYY-MM-DDHH:MI:SS&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;YYYY-MM-DDTHH:MI:SS+xx:xx&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;YYYY-MM-DDTHH:MI:SS-xx:xx&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;YYYYMMDDHH:MI:SS&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;YYYYMMDD HH:MI:SS&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;MM-DD-YYYY&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;MM/DD/YYYY&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;YYYYMMDD&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; || Yes || Client &lt;br /&gt;
|-&lt;br /&gt;
| isfullepisode || Full episode flag to identify differences between long form content. || &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;- full episode, &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt;- non full episode(clip,teaser,promo,etc.)&lt;br /&gt;
&amp;lt;small&amp;gt;Also accept: &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;lf&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;yes&amp;lt;/code&amp;gt;- longform&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;sf&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;no&amp;lt;/code&amp;gt;- shortform&lt;br /&gt;
|| Yes || Nielsen&lt;br /&gt;
|-style=&amp;quot;background-color:#e9f9fa;&amp;quot;&lt;br /&gt;
| adloadtype || &amp;lt;big&amp;gt;&amp;lt;small&amp;gt;Type of ad load: &lt;br /&gt;
&amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; Linear – matches TV ad load&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;2&amp;lt;/code&amp;gt; Dynamic – Dynamic Ad Insertion (DAI)&amp;lt;/small&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
|| &amp;lt;code&amp;gt;2&amp;lt;/code&amp;gt; - DCR measures content with dynamic ads || Yes || Nielsen&lt;br /&gt;
|-&lt;br /&gt;
| segB || One of two custom segment for the clients granular reporting within a brand. || Examples:&amp;lt;br&amp;gt;Genre - &amp;lt;code&amp;gt;horror&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;comedy&amp;lt;/code&amp;gt;, etc.&amp;lt;br&amp;gt;Timeslot - &amp;lt;code&amp;gt;primetime&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;daytime&amp;lt;/code&amp;gt;, etc.&amp;lt;br&amp;gt;News type - &amp;lt;code&amp;gt;breakingnews&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;weather&amp;lt;/code&amp;gt;, etc. || Optional || Client &lt;br /&gt;
|-style=&amp;quot;background-color:#e9f9fa;&amp;quot;&lt;br /&gt;
| segC || One of two custom segment for the clients granular reporting within a brand. || Examples:&amp;lt;br&amp;gt;Genre - &amp;lt;code&amp;gt;horror&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;comedy&amp;lt;/code&amp;gt;, etc.&amp;lt;br&amp;gt;Timeslot - &amp;lt;code&amp;gt;primetime&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;daytime&amp;lt;/code&amp;gt;, etc.&amp;lt;br&amp;gt;News type - &amp;lt;code&amp;gt;breakingnews&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;weather&amp;lt;/code&amp;gt;, etc. || Optional || Client &lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Custom segments (segB and segC) can be used to aggregate video and/or static content within a single Brand to receive more granular reports within a brand.&lt;br /&gt;
&lt;br /&gt;
Examples regarding usage of segments within SDK:&lt;br /&gt;
* All comedy clips and stories for a Brand rolled into a &amp;quot;Comedy&amp;quot; segment&lt;br /&gt;
* genre grouping content by Comedy vs. Drama&lt;br /&gt;
* group related Text + Video content - i.e. for a show that has a lot of - static pages associated with it&lt;br /&gt;
* packaging based on how clients sell inventory&lt;br /&gt;
* grouping related types of content either by genre, category or platform.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Metadata Example =====&lt;br /&gt;
&amp;lt;code&amp;gt;Swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&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;program&amp;quot;: &amp;quot;The Big Bang Theory&amp;quot;,&lt;br /&gt;
    &amp;quot;title&amp;quot;: &amp;quot;The Pants Alternative S03E18&amp;quot;,  //Formats accepted: S01E03, S1E3, S1 E3&lt;br /&gt;
    &amp;quot;crossId1&amp;quot;: &amp;quot;EP009311820061&amp;quot;, //optional&lt;br /&gt;
    &amp;quot;crossId2&amp;quot;: &amp;quot;Content Originator&amp;quot;, //optional&lt;br /&gt;
    &amp;quot;length&amp;quot;: &amp;quot;3600&amp;quot;,&lt;br /&gt;
    &amp;quot;airdate&amp;quot;: &amp;quot;2022-03-21T10:05:00&amp;quot;, &lt;br /&gt;
    &amp;quot;isfullepisode&amp;quot;: &amp;quot;Yes&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;
];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;Objective-C&amp;lt;/code&amp;gt;    &lt;br /&gt;
&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;program&amp;quot;: @ &amp;quot;The Big Bang Theory&amp;quot;,&lt;br /&gt;
    @ &amp;quot;title&amp;quot;: @ &amp;quot;The Pants Alternative S03E18&amp;quot;, //Formats accepted: S01E03, S1E3, S1 E3&lt;br /&gt;
    @ &amp;quot;crossId1&amp;quot;: @ &amp;quot;EP009311820061&amp;quot;, //optional&lt;br /&gt;
    @ &amp;quot;crossId2&amp;quot;: @ &amp;quot;Content Originator&amp;quot;, //optional&lt;br /&gt;
    @ &amp;quot;length&amp;quot;: @ &amp;quot;3600&amp;quot;,&lt;br /&gt;
    @ &amp;quot;airdate&amp;quot;: @ &amp;quot;2022-03-21T10:05:00&amp;quot;,&lt;br /&gt;
    @ &amp;quot;isfullepisode&amp;quot;: @ &amp;quot;y&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;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== iOS DCR Video Step 4 - Basic Set of Events - Sample Playback ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv6&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 4 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv6&amp;quot;&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;
| '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;
| 'playheadPosition'	|| 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: 'PlayheadPosition' 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 '''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 content or Ad playback is interrupted and at the end of each Ad. &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. &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;'''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;
==== Sample Use Case: 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 [[playheadPosition|playheadPosition()]] 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;
|-style=&amp;quot;background-color:#d8f5d7;&amp;quot;&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;
|-style=&amp;quot;background-color:#d8f5d7;&amp;quot;&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;
|- style=&amp;quot;background-color:#d8f5d7;&amp;quot;&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;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Keep Going ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv9&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv9&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Congratulations, you've successfully integrated the iOS SDK in your app for a basic content playback scenario!&lt;br /&gt;
&lt;br /&gt;
You can add more content to see channel-change scenarios or continue to next steps below.&lt;br /&gt;
&lt;br /&gt;
View your application's debug logs and search for the term (AppSDK) to see messages emitted by Nielsen AppSDK during video playback.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Next Steps ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv10&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv10&amp;quot;&amp;gt;&lt;br /&gt;
====Going Live====&lt;br /&gt;
&lt;br /&gt;
In addition to the basic steps above, before going live developers need to handle app background/foreground events, make certain privacy disclosures, handle interruption events (stop, fast-forward, rewind), remove iOS simulator slices, and allow users to opt out of Nielsen measurement. More details can be found [[DCR_Video_iOS_SDK|here]], along with a more comprehensive reference for implementing DCR Video measurement with AppSDK.&lt;br /&gt;
&lt;br /&gt;
Once the DCR Tracking Code is added, Nielsen will validate the implementation. Following Nielsen testing, developers need to make a few updates to the initialization call to ensure that the app is being measured properly.&lt;br /&gt;
&lt;br /&gt;
#'''App ID''': Ensure that correct  is used during initialization '''PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'''&lt;br /&gt;
#'''Debug Logging''': Disable logging by changing initialization call to use @&amp;quot;nol_devDebug&amp;quot;:@&amp;quot;INFO&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== &amp;amp;rarr; iOS DTVR (coming soon) ==&lt;/div&gt;</summary>
		<author><name>NickParrucci</name></author>
	</entry>
	<entry>
		<id>https://nielsentest.mywikis.net/w/index.php?title=iOS_Step_By_Step&amp;diff=6467</id>
		<title>iOS Step By Step</title>
		<link rel="alternate" type="text/html" href="https://nielsentest.mywikis.net/w/index.php?title=iOS_Step_By_Step&amp;diff=6467"/>
		<updated>2023-07-27T13:29:26Z</updated>

		<summary type="html">&lt;p&gt;NickParrucci: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
__NOTOC__&lt;br /&gt;
&lt;br /&gt;
Provided below are step-by-step quick start guides for implementing Nielsen iOS SDK for DCR Static, DCR Video, and DTVR products. Click each section to get started. &lt;br /&gt;
&lt;br /&gt;
== &amp;amp;rarr; iOS DCR Static ==&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivision&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide DCR Static &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivision&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== iOS DCR Static Introduction ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisiona-&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide Intro &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisiona-&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Digital Content Ratings (DCR) Static product provides content consumption measurement in client mobile apps and webpages. This measurement includes insight into the total time a user spent on a webpage, how they navigated through the page via links, and many other data points.&lt;br /&gt;
This tutorial provides the steps to implement the DCR Static product in a sample iOS app. It includes:&lt;br /&gt;
&lt;br /&gt;
*SDK Initialization Call&lt;br /&gt;
*DCR Static Metadata: information about the sections being tracked&lt;br /&gt;
&lt;br /&gt;
By the end of this guide you will have the needed steps to integrate Nielsen's AppSDK in the background of your app.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== iOS DCR Static Step 1 - Obtain AppID ===&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisiona1&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 1 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisiona1&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To begin using the iOS SDK (AppSDK) you will need to obtain an Application ID (AppId)&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! !! Item !! Description !! Source&lt;br /&gt;
|-&lt;br /&gt;
|&amp;amp;#9989; || App ID (appid) || Unique ID assigned to the player/site and configured by product || Contact your Nielsen TAM&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The appid is a 37 character unique ID assigned to the player/site and configured by product and is required when creating a new instance of the AppSDK in the app.&lt;br /&gt;
&amp;lt;/br&amp;gt;Example: '''PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== iOS DCR Static Step 2 - SDK Initialization ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionc&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 2 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionc&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== How to obtain the NielsenAppApi.Framework ====&lt;br /&gt;
The Nielsen AppSDK can either be downloaded directly or can be integrated directly within an application through the use of CocoaPods. We recommend using the CocoaPods-based integration whenever possible to ensure you maintain the most recent changes and enhancements to the Nielsen libraries.&lt;br /&gt;
* [[Digital_Measurement_iOS_Artifactory_Guide|Select to obtain CocoaPods implementation guide]]&lt;br /&gt;
* [[Special:Downloads|Select to Download Directly]]&lt;br /&gt;
&lt;br /&gt;
==== Configuring Xcode Development Environment ====&lt;br /&gt;
Starting with SDK version 6.0.0.0, the Nielsen App SDK is compatible with Apple iOS versions 8.0 and above.  In addition, when using the dynamic framework,  all the required frameworks are linked automatically as the are needed.  More details can be found here: https://stackoverflow.com/questions/24902787/dont-we-need-to-link-framework-to-xcode-project-anymore&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': All communications between the SDK and the Census (Collection Facility) use HTTPS.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Download Framework ====&lt;br /&gt;
The first step is to download and copy the [[Special:Downloads|NielsenAppApi.framework]] bundle to the app project directory. (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
==== Add Framework ====&lt;br /&gt;
In the General tab for app configuration add NielsenAppApi.framework in the list of Embedded Binaries.  (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
==== Add Path ====&lt;br /&gt;
Add path to the NielsenAppApi.framework in the Framework Search Paths build setting.  (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
==== Import Framework ====&lt;br /&gt;
Add NielsenAppApi.framework module in the source file of your app:&lt;br /&gt;
&lt;br /&gt;
==== Using Swift ====&lt;br /&gt;
Add the following:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
import NielsenAppApi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using Objective-C ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang =&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
@import NielsenAppApi;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sample SDK Initialization Code ===&lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Swift  = &lt;br /&gt;
Swift 4.0 Example:&lt;br /&gt;
&amp;lt;code&amp;gt;NielsenInit.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
import Foundation&lt;br /&gt;
import NielsenAppApi&lt;br /&gt;
&lt;br /&gt;
class NielsenInit : NSObject {&lt;br /&gt;
    class func createNielsenApi(delegate: NielsenAppApiDelegate) -&amp;gt; NielsenAppApi?{&lt;br /&gt;
        &lt;br /&gt;
        let appInformation:[String: String] = [&lt;br /&gt;
            &amp;quot;appid&amp;quot;: &amp;quot;PDA7D5EE6-B1B8-4123-9277-2A788XXXXXXX&amp;quot;,&lt;br /&gt;
            &amp;quot;sfcode&amp;quot;: &amp;quot;dcr&amp;quot;,&lt;br /&gt;
            &amp;quot;nol_devDebug&amp;quot;: &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
        ]       &lt;br /&gt;
        return NielsenAppApi(appInfo:appInformation, delegate:delegate)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sample code using AVPlayer.&lt;br /&gt;
&amp;lt;code&amp;gt;LandingVC.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
import UIKit&lt;br /&gt;
import NielsenAppApi&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class LandingVC: UIViewController, NielsenAppApiDelegate {&lt;br /&gt;
    &lt;br /&gt;
    var nielsenMain : NielsenAppApi!&lt;br /&gt;
    var sdkMethods : SDKMethods!&lt;br /&gt;
    var data : [String : Any]!&lt;br /&gt;
&lt;br /&gt;
class ViewController: UIViewController, NielsenAppApiDelegate, AVPlayerViewControllerDelegate  {&lt;br /&gt;
&lt;br /&gt;
// your code//    &lt;br /&gt;
&lt;br /&gt;
  override func viewDidLoad() {&lt;br /&gt;
        super.viewDidLoad()&lt;br /&gt;
        //Getting the instance of NielsenApi&lt;br /&gt;
        self.nielsenApi = NielsenInit.createNielsenApi(delegate: self)&lt;br /&gt;
            }&lt;br /&gt;
  }&lt;br /&gt;
    override func viewDidAppear(_ animated: Bool) {      &lt;br /&gt;
        self.data = sdkMethods.loadStaticMaster()     // This is just an example of populating the metadata&lt;br /&gt;
        self.nielsenMain.loadMetadata(self.data)&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Objective C = &lt;br /&gt;
Initialize the Nielsen App object within the viewDidLoad view controller delegate method using initWithAppInfo:delegate:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;If App SDK is initialized using init or new methods, it will ignore the API calls resulting in no measurement. The SDK will not return any errors.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;    &lt;br /&gt;
#import &amp;quot;NielsenInit.h&amp;quot;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenEventTracker.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@implementation NielsenInit&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppApi *)createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate&lt;br /&gt;
{    &lt;br /&gt;
    //Initialising the NielsenEventTracker class by passing app information which returns the instance of NielsenEventTracker.&lt;br /&gt;
    &lt;br /&gt;
    NSDictionary *appInformation = @{ @&amp;quot;appid&amp;quot;: @&amp;quot;PDA7D5EE6-B1B8-4123-9277-2A788XXXXXXX&amp;quot;,&lt;br /&gt;
                            @&amp;quot;appversion&amp;quot;: @&amp;quot;1.0&amp;quot;,&lt;br /&gt;
                            @&amp;quot;sfcode&amp;quot;: @&amp;quot;dcr&amp;quot;,&lt;br /&gt;
                            @&amp;quot;nol_devDebug&amp;quot;: @&amp;quot;DEBUG&amp;quot;, };&lt;br /&gt;
    &lt;br /&gt;
    return [[NielsenAppApi alloc] initWithAppInfo:appInformation delegate:delegate];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following would be the &amp;lt;code&amp;gt;NielsenInit.h&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;Foundation/Foundation.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@class NielsenAppApi;&lt;br /&gt;
@protocol NielsenAppApiDelegate;&lt;br /&gt;
&lt;br /&gt;
@interface NielsenInit : NSObject&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppApi *)createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Sample Code:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
@implementation ViewController&lt;br /&gt;
&lt;br /&gt;
- (void)viewDidLoad {&lt;br /&gt;
    [super viewDidLoad];&lt;br /&gt;
        &lt;br /&gt;
    //Getting the instance of Nielsen SDK&lt;br /&gt;
    nielsenApi = [NielsenInit createNielsenAppApiWithDelegate:nil];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== iOS DCR Static Step 3 - Create/Load DCR Static Metadata Object ===&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisiond&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 3 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisiond&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Configure Metadata ====&lt;br /&gt;
Map the Nielsen keys to variables so that the content metadata is dynamically updated.&lt;br /&gt;
&lt;br /&gt;
The Nielsen reserved keys are:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Key !! Description !! Data Type !! Value !! Required?&lt;br /&gt;
|-&lt;br /&gt;
| type || asset type || fixed || &amp;lt;code&amp;gt;'static'&amp;lt;/code&amp;gt; || Yes&lt;br /&gt;
|-&lt;br /&gt;
| assetid || Unique ID for each article || dynamic || custom &amp;lt;br&amp;gt;(no [[Special Characters]]) || No&lt;br /&gt;
|-&lt;br /&gt;
| section || section of each site (e.g. section value should be first level in page URL: website.com/section). Limit to 25 unique values || dynamic || custom || Yes&lt;br /&gt;
|-&lt;br /&gt;
| segA || custom segment for reporting: Limit to 25 unique values across custom segments (segA + segB + segC) || dynamic || custom || No&lt;br /&gt;
|-&lt;br /&gt;
| segB || custom segment for reporting: Limit to 25 unique values across custom segments (segA + segB + segC) || dynamic || custom || No&lt;br /&gt;
|-&lt;br /&gt;
| segC || custom segment for reporting: Limit to 25 unique values across custom segments (segA + segB + segC) || dynamic || custom || No&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The values passed through the Nielsen keys will determine the breakouts that are seen in reporting. The custom segments (A, B &amp;amp; C) will roll into the sub-brand. To not use custom segments A, B and C, do not pass any value in these keys.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Configure API calls - loadMetadata ====&lt;br /&gt;
Use [[loadMetadata]] to pass 'content' [[Digital Measurement Metadata]]. The CMS data must be passed as a JSON object.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;    loadMetadata(JSONObject jsonMetadata);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Note: The [[loadMetadata]] call must have (&amp;quot;type&amp;quot;: &amp;quot;static&amp;quot;). &amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Call [[loadMetadata]] with JSON metadata as below.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;    new JSONObject()&lt;br /&gt;
        .put(&amp;quot;type&amp;quot;, &amp;quot;static&amp;quot;)&lt;br /&gt;
        .put(&amp;quot;section&amp;quot;, &amp;quot;siteSection&amp;quot;)&lt;br /&gt;
        .put(&amp;quot;assetid&amp;quot;, &amp;quot;vid345-67483&amp;quot;)&lt;br /&gt;
        .put(&amp;quot;segA&amp;quot;, &amp;quot;segmentA&amp;quot;)&lt;br /&gt;
        .put(&amp;quot;segB&amp;quot;, &amp;quot;segmentB&amp;quot;)&lt;br /&gt;
        .put(&amp;quot;segC&amp;quot;,&amp;quot;segmentC&amp;quot;)&lt;br /&gt;
    }&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As soon as this loadMetadata call is made, AppSDK will record a view event and start tracking the section/page time spent (AppSDK 9.1 and above).&lt;br /&gt;
&lt;br /&gt;
==== DCR Static Duration Measurement per Section/Page/Asset ====&lt;br /&gt;
If your Nielsen AppID is enabled for DCR Static duration measurement, a view event will be recorded and a timer will be started for each screen/page. Duration will be measured until a new page is loaded or the app is moved to the background. The event which triggers recognition of page view and timer start is the loadMetadata API call with a metadata object of type 'static'. Once a page is viewed and the timer has started, duration will be measured until a new page has loaded ''with associated loadMetadata call having a different '''section name''' from the previous page''. If a new loadMetadata call is made with the same '''section name''', it will be ignored - no new view will be recorded. If it is desired to have a new view event even though the metadata contains the same '''section name''' (example: single-page apps having several assedIDs but common section name), staticEnd API can be called between page views. For the purposes of this overview, staticend will not be used. See [[DCR_Static_iOS_SDK|this page]] for more information. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Keep Going ===&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisiong&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisiong&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Congratulations, you've successfully integrated the iOS SDK in your app!&lt;br /&gt;
&lt;br /&gt;
You can add static loadMetadata calls for more sections/pages in your app to see what happens when transitioning between sections.&lt;br /&gt;
&lt;br /&gt;
View your application's debug logs and search for the term (AppSDK) to see messages emitted by Nielsen AppSDK.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Next Steps ===&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisioni&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisioni&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now that you've integrated DCR Static for the AppSDK, what's next?&lt;br /&gt;
&lt;br /&gt;
====Going Live====&lt;br /&gt;
&lt;br /&gt;
In addition to the basic steps above, before going live developers need to handle app background/foreground events, make certain privacy disclosures, and allow users to opt out of Nielsen measurement. More details can be found [[DCR_Static_iOS_SDK|here]], along with a more comprehensive reference for implementing DCR Static measurement with AppSDK.&lt;br /&gt;
&lt;br /&gt;
Once the DCR Tracking Code is added, Nielsen will validate the implementation. Following Nielsen testing, developers need to make a few updates to the initialization call to ensure that the app is being measured properly.&lt;br /&gt;
&lt;br /&gt;
#'''App ID''': Ensure that correct  is used during initialization '''PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'''&lt;br /&gt;
#'''Debug Logging''': Disable logging by changing initialization call to use @&amp;quot;nol_devDebug&amp;quot;:@&amp;quot;INFO&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== &amp;amp;rarr; iOS DCR Video ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivision1&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide DCR Video &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivision1&amp;quot;&amp;gt;&lt;br /&gt;
==== iOS DCR Video Introduction ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv2-&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide Intro &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv2-&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Digital Content Ratings (DCR) Video product provides content consumption measurement in client mobile apps and webpages. This measurement includes insight into the total time a user spent watching the tracked content, video player events, and much more.&lt;br /&gt;
This example provides the steps to implement the DCR Video product in a sample iOS app. It includes:&lt;br /&gt;
&lt;br /&gt;
*SDK Initialization&lt;br /&gt;
*DCR Video Metadata: information about the content being tracked&lt;br /&gt;
*DCR Video Events/API calls&lt;br /&gt;
&lt;br /&gt;
By the end of this guide you will have the needed steps to integrate Nielsen's AppSDK in the background of your app.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== iOS DCR Video Step 1 - Obtain AppID ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv3&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 1 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv3&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To begin using the iOS AppSDK, you will need to obtain an Application ID (AppId)&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! !! Item !! Description !! Source&lt;br /&gt;
|-&lt;br /&gt;
|&amp;amp;#9989; || App ID (appid) || Unique ID assigned to the player/site and configured by product || Contact your Nielsen Representative&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The appid is a 37 character unique ID assigned to the player/site and configured by product and is required when creating a new instance of the AppSDK in the app.&lt;br /&gt;
&amp;lt;/br&amp;gt;Example: '''PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== iOS DCR Video Step 2 - SDK Initialization ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionc&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 2 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionc&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== How to obtain the NielsenAppApi.Framework =====&lt;br /&gt;
The Nielsen AppSDK can either be downloaded directly or can be integrated directly within an application through the use of CocoaPods. We recommend using the CocoaPods-based integration whenever possible to ensure you maintain the most recent changes and enhancements to the Nielsen libraries.&lt;br /&gt;
* [[Digital_Measurement_iOS_Artifactory_Guide|Select to obtain CocoaPods implementation guide]]&lt;br /&gt;
* [[Special:Downloads|Select to Download Directly]]&lt;br /&gt;
&lt;br /&gt;
===== Configuring Xcode Development Environment =====&lt;br /&gt;
Starting with SDK version 6.0.0.0, the Nielsen App SDK is compatible with Apple iOS versions 8.0 and above.  In addition, when using the dynamic framework,  all the required frameworks are linked automatically as the are needed.  More details can be found here: https://stackoverflow.com/questions/24902787/dont-we-need-to-link-framework-to-xcode-project-anymore&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': All communications between the SDK and the Census (Collection Facility) use HTTPS.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======= Download Framework =======&lt;br /&gt;
The first step is to download and copy the [[Special:Downloads|NielsenAppApi.framework]] bundle to the app project directory. (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
======= Add Framework =======&lt;br /&gt;
In the General tab for app configuration add NielsenAppApi.framework in the list of Embedded Binaries.  (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
======= Add Path =======&lt;br /&gt;
Add path to the NielsenAppApi.framework in the Framework Search Paths build setting.  (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
======= Import Framework =======&lt;br /&gt;
Add NielsenAppApi.framework module in the source file of your app:&lt;br /&gt;
&lt;br /&gt;
======= Using Swift =======&lt;br /&gt;
Add the following:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
import NielsenAppApi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======= Using Objective-C =======&lt;br /&gt;
&amp;lt;syntaxhighlight lang =&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
@import NielsenAppApi;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======= SDK Initialization =======&lt;br /&gt;
&lt;br /&gt;
The following table contains the list of arguments that can be passed via the AppInfo JSON schema.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter / Argument !! Description !! Source !! Required? !! Example&lt;br /&gt;
|--style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
| appid || Unique Nielsen ID for the application. The ID is a GUID data type. If you did not receive your App ID, let us know and we will provide you. || Nielsen-specified || Yes || PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&lt;br /&gt;
|--style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
| nol_devDebug || Enables Nielsen console logging. Only required for testing &amp;lt;br&amp;gt;&lt;br /&gt;
|| Nielsen-specified || Optional || DEBUG&lt;br /&gt;
|}&lt;br /&gt;
==== Debug flag for development environment ====&lt;br /&gt;
Player application developers / integrators can use Debug flag to check whether an App SDK API call made is successful. To activate the Debug flag,&lt;br /&gt;
Pass the argument &amp;lt;code&amp;gt;@&amp;quot;nol_devDebug&amp;quot;:@&amp;quot;DEBUG&amp;quot;&amp;lt;/code&amp;gt;, in the JSON string . &lt;br /&gt;
&lt;br /&gt;
Once the flag is active, it logs each API call made and the data passed. The log created by this flag is minimal.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': DO NOT activate the Debug flag in a production environment.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Swift Example ===&lt;br /&gt;
==== Sample SDK Initialization Code ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;NielsenInit.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class NielsenInit: NSObject {&lt;br /&gt;
    class func createNielsenAppApi(delegate: NielsenAppApiDelegate) -&amp;gt; NielsenAppApi?{&lt;br /&gt;
    let appInformation:[String: String] = [&lt;br /&gt;
           &amp;quot;appid&amp;quot;: &amp;quot;PE392366B-F2C1-4BC4-AB62-A7DAFDCXXXX&amp;quot;,&lt;br /&gt;
           &amp;quot;nol_devDebug&amp;quot;: &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
        ]&lt;br /&gt;
        return NielsenAppApi(appInfo:appInformation, delegate:delegate)}}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;ViewController.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class ViewController: UIViewController, NielsenAppApiDelegate, AVPictureInPictureControllerDelegate, CLLocationManagerDelegate  {&lt;br /&gt;
&lt;br /&gt;
    let avPlayerViewController = AVPlayerViewController()&lt;br /&gt;
    var avPlayer:AVPlayer?&lt;br /&gt;
    var nielsenAppApi: NielsenAppApi!&lt;br /&gt;
&lt;br /&gt;
  override func viewDidLoad() {&lt;br /&gt;
        super.viewDidLoad()&lt;br /&gt;
        self.nielsenAppApi = NielsenInit.createNielsenAppApi(delegate: self)&lt;br /&gt;
        NSLog(&amp;quot;Nielsen SDK initialized&amp;quot;)&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Objective C ===&lt;br /&gt;
==== Sample SDK Initialization Code ====&lt;br /&gt;
Initialize the Nielsen App object within the viewDidLoad view controller delegate method using initWithAppInfo:delegate:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;If App SDK is initialized using init or new methods, it will ignore the API calls resulting in no measurement. The SDK will not return any errors.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;quot;NlsAppApiFactory.h&amp;quot;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenAppApi.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@implementation NlsAppApiFactory&lt;br /&gt;
+ (NielsenAppApi *)createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
{&lt;br /&gt;
    NSDictionary *appInformation = @{&lt;br /&gt;
                                     @&amp;quot;appid&amp;quot;: &amp;quot;PE392366B-F2C1-4BC4-AB62-A7DAFDC51XXX&amp;quot;,&lt;br /&gt;
                                     @&amp;quot;nol_devDebug&amp;quot;: @&amp;quot;DEBUG&amp;quot;&lt;br /&gt;
                                     };&lt;br /&gt;
    return [[NielsenAppApi alloc] initWithAppInfo:appInformation delegate:delegate];&lt;br /&gt;
}&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following would be the &amp;lt;code&amp;gt;NlsAppApiFactory.h&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;Foundation/Foundation.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@class NielsenAppApi;&lt;br /&gt;
@protocol NielsenAppApiDeligate;&lt;br /&gt;
@interface NlsAppApiFactory : NSObject&lt;br /&gt;
+ (NielsenAppAPI *) createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
@end&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
The following might be in the &amp;lt;code&amp;gt;Viewcontroller.m&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
@implementation ViewController&lt;br /&gt;
&lt;br /&gt;
- (void)viewDidLoad {&lt;br /&gt;
    [super viewDidLoad];&lt;br /&gt;
    &lt;br /&gt;
    //Setting background image&lt;br /&gt;
    UIImage *backgroundImage = [UIImage imageNamed:@&amp;quot;new_ios_bg.png&amp;quot;];&lt;br /&gt;
    UIImageView *backgroundImageView=[[UIImageView alloc]initWithFrame:self.view.frame];&lt;br /&gt;
    backgroundImageView.image=backgroundImage;&lt;br /&gt;
    [self.view insertSubview:backgroundImageView atIndex:0];&lt;br /&gt;
    &lt;br /&gt;
    //Mark: In NielsenInit class we are initialising the Nielsen SDK.&lt;br /&gt;
    &lt;br /&gt;
    //Getting the instance of Nielsen SDK&lt;br /&gt;
    nielsenApi = [NielsenInit createNielsenAppApiWithDelegate:nil];&lt;br /&gt;
}&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== iOS DCR Video Step 3 - Create DCR Video Content Metadata Object ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv5&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 3 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv5&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Configure Metadata =====&lt;br /&gt;
The SDK methods handle 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 Nielsen Key names (e.g. appid, program) 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;br&amp;gt;&lt;br /&gt;
===== Create channelName Metadata =====&lt;br /&gt;
channelName 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;
|--style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
! Key !! Description !!	Values	 !! Required&lt;br /&gt;
|--style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
| channelName	|| Any string representing the channel/stream	|| custom	|| ✓&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== Create Content Metadata =====&lt;br /&gt;
Content metadata should remain constant throughout the entirety of an episode/clip including when ads play.&lt;br /&gt;
&amp;lt;blockquote&amp;gt; program and title metadata values should be passed to SDK as UTF-8 strings. &amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;height: 45em; overflow-y:auto;&amp;quot;&amp;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'''!!'''Provider'''&lt;br /&gt;
|-&lt;br /&gt;
| type || Type of asset ||For Video use: &amp;lt;code&amp;gt;content&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt; For Static or text &amp;lt;code&amp;gt;static&amp;lt;/code&amp;gt; || Yes || Nielsen&lt;br /&gt;
|-style=&amp;quot;background-color:#e9f9fa;&amp;quot;&lt;br /&gt;
| assetid || Unique ID assigned to asset &amp;lt;br&amp;gt; Note: Refrain from using the following special characters [[Special_Characters|(Special Characters)]]. || Examples: &amp;lt;br&amp;gt; &amp;lt;code&amp;gt;BBT345a234 &amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; &amp;lt;code&amp;gt;CBSs5e234F2021&amp;lt;/code&amp;gt;  || Yes || Client &lt;br /&gt;
|-&lt;br /&gt;
| program ||Complete program or movie title &amp;lt;br&amp;gt; (no abbreviations or shorthand) &amp;lt;br&amp;gt; Note: there is a 25 character limit.  ||&amp;lt;code&amp;gt; The Big Bang Theory&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; &amp;lt;code&amp;gt; TheBigBangTheory&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt;&amp;lt;code&amp;gt; The Dark Knight&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt;&amp;lt;code&amp;gt; TheDarkKnight&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; || Yes || Client &lt;br /&gt;
|-style=&amp;quot;background-color:#e9f9fa;&amp;quot;&lt;br /&gt;
| title ||Episode title with season and episode number (40 character limit) &amp;lt;br&amp;gt; (Formats accepted: S01E03, S1E3, S1 E3). || Examples: &amp;lt;br&amp;gt; &amp;lt;code&amp;gt;The Pants Alternative S03E18&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; &amp;lt;code&amp;gt;The Pants Alternative S3E18&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; &amp;lt;code&amp;gt;The Pants Alternative S3 E18&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; Can also accept: &amp;lt;code&amp;gt; S3E18&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; Not Valid: &amp;lt;code&amp;gt; 318 &amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt; 0318 &amp;lt;/code&amp;gt;|| Yes || Client &lt;br /&gt;
|-&lt;br /&gt;
| crossId1 || Gracenote TMS ID (If available) should be passed for all telecasted content for clients using the Gracenote solution for proper matching purposes. &amp;lt;br&amp;gt;Note: The TMS ID will be a 14 character string. Normally leading with 2 alpha characerts ('EP', 'MV', 'SH' or 'SP'), followed by 12 numbers.&lt;br /&gt;
|| The TMS ID will be a 14 character string. &amp;lt;br&amp;gt; Normally being with  'EV,' 'EP', 'SH', 'SP', or 'MV' &amp;lt;br&amp;gt; Followed by 12 numbers after the initial two letter prefix. &amp;lt;br&amp;gt; &amp;lt;br&amp;gt; The Giant Morning Show: &amp;lt;code&amp;gt;SH009311820022&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; The Pants Alternative Episode : &amp;lt;code&amp;gt;EP009311820061&amp;lt;/code&amp;gt; || Optional || Nielsen&lt;br /&gt;
|-style=&amp;quot;background-color:#e9f9fa;&amp;quot;&lt;br /&gt;
| crossId2 || Populated by content distributor to contribute viewing from that distributor to the given content originator. || For a full list of acceptable values, please contact your Nielsen reprentative. || Yes, for distributors || Nielsen&lt;br /&gt;
|-&lt;br /&gt;
| length || Length of content in seconds&amp;lt;br&amp;gt;Note: Integers and decimals are acceptable values are acceptable for the length parameter. || Examples:&lt;br /&gt;
&amp;lt;small&amp;gt;For standard VOD content - &amp;lt;code&amp;gt;300&amp;lt;/code&amp;gt; to represent 5 minutes, &amp;lt;code&amp;gt;1320&amp;lt;/code&amp;gt; to represent 22 minutes, etc.&lt;br /&gt;
&amp;lt;br&amp;gt;If DAI live stream of a discrete program (Live Event/Sporting Event), pass length of content. See example for standard VOD content above.&lt;br /&gt;
&amp;lt;br&amp;gt;If unknown DAI live steam, pass a value of &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;.&amp;lt;/small&amp;gt; &lt;br /&gt;
|| Yes || Client &lt;br /&gt;
|-style=&amp;quot;background-color:#e9f9fa;&amp;quot;&lt;br /&gt;
| airdate ||Original broadcast or release date for the program &amp;lt;br&amp;gt;For USA, date should be EST &amp;lt;br&amp;gt; Outside USA, date should be local time.&amp;lt;br&amp;gt;If not applicable or available, original broadcast or release date for the Program. || Acceptable Formats:&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;YYYY-MM-DDTHH:MI:SS&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;YYYY-MM-DDHH:MI:SS&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;YYYY-MM-DDTHH:MI:SS+xx:xx&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;YYYY-MM-DDTHH:MI:SS-xx:xx&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;YYYYMMDDHH:MI:SS&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;YYYYMMDD HH:MI:SS&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;MM-DD-YYYY&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;MM/DD/YYYY&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;YYYYMMDD&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; || Yes || Client &lt;br /&gt;
|-&lt;br /&gt;
| isfullepisode || Full episode flag to identify differences between long form content. || &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;- full episode, &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt;- non full episode(clip,teaser,promo,etc.)&lt;br /&gt;
&amp;lt;small&amp;gt;Also accept: &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;lf&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;yes&amp;lt;/code&amp;gt;- longform&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;sf&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;no&amp;lt;/code&amp;gt;- shortform&lt;br /&gt;
|| Yes || Nielsen&lt;br /&gt;
|-style=&amp;quot;background-color:#e9f9fa;&amp;quot;&lt;br /&gt;
| adloadtype || &amp;lt;big&amp;gt;&amp;lt;small&amp;gt;Type of ad load: &lt;br /&gt;
&amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; Linear – matches TV ad load&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;2&amp;lt;/code&amp;gt; Dynamic – Dynamic Ad Insertion (DAI)&amp;lt;/small&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
|| &amp;lt;code&amp;gt;2&amp;lt;/code&amp;gt; - DCR measures content with dynamic ads || Yes || Nielsen&lt;br /&gt;
|-&lt;br /&gt;
| segB || One of two custom segment for the clients granular reporting within a brand. || Examples:&amp;lt;br&amp;gt;Genre - &amp;lt;code&amp;gt;horror&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;comedy&amp;lt;/code&amp;gt;, etc.&amp;lt;br&amp;gt;Timeslot - &amp;lt;code&amp;gt;primetime&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;daytime&amp;lt;/code&amp;gt;, etc.&amp;lt;br&amp;gt;News type - &amp;lt;code&amp;gt;breakingnews&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;weather&amp;lt;/code&amp;gt;, etc. || Optional || Client &lt;br /&gt;
|-style=&amp;quot;background-color:#e9f9fa;&amp;quot;&lt;br /&gt;
| segC || One of two custom segment for the clients granular reporting within a brand. || Examples:&amp;lt;br&amp;gt;Genre - &amp;lt;code&amp;gt;horror&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;comedy&amp;lt;/code&amp;gt;, etc.&amp;lt;br&amp;gt;Timeslot - &amp;lt;code&amp;gt;primetime&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;daytime&amp;lt;/code&amp;gt;, etc.&amp;lt;br&amp;gt;News type - &amp;lt;code&amp;gt;breakingnews&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;weather&amp;lt;/code&amp;gt;, etc. || Optional || Client &lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Custom segments (segB and segC) can be used to aggregate video and/or static content within a single Brand to receive more granular reports within a brand.&lt;br /&gt;
&lt;br /&gt;
Examples regarding usage of segments within SDK:&lt;br /&gt;
* All comedy clips and stories for a Brand rolled into a &amp;quot;Comedy&amp;quot; segment&lt;br /&gt;
* genre grouping content by Comedy vs. Drama&lt;br /&gt;
* group related Text + Video content - i.e. for a show that has a lot of - static pages associated with it&lt;br /&gt;
* packaging based on how clients sell inventory&lt;br /&gt;
* grouping related types of content either by genre, category or platform.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Metadata Example =====&lt;br /&gt;
&amp;lt;code&amp;gt;Swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&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;program&amp;quot;: &amp;quot;The Big Bang Theory&amp;quot;,&lt;br /&gt;
    &amp;quot;title&amp;quot;: &amp;quot;The Pants Alternative S03E18&amp;quot;,  //Formats accepted: S01E03, S1E3, S1 E3&lt;br /&gt;
    &amp;quot;crossId1&amp;quot;: &amp;quot;EP009311820061&amp;quot;, //optional&lt;br /&gt;
    &amp;quot;crossId2&amp;quot;: &amp;quot;Content Originator&amp;quot;, //optional&lt;br /&gt;
    &amp;quot;length&amp;quot;: &amp;quot;3600&amp;quot;,&lt;br /&gt;
    &amp;quot;airdate&amp;quot;: &amp;quot;2022-03-21T10:05:00&amp;quot;, &lt;br /&gt;
    &amp;quot;isfullepisode&amp;quot;: &amp;quot;Yes&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;
];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;Objective-C&amp;lt;/code&amp;gt;    &lt;br /&gt;
&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;program&amp;quot;: @ &amp;quot;The Big Bang Theory&amp;quot;,&lt;br /&gt;
    @ &amp;quot;title&amp;quot;: @ &amp;quot;The Pants Alternative S03E18&amp;quot;, //Formats accepted: S01E03, S1E3, S1 E3&lt;br /&gt;
    @ &amp;quot;crossId1&amp;quot;: @ &amp;quot;EP009311820061&amp;quot;, //optional&lt;br /&gt;
    @ &amp;quot;crossId2&amp;quot;: @ &amp;quot;Content Originator&amp;quot;, //optional&lt;br /&gt;
    @ &amp;quot;length&amp;quot;: @ &amp;quot;3600&amp;quot;,&lt;br /&gt;
    @ &amp;quot;airdate&amp;quot;: @ &amp;quot;2022-03-21T10:05:00&amp;quot;,&lt;br /&gt;
    @ &amp;quot;isfullepisode&amp;quot;: @ &amp;quot;y&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;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== iOS DCR Video Step 4 - Basic Set of Events - Sample Playback ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv6&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 4 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv6&amp;quot;&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;
| '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;
| 'playheadPosition'	|| 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: 'PlayheadPosition' 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 '''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 content or Ad playback is interrupted and at the end of each Ad. &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. &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;'''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;
==== Sample Use Case: 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 [[playheadPosition|playheadPosition()]] 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;
|-style=&amp;quot;background-color:#d8f5d7;&amp;quot;&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;
|-style=&amp;quot;background-color:#d8f5d7;&amp;quot;&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;
|- style=&amp;quot;background-color:#d8f5d7;&amp;quot;&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;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Keep Going ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv9&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv9&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Congratulations, you've successfully integrated the iOS SDK in your app for a basic content playback scenario!&lt;br /&gt;
&lt;br /&gt;
You can add more content to see channel-change scenarios or continue to next steps below.&lt;br /&gt;
&lt;br /&gt;
View your application's debug logs and search for the term (AppSDK) to see messages emitted by Nielsen AppSDK during video playback.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Next Steps ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv10&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv10&amp;quot;&amp;gt;&lt;br /&gt;
====Going Live====&lt;br /&gt;
&lt;br /&gt;
In addition to the basic steps above, before going live developers need to handle app background/foreground events, make certain privacy disclosures, handle interruption events (stop, fast-forward, rewind), remove iOS simulator slices, and allow users to opt out of Nielsen measurement. More details can be found [[DCR_Video_iOS_SDK|here]], along with a more comprehensive reference for implementing DCR Video measurement with AppSDK.&lt;br /&gt;
&lt;br /&gt;
Once the DCR Tracking Code is added, Nielsen will validate the implementation. Following Nielsen testing, developers need to make a few updates to the initialization call to ensure that the app is being measured properly.&lt;br /&gt;
&lt;br /&gt;
#'''App ID''': Ensure that correct  is used during initialization '''PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'''&lt;br /&gt;
#'''Debug Logging''': Disable logging by changing initialization call to use @&amp;quot;nol_devDebug&amp;quot;:@&amp;quot;INFO&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== &amp;amp;rarr; iOS DTVR (coming soon) ==&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivision100&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide iOS DTVR &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivision100&amp;quot;&amp;gt;&lt;br /&gt;
==== iOS DTVR Introduction ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv200-&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide Intro &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv200-&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Nielsen DTVR (Digital TV Ratings) product provides content consumption measurement in client mobile apps and webpages. This measurement includes insight into the total time a user spent watching the tracked content, video player events, and much more.&lt;br /&gt;
This example provides the steps to implement the DTVR product in a sample iOS app using Nielsen AppSDK. It includes:&lt;br /&gt;
&lt;br /&gt;
*SDK Initialization&lt;br /&gt;
*DTVR Video Metadata: information about the content being tracked&lt;br /&gt;
*DTVR Video Events/API calls&lt;br /&gt;
*Extracting ID3 tags from the video stream and passing to AppSDK for measurement&lt;br /&gt;
&lt;br /&gt;
By the end of this guide you will have the needed steps to integrate Nielsen's AppSDK in the background of your app for DTVR measurement.&lt;br /&gt;
&lt;br /&gt;
'''NOTE: video streams must have Nielsen ID3 tags embedded in order to be measured using the DTVR product. See the section in this guide &amp;quot;Extracting ID3 Tags&amp;quot; or contact your Nielsen representative for more information.'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== iOS DTVR Step 1 - Obtain AppID ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv300&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 1 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv300&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To begin using the iOS AppSDK, you will need to obtain an Application ID (AppId)&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! !! Item !! Description !! Source&lt;br /&gt;
|-&lt;br /&gt;
|&amp;amp;#9989; || App ID (appid) || Unique ID assigned to the player/site and configured by product || Contact your Nielsen Representative&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The appid is a 37 character unique ID assigned to the player/site and configured by product and is required when creating a new instance of the AppSDK in the app.&lt;br /&gt;
&amp;lt;/br&amp;gt;Example: '''PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== iOS DTVR Step 2 - SDK Initialization ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivision400&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 2 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivision400&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== How to obtain the NielsenAppApi.Framework =====&lt;br /&gt;
The Nielsen AppSDK can either be downloaded directly or can be integrated directly within an application through the use of CocoaPods. We recommend using the CocoaPods-based integration whenever possible to ensure you maintain the most recent changes and enhancements to the Nielsen libraries.&lt;br /&gt;
* [[Digital_Measurement_iOS_Artifactory_Guide|Select to obtain CocoaPods implementation guide]]&lt;br /&gt;
* [[Special:Downloads|Select to Download Directly]]&lt;br /&gt;
&lt;br /&gt;
===== Configuring Xcode Development Environment =====&lt;br /&gt;
Starting with SDK version 6.0.0.0, the Nielsen App SDK is compatible with Apple iOS versions 8.0 and above.  In addition, when using the dynamic framework,  all the required frameworks are linked automatically as the are needed.  More details can be found here: https://stackoverflow.com/questions/24902787/dont-we-need-to-link-framework-to-xcode-project-anymore&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': All communications between the SDK and the Census (Collection Facility) use HTTPS.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======= Download Framework =======&lt;br /&gt;
The first step is to download and copy the [[Special:Downloads|NielsenAppApi.framework]] bundle to the app project directory. (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
======= Add Framework =======&lt;br /&gt;
In the General tab for app configuration add NielsenAppApi.framework in the list of Embedded Binaries.  (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
======= Add Path =======&lt;br /&gt;
Add path to the NielsenAppApi.framework in the Framework Search Paths build setting.  (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
======= Import Framework =======&lt;br /&gt;
Add NielsenAppApi.framework module in the source file of your app:&lt;br /&gt;
&lt;br /&gt;
======= Using Swift =======&lt;br /&gt;
Add the following:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
import NielsenAppApi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======= Using Objective-C =======&lt;br /&gt;
&amp;lt;syntaxhighlight lang =&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
@import NielsenAppApi;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======= SDK Initialization =======&lt;br /&gt;
&lt;br /&gt;
The following table contains the list of arguments that can be passed via the AppInfo JSON schema.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter / Argument !! Description !! Source !! Required? !! Example&lt;br /&gt;
|--style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
| appid || Unique Nielsen ID for the application. The ID is a GUID data type. If you did not receive your App ID, let us know and we will provide you. || Nielsen-specified || Yes || PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&lt;br /&gt;
|--style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
| nol_devDebug || Enables Nielsen console logging. Only required for testing &amp;lt;br&amp;gt;&lt;br /&gt;
|| Nielsen-specified || Optional || DEBUG&lt;br /&gt;
|}&lt;br /&gt;
==== Debug flag for development environment ====&lt;br /&gt;
Player application developers / integrators can use Debug flag to check whether an App SDK API call made is successful. To activate the Debug flag,&lt;br /&gt;
Pass the argument &amp;lt;code&amp;gt;@&amp;quot;nol_devDebug&amp;quot;:@&amp;quot;DEBUG&amp;quot;&amp;lt;/code&amp;gt;, in the JSON string . &lt;br /&gt;
&lt;br /&gt;
Once the flag is active, it logs each API call made and the data passed. The log created by this flag is minimal.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': DO NOT activate the Debug flag in a production environment.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Swift Example ===&lt;br /&gt;
==== Sample SDK Initialization Code ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;NielsenInit.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class NielsenInit: NSObject {&lt;br /&gt;
    class func createNielsenAppApi(delegate: NielsenAppApiDelegate) -&amp;gt; NielsenAppApi?{&lt;br /&gt;
    let appInformation:[String: String] = [&lt;br /&gt;
           &amp;quot;appid&amp;quot;: &amp;quot;PE392366B-F2C1-4BC4-AB62-A7DAFDCXXXX&amp;quot;,&lt;br /&gt;
           &amp;quot;nol_devDebug&amp;quot;: &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
        ]&lt;br /&gt;
        return NielsenAppApi(appInfo:appInformation, delegate:delegate)}}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;ViewController.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class ViewController: UIViewController, NielsenAppApiDelegate, AVPictureInPictureControllerDelegate, CLLocationManagerDelegate  {&lt;br /&gt;
&lt;br /&gt;
    let avPlayerViewController = AVPlayerViewController()&lt;br /&gt;
    var avPlayer:AVPlayer?&lt;br /&gt;
    var nielsenAppApi: NielsenAppApi!&lt;br /&gt;
&lt;br /&gt;
  override func viewDidLoad() {&lt;br /&gt;
        super.viewDidLoad()&lt;br /&gt;
        self.nielsenAppApi = NielsenInit.createNielsenAppApi(delegate: self)&lt;br /&gt;
        NSLog(&amp;quot;Nielsen SDK initialized&amp;quot;)&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Objective C ===&lt;br /&gt;
==== Sample SDK Initialization Code ====&lt;br /&gt;
Initialize the Nielsen App object within the viewDidLoad view controller delegate method using initWithAppInfo:delegate:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;If App SDK is initialized using init or new methods, it will ignore the API calls resulting in no measurement. The SDK will not return any errors.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;quot;NlsAppApiFactory.h&amp;quot;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenAppApi.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@implementation NlsAppApiFactory&lt;br /&gt;
+ (NielsenAppApi *)createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
{&lt;br /&gt;
    NSDictionary *appInformation = @{&lt;br /&gt;
                                     @&amp;quot;appid&amp;quot;: &amp;quot;PE392366B-F2C1-4BC4-AB62-A7DAFDC51XXX&amp;quot;,&lt;br /&gt;
                                     @&amp;quot;nol_devDebug&amp;quot;: @&amp;quot;DEBUG&amp;quot;&lt;br /&gt;
                                     };&lt;br /&gt;
    return [[NielsenAppApi alloc] initWithAppInfo:appInformation delegate:delegate];&lt;br /&gt;
}&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following would be the &amp;lt;code&amp;gt;NlsAppApiFactory.h&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;Foundation/Foundation.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@class NielsenAppApi;&lt;br /&gt;
@protocol NielsenAppApiDeligate;&lt;br /&gt;
@interface NlsAppApiFactory : NSObject&lt;br /&gt;
+ (NielsenAppAPI *) createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
@end&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
The following might be in the &amp;lt;code&amp;gt;Viewcontroller.m&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
@implementation ViewController&lt;br /&gt;
&lt;br /&gt;
- (void)viewDidLoad {&lt;br /&gt;
    [super viewDidLoad];&lt;br /&gt;
    &lt;br /&gt;
    //Setting background image&lt;br /&gt;
    UIImage *backgroundImage = [UIImage imageNamed:@&amp;quot;new_ios_bg.png&amp;quot;];&lt;br /&gt;
    UIImageView *backgroundImageView=[[UIImageView alloc]initWithFrame:self.view.frame];&lt;br /&gt;
    backgroundImageView.image=backgroundImage;&lt;br /&gt;
    [self.view insertSubview:backgroundImageView atIndex:0];&lt;br /&gt;
    &lt;br /&gt;
    //Mark: In NielsenInit class we are initialising the Nielsen SDK.&lt;br /&gt;
    &lt;br /&gt;
    //Getting the instance of Nielsen SDK&lt;br /&gt;
    nielsenApi = [NielsenInit createNielsenAppApiWithDelegate:nil];&lt;br /&gt;
}&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== iOS DTVR Step 3 - Create DTVR Content Metadata Object ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv500&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 3 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv500&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Configure Metadata =====&lt;br /&gt;
Content metadata should remain constant throughout the completion of an episode or live stream.&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 for DTVR      || ✓&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
- (NSDictionary *)loadChannelInfo&lt;br /&gt;
{&lt;br /&gt;
    //Loading Channel Info.    &lt;br /&gt;
    NSString *strUrl = self.url.absoluteString;  &lt;br /&gt;
    NSDictionary *channel = @{  @&amp;quot;channelName&amp;quot; : @&amp;quot;TheGreatBigMovie&amp;quot;: strUrl };   &lt;br /&gt;
    return channel;&lt;br /&gt;
}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objectivec&amp;quot;&amp;gt;    &lt;br /&gt;
- (NSDictionary *)loadDtvr{&lt;br /&gt;
    &lt;br /&gt;
    //Loading DTVR data  &lt;br /&gt;
    NSDictionary *dtvr = @{ @&amp;quot;adModel&amp;quot;:@&amp;quot;1&amp;quot; ,  &lt;br /&gt;
                            @&amp;quot;type&amp;quot;:@&amp;quot;content&amp;quot;,};  &lt;br /&gt;
    return dtvr;&lt;br /&gt;
}&lt;br /&gt;
    &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== iOS DTVR Step 4 - Basic Set of Events - Sample Playback ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv600&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 4 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv600&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== SDK Events/APIs =====&lt;br /&gt;
&amp;lt;!--[[File:appsdkTimeline-DTVR-V2.png|icon]]--&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;
&lt;br /&gt;
===== Configure API calls - loadMetadata =====&lt;br /&gt;
Use &amp;lt;code&amp;gt;loadMetadata&amp;lt;/code&amp;gt; to pass the metadata object created above. &lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Objective C = &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;[nielsenApi loadMetadata:(dtvr)];&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Swift = &amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;self.nielsenAppApi?.loadMetadata(dtvr)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Configure API calls - sendID3 =====&lt;br /&gt;
[[sendID3]] API is a Nielsen AppSDK receiver for timed metadata events (ID3 tags) provided through iOS’s NSNotificationCenter notification system. This API filters out Nielsen-specific ID3 tags from the system and uses them to create duration data. These ID3 tags are used by Nielsen SDK for DTVR measurement, and the stream that is played must contain ID3 tags and have these tags extracted and passed to SDK using the below procedure in order for DTVR measurement to occur. &lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Objective C = &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;[nielsenApi sendID3:extraString];&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Swift = &amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt; [nielsenApi sendID3:extraString];&amp;lt;/syntaxhighlight&amp;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;
Refer to [[iOS SDK API Reference#Retrieving ID3 Tags|Retrieving ID3 Tags]] section to know more details.&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;
As Apple has deprecated the use of [https://developer.apple.com/documentation/avfoundation/avplayeritem/1389602-timedmetadata?language=objc timedMetadata], we now recommend using [https://developer.apple.com/documentation/avfoundation/avplayeritemmetadataoutput?language=objc AVPlayerItemMetadataOutput] for extracting ID3 tags from the iOS Native Player.&lt;br /&gt;
&lt;br /&gt;
If any other player apart from the iOS native player is used, check and ensure that the player has the capability to extract metadata such as 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;
|Swift = &amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt; &lt;br /&gt;
        //First, ensure your class conforms to the AVPlayerItemMetadataOutputPushDelegate protocol.&lt;br /&gt;
           class YourClass: AVPlayerItemMetadataOutputPushDelegate { &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;
       // Then create an instance of AVPlayerItemMetadataOutput and add it to the player item&lt;br /&gt;
          let metadataOutput = AVPlayerItemMetadataOutput(identifiers: nil)&lt;br /&gt;
           playerItem.add(metadataOutput)&lt;br /&gt;
 &lt;br /&gt;
       // and set the delegate and a dispatch queue&lt;br /&gt;
           metadataOutput.setDelegate(self, queue: DispatchQueue.main)&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;
        // After that below callback function of AVPlayerItemMetadataOutputPushDelegate &lt;br /&gt;
        // protocol will be triggered whenever ID3 tag is received from stream. &lt;br /&gt;
          func metadataOutput(_ output: AVPlayerItemMetadataOutput, didOutputTimedMetadataGroups groups: [AVTimedMetadataGroup], from track: AVPlayerItemTrack?) {&lt;br /&gt;
    for group in groups {&lt;br /&gt;
        for item in group.items {&lt;br /&gt;
            // Handle the metadata item&lt;br /&gt;
            handleTimedMetadata(metadataItem: item)&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;
          // Then further metadata item can be handled like below &lt;br /&gt;
          func handleTimedMetadata(metadataItem: AVMetadataItem) {&lt;br /&gt;
    guard let key = metadataItem.key as? String,&lt;br /&gt;
          let extraString = metadataItem.extraAttributes?[AVMetadataExtraAttributeInfoKey] as? String else {&lt;br /&gt;
        return&lt;br /&gt;
    }&lt;br /&gt;
    // If the extra string(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.hasPrefix(&amp;quot;www.nielsen.com&amp;quot;) {&lt;br /&gt;
        DispatchQueue.global(qos: .default).async {&lt;br /&gt;
            self.nielsenApi?.sendID3(extraString)&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&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;
        //First, ensure your class conforms to the AVPlayerItemMetadataOutputPushDelegate protocol.&lt;br /&gt;
          @interface YourClass : NSObject &amp;lt;AVPlayerItemMetadataOutputPushDelegate&amp;gt; &lt;br /&gt;
&lt;br /&gt;
          @end&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;
        // Then create an instance of AVPlayerItemMetadataOutput and add it to the player item&lt;br /&gt;
          AVPlayerItemMetadataOutput *metadataOutput = [[AVPlayerItemMetadataOutput alloc] initWithIdentifiers:nil];&lt;br /&gt;
          [playerItem addOutput:metadataOutput];&lt;br /&gt;
&lt;br /&gt;
        // and set the delegate and a dispatch queue&lt;br /&gt;
          [metadataOutput setDelegate:self queue:dispatch_get_main_queue()];&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;
        // After that below callback function of AVPlayerItemMetadataOutputPushDelegate &lt;br /&gt;
        // protocol will be triggered whenever ID3 tag is received from stream.&lt;br /&gt;
           - (void)metadataOutput:(AVPlayerItemMetadataOutput *)output didOutputTimedMetadataGroups:(NSArray&amp;lt;AVTimedMetadataGroup *&amp;gt; *)groups fromPlayerItemTrack:(AVPlayerItemTrack *)track {&lt;br /&gt;
    for (AVTimedMetadataGroup *group in groups) {&lt;br /&gt;
        for (AVMetadataItem *item in group.items) {&lt;br /&gt;
            // Handle the metadata item&lt;br /&gt;
            [self handleTimedMetadata:item];&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;
        // Then further metadata item can be handled like below &lt;br /&gt;
          - (void)handleTimedMetadata:(AVMetadataItem *)item {&lt;br /&gt;
    NSString *key = (NSString *)item.key;&lt;br /&gt;
    NSString *extraString = item.extraAttributes[AVMetadataExtraAttributeInfoKey];&lt;br /&gt;
    // If the key is &amp;quot;PRIV&amp;quot; and the extra string starts with &amp;quot;www.nielsen.com&amp;quot;, send it to the Nielsen API&lt;br /&gt;
    if ([key isEqualToString:@&amp;quot;PRIV&amp;quot;] &amp;amp;&amp;amp; [extraString hasPrefix:@&amp;quot;www.nielsen.com&amp;quot;]) {&lt;br /&gt;
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{&lt;br /&gt;
            [self.nielsenApi sendID3:extraString];&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;
===== 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. &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 loadMetadata and sendID3 events to occur.&lt;br /&gt;
# '''Processing state''' – The SDK instance is processing playing information. For DTVR, the &amp;lt;code&amp;gt;'''loadMetadata''' &amp;lt;/code&amp;gt; call moves the SDK instance into this state. In this state, the SDK instance will be able to process sendID3 calls and measure content.&lt;br /&gt;
# '''Disabled state''' – The SDK instance is disabled.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Keep Going ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv900&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv900&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Congratulations, you've successfully integrated the iOS SDK in your app for a basic content playback scenario!&lt;br /&gt;
&lt;br /&gt;
You can add more content to see channel-change scenarios or continue to next steps below.&lt;br /&gt;
&lt;br /&gt;
View your application's debug logs and search for the term (AppSDK) to see messages emitted by Nielsen AppSDK during video playback.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Next Steps ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv1000&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv1000&amp;quot;&amp;gt;&lt;br /&gt;
====Going Live====&lt;br /&gt;
&lt;br /&gt;
In addition to the basic steps above, before going live developers need to handle app background/foreground events, make certain privacy disclosures, handle interruption events (stop, fast-forward, rewind), remove iOS simulator slices, and allow users to opt out of Nielsen measurement. More details can be found [[DTVR_iOS_SDK|here]], along with a more comprehensive reference for implementing DTVR measurement with AppSDK.&lt;br /&gt;
&lt;br /&gt;
Once the DTVR Tracking Code is added, Nielsen will validate the implementation. Following Nielsen testing, developers need to make a few updates to the initialization call to ensure that the app is being measured properly.&lt;br /&gt;
&lt;br /&gt;
#'''App ID''': Ensure that correct  is used during initialization '''PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'''&lt;br /&gt;
#'''Debug Logging''': Disable logging by changing initialization call to use @&amp;quot;nol_devDebug&amp;quot;:@&amp;quot;INFO&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>NickParrucci</name></author>
	</entry>
	<entry>
		<id>https://nielsentest.mywikis.net/w/index.php?title=iOS_Step_By_Step&amp;diff=6466</id>
		<title>iOS Step By Step</title>
		<link rel="alternate" type="text/html" href="https://nielsentest.mywikis.net/w/index.php?title=iOS_Step_By_Step&amp;diff=6466"/>
		<updated>2023-07-27T13:26:30Z</updated>

		<summary type="html">&lt;p&gt;NickParrucci: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
__NOTOC__&lt;br /&gt;
&lt;br /&gt;
Provided below are step-by-step quick start guides for implementing Nielsen iOS SDK for DCR Static, DCR Video, and DTVR products. Click each section to get started. &lt;br /&gt;
&lt;br /&gt;
== &amp;amp;rarr; iOS DCR Static ==&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivision&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide DCR Static &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivision&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== iOS DCR Static Introduction ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisiona-&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide Intro &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisiona-&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Digital Content Ratings (DCR) Static product provides content consumption measurement in client mobile apps and webpages. This measurement includes insight into the total time a user spent on a webpage, how they navigated through the page via links, and many other data points.&lt;br /&gt;
This tutorial provides the steps to implement the DCR Static product in a sample iOS app. It includes:&lt;br /&gt;
&lt;br /&gt;
*SDK Initialization Call&lt;br /&gt;
*DCR Static Metadata: information about the sections being tracked&lt;br /&gt;
&lt;br /&gt;
By the end of this guide you will have the needed steps to integrate Nielsen's AppSDK in the background of your app.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== iOS DCR Static Step 1 - Obtain AppID ===&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisiona1&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 1 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisiona1&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To begin using the iOS SDK (AppSDK) you will need to obtain an Application ID (AppId)&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! !! Item !! Description !! Source&lt;br /&gt;
|-&lt;br /&gt;
|&amp;amp;#9989; || App ID (appid) || Unique ID assigned to the player/site and configured by product || Contact your Nielsen TAM&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The appid is a 37 character unique ID assigned to the player/site and configured by product and is required when creating a new instance of the AppSDK in the app.&lt;br /&gt;
&amp;lt;/br&amp;gt;Example: '''PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== iOS DCR Static Step 2 - SDK Initialization ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionc&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 2 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionc&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== How to obtain the NielsenAppApi.Framework ====&lt;br /&gt;
The Nielsen AppSDK can either be downloaded directly or can be integrated directly within an application through the use of CocoaPods. We recommend using the CocoaPods-based integration whenever possible to ensure you maintain the most recent changes and enhancements to the Nielsen libraries.&lt;br /&gt;
* [[Digital_Measurement_iOS_Artifactory_Guide|Select to obtain CocoaPods implementation guide]]&lt;br /&gt;
* [[Special:Downloads|Select to Download Directly]]&lt;br /&gt;
&lt;br /&gt;
==== Configuring Xcode Development Environment ====&lt;br /&gt;
Starting with SDK version 6.0.0.0, the Nielsen App SDK is compatible with Apple iOS versions 8.0 and above.  In addition, when using the dynamic framework,  all the required frameworks are linked automatically as the are needed.  More details can be found here: https://stackoverflow.com/questions/24902787/dont-we-need-to-link-framework-to-xcode-project-anymore&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': All communications between the SDK and the Census (Collection Facility) use HTTPS.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Download Framework ====&lt;br /&gt;
The first step is to download and copy the [[Special:Downloads|NielsenAppApi.framework]] bundle to the app project directory. (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
==== Add Framework ====&lt;br /&gt;
In the General tab for app configuration add NielsenAppApi.framework in the list of Embedded Binaries.  (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
==== Add Path ====&lt;br /&gt;
Add path to the NielsenAppApi.framework in the Framework Search Paths build setting.  (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
==== Import Framework ====&lt;br /&gt;
Add NielsenAppApi.framework module in the source file of your app:&lt;br /&gt;
&lt;br /&gt;
==== Using Swift ====&lt;br /&gt;
Add the following:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
import NielsenAppApi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using Objective-C ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang =&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
@import NielsenAppApi;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sample SDK Initialization Code ===&lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Swift  = &lt;br /&gt;
Swift 4.0 Example:&lt;br /&gt;
&amp;lt;code&amp;gt;NielsenInit.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
import Foundation&lt;br /&gt;
import NielsenAppApi&lt;br /&gt;
&lt;br /&gt;
class NielsenInit : NSObject {&lt;br /&gt;
    class func createNielsenApi(delegate: NielsenAppApiDelegate) -&amp;gt; NielsenAppApi?{&lt;br /&gt;
        &lt;br /&gt;
        let appInformation:[String: String] = [&lt;br /&gt;
            &amp;quot;appid&amp;quot;: &amp;quot;PDA7D5EE6-B1B8-4123-9277-2A788XXXXXXX&amp;quot;,&lt;br /&gt;
            &amp;quot;sfcode&amp;quot;: &amp;quot;dcr&amp;quot;,&lt;br /&gt;
            &amp;quot;nol_devDebug&amp;quot;: &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
        ]       &lt;br /&gt;
        return NielsenAppApi(appInfo:appInformation, delegate:delegate)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sample code using AVPlayer.&lt;br /&gt;
&amp;lt;code&amp;gt;LandingVC.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
import UIKit&lt;br /&gt;
import NielsenAppApi&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class LandingVC: UIViewController, NielsenAppApiDelegate {&lt;br /&gt;
    &lt;br /&gt;
    var nielsenMain : NielsenAppApi!&lt;br /&gt;
    var sdkMethods : SDKMethods!&lt;br /&gt;
    var data : [String : Any]!&lt;br /&gt;
&lt;br /&gt;
class ViewController: UIViewController, NielsenAppApiDelegate, AVPlayerViewControllerDelegate  {&lt;br /&gt;
&lt;br /&gt;
// your code//    &lt;br /&gt;
&lt;br /&gt;
  override func viewDidLoad() {&lt;br /&gt;
        super.viewDidLoad()&lt;br /&gt;
        //Getting the instance of NielsenApi&lt;br /&gt;
        self.nielsenApi = NielsenInit.createNielsenApi(delegate: self)&lt;br /&gt;
            }&lt;br /&gt;
  }&lt;br /&gt;
    override func viewDidAppear(_ animated: Bool) {      &lt;br /&gt;
        self.data = sdkMethods.loadStaticMaster()     // This is just an example of populating the metadata&lt;br /&gt;
        self.nielsenMain.loadMetadata(self.data)&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Objective C = &lt;br /&gt;
Initialize the Nielsen App object within the viewDidLoad view controller delegate method using initWithAppInfo:delegate:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;If App SDK is initialized using init or new methods, it will ignore the API calls resulting in no measurement. The SDK will not return any errors.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;    &lt;br /&gt;
#import &amp;quot;NielsenInit.h&amp;quot;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenEventTracker.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@implementation NielsenInit&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppApi *)createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate&lt;br /&gt;
{    &lt;br /&gt;
    //Initialising the NielsenEventTracker class by passing app information which returns the instance of NielsenEventTracker.&lt;br /&gt;
    &lt;br /&gt;
    NSDictionary *appInformation = @{ @&amp;quot;appid&amp;quot;: @&amp;quot;PDA7D5EE6-B1B8-4123-9277-2A788XXXXXXX&amp;quot;,&lt;br /&gt;
                            @&amp;quot;appversion&amp;quot;: @&amp;quot;1.0&amp;quot;,&lt;br /&gt;
                            @&amp;quot;sfcode&amp;quot;: @&amp;quot;dcr&amp;quot;,&lt;br /&gt;
                            @&amp;quot;nol_devDebug&amp;quot;: @&amp;quot;DEBUG&amp;quot;, };&lt;br /&gt;
    &lt;br /&gt;
    return [[NielsenAppApi alloc] initWithAppInfo:appInformation delegate:delegate];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following would be the &amp;lt;code&amp;gt;NielsenInit.h&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;Foundation/Foundation.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@class NielsenAppApi;&lt;br /&gt;
@protocol NielsenAppApiDelegate;&lt;br /&gt;
&lt;br /&gt;
@interface NielsenInit : NSObject&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppApi *)createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Sample Code:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
@implementation ViewController&lt;br /&gt;
&lt;br /&gt;
- (void)viewDidLoad {&lt;br /&gt;
    [super viewDidLoad];&lt;br /&gt;
        &lt;br /&gt;
    //Getting the instance of Nielsen SDK&lt;br /&gt;
    nielsenApi = [NielsenInit createNielsenAppApiWithDelegate:nil];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== iOS DCR Static Step 3 - Create/Load DCR Static Metadata Object ===&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisiond&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 3 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisiond&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Configure Metadata ====&lt;br /&gt;
Map the Nielsen keys to variables so that the content metadata is dynamically updated.&lt;br /&gt;
&lt;br /&gt;
The Nielsen reserved keys are:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Key !! Description !! Data Type !! Value !! Required?&lt;br /&gt;
|-&lt;br /&gt;
| type || asset type || fixed || &amp;lt;code&amp;gt;'static'&amp;lt;/code&amp;gt; || Yes&lt;br /&gt;
|-&lt;br /&gt;
| assetid || Unique ID for each article || dynamic || custom &amp;lt;br&amp;gt;(no [[Special Characters]]) || No&lt;br /&gt;
|-&lt;br /&gt;
| section || section of each site (e.g. section value should be first level in page URL: website.com/section). Limit to 25 unique values || dynamic || custom || Yes&lt;br /&gt;
|-&lt;br /&gt;
| segA || custom segment for reporting: Limit to 25 unique values across custom segments (segA + segB + segC) || dynamic || custom || No&lt;br /&gt;
|-&lt;br /&gt;
| segB || custom segment for reporting: Limit to 25 unique values across custom segments (segA + segB + segC) || dynamic || custom || No&lt;br /&gt;
|-&lt;br /&gt;
| segC || custom segment for reporting: Limit to 25 unique values across custom segments (segA + segB + segC) || dynamic || custom || No&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The values passed through the Nielsen keys will determine the breakouts that are seen in reporting. The custom segments (A, B &amp;amp; C) will roll into the sub-brand. To not use custom segments A, B and C, do not pass any value in these keys.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Configure API calls - loadMetadata ====&lt;br /&gt;
Use [[loadMetadata]] to pass 'content' [[Digital Measurement Metadata]]. The CMS data must be passed as a JSON object.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;    loadMetadata(JSONObject jsonMetadata);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Note: The [[loadMetadata]] call must have (&amp;quot;type&amp;quot;: &amp;quot;static&amp;quot;). &amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Call [[loadMetadata]] with JSON metadata as below.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;    new JSONObject()&lt;br /&gt;
        .put(&amp;quot;type&amp;quot;, &amp;quot;static&amp;quot;)&lt;br /&gt;
        .put(&amp;quot;section&amp;quot;, &amp;quot;siteSection&amp;quot;)&lt;br /&gt;
        .put(&amp;quot;assetid&amp;quot;, &amp;quot;vid345-67483&amp;quot;)&lt;br /&gt;
        .put(&amp;quot;segA&amp;quot;, &amp;quot;segmentA&amp;quot;)&lt;br /&gt;
        .put(&amp;quot;segB&amp;quot;, &amp;quot;segmentB&amp;quot;)&lt;br /&gt;
        .put(&amp;quot;segC&amp;quot;,&amp;quot;segmentC&amp;quot;)&lt;br /&gt;
    }&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As soon as this loadMetadata call is made, AppSDK will record a view event and start tracking the section/page time spent (AppSDK 9.1 and above).&lt;br /&gt;
&lt;br /&gt;
==== DCR Static Duration Measurement per Section/Page/Asset ====&lt;br /&gt;
If your Nielsen AppID is enabled for DCR Static duration measurement, a view event will be recorded and a timer will be started for each screen/page. Duration will be measured until a new page is loaded or the app is moved to the background. The event which triggers recognition of page view and timer start is the loadMetadata API call with a metadata object of type 'static'. Once a page is viewed and the timer has started, duration will be measured until a new page has loaded ''with associated loadMetadata call having a different '''section name''' from the previous page''. If a new loadMetadata call is made with the same '''section name''', it will be ignored - no new view will be recorded. If it is desired to have a new view event even though the metadata contains the same '''section name''' (example: single-page apps having several assedIDs but common section name), staticEnd API can be called between page views. For the purposes of this overview, staticend will not be used. See [[DCR_Static_iOS_SDK|this page]] for more information. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Keep Going ===&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisiong&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisiong&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Congratulations, you've successfully integrated the iOS SDK in your app!&lt;br /&gt;
&lt;br /&gt;
You can add static loadMetadata calls for more sections/pages in your app to see what happens when transitioning between sections.&lt;br /&gt;
&lt;br /&gt;
View your application's debug logs and search for the term (AppSDK) to see messages emitted by Nielsen AppSDK.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Next Steps ===&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisioni&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisioni&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now that you've integrated DCR Static for the AppSDK, what's next?&lt;br /&gt;
&lt;br /&gt;
====Going Live====&lt;br /&gt;
&lt;br /&gt;
In addition to the basic steps above, before going live developers need to handle app background/foreground events, make certain privacy disclosures, and allow users to opt out of Nielsen measurement. More details can be found [[DCR_Static_iOS_SDK|here]], along with a more comprehensive reference for implementing DCR Static measurement with AppSDK.&lt;br /&gt;
&lt;br /&gt;
Once the DCR Tracking Code is added, Nielsen will validate the implementation. Following Nielsen testing, developers need to make a few updates to the initialization call to ensure that the app is being measured properly.&lt;br /&gt;
&lt;br /&gt;
#'''App ID''': Ensure that correct  is used during initialization '''PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'''&lt;br /&gt;
#'''Debug Logging''': Disable logging by changing initialization call to use @&amp;quot;nol_devDebug&amp;quot;:@&amp;quot;INFO&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== &amp;amp;rarr; iOS DCR Video ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivision1&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide DCR Video &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivision1&amp;quot;&amp;gt;&lt;br /&gt;
==== iOS DCR Video Introduction ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv2-&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide Intro &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv2-&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Digital Content Ratings (DCR) Video product provides content consumption measurement in client mobile apps and webpages. This measurement includes insight into the total time a user spent watching the tracked content, video player events, and much more.&lt;br /&gt;
This example provides the steps to implement the DCR Video product in a sample iOS app. It includes:&lt;br /&gt;
&lt;br /&gt;
*SDK Initialization&lt;br /&gt;
*DCR Video Metadata: information about the content being tracked&lt;br /&gt;
*DCR Video Events/API calls&lt;br /&gt;
&lt;br /&gt;
By the end of this guide you will have the needed steps to integrate Nielsen's AppSDK in the background of your app.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== iOS DCR Video Step 1 - Obtain AppID ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv3&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 1 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv3&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To begin using the iOS AppSDK, you will need to obtain an Application ID (AppId)&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! !! Item !! Description !! Source&lt;br /&gt;
|-&lt;br /&gt;
|&amp;amp;#9989; || App ID (appid) || Unique ID assigned to the player/site and configured by product || Contact your Nielsen Representative&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The appid is a 37 character unique ID assigned to the player/site and configured by product and is required when creating a new instance of the AppSDK in the app.&lt;br /&gt;
&amp;lt;/br&amp;gt;Example: '''PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== iOS DCR Video Step 2 - SDK Initialization ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionc&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 2 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionc&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== How to obtain the NielsenAppApi.Framework =====&lt;br /&gt;
The Nielsen AppSDK can either be downloaded directly or can be integrated directly within an application through the use of CocoaPods. We recommend using the CocoaPods-based integration whenever possible to ensure you maintain the most recent changes and enhancements to the Nielsen libraries.&lt;br /&gt;
* [[Digital_Measurement_iOS_Artifactory_Guide|Select to obtain CocoaPods implementation guide]]&lt;br /&gt;
* [[Special:Downloads|Select to Download Directly]]&lt;br /&gt;
&lt;br /&gt;
===== Configuring Xcode Development Environment =====&lt;br /&gt;
Starting with SDK version 6.0.0.0, the Nielsen App SDK is compatible with Apple iOS versions 8.0 and above.  In addition, when using the dynamic framework,  all the required frameworks are linked automatically as the are needed.  More details can be found here: https://stackoverflow.com/questions/24902787/dont-we-need-to-link-framework-to-xcode-project-anymore&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': All communications between the SDK and the Census (Collection Facility) use HTTPS.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======= Download Framework =======&lt;br /&gt;
The first step is to download and copy the [[Special:Downloads|NielsenAppApi.framework]] bundle to the app project directory. (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
======= Add Framework =======&lt;br /&gt;
In the General tab for app configuration add NielsenAppApi.framework in the list of Embedded Binaries.  (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
======= Add Path =======&lt;br /&gt;
Add path to the NielsenAppApi.framework in the Framework Search Paths build setting.  (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
======= Import Framework =======&lt;br /&gt;
Add NielsenAppApi.framework module in the source file of your app:&lt;br /&gt;
&lt;br /&gt;
======= Using Swift =======&lt;br /&gt;
Add the following:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
import NielsenAppApi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======= Using Objective-C =======&lt;br /&gt;
&amp;lt;syntaxhighlight lang =&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
@import NielsenAppApi;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======= SDK Initialization =======&lt;br /&gt;
&lt;br /&gt;
The following table contains the list of arguments that can be passed via the AppInfo JSON schema.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter / Argument !! Description !! Source !! Required? !! Example&lt;br /&gt;
|--style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
| appid || Unique Nielsen ID for the application. The ID is a GUID data type. If you did not receive your App ID, let us know and we will provide you. || Nielsen-specified || Yes || PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&lt;br /&gt;
|--style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
| nol_devDebug || Enables Nielsen console logging. Only required for testing &amp;lt;br&amp;gt;&lt;br /&gt;
|| Nielsen-specified || Optional || DEBUG&lt;br /&gt;
|}&lt;br /&gt;
==== Debug flag for development environment ====&lt;br /&gt;
Player application developers / integrators can use Debug flag to check whether an App SDK API call made is successful. To activate the Debug flag,&lt;br /&gt;
Pass the argument &amp;lt;code&amp;gt;@&amp;quot;nol_devDebug&amp;quot;:@&amp;quot;DEBUG&amp;quot;&amp;lt;/code&amp;gt;, in the JSON string . &lt;br /&gt;
&lt;br /&gt;
Once the flag is active, it logs each API call made and the data passed. The log created by this flag is minimal.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': DO NOT activate the Debug flag in a production environment.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Swift Example ===&lt;br /&gt;
==== Sample SDK Initialization Code ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;NielsenInit.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class NielsenInit: NSObject {&lt;br /&gt;
    class func createNielsenAppApi(delegate: NielsenAppApiDelegate) -&amp;gt; NielsenAppApi?{&lt;br /&gt;
    let appInformation:[String: String] = [&lt;br /&gt;
           &amp;quot;appid&amp;quot;: &amp;quot;PE392366B-F2C1-4BC4-AB62-A7DAFDCXXXX&amp;quot;,&lt;br /&gt;
           &amp;quot;nol_devDebug&amp;quot;: &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
        ]&lt;br /&gt;
        return NielsenAppApi(appInfo:appInformation, delegate:delegate)}}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;ViewController.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class ViewController: UIViewController, NielsenAppApiDelegate, AVPictureInPictureControllerDelegate, CLLocationManagerDelegate  {&lt;br /&gt;
&lt;br /&gt;
    let avPlayerViewController = AVPlayerViewController()&lt;br /&gt;
    var avPlayer:AVPlayer?&lt;br /&gt;
    var nielsenAppApi: NielsenAppApi!&lt;br /&gt;
&lt;br /&gt;
  override func viewDidLoad() {&lt;br /&gt;
        super.viewDidLoad()&lt;br /&gt;
        self.nielsenAppApi = NielsenInit.createNielsenAppApi(delegate: self)&lt;br /&gt;
        NSLog(&amp;quot;Nielsen SDK initialized&amp;quot;)&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Objective C ===&lt;br /&gt;
==== Sample SDK Initialization Code ====&lt;br /&gt;
Initialize the Nielsen App object within the viewDidLoad view controller delegate method using initWithAppInfo:delegate:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;If App SDK is initialized using init or new methods, it will ignore the API calls resulting in no measurement. The SDK will not return any errors.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;quot;NlsAppApiFactory.h&amp;quot;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenAppApi.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@implementation NlsAppApiFactory&lt;br /&gt;
+ (NielsenAppApi *)createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
{&lt;br /&gt;
    NSDictionary *appInformation = @{&lt;br /&gt;
                                     @&amp;quot;appid&amp;quot;: &amp;quot;PE392366B-F2C1-4BC4-AB62-A7DAFDC51XXX&amp;quot;,&lt;br /&gt;
                                     @&amp;quot;nol_devDebug&amp;quot;: @&amp;quot;DEBUG&amp;quot;&lt;br /&gt;
                                     };&lt;br /&gt;
    return [[NielsenAppApi alloc] initWithAppInfo:appInformation delegate:delegate];&lt;br /&gt;
}&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following would be the &amp;lt;code&amp;gt;NlsAppApiFactory.h&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;Foundation/Foundation.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@class NielsenAppApi;&lt;br /&gt;
@protocol NielsenAppApiDeligate;&lt;br /&gt;
@interface NlsAppApiFactory : NSObject&lt;br /&gt;
+ (NielsenAppAPI *) createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
@end&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
The following might be in the &amp;lt;code&amp;gt;Viewcontroller.m&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
@implementation ViewController&lt;br /&gt;
&lt;br /&gt;
- (void)viewDidLoad {&lt;br /&gt;
    [super viewDidLoad];&lt;br /&gt;
    &lt;br /&gt;
    //Setting background image&lt;br /&gt;
    UIImage *backgroundImage = [UIImage imageNamed:@&amp;quot;new_ios_bg.png&amp;quot;];&lt;br /&gt;
    UIImageView *backgroundImageView=[[UIImageView alloc]initWithFrame:self.view.frame];&lt;br /&gt;
    backgroundImageView.image=backgroundImage;&lt;br /&gt;
    [self.view insertSubview:backgroundImageView atIndex:0];&lt;br /&gt;
    &lt;br /&gt;
    //Mark: In NielsenInit class we are initialising the Nielsen SDK.&lt;br /&gt;
    &lt;br /&gt;
    //Getting the instance of Nielsen SDK&lt;br /&gt;
    nielsenApi = [NielsenInit createNielsenAppApiWithDelegate:nil];&lt;br /&gt;
}&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== iOS DCR Video Step 3 - Create DCR Video Content Metadata Object ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv5&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 3 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv5&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Configure Metadata =====&lt;br /&gt;
The SDK methods handle 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 Nielsen Key names (e.g. appid, program) 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;br&amp;gt;&lt;br /&gt;
===== Create channelName Metadata =====&lt;br /&gt;
channelName 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;
|--style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
! Key !! Description !!	Values	 !! Required&lt;br /&gt;
|--style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
| channelName	|| Any string representing the channel/stream	|| custom	|| ✓&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== Create Content Metadata =====&lt;br /&gt;
Content metadata should remain constant throughout the entirety of an episode/clip including when ads play.&lt;br /&gt;
&amp;lt;blockquote&amp;gt; program and title metadata values should be passed to SDK as UTF-8 strings. &amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;height: 45em; overflow-y:auto;&amp;quot;&amp;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'''!!'''Provider'''&lt;br /&gt;
|-&lt;br /&gt;
| type || Type of asset ||For Video use: &amp;lt;code&amp;gt;content&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt; For Static or text &amp;lt;code&amp;gt;static&amp;lt;/code&amp;gt; || Yes || Nielsen&lt;br /&gt;
|-style=&amp;quot;background-color:#e9f9fa;&amp;quot;&lt;br /&gt;
| assetid || Unique ID assigned to asset &amp;lt;br&amp;gt; Note: Refrain from using the following special characters [[Special_Characters|(Special Characters)]]. || Examples: &amp;lt;br&amp;gt; &amp;lt;code&amp;gt;BBT345a234 &amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; &amp;lt;code&amp;gt;CBSs5e234F2021&amp;lt;/code&amp;gt;  || Yes || Client &lt;br /&gt;
|-&lt;br /&gt;
| program ||Complete program or movie title &amp;lt;br&amp;gt; (no abbreviations or shorthand) &amp;lt;br&amp;gt; Note: there is a 25 character limit.  ||&amp;lt;code&amp;gt; The Big Bang Theory&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; &amp;lt;code&amp;gt; TheBigBangTheory&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt;&amp;lt;code&amp;gt; The Dark Knight&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt;&amp;lt;code&amp;gt; TheDarkKnight&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; || Yes || Client &lt;br /&gt;
|-style=&amp;quot;background-color:#e9f9fa;&amp;quot;&lt;br /&gt;
| title ||Episode title with season and episode number (40 character limit) &amp;lt;br&amp;gt; (Formats accepted: S01E03, S1E3, S1 E3). || Examples: &amp;lt;br&amp;gt; &amp;lt;code&amp;gt;The Pants Alternative S03E18&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; &amp;lt;code&amp;gt;The Pants Alternative S3E18&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; &amp;lt;code&amp;gt;The Pants Alternative S3 E18&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; Can also accept: &amp;lt;code&amp;gt; S3E18&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; Not Valid: &amp;lt;code&amp;gt; 318 &amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt; 0318 &amp;lt;/code&amp;gt;|| Yes || Client &lt;br /&gt;
|-&lt;br /&gt;
| crossId1 || Gracenote TMS ID (If available) should be passed for all telecasted content for clients using the Gracenote solution for proper matching purposes. &amp;lt;br&amp;gt;Note: The TMS ID will be a 14 character string. Normally leading with 2 alpha characerts ('EP', 'MV', 'SH' or 'SP'), followed by 12 numbers.&lt;br /&gt;
|| The TMS ID will be a 14 character string. &amp;lt;br&amp;gt; Normally being with  'EV,' 'EP', 'SH', 'SP', or 'MV' &amp;lt;br&amp;gt; Followed by 12 numbers after the initial two letter prefix. &amp;lt;br&amp;gt; &amp;lt;br&amp;gt; The Giant Morning Show: &amp;lt;code&amp;gt;SH009311820022&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; The Pants Alternative Episode : &amp;lt;code&amp;gt;EP009311820061&amp;lt;/code&amp;gt; || Optional || Nielsen&lt;br /&gt;
|-style=&amp;quot;background-color:#e9f9fa;&amp;quot;&lt;br /&gt;
| crossId2 || Populated by content distributor to contribute viewing from that distributor to the given content originator. || For a full list of acceptable values, please contact your Nielsen reprentative. || Yes, for distributors || Nielsen&lt;br /&gt;
|-&lt;br /&gt;
| length || Length of content in seconds&amp;lt;br&amp;gt;Note: Integers and decimals are acceptable values are acceptable for the length parameter. || Examples:&lt;br /&gt;
&amp;lt;small&amp;gt;For standard VOD content - &amp;lt;code&amp;gt;300&amp;lt;/code&amp;gt; to represent 5 minutes, &amp;lt;code&amp;gt;1320&amp;lt;/code&amp;gt; to represent 22 minutes, etc.&lt;br /&gt;
&amp;lt;br&amp;gt;If DAI live stream of a discrete program (Live Event/Sporting Event), pass length of content. See example for standard VOD content above.&lt;br /&gt;
&amp;lt;br&amp;gt;If unknown DAI live steam, pass a value of &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;.&amp;lt;/small&amp;gt; &lt;br /&gt;
|| Yes || Client &lt;br /&gt;
|-style=&amp;quot;background-color:#e9f9fa;&amp;quot;&lt;br /&gt;
| airdate ||Original broadcast or release date for the program &amp;lt;br&amp;gt;For USA, date should be EST &amp;lt;br&amp;gt; Outside USA, date should be local time.&amp;lt;br&amp;gt;If not applicable or available, original broadcast or release date for the Program. || Acceptable Formats:&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;YYYY-MM-DDTHH:MI:SS&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;YYYY-MM-DDHH:MI:SS&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;YYYY-MM-DDTHH:MI:SS+xx:xx&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;YYYY-MM-DDTHH:MI:SS-xx:xx&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;YYYYMMDDHH:MI:SS&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;YYYYMMDD HH:MI:SS&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;MM-DD-YYYY&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;MM/DD/YYYY&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;YYYYMMDD&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; || Yes || Client &lt;br /&gt;
|-&lt;br /&gt;
| isfullepisode || Full episode flag to identify differences between long form content. || &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;- full episode, &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt;- non full episode(clip,teaser,promo,etc.)&lt;br /&gt;
&amp;lt;small&amp;gt;Also accept: &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;lf&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;yes&amp;lt;/code&amp;gt;- longform&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;sf&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;no&amp;lt;/code&amp;gt;- shortform&lt;br /&gt;
|| Yes || Nielsen&lt;br /&gt;
|-style=&amp;quot;background-color:#e9f9fa;&amp;quot;&lt;br /&gt;
| adloadtype || &amp;lt;big&amp;gt;&amp;lt;small&amp;gt;Type of ad load: &lt;br /&gt;
&amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; Linear – matches TV ad load&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;2&amp;lt;/code&amp;gt; Dynamic – Dynamic Ad Insertion (DAI)&amp;lt;/small&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
|| &amp;lt;code&amp;gt;2&amp;lt;/code&amp;gt; - DCR measures content with dynamic ads || Yes || Nielsen&lt;br /&gt;
|-&lt;br /&gt;
| segB || One of two custom segment for the clients granular reporting within a brand. || Examples:&amp;lt;br&amp;gt;Genre - &amp;lt;code&amp;gt;horror&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;comedy&amp;lt;/code&amp;gt;, etc.&amp;lt;br&amp;gt;Timeslot - &amp;lt;code&amp;gt;primetime&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;daytime&amp;lt;/code&amp;gt;, etc.&amp;lt;br&amp;gt;News type - &amp;lt;code&amp;gt;breakingnews&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;weather&amp;lt;/code&amp;gt;, etc. || Optional || Client &lt;br /&gt;
|-style=&amp;quot;background-color:#e9f9fa;&amp;quot;&lt;br /&gt;
| segC || One of two custom segment for the clients granular reporting within a brand. || Examples:&amp;lt;br&amp;gt;Genre - &amp;lt;code&amp;gt;horror&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;comedy&amp;lt;/code&amp;gt;, etc.&amp;lt;br&amp;gt;Timeslot - &amp;lt;code&amp;gt;primetime&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;daytime&amp;lt;/code&amp;gt;, etc.&amp;lt;br&amp;gt;News type - &amp;lt;code&amp;gt;breakingnews&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;weather&amp;lt;/code&amp;gt;, etc. || Optional || Client &lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Custom segments (segB and segC) can be used to aggregate video and/or static content within a single Brand to receive more granular reports within a brand.&lt;br /&gt;
&lt;br /&gt;
Examples regarding usage of segments within SDK:&lt;br /&gt;
* All comedy clips and stories for a Brand rolled into a &amp;quot;Comedy&amp;quot; segment&lt;br /&gt;
* genre grouping content by Comedy vs. Drama&lt;br /&gt;
* group related Text + Video content - i.e. for a show that has a lot of - static pages associated with it&lt;br /&gt;
* packaging based on how clients sell inventory&lt;br /&gt;
* grouping related types of content either by genre, category or platform.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Metadata Example =====&lt;br /&gt;
&amp;lt;code&amp;gt;Swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&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;program&amp;quot;: &amp;quot;The Big Bang Theory&amp;quot;,&lt;br /&gt;
    &amp;quot;title&amp;quot;: &amp;quot;The Pants Alternative S03E18&amp;quot;,  //Formats accepted: S01E03, S1E3, S1 E3&lt;br /&gt;
    &amp;quot;crossId1&amp;quot;: &amp;quot;EP009311820061&amp;quot;, //optional&lt;br /&gt;
    &amp;quot;crossId2&amp;quot;: &amp;quot;Content Originator&amp;quot;, //optional&lt;br /&gt;
    &amp;quot;length&amp;quot;: &amp;quot;3600&amp;quot;,&lt;br /&gt;
    &amp;quot;airdate&amp;quot;: &amp;quot;2022-03-21T10:05:00&amp;quot;, &lt;br /&gt;
    &amp;quot;isfullepisode&amp;quot;: &amp;quot;Yes&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;
];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;Objective-C&amp;lt;/code&amp;gt;    &lt;br /&gt;
&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;program&amp;quot;: @ &amp;quot;The Big Bang Theory&amp;quot;,&lt;br /&gt;
    @ &amp;quot;title&amp;quot;: @ &amp;quot;The Pants Alternative S03E18&amp;quot;, //Formats accepted: S01E03, S1E3, S1 E3&lt;br /&gt;
    @ &amp;quot;crossId1&amp;quot;: @ &amp;quot;EP009311820061&amp;quot;, //optional&lt;br /&gt;
    @ &amp;quot;crossId2&amp;quot;: @ &amp;quot;Content Originator&amp;quot;, //optional&lt;br /&gt;
    @ &amp;quot;length&amp;quot;: @ &amp;quot;3600&amp;quot;,&lt;br /&gt;
    @ &amp;quot;airdate&amp;quot;: @ &amp;quot;2022-03-21T10:05:00&amp;quot;,&lt;br /&gt;
    @ &amp;quot;isfullepisode&amp;quot;: @ &amp;quot;y&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;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== iOS DCR Video Step 4 - Basic Set of Events - Sample Playback ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv6&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 4 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv6&amp;quot;&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;
| '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;
| 'playheadPosition'	|| 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: 'PlayheadPosition' 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 '''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 content or Ad playback is interrupted and at the end of each Ad. &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. &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;'''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;
==== Sample Use Case: 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 [[playheadPosition|playheadPosition()]] 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;
|-style=&amp;quot;background-color:#d8f5d7;&amp;quot;&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;
|-style=&amp;quot;background-color:#d8f5d7;&amp;quot;&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;
|- style=&amp;quot;background-color:#d8f5d7;&amp;quot;&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;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Keep Going ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv9&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv9&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Congratulations, you've successfully integrated the iOS SDK in your app for a basic content playback scenario!&lt;br /&gt;
&lt;br /&gt;
You can add more content to see channel-change scenarios or continue to next steps below.&lt;br /&gt;
&lt;br /&gt;
View your application's debug logs and search for the term (AppSDK) to see messages emitted by Nielsen AppSDK during video playback.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Next Steps ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv10&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv10&amp;quot;&amp;gt;&lt;br /&gt;
====Going Live====&lt;br /&gt;
&lt;br /&gt;
In addition to the basic steps above, before going live developers need to handle app background/foreground events, make certain privacy disclosures, handle interruption events (stop, fast-forward, rewind), remove iOS simulator slices, and allow users to opt out of Nielsen measurement. More details can be found [[DCR_Video_iOS_SDK|here]], along with a more comprehensive reference for implementing DCR Video measurement with AppSDK.&lt;br /&gt;
&lt;br /&gt;
Once the DCR Tracking Code is added, Nielsen will validate the implementation. Following Nielsen testing, developers need to make a few updates to the initialization call to ensure that the app is being measured properly.&lt;br /&gt;
&lt;br /&gt;
#'''App ID''': Ensure that correct  is used during initialization '''PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'''&lt;br /&gt;
#'''Debug Logging''': Disable logging by changing initialization call to use @&amp;quot;nol_devDebug&amp;quot;:@&amp;quot;INFO&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== &amp;amp;rarr; iOS DTVR (coming soon) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivision100&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide iOS DTVR &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivision100&amp;quot;&amp;gt;&lt;br /&gt;
==== iOS DTVR Introduction ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv200-&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide Intro &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv200-&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Nielsen DTVR (Digital TV Ratings) product provides content consumption measurement in client mobile apps and webpages. This measurement includes insight into the total time a user spent watching the tracked content, video player events, and much more.&lt;br /&gt;
This example provides the steps to implement the DTVR product in a sample iOS app using Nielsen AppSDK. It includes:&lt;br /&gt;
&lt;br /&gt;
*SDK Initialization&lt;br /&gt;
*DTVR Video Metadata: information about the content being tracked&lt;br /&gt;
*DTVR Video Events/API calls&lt;br /&gt;
*Extracting ID3 tags from the video stream and passing to AppSDK for measurement&lt;br /&gt;
&lt;br /&gt;
By the end of this guide you will have the needed steps to integrate Nielsen's AppSDK in the background of your app for DTVR measurement.&lt;br /&gt;
&lt;br /&gt;
'''NOTE: video streams must have Nielsen ID3 tags embedded in order to be measured using the DTVR product. See the section in this guide &amp;quot;Extracting ID3 Tags&amp;quot; or contact your Nielsen representative for more information.'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== iOS DTVR Step 1 - Obtain AppID ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv300&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 1 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv300&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To begin using the iOS AppSDK, you will need to obtain an Application ID (AppId)&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! !! Item !! Description !! Source&lt;br /&gt;
|-&lt;br /&gt;
|&amp;amp;#9989; || App ID (appid) || Unique ID assigned to the player/site and configured by product || Contact your Nielsen Representative&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The appid is a 37 character unique ID assigned to the player/site and configured by product and is required when creating a new instance of the AppSDK in the app.&lt;br /&gt;
&amp;lt;/br&amp;gt;Example: '''PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== iOS DTVR Step 2 - SDK Initialization ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivision400&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 2 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivision400&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== How to obtain the NielsenAppApi.Framework =====&lt;br /&gt;
The Nielsen AppSDK can either be downloaded directly or can be integrated directly within an application through the use of CocoaPods. We recommend using the CocoaPods-based integration whenever possible to ensure you maintain the most recent changes and enhancements to the Nielsen libraries.&lt;br /&gt;
* [[Digital_Measurement_iOS_Artifactory_Guide|Select to obtain CocoaPods implementation guide]]&lt;br /&gt;
* [[Special:Downloads|Select to Download Directly]]&lt;br /&gt;
&lt;br /&gt;
===== Configuring Xcode Development Environment =====&lt;br /&gt;
Starting with SDK version 6.0.0.0, the Nielsen App SDK is compatible with Apple iOS versions 8.0 and above.  In addition, when using the dynamic framework,  all the required frameworks are linked automatically as the are needed.  More details can be found here: https://stackoverflow.com/questions/24902787/dont-we-need-to-link-framework-to-xcode-project-anymore&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': All communications between the SDK and the Census (Collection Facility) use HTTPS.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======= Download Framework =======&lt;br /&gt;
The first step is to download and copy the [[Special:Downloads|NielsenAppApi.framework]] bundle to the app project directory. (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
======= Add Framework =======&lt;br /&gt;
In the General tab for app configuration add NielsenAppApi.framework in the list of Embedded Binaries.  (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
======= Add Path =======&lt;br /&gt;
Add path to the NielsenAppApi.framework in the Framework Search Paths build setting.  (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
======= Import Framework =======&lt;br /&gt;
Add NielsenAppApi.framework module in the source file of your app:&lt;br /&gt;
&lt;br /&gt;
======= Using Swift =======&lt;br /&gt;
Add the following:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
import NielsenAppApi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======= Using Objective-C =======&lt;br /&gt;
&amp;lt;syntaxhighlight lang =&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
@import NielsenAppApi;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======= SDK Initialization =======&lt;br /&gt;
&lt;br /&gt;
The following table contains the list of arguments that can be passed via the AppInfo JSON schema.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter / Argument !! Description !! Source !! Required? !! Example&lt;br /&gt;
|--style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
| appid || Unique Nielsen ID for the application. The ID is a GUID data type. If you did not receive your App ID, let us know and we will provide you. || Nielsen-specified || Yes || PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&lt;br /&gt;
|--style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
| nol_devDebug || Enables Nielsen console logging. Only required for testing &amp;lt;br&amp;gt;&lt;br /&gt;
|| Nielsen-specified || Optional || DEBUG&lt;br /&gt;
|}&lt;br /&gt;
==== Debug flag for development environment ====&lt;br /&gt;
Player application developers / integrators can use Debug flag to check whether an App SDK API call made is successful. To activate the Debug flag,&lt;br /&gt;
Pass the argument &amp;lt;code&amp;gt;@&amp;quot;nol_devDebug&amp;quot;:@&amp;quot;DEBUG&amp;quot;&amp;lt;/code&amp;gt;, in the JSON string . &lt;br /&gt;
&lt;br /&gt;
Once the flag is active, it logs each API call made and the data passed. The log created by this flag is minimal.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': DO NOT activate the Debug flag in a production environment.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Swift Example ===&lt;br /&gt;
==== Sample SDK Initialization Code ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;NielsenInit.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class NielsenInit: NSObject {&lt;br /&gt;
    class func createNielsenAppApi(delegate: NielsenAppApiDelegate) -&amp;gt; NielsenAppApi?{&lt;br /&gt;
    let appInformation:[String: String] = [&lt;br /&gt;
           &amp;quot;appid&amp;quot;: &amp;quot;PE392366B-F2C1-4BC4-AB62-A7DAFDCXXXX&amp;quot;,&lt;br /&gt;
           &amp;quot;nol_devDebug&amp;quot;: &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
        ]&lt;br /&gt;
        return NielsenAppApi(appInfo:appInformation, delegate:delegate)}}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;ViewController.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class ViewController: UIViewController, NielsenAppApiDelegate, AVPictureInPictureControllerDelegate, CLLocationManagerDelegate  {&lt;br /&gt;
&lt;br /&gt;
    let avPlayerViewController = AVPlayerViewController()&lt;br /&gt;
    var avPlayer:AVPlayer?&lt;br /&gt;
    var nielsenAppApi: NielsenAppApi!&lt;br /&gt;
&lt;br /&gt;
  override func viewDidLoad() {&lt;br /&gt;
        super.viewDidLoad()&lt;br /&gt;
        self.nielsenAppApi = NielsenInit.createNielsenAppApi(delegate: self)&lt;br /&gt;
        NSLog(&amp;quot;Nielsen SDK initialized&amp;quot;)&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Objective C ===&lt;br /&gt;
==== Sample SDK Initialization Code ====&lt;br /&gt;
Initialize the Nielsen App object within the viewDidLoad view controller delegate method using initWithAppInfo:delegate:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;If App SDK is initialized using init or new methods, it will ignore the API calls resulting in no measurement. The SDK will not return any errors.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;quot;NlsAppApiFactory.h&amp;quot;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenAppApi.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@implementation NlsAppApiFactory&lt;br /&gt;
+ (NielsenAppApi *)createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
{&lt;br /&gt;
    NSDictionary *appInformation = @{&lt;br /&gt;
                                     @&amp;quot;appid&amp;quot;: &amp;quot;PE392366B-F2C1-4BC4-AB62-A7DAFDC51XXX&amp;quot;,&lt;br /&gt;
                                     @&amp;quot;nol_devDebug&amp;quot;: @&amp;quot;DEBUG&amp;quot;&lt;br /&gt;
                                     };&lt;br /&gt;
    return [[NielsenAppApi alloc] initWithAppInfo:appInformation delegate:delegate];&lt;br /&gt;
}&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following would be the &amp;lt;code&amp;gt;NlsAppApiFactory.h&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;Foundation/Foundation.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@class NielsenAppApi;&lt;br /&gt;
@protocol NielsenAppApiDeligate;&lt;br /&gt;
@interface NlsAppApiFactory : NSObject&lt;br /&gt;
+ (NielsenAppAPI *) createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
@end&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
The following might be in the &amp;lt;code&amp;gt;Viewcontroller.m&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
@implementation ViewController&lt;br /&gt;
&lt;br /&gt;
- (void)viewDidLoad {&lt;br /&gt;
    [super viewDidLoad];&lt;br /&gt;
    &lt;br /&gt;
    //Setting background image&lt;br /&gt;
    UIImage *backgroundImage = [UIImage imageNamed:@&amp;quot;new_ios_bg.png&amp;quot;];&lt;br /&gt;
    UIImageView *backgroundImageView=[[UIImageView alloc]initWithFrame:self.view.frame];&lt;br /&gt;
    backgroundImageView.image=backgroundImage;&lt;br /&gt;
    [self.view insertSubview:backgroundImageView atIndex:0];&lt;br /&gt;
    &lt;br /&gt;
    //Mark: In NielsenInit class we are initialising the Nielsen SDK.&lt;br /&gt;
    &lt;br /&gt;
    //Getting the instance of Nielsen SDK&lt;br /&gt;
    nielsenApi = [NielsenInit createNielsenAppApiWithDelegate:nil];&lt;br /&gt;
}&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== iOS DTVR Step 3 - Create DTVR Content Metadata Object ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv500&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 3 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv500&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Configure Metadata =====&lt;br /&gt;
Content metadata should remain constant throughout the completion of an episode or live stream.&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 for DTVR      || ✓&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
- (NSDictionary *)loadChannelInfo&lt;br /&gt;
{&lt;br /&gt;
    //Loading Channel Info.    &lt;br /&gt;
    NSString *strUrl = self.url.absoluteString;  &lt;br /&gt;
    NSDictionary *channel = @{  @&amp;quot;channelName&amp;quot; : @&amp;quot;TheGreatBigMovie&amp;quot;: strUrl };   &lt;br /&gt;
    return channel;&lt;br /&gt;
}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objectivec&amp;quot;&amp;gt;    &lt;br /&gt;
- (NSDictionary *)loadDtvr{&lt;br /&gt;
    &lt;br /&gt;
    //Loading DTVR data  &lt;br /&gt;
    NSDictionary *dtvr = @{ @&amp;quot;adModel&amp;quot;:@&amp;quot;1&amp;quot; ,  &lt;br /&gt;
                            @&amp;quot;type&amp;quot;:@&amp;quot;content&amp;quot;,};  &lt;br /&gt;
    return dtvr;&lt;br /&gt;
}&lt;br /&gt;
    &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== iOS DTVR Step 4 - Basic Set of Events - Sample Playback ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv600&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 4 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv600&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== SDK Events/APIs =====&lt;br /&gt;
&amp;lt;!--[[File:appsdkTimeline-DTVR-V2.png|icon]]--&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;
&lt;br /&gt;
===== Configure API calls - loadMetadata =====&lt;br /&gt;
Use &amp;lt;code&amp;gt;loadMetadata&amp;lt;/code&amp;gt; to pass the metadata object created above. &lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Objective C = &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;[nielsenApi loadMetadata:(dtvr)];&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Swift = &amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;self.nielsenAppApi?.loadMetadata(dtvr)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Configure API calls - sendID3 =====&lt;br /&gt;
[[sendID3]] API is a Nielsen AppSDK receiver for timed metadata events (ID3 tags) provided through iOS’s NSNotificationCenter notification system. This API filters out Nielsen-specific ID3 tags from the system and uses them to create duration data. These ID3 tags are used by Nielsen SDK for DTVR measurement, and the stream that is played must contain ID3 tags and have these tags extracted and passed to SDK using the below procedure in order for DTVR measurement to occur. &lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Objective C = &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;[nielsenApi sendID3:extraString];&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Swift = &amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt; [nielsenApi sendID3:extraString];&amp;lt;/syntaxhighlight&amp;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;
Refer to [[iOS SDK API Reference#Retrieving ID3 Tags|Retrieving ID3 Tags]] section to know more details.&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;
As Apple has deprecated the use of [https://developer.apple.com/documentation/avfoundation/avplayeritem/1389602-timedmetadata?language=objc timedMetadata], we now recommend using [https://developer.apple.com/documentation/avfoundation/avplayeritemmetadataoutput?language=objc AVPlayerItemMetadataOutput] for extracting ID3 tags from the iOS Native Player.&lt;br /&gt;
&lt;br /&gt;
If any other player apart from the iOS native player is used, check and ensure that the player has the capability to extract metadata such as 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;
|Swift = &amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt; &lt;br /&gt;
        //First, ensure your class conforms to the AVPlayerItemMetadataOutputPushDelegate protocol.&lt;br /&gt;
           class YourClass: AVPlayerItemMetadataOutputPushDelegate { &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;
       // Then create an instance of AVPlayerItemMetadataOutput and add it to the player item&lt;br /&gt;
          let metadataOutput = AVPlayerItemMetadataOutput(identifiers: nil)&lt;br /&gt;
           playerItem.add(metadataOutput)&lt;br /&gt;
 &lt;br /&gt;
       // and set the delegate and a dispatch queue&lt;br /&gt;
           metadataOutput.setDelegate(self, queue: DispatchQueue.main)&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;
        // After that below callback function of AVPlayerItemMetadataOutputPushDelegate &lt;br /&gt;
        // protocol will be triggered whenever ID3 tag is received from stream. &lt;br /&gt;
          func metadataOutput(_ output: AVPlayerItemMetadataOutput, didOutputTimedMetadataGroups groups: [AVTimedMetadataGroup], from track: AVPlayerItemTrack?) {&lt;br /&gt;
    for group in groups {&lt;br /&gt;
        for item in group.items {&lt;br /&gt;
            // Handle the metadata item&lt;br /&gt;
            handleTimedMetadata(metadataItem: item)&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;
          // Then further metadata item can be handled like below &lt;br /&gt;
          func handleTimedMetadata(metadataItem: AVMetadataItem) {&lt;br /&gt;
    guard let key = metadataItem.key as? String,&lt;br /&gt;
          let extraString = metadataItem.extraAttributes?[AVMetadataExtraAttributeInfoKey] as? String else {&lt;br /&gt;
        return&lt;br /&gt;
    }&lt;br /&gt;
    // If the extra string(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.hasPrefix(&amp;quot;www.nielsen.com&amp;quot;) {&lt;br /&gt;
        DispatchQueue.global(qos: .default).async {&lt;br /&gt;
            self.nielsenApi?.sendID3(extraString)&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&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;
        //First, ensure your class conforms to the AVPlayerItemMetadataOutputPushDelegate protocol.&lt;br /&gt;
          @interface YourClass : NSObject &amp;lt;AVPlayerItemMetadataOutputPushDelegate&amp;gt; &lt;br /&gt;
&lt;br /&gt;
          @end&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;
        // Then create an instance of AVPlayerItemMetadataOutput and add it to the player item&lt;br /&gt;
          AVPlayerItemMetadataOutput *metadataOutput = [[AVPlayerItemMetadataOutput alloc] initWithIdentifiers:nil];&lt;br /&gt;
          [playerItem addOutput:metadataOutput];&lt;br /&gt;
&lt;br /&gt;
        // and set the delegate and a dispatch queue&lt;br /&gt;
          [metadataOutput setDelegate:self queue:dispatch_get_main_queue()];&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;
        // After that below callback function of AVPlayerItemMetadataOutputPushDelegate &lt;br /&gt;
        // protocol will be triggered whenever ID3 tag is received from stream.&lt;br /&gt;
           - (void)metadataOutput:(AVPlayerItemMetadataOutput *)output didOutputTimedMetadataGroups:(NSArray&amp;lt;AVTimedMetadataGroup *&amp;gt; *)groups fromPlayerItemTrack:(AVPlayerItemTrack *)track {&lt;br /&gt;
    for (AVTimedMetadataGroup *group in groups) {&lt;br /&gt;
        for (AVMetadataItem *item in group.items) {&lt;br /&gt;
            // Handle the metadata item&lt;br /&gt;
            [self handleTimedMetadata:item];&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;
        // Then further metadata item can be handled like below &lt;br /&gt;
          - (void)handleTimedMetadata:(AVMetadataItem *)item {&lt;br /&gt;
    NSString *key = (NSString *)item.key;&lt;br /&gt;
    NSString *extraString = item.extraAttributes[AVMetadataExtraAttributeInfoKey];&lt;br /&gt;
    // If the key is &amp;quot;PRIV&amp;quot; and the extra string starts with &amp;quot;www.nielsen.com&amp;quot;, send it to the Nielsen API&lt;br /&gt;
    if ([key isEqualToString:@&amp;quot;PRIV&amp;quot;] &amp;amp;&amp;amp; [extraString hasPrefix:@&amp;quot;www.nielsen.com&amp;quot;]) {&lt;br /&gt;
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{&lt;br /&gt;
            [self.nielsenApi sendID3:extraString];&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;
===== 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. &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 loadMetadata and sendID3 events to occur.&lt;br /&gt;
# '''Processing state''' – The SDK instance is processing playing information. For DTVR, the &amp;lt;code&amp;gt;'''loadMetadata''' &amp;lt;/code&amp;gt; call moves the SDK instance into this state. In this state, the SDK instance will be able to process sendID3 calls and measure content.&lt;br /&gt;
# '''Disabled state''' – The SDK instance is disabled.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Keep Going ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv900&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv900&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Congratulations, you've successfully integrated the iOS SDK in your app for a basic content playback scenario!&lt;br /&gt;
&lt;br /&gt;
You can add more content to see channel-change scenarios or continue to next steps below.&lt;br /&gt;
&lt;br /&gt;
View your application's debug logs and search for the term (AppSDK) to see messages emitted by Nielsen AppSDK during video playback.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Next Steps ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv1000&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv1000&amp;quot;&amp;gt;&lt;br /&gt;
====Going Live====&lt;br /&gt;
&lt;br /&gt;
In addition to the basic steps above, before going live developers need to handle app background/foreground events, make certain privacy disclosures, handle interruption events (stop, fast-forward, rewind), remove iOS simulator slices, and allow users to opt out of Nielsen measurement. More details can be found [[DTVR_iOS_SDK|here]], along with a more comprehensive reference for implementing DTVR measurement with AppSDK.&lt;br /&gt;
&lt;br /&gt;
Once the DTVR Tracking Code is added, Nielsen will validate the implementation. Following Nielsen testing, developers need to make a few updates to the initialization call to ensure that the app is being measured properly.&lt;br /&gt;
&lt;br /&gt;
#'''App ID''': Ensure that correct  is used during initialization '''PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'''&lt;br /&gt;
#'''Debug Logging''': Disable logging by changing initialization call to use @&amp;quot;nol_devDebug&amp;quot;:@&amp;quot;INFO&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;/div&gt;</summary>
		<author><name>NickParrucci</name></author>
	</entry>
	<entry>
		<id>https://nielsentest.mywikis.net/w/index.php?title=iOS_Step_By_Step&amp;diff=6465</id>
		<title>iOS Step By Step</title>
		<link rel="alternate" type="text/html" href="https://nielsentest.mywikis.net/w/index.php?title=iOS_Step_By_Step&amp;diff=6465"/>
		<updated>2023-07-27T13:25:16Z</updated>

		<summary type="html">&lt;p&gt;NickParrucci: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
__NOTOC__&lt;br /&gt;
&lt;br /&gt;
Provided below are step-by-step quick start guides for implementing Nielsen iOS SDK for DCR Static, DCR Video, and DTVR products. Click each section to get started. &lt;br /&gt;
&lt;br /&gt;
== &amp;amp;rarr; iOS DCR Static ==&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivision&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide DCR Static &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivision&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== iOS DCR Static Introduction ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisiona-&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide Intro &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisiona-&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Digital Content Ratings (DCR) Static product provides content consumption measurement in client mobile apps and webpages. This measurement includes insight into the total time a user spent on a webpage, how they navigated through the page via links, and many other data points.&lt;br /&gt;
This tutorial provides the steps to implement the DCR Static product in a sample iOS app. It includes:&lt;br /&gt;
&lt;br /&gt;
*SDK Initialization Call&lt;br /&gt;
*DCR Static Metadata: information about the sections being tracked&lt;br /&gt;
&lt;br /&gt;
By the end of this guide you will have the needed steps to integrate Nielsen's AppSDK in the background of your app.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== iOS DCR Static Step 1 - Obtain AppID ===&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisiona1&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 1 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisiona1&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To begin using the iOS SDK (AppSDK) you will need to obtain an Application ID (AppId)&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! !! Item !! Description !! Source&lt;br /&gt;
|-&lt;br /&gt;
|&amp;amp;#9989; || App ID (appid) || Unique ID assigned to the player/site and configured by product || Contact your Nielsen TAM&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The appid is a 37 character unique ID assigned to the player/site and configured by product and is required when creating a new instance of the AppSDK in the app.&lt;br /&gt;
&amp;lt;/br&amp;gt;Example: '''PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== iOS DCR Static Step 2 - SDK Initialization ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionc&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 2 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionc&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== How to obtain the NielsenAppApi.Framework ====&lt;br /&gt;
The Nielsen AppSDK can either be downloaded directly or can be integrated directly within an application through the use of CocoaPods. We recommend using the CocoaPods-based integration whenever possible to ensure you maintain the most recent changes and enhancements to the Nielsen libraries.&lt;br /&gt;
* [[Digital_Measurement_iOS_Artifactory_Guide|Select to obtain CocoaPods implementation guide]]&lt;br /&gt;
* [[Special:Downloads|Select to Download Directly]]&lt;br /&gt;
&lt;br /&gt;
==== Configuring Xcode Development Environment ====&lt;br /&gt;
Starting with SDK version 6.0.0.0, the Nielsen App SDK is compatible with Apple iOS versions 8.0 and above.  In addition, when using the dynamic framework,  all the required frameworks are linked automatically as the are needed.  More details can be found here: https://stackoverflow.com/questions/24902787/dont-we-need-to-link-framework-to-xcode-project-anymore&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': All communications between the SDK and the Census (Collection Facility) use HTTPS.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Download Framework ====&lt;br /&gt;
The first step is to download and copy the [[Special:Downloads|NielsenAppApi.framework]] bundle to the app project directory. (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
==== Add Framework ====&lt;br /&gt;
In the General tab for app configuration add NielsenAppApi.framework in the list of Embedded Binaries.  (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
==== Add Path ====&lt;br /&gt;
Add path to the NielsenAppApi.framework in the Framework Search Paths build setting.  (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
==== Import Framework ====&lt;br /&gt;
Add NielsenAppApi.framework module in the source file of your app:&lt;br /&gt;
&lt;br /&gt;
==== Using Swift ====&lt;br /&gt;
Add the following:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
import NielsenAppApi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using Objective-C ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang =&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
@import NielsenAppApi;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sample SDK Initialization Code ===&lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Swift  = &lt;br /&gt;
Swift 4.0 Example:&lt;br /&gt;
&amp;lt;code&amp;gt;NielsenInit.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
import Foundation&lt;br /&gt;
import NielsenAppApi&lt;br /&gt;
&lt;br /&gt;
class NielsenInit : NSObject {&lt;br /&gt;
    class func createNielsenApi(delegate: NielsenAppApiDelegate) -&amp;gt; NielsenAppApi?{&lt;br /&gt;
        &lt;br /&gt;
        let appInformation:[String: String] = [&lt;br /&gt;
            &amp;quot;appid&amp;quot;: &amp;quot;PDA7D5EE6-B1B8-4123-9277-2A788XXXXXXX&amp;quot;,&lt;br /&gt;
            &amp;quot;sfcode&amp;quot;: &amp;quot;dcr&amp;quot;,&lt;br /&gt;
            &amp;quot;nol_devDebug&amp;quot;: &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
        ]       &lt;br /&gt;
        return NielsenAppApi(appInfo:appInformation, delegate:delegate)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sample code using AVPlayer.&lt;br /&gt;
&amp;lt;code&amp;gt;LandingVC.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
import UIKit&lt;br /&gt;
import NielsenAppApi&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class LandingVC: UIViewController, NielsenAppApiDelegate {&lt;br /&gt;
    &lt;br /&gt;
    var nielsenMain : NielsenAppApi!&lt;br /&gt;
    var sdkMethods : SDKMethods!&lt;br /&gt;
    var data : [String : Any]!&lt;br /&gt;
&lt;br /&gt;
class ViewController: UIViewController, NielsenAppApiDelegate, AVPlayerViewControllerDelegate  {&lt;br /&gt;
&lt;br /&gt;
// your code//    &lt;br /&gt;
&lt;br /&gt;
  override func viewDidLoad() {&lt;br /&gt;
        super.viewDidLoad()&lt;br /&gt;
        //Getting the instance of NielsenApi&lt;br /&gt;
        self.nielsenApi = NielsenInit.createNielsenApi(delegate: self)&lt;br /&gt;
            }&lt;br /&gt;
  }&lt;br /&gt;
    override func viewDidAppear(_ animated: Bool) {      &lt;br /&gt;
        self.data = sdkMethods.loadStaticMaster()     // This is just an example of populating the metadata&lt;br /&gt;
        self.nielsenMain.loadMetadata(self.data)&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Objective C = &lt;br /&gt;
Initialize the Nielsen App object within the viewDidLoad view controller delegate method using initWithAppInfo:delegate:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;If App SDK is initialized using init or new methods, it will ignore the API calls resulting in no measurement. The SDK will not return any errors.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;    &lt;br /&gt;
#import &amp;quot;NielsenInit.h&amp;quot;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenEventTracker.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@implementation NielsenInit&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppApi *)createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate&lt;br /&gt;
{    &lt;br /&gt;
    //Initialising the NielsenEventTracker class by passing app information which returns the instance of NielsenEventTracker.&lt;br /&gt;
    &lt;br /&gt;
    NSDictionary *appInformation = @{ @&amp;quot;appid&amp;quot;: @&amp;quot;PDA7D5EE6-B1B8-4123-9277-2A788XXXXXXX&amp;quot;,&lt;br /&gt;
                            @&amp;quot;appversion&amp;quot;: @&amp;quot;1.0&amp;quot;,&lt;br /&gt;
                            @&amp;quot;sfcode&amp;quot;: @&amp;quot;dcr&amp;quot;,&lt;br /&gt;
                            @&amp;quot;nol_devDebug&amp;quot;: @&amp;quot;DEBUG&amp;quot;, };&lt;br /&gt;
    &lt;br /&gt;
    return [[NielsenAppApi alloc] initWithAppInfo:appInformation delegate:delegate];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following would be the &amp;lt;code&amp;gt;NielsenInit.h&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;Foundation/Foundation.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@class NielsenAppApi;&lt;br /&gt;
@protocol NielsenAppApiDelegate;&lt;br /&gt;
&lt;br /&gt;
@interface NielsenInit : NSObject&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppApi *)createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Sample Code:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
@implementation ViewController&lt;br /&gt;
&lt;br /&gt;
- (void)viewDidLoad {&lt;br /&gt;
    [super viewDidLoad];&lt;br /&gt;
        &lt;br /&gt;
    //Getting the instance of Nielsen SDK&lt;br /&gt;
    nielsenApi = [NielsenInit createNielsenAppApiWithDelegate:nil];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== iOS DCR Static Step 3 - Create/Load DCR Static Metadata Object ===&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisiond&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 3 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisiond&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Configure Metadata ====&lt;br /&gt;
Map the Nielsen keys to variables so that the content metadata is dynamically updated.&lt;br /&gt;
&lt;br /&gt;
The Nielsen reserved keys are:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Key !! Description !! Data Type !! Value !! Required?&lt;br /&gt;
|-&lt;br /&gt;
| type || asset type || fixed || &amp;lt;code&amp;gt;'static'&amp;lt;/code&amp;gt; || Yes&lt;br /&gt;
|-&lt;br /&gt;
| assetid || Unique ID for each article || dynamic || custom &amp;lt;br&amp;gt;(no [[Special Characters]]) || No&lt;br /&gt;
|-&lt;br /&gt;
| section || section of each site (e.g. section value should be first level in page URL: website.com/section). Limit to 25 unique values || dynamic || custom || Yes&lt;br /&gt;
|-&lt;br /&gt;
| segA || custom segment for reporting: Limit to 25 unique values across custom segments (segA + segB + segC) || dynamic || custom || No&lt;br /&gt;
|-&lt;br /&gt;
| segB || custom segment for reporting: Limit to 25 unique values across custom segments (segA + segB + segC) || dynamic || custom || No&lt;br /&gt;
|-&lt;br /&gt;
| segC || custom segment for reporting: Limit to 25 unique values across custom segments (segA + segB + segC) || dynamic || custom || No&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The values passed through the Nielsen keys will determine the breakouts that are seen in reporting. The custom segments (A, B &amp;amp; C) will roll into the sub-brand. To not use custom segments A, B and C, do not pass any value in these keys.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Configure API calls - loadMetadata ====&lt;br /&gt;
Use [[loadMetadata]] to pass 'content' [[Digital Measurement Metadata]]. The CMS data must be passed as a JSON object.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;    loadMetadata(JSONObject jsonMetadata);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Note: The [[loadMetadata]] call must have (&amp;quot;type&amp;quot;: &amp;quot;static&amp;quot;). &amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Call [[loadMetadata]] with JSON metadata as below.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;    new JSONObject()&lt;br /&gt;
        .put(&amp;quot;type&amp;quot;, &amp;quot;static&amp;quot;)&lt;br /&gt;
        .put(&amp;quot;section&amp;quot;, &amp;quot;siteSection&amp;quot;)&lt;br /&gt;
        .put(&amp;quot;assetid&amp;quot;, &amp;quot;vid345-67483&amp;quot;)&lt;br /&gt;
        .put(&amp;quot;segA&amp;quot;, &amp;quot;segmentA&amp;quot;)&lt;br /&gt;
        .put(&amp;quot;segB&amp;quot;, &amp;quot;segmentB&amp;quot;)&lt;br /&gt;
        .put(&amp;quot;segC&amp;quot;,&amp;quot;segmentC&amp;quot;)&lt;br /&gt;
    }&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As soon as this loadMetadata call is made, AppSDK will record a view event and start tracking the section/page time spent (AppSDK 9.1 and above).&lt;br /&gt;
&lt;br /&gt;
==== DCR Static Duration Measurement per Section/Page/Asset ====&lt;br /&gt;
If your Nielsen AppID is enabled for DCR Static duration measurement, a view event will be recorded and a timer will be started for each screen/page. Duration will be measured until a new page is loaded or the app is moved to the background. The event which triggers recognition of page view and timer start is the loadMetadata API call with a metadata object of type 'static'. Once a page is viewed and the timer has started, duration will be measured until a new page has loaded ''with associated loadMetadata call having a different '''section name''' from the previous page''. If a new loadMetadata call is made with the same '''section name''', it will be ignored - no new view will be recorded. If it is desired to have a new view event even though the metadata contains the same '''section name''' (example: single-page apps having several assedIDs but common section name), staticEnd API can be called between page views. For the purposes of this overview, staticend will not be used. See [[DCR_Static_iOS_SDK|this page]] for more information. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Keep Going ===&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisiong&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisiong&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Congratulations, you've successfully integrated the iOS SDK in your app!&lt;br /&gt;
&lt;br /&gt;
You can add static loadMetadata calls for more sections/pages in your app to see what happens when transitioning between sections.&lt;br /&gt;
&lt;br /&gt;
View your application's debug logs and search for the term (AppSDK) to see messages emitted by Nielsen AppSDK.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Next Steps ===&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisioni&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisioni&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now that you've integrated DCR Static for the AppSDK, what's next?&lt;br /&gt;
&lt;br /&gt;
====Going Live====&lt;br /&gt;
&lt;br /&gt;
In addition to the basic steps above, before going live developers need to handle app background/foreground events, make certain privacy disclosures, and allow users to opt out of Nielsen measurement. More details can be found [[DCR_Static_iOS_SDK|here]], along with a more comprehensive reference for implementing DCR Static measurement with AppSDK.&lt;br /&gt;
&lt;br /&gt;
Once the DCR Tracking Code is added, Nielsen will validate the implementation. Following Nielsen testing, developers need to make a few updates to the initialization call to ensure that the app is being measured properly.&lt;br /&gt;
&lt;br /&gt;
#'''App ID''': Ensure that correct  is used during initialization '''PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'''&lt;br /&gt;
#'''Debug Logging''': Disable logging by changing initialization call to use @&amp;quot;nol_devDebug&amp;quot;:@&amp;quot;INFO&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== &amp;amp;rarr; iOS DCR Video ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivision1&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide DCR Video &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivision1&amp;quot;&amp;gt;&lt;br /&gt;
==== iOS DCR Video Introduction ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv2-&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide Intro &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv2-&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Digital Content Ratings (DCR) Video product provides content consumption measurement in client mobile apps and webpages. This measurement includes insight into the total time a user spent watching the tracked content, video player events, and much more.&lt;br /&gt;
This example provides the steps to implement the DCR Video product in a sample iOS app. It includes:&lt;br /&gt;
&lt;br /&gt;
*SDK Initialization&lt;br /&gt;
*DCR Video Metadata: information about the content being tracked&lt;br /&gt;
*DCR Video Events/API calls&lt;br /&gt;
&lt;br /&gt;
By the end of this guide you will have the needed steps to integrate Nielsen's AppSDK in the background of your app.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== iOS DCR Video Step 1 - Obtain AppID ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv3&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 1 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv3&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To begin using the iOS AppSDK, you will need to obtain an Application ID (AppId)&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! !! Item !! Description !! Source&lt;br /&gt;
|-&lt;br /&gt;
|&amp;amp;#9989; || App ID (appid) || Unique ID assigned to the player/site and configured by product || Contact your Nielsen Representative&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The appid is a 37 character unique ID assigned to the player/site and configured by product and is required when creating a new instance of the AppSDK in the app.&lt;br /&gt;
&amp;lt;/br&amp;gt;Example: '''PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== iOS DCR Video Step 2 - SDK Initialization ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionc&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 2 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionc&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== How to obtain the NielsenAppApi.Framework =====&lt;br /&gt;
The Nielsen AppSDK can either be downloaded directly or can be integrated directly within an application through the use of CocoaPods. We recommend using the CocoaPods-based integration whenever possible to ensure you maintain the most recent changes and enhancements to the Nielsen libraries.&lt;br /&gt;
* [[Digital_Measurement_iOS_Artifactory_Guide|Select to obtain CocoaPods implementation guide]]&lt;br /&gt;
* [[Special:Downloads|Select to Download Directly]]&lt;br /&gt;
&lt;br /&gt;
===== Configuring Xcode Development Environment =====&lt;br /&gt;
Starting with SDK version 6.0.0.0, the Nielsen App SDK is compatible with Apple iOS versions 8.0 and above.  In addition, when using the dynamic framework,  all the required frameworks are linked automatically as the are needed.  More details can be found here: https://stackoverflow.com/questions/24902787/dont-we-need-to-link-framework-to-xcode-project-anymore&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': All communications between the SDK and the Census (Collection Facility) use HTTPS.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======= Download Framework =======&lt;br /&gt;
The first step is to download and copy the [[Special:Downloads|NielsenAppApi.framework]] bundle to the app project directory. (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
======= Add Framework =======&lt;br /&gt;
In the General tab for app configuration add NielsenAppApi.framework in the list of Embedded Binaries.  (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
======= Add Path =======&lt;br /&gt;
Add path to the NielsenAppApi.framework in the Framework Search Paths build setting.  (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
======= Import Framework =======&lt;br /&gt;
Add NielsenAppApi.framework module in the source file of your app:&lt;br /&gt;
&lt;br /&gt;
======= Using Swift =======&lt;br /&gt;
Add the following:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
import NielsenAppApi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======= Using Objective-C =======&lt;br /&gt;
&amp;lt;syntaxhighlight lang =&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
@import NielsenAppApi;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======= SDK Initialization =======&lt;br /&gt;
&lt;br /&gt;
The following table contains the list of arguments that can be passed via the AppInfo JSON schema.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter / Argument !! Description !! Source !! Required? !! Example&lt;br /&gt;
|--style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
| appid || Unique Nielsen ID for the application. The ID is a GUID data type. If you did not receive your App ID, let us know and we will provide you. || Nielsen-specified || Yes || PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&lt;br /&gt;
|--style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
| nol_devDebug || Enables Nielsen console logging. Only required for testing &amp;lt;br&amp;gt;&lt;br /&gt;
|| Nielsen-specified || Optional || DEBUG&lt;br /&gt;
|}&lt;br /&gt;
==== Debug flag for development environment ====&lt;br /&gt;
Player application developers / integrators can use Debug flag to check whether an App SDK API call made is successful. To activate the Debug flag,&lt;br /&gt;
Pass the argument &amp;lt;code&amp;gt;@&amp;quot;nol_devDebug&amp;quot;:@&amp;quot;DEBUG&amp;quot;&amp;lt;/code&amp;gt;, in the JSON string . &lt;br /&gt;
&lt;br /&gt;
Once the flag is active, it logs each API call made and the data passed. The log created by this flag is minimal.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': DO NOT activate the Debug flag in a production environment.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Swift Example ===&lt;br /&gt;
==== Sample SDK Initialization Code ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;NielsenInit.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class NielsenInit: NSObject {&lt;br /&gt;
    class func createNielsenAppApi(delegate: NielsenAppApiDelegate) -&amp;gt; NielsenAppApi?{&lt;br /&gt;
    let appInformation:[String: String] = [&lt;br /&gt;
           &amp;quot;appid&amp;quot;: &amp;quot;PE392366B-F2C1-4BC4-AB62-A7DAFDCXXXX&amp;quot;,&lt;br /&gt;
           &amp;quot;nol_devDebug&amp;quot;: &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
        ]&lt;br /&gt;
        return NielsenAppApi(appInfo:appInformation, delegate:delegate)}}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;ViewController.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class ViewController: UIViewController, NielsenAppApiDelegate, AVPictureInPictureControllerDelegate, CLLocationManagerDelegate  {&lt;br /&gt;
&lt;br /&gt;
    let avPlayerViewController = AVPlayerViewController()&lt;br /&gt;
    var avPlayer:AVPlayer?&lt;br /&gt;
    var nielsenAppApi: NielsenAppApi!&lt;br /&gt;
&lt;br /&gt;
  override func viewDidLoad() {&lt;br /&gt;
        super.viewDidLoad()&lt;br /&gt;
        self.nielsenAppApi = NielsenInit.createNielsenAppApi(delegate: self)&lt;br /&gt;
        NSLog(&amp;quot;Nielsen SDK initialized&amp;quot;)&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Objective C ===&lt;br /&gt;
==== Sample SDK Initialization Code ====&lt;br /&gt;
Initialize the Nielsen App object within the viewDidLoad view controller delegate method using initWithAppInfo:delegate:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;If App SDK is initialized using init or new methods, it will ignore the API calls resulting in no measurement. The SDK will not return any errors.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;quot;NlsAppApiFactory.h&amp;quot;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenAppApi.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@implementation NlsAppApiFactory&lt;br /&gt;
+ (NielsenAppApi *)createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
{&lt;br /&gt;
    NSDictionary *appInformation = @{&lt;br /&gt;
                                     @&amp;quot;appid&amp;quot;: &amp;quot;PE392366B-F2C1-4BC4-AB62-A7DAFDC51XXX&amp;quot;,&lt;br /&gt;
                                     @&amp;quot;nol_devDebug&amp;quot;: @&amp;quot;DEBUG&amp;quot;&lt;br /&gt;
                                     };&lt;br /&gt;
    return [[NielsenAppApi alloc] initWithAppInfo:appInformation delegate:delegate];&lt;br /&gt;
}&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following would be the &amp;lt;code&amp;gt;NlsAppApiFactory.h&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;Foundation/Foundation.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@class NielsenAppApi;&lt;br /&gt;
@protocol NielsenAppApiDeligate;&lt;br /&gt;
@interface NlsAppApiFactory : NSObject&lt;br /&gt;
+ (NielsenAppAPI *) createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
@end&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
The following might be in the &amp;lt;code&amp;gt;Viewcontroller.m&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
@implementation ViewController&lt;br /&gt;
&lt;br /&gt;
- (void)viewDidLoad {&lt;br /&gt;
    [super viewDidLoad];&lt;br /&gt;
    &lt;br /&gt;
    //Setting background image&lt;br /&gt;
    UIImage *backgroundImage = [UIImage imageNamed:@&amp;quot;new_ios_bg.png&amp;quot;];&lt;br /&gt;
    UIImageView *backgroundImageView=[[UIImageView alloc]initWithFrame:self.view.frame];&lt;br /&gt;
    backgroundImageView.image=backgroundImage;&lt;br /&gt;
    [self.view insertSubview:backgroundImageView atIndex:0];&lt;br /&gt;
    &lt;br /&gt;
    //Mark: In NielsenInit class we are initialising the Nielsen SDK.&lt;br /&gt;
    &lt;br /&gt;
    //Getting the instance of Nielsen SDK&lt;br /&gt;
    nielsenApi = [NielsenInit createNielsenAppApiWithDelegate:nil];&lt;br /&gt;
}&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== iOS DCR Video Step 3 - Create DCR Video Content Metadata Object ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv5&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 3 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv5&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Configure Metadata =====&lt;br /&gt;
The SDK methods handle 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 Nielsen Key names (e.g. appid, program) 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;br&amp;gt;&lt;br /&gt;
===== Create channelName Metadata =====&lt;br /&gt;
channelName 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;
|--style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
! Key !! Description !!	Values	 !! Required&lt;br /&gt;
|--style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
| channelName	|| Any string representing the channel/stream	|| custom	|| ✓&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== Create Content Metadata =====&lt;br /&gt;
Content metadata should remain constant throughout the entirety of an episode/clip including when ads play.&lt;br /&gt;
&amp;lt;blockquote&amp;gt; program and title metadata values should be passed to SDK as UTF-8 strings. &amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;height: 45em; overflow-y:auto;&amp;quot;&amp;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'''!!'''Provider'''&lt;br /&gt;
|-&lt;br /&gt;
| type || Type of asset ||For Video use: &amp;lt;code&amp;gt;content&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt; For Static or text &amp;lt;code&amp;gt;static&amp;lt;/code&amp;gt; || Yes || Nielsen&lt;br /&gt;
|-style=&amp;quot;background-color:#e9f9fa;&amp;quot;&lt;br /&gt;
| assetid || Unique ID assigned to asset &amp;lt;br&amp;gt; Note: Refrain from using the following special characters [[Special_Characters|(Special Characters)]]. || Examples: &amp;lt;br&amp;gt; &amp;lt;code&amp;gt;BBT345a234 &amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; &amp;lt;code&amp;gt;CBSs5e234F2021&amp;lt;/code&amp;gt;  || Yes || Client &lt;br /&gt;
|-&lt;br /&gt;
| program ||Complete program or movie title &amp;lt;br&amp;gt; (no abbreviations or shorthand) &amp;lt;br&amp;gt; Note: there is a 25 character limit.  ||&amp;lt;code&amp;gt; The Big Bang Theory&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; &amp;lt;code&amp;gt; TheBigBangTheory&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt;&amp;lt;code&amp;gt; The Dark Knight&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt;&amp;lt;code&amp;gt; TheDarkKnight&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; || Yes || Client &lt;br /&gt;
|-style=&amp;quot;background-color:#e9f9fa;&amp;quot;&lt;br /&gt;
| title ||Episode title with season and episode number (40 character limit) &amp;lt;br&amp;gt; (Formats accepted: S01E03, S1E3, S1 E3). || Examples: &amp;lt;br&amp;gt; &amp;lt;code&amp;gt;The Pants Alternative S03E18&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; &amp;lt;code&amp;gt;The Pants Alternative S3E18&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; &amp;lt;code&amp;gt;The Pants Alternative S3 E18&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; Can also accept: &amp;lt;code&amp;gt; S3E18&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; Not Valid: &amp;lt;code&amp;gt; 318 &amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt; 0318 &amp;lt;/code&amp;gt;|| Yes || Client &lt;br /&gt;
|-&lt;br /&gt;
| crossId1 || Gracenote TMS ID (If available) should be passed for all telecasted content for clients using the Gracenote solution for proper matching purposes. &amp;lt;br&amp;gt;Note: The TMS ID will be a 14 character string. Normally leading with 2 alpha characerts ('EP', 'MV', 'SH' or 'SP'), followed by 12 numbers.&lt;br /&gt;
|| The TMS ID will be a 14 character string. &amp;lt;br&amp;gt; Normally being with  'EV,' 'EP', 'SH', 'SP', or 'MV' &amp;lt;br&amp;gt; Followed by 12 numbers after the initial two letter prefix. &amp;lt;br&amp;gt; &amp;lt;br&amp;gt; The Giant Morning Show: &amp;lt;code&amp;gt;SH009311820022&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; The Pants Alternative Episode : &amp;lt;code&amp;gt;EP009311820061&amp;lt;/code&amp;gt; || Optional || Nielsen&lt;br /&gt;
|-style=&amp;quot;background-color:#e9f9fa;&amp;quot;&lt;br /&gt;
| crossId2 || Populated by content distributor to contribute viewing from that distributor to the given content originator. || For a full list of acceptable values, please contact your Nielsen reprentative. || Yes, for distributors || Nielsen&lt;br /&gt;
|-&lt;br /&gt;
| length || Length of content in seconds&amp;lt;br&amp;gt;Note: Integers and decimals are acceptable values are acceptable for the length parameter. || Examples:&lt;br /&gt;
&amp;lt;small&amp;gt;For standard VOD content - &amp;lt;code&amp;gt;300&amp;lt;/code&amp;gt; to represent 5 minutes, &amp;lt;code&amp;gt;1320&amp;lt;/code&amp;gt; to represent 22 minutes, etc.&lt;br /&gt;
&amp;lt;br&amp;gt;If DAI live stream of a discrete program (Live Event/Sporting Event), pass length of content. See example for standard VOD content above.&lt;br /&gt;
&amp;lt;br&amp;gt;If unknown DAI live steam, pass a value of &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;.&amp;lt;/small&amp;gt; &lt;br /&gt;
|| Yes || Client &lt;br /&gt;
|-style=&amp;quot;background-color:#e9f9fa;&amp;quot;&lt;br /&gt;
| airdate ||Original broadcast or release date for the program &amp;lt;br&amp;gt;For USA, date should be EST &amp;lt;br&amp;gt; Outside USA, date should be local time.&amp;lt;br&amp;gt;If not applicable or available, original broadcast or release date for the Program. || Acceptable Formats:&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;YYYY-MM-DDTHH:MI:SS&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;YYYY-MM-DDHH:MI:SS&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;YYYY-MM-DDTHH:MI:SS+xx:xx&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;YYYY-MM-DDTHH:MI:SS-xx:xx&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;YYYYMMDDHH:MI:SS&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;YYYYMMDD HH:MI:SS&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;MM-DD-YYYY&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;MM/DD/YYYY&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;YYYYMMDD&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; || Yes || Client &lt;br /&gt;
|-&lt;br /&gt;
| isfullepisode || Full episode flag to identify differences between long form content. || &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;- full episode, &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt;- non full episode(clip,teaser,promo,etc.)&lt;br /&gt;
&amp;lt;small&amp;gt;Also accept: &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;lf&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;yes&amp;lt;/code&amp;gt;- longform&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;sf&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;no&amp;lt;/code&amp;gt;- shortform&lt;br /&gt;
|| Yes || Nielsen&lt;br /&gt;
|-style=&amp;quot;background-color:#e9f9fa;&amp;quot;&lt;br /&gt;
| adloadtype || &amp;lt;big&amp;gt;&amp;lt;small&amp;gt;Type of ad load: &lt;br /&gt;
&amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; Linear – matches TV ad load&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;2&amp;lt;/code&amp;gt; Dynamic – Dynamic Ad Insertion (DAI)&amp;lt;/small&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
|| &amp;lt;code&amp;gt;2&amp;lt;/code&amp;gt; - DCR measures content with dynamic ads || Yes || Nielsen&lt;br /&gt;
|-&lt;br /&gt;
| segB || One of two custom segment for the clients granular reporting within a brand. || Examples:&amp;lt;br&amp;gt;Genre - &amp;lt;code&amp;gt;horror&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;comedy&amp;lt;/code&amp;gt;, etc.&amp;lt;br&amp;gt;Timeslot - &amp;lt;code&amp;gt;primetime&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;daytime&amp;lt;/code&amp;gt;, etc.&amp;lt;br&amp;gt;News type - &amp;lt;code&amp;gt;breakingnews&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;weather&amp;lt;/code&amp;gt;, etc. || Optional || Client &lt;br /&gt;
|-style=&amp;quot;background-color:#e9f9fa;&amp;quot;&lt;br /&gt;
| segC || One of two custom segment for the clients granular reporting within a brand. || Examples:&amp;lt;br&amp;gt;Genre - &amp;lt;code&amp;gt;horror&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;comedy&amp;lt;/code&amp;gt;, etc.&amp;lt;br&amp;gt;Timeslot - &amp;lt;code&amp;gt;primetime&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;daytime&amp;lt;/code&amp;gt;, etc.&amp;lt;br&amp;gt;News type - &amp;lt;code&amp;gt;breakingnews&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;weather&amp;lt;/code&amp;gt;, etc. || Optional || Client &lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Custom segments (segB and segC) can be used to aggregate video and/or static content within a single Brand to receive more granular reports within a brand.&lt;br /&gt;
&lt;br /&gt;
Examples regarding usage of segments within SDK:&lt;br /&gt;
* All comedy clips and stories for a Brand rolled into a &amp;quot;Comedy&amp;quot; segment&lt;br /&gt;
* genre grouping content by Comedy vs. Drama&lt;br /&gt;
* group related Text + Video content - i.e. for a show that has a lot of - static pages associated with it&lt;br /&gt;
* packaging based on how clients sell inventory&lt;br /&gt;
* grouping related types of content either by genre, category or platform.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Metadata Example =====&lt;br /&gt;
&amp;lt;code&amp;gt;Swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&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;program&amp;quot;: &amp;quot;The Big Bang Theory&amp;quot;,&lt;br /&gt;
    &amp;quot;title&amp;quot;: &amp;quot;The Pants Alternative S03E18&amp;quot;,  //Formats accepted: S01E03, S1E3, S1 E3&lt;br /&gt;
    &amp;quot;crossId1&amp;quot;: &amp;quot;EP009311820061&amp;quot;, //optional&lt;br /&gt;
    &amp;quot;crossId2&amp;quot;: &amp;quot;Content Originator&amp;quot;, //optional&lt;br /&gt;
    &amp;quot;length&amp;quot;: &amp;quot;3600&amp;quot;,&lt;br /&gt;
    &amp;quot;airdate&amp;quot;: &amp;quot;2022-03-21T10:05:00&amp;quot;, &lt;br /&gt;
    &amp;quot;isfullepisode&amp;quot;: &amp;quot;Yes&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;
];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;Objective-C&amp;lt;/code&amp;gt;    &lt;br /&gt;
&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;program&amp;quot;: @ &amp;quot;The Big Bang Theory&amp;quot;,&lt;br /&gt;
    @ &amp;quot;title&amp;quot;: @ &amp;quot;The Pants Alternative S03E18&amp;quot;, //Formats accepted: S01E03, S1E3, S1 E3&lt;br /&gt;
    @ &amp;quot;crossId1&amp;quot;: @ &amp;quot;EP009311820061&amp;quot;, //optional&lt;br /&gt;
    @ &amp;quot;crossId2&amp;quot;: @ &amp;quot;Content Originator&amp;quot;, //optional&lt;br /&gt;
    @ &amp;quot;length&amp;quot;: @ &amp;quot;3600&amp;quot;,&lt;br /&gt;
    @ &amp;quot;airdate&amp;quot;: @ &amp;quot;2022-03-21T10:05:00&amp;quot;,&lt;br /&gt;
    @ &amp;quot;isfullepisode&amp;quot;: @ &amp;quot;y&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;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== iOS DCR Video Step 4 - Basic Set of Events - Sample Playback ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv6&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 4 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv6&amp;quot;&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;
| '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;
| 'playheadPosition'	|| 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: 'PlayheadPosition' 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 '''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 content or Ad playback is interrupted and at the end of each Ad. &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. &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;'''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;
==== Sample Use Case: 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 [[playheadPosition|playheadPosition()]] 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;
|-style=&amp;quot;background-color:#d8f5d7;&amp;quot;&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;
|-style=&amp;quot;background-color:#d8f5d7;&amp;quot;&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;
|- style=&amp;quot;background-color:#d8f5d7;&amp;quot;&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;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Keep Going ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv9&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv9&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Congratulations, you've successfully integrated the iOS SDK in your app for a basic content playback scenario!&lt;br /&gt;
&lt;br /&gt;
You can add more content to see channel-change scenarios or continue to next steps below.&lt;br /&gt;
&lt;br /&gt;
View your application's debug logs and search for the term (AppSDK) to see messages emitted by Nielsen AppSDK during video playback.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Next Steps ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv10&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv10&amp;quot;&amp;gt;&lt;br /&gt;
====Going Live====&lt;br /&gt;
&lt;br /&gt;
In addition to the basic steps above, before going live developers need to handle app background/foreground events, make certain privacy disclosures, handle interruption events (stop, fast-forward, rewind), remove iOS simulator slices, and allow users to opt out of Nielsen measurement. More details can be found [[DCR_Video_iOS_SDK|here]], along with a more comprehensive reference for implementing DCR Video measurement with AppSDK.&lt;br /&gt;
&lt;br /&gt;
Once the DCR Tracking Code is added, Nielsen will validate the implementation. Following Nielsen testing, developers need to make a few updates to the initialization call to ensure that the app is being measured properly.&lt;br /&gt;
&lt;br /&gt;
#'''App ID''': Ensure that correct  is used during initialization '''PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'''&lt;br /&gt;
#'''Debug Logging''': Disable logging by changing initialization call to use @&amp;quot;nol_devDebug&amp;quot;:@&amp;quot;INFO&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== &amp;amp;rarr; iOS DTVR (coming soon) ==&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivision100&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide iOS DTVR &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivision100&amp;quot;&amp;gt;&lt;br /&gt;
==== iOS DTVR Introduction ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv200-&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide Intro &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv200-&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Nielsen DTVR (Digital TV Ratings) product provides content consumption measurement in client mobile apps and webpages. This measurement includes insight into the total time a user spent watching the tracked content, video player events, and much more.&lt;br /&gt;
This example provides the steps to implement the DTVR product in a sample iOS app using Nielsen AppSDK. It includes:&lt;br /&gt;
&lt;br /&gt;
*SDK Initialization&lt;br /&gt;
*DTVR Video Metadata: information about the content being tracked&lt;br /&gt;
*DTVR Video Events/API calls&lt;br /&gt;
*Extracting ID3 tags from the video stream and passing to AppSDK for measurement&lt;br /&gt;
&lt;br /&gt;
By the end of this guide you will have the needed steps to integrate Nielsen's AppSDK in the background of your app for DTVR measurement.&lt;br /&gt;
&lt;br /&gt;
'''NOTE: video streams must have Nielsen ID3 tags embedded in order to be measured using the DTVR product. See the section in this guide &amp;quot;Extracting ID3 Tags&amp;quot; or contact your Nielsen representative for more information.'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== iOS DTVR Step 1 - Obtain AppID ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv300&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 1 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv300&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To begin using the iOS AppSDK, you will need to obtain an Application ID (AppId)&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! !! Item !! Description !! Source&lt;br /&gt;
|-&lt;br /&gt;
|&amp;amp;#9989; || App ID (appid) || Unique ID assigned to the player/site and configured by product || Contact your Nielsen Representative&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The appid is a 37 character unique ID assigned to the player/site and configured by product and is required when creating a new instance of the AppSDK in the app.&lt;br /&gt;
&amp;lt;/br&amp;gt;Example: '''PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== iOS DTVR Step 2 - SDK Initialization ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivision400&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 2 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivision400&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== How to obtain the NielsenAppApi.Framework =====&lt;br /&gt;
The Nielsen AppSDK can either be downloaded directly or can be integrated directly within an application through the use of CocoaPods. We recommend using the CocoaPods-based integration whenever possible to ensure you maintain the most recent changes and enhancements to the Nielsen libraries.&lt;br /&gt;
* [[Digital_Measurement_iOS_Artifactory_Guide|Select to obtain CocoaPods implementation guide]]&lt;br /&gt;
* [[Special:Downloads|Select to Download Directly]]&lt;br /&gt;
&lt;br /&gt;
===== Configuring Xcode Development Environment =====&lt;br /&gt;
Starting with SDK version 6.0.0.0, the Nielsen App SDK is compatible with Apple iOS versions 8.0 and above.  In addition, when using the dynamic framework,  all the required frameworks are linked automatically as the are needed.  More details can be found here: https://stackoverflow.com/questions/24902787/dont-we-need-to-link-framework-to-xcode-project-anymore&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': All communications between the SDK and the Census (Collection Facility) use HTTPS.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======= Download Framework =======&lt;br /&gt;
The first step is to download and copy the [[Special:Downloads|NielsenAppApi.framework]] bundle to the app project directory. (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
======= Add Framework =======&lt;br /&gt;
In the General tab for app configuration add NielsenAppApi.framework in the list of Embedded Binaries.  (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
======= Add Path =======&lt;br /&gt;
Add path to the NielsenAppApi.framework in the Framework Search Paths build setting.  (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
======= Import Framework =======&lt;br /&gt;
Add NielsenAppApi.framework module in the source file of your app:&lt;br /&gt;
&lt;br /&gt;
======= Using Swift =======&lt;br /&gt;
Add the following:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
import NielsenAppApi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======= Using Objective-C =======&lt;br /&gt;
&amp;lt;syntaxhighlight lang =&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
@import NielsenAppApi;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======= SDK Initialization =======&lt;br /&gt;
&lt;br /&gt;
The following table contains the list of arguments that can be passed via the AppInfo JSON schema.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter / Argument !! Description !! Source !! Required? !! Example&lt;br /&gt;
|--style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
| appid || Unique Nielsen ID for the application. The ID is a GUID data type. If you did not receive your App ID, let us know and we will provide you. || Nielsen-specified || Yes || PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&lt;br /&gt;
|--style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
| nol_devDebug || Enables Nielsen console logging. Only required for testing &amp;lt;br&amp;gt;&lt;br /&gt;
|| Nielsen-specified || Optional || DEBUG&lt;br /&gt;
|}&lt;br /&gt;
==== Debug flag for development environment ====&lt;br /&gt;
Player application developers / integrators can use Debug flag to check whether an App SDK API call made is successful. To activate the Debug flag,&lt;br /&gt;
Pass the argument &amp;lt;code&amp;gt;@&amp;quot;nol_devDebug&amp;quot;:@&amp;quot;DEBUG&amp;quot;&amp;lt;/code&amp;gt;, in the JSON string . &lt;br /&gt;
&lt;br /&gt;
Once the flag is active, it logs each API call made and the data passed. The log created by this flag is minimal.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': DO NOT activate the Debug flag in a production environment.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Swift Example ===&lt;br /&gt;
==== Sample SDK Initialization Code ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;NielsenInit.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class NielsenInit: NSObject {&lt;br /&gt;
    class func createNielsenAppApi(delegate: NielsenAppApiDelegate) -&amp;gt; NielsenAppApi?{&lt;br /&gt;
    let appInformation:[String: String] = [&lt;br /&gt;
           &amp;quot;appid&amp;quot;: &amp;quot;PE392366B-F2C1-4BC4-AB62-A7DAFDCXXXX&amp;quot;,&lt;br /&gt;
           &amp;quot;nol_devDebug&amp;quot;: &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
        ]&lt;br /&gt;
        return NielsenAppApi(appInfo:appInformation, delegate:delegate)}}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;ViewController.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class ViewController: UIViewController, NielsenAppApiDelegate, AVPictureInPictureControllerDelegate, CLLocationManagerDelegate  {&lt;br /&gt;
&lt;br /&gt;
    let avPlayerViewController = AVPlayerViewController()&lt;br /&gt;
    var avPlayer:AVPlayer?&lt;br /&gt;
    var nielsenAppApi: NielsenAppApi!&lt;br /&gt;
&lt;br /&gt;
  override func viewDidLoad() {&lt;br /&gt;
        super.viewDidLoad()&lt;br /&gt;
        self.nielsenAppApi = NielsenInit.createNielsenAppApi(delegate: self)&lt;br /&gt;
        NSLog(&amp;quot;Nielsen SDK initialized&amp;quot;)&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Objective C ===&lt;br /&gt;
==== Sample SDK Initialization Code ====&lt;br /&gt;
Initialize the Nielsen App object within the viewDidLoad view controller delegate method using initWithAppInfo:delegate:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;If App SDK is initialized using init or new methods, it will ignore the API calls resulting in no measurement. The SDK will not return any errors.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;quot;NlsAppApiFactory.h&amp;quot;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenAppApi.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@implementation NlsAppApiFactory&lt;br /&gt;
+ (NielsenAppApi *)createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
{&lt;br /&gt;
    NSDictionary *appInformation = @{&lt;br /&gt;
                                     @&amp;quot;appid&amp;quot;: &amp;quot;PE392366B-F2C1-4BC4-AB62-A7DAFDC51XXX&amp;quot;,&lt;br /&gt;
                                     @&amp;quot;nol_devDebug&amp;quot;: @&amp;quot;DEBUG&amp;quot;&lt;br /&gt;
                                     };&lt;br /&gt;
    return [[NielsenAppApi alloc] initWithAppInfo:appInformation delegate:delegate];&lt;br /&gt;
}&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following would be the &amp;lt;code&amp;gt;NlsAppApiFactory.h&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;Foundation/Foundation.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@class NielsenAppApi;&lt;br /&gt;
@protocol NielsenAppApiDeligate;&lt;br /&gt;
@interface NlsAppApiFactory : NSObject&lt;br /&gt;
+ (NielsenAppAPI *) createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
@end&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
The following might be in the &amp;lt;code&amp;gt;Viewcontroller.m&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
@implementation ViewController&lt;br /&gt;
&lt;br /&gt;
- (void)viewDidLoad {&lt;br /&gt;
    [super viewDidLoad];&lt;br /&gt;
    &lt;br /&gt;
    //Setting background image&lt;br /&gt;
    UIImage *backgroundImage = [UIImage imageNamed:@&amp;quot;new_ios_bg.png&amp;quot;];&lt;br /&gt;
    UIImageView *backgroundImageView=[[UIImageView alloc]initWithFrame:self.view.frame];&lt;br /&gt;
    backgroundImageView.image=backgroundImage;&lt;br /&gt;
    [self.view insertSubview:backgroundImageView atIndex:0];&lt;br /&gt;
    &lt;br /&gt;
    //Mark: In NielsenInit class we are initialising the Nielsen SDK.&lt;br /&gt;
    &lt;br /&gt;
    //Getting the instance of Nielsen SDK&lt;br /&gt;
    nielsenApi = [NielsenInit createNielsenAppApiWithDelegate:nil];&lt;br /&gt;
}&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== iOS DTVR Step 3 - Create DTVR Content Metadata Object ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv500&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 3 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv500&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Configure Metadata =====&lt;br /&gt;
Content metadata should remain constant throughout the completion of an episode or live stream.&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 for DTVR      || ✓&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
- (NSDictionary *)loadChannelInfo&lt;br /&gt;
{&lt;br /&gt;
    //Loading Channel Info.    &lt;br /&gt;
    NSString *strUrl = self.url.absoluteString;  &lt;br /&gt;
    NSDictionary *channel = @{  @&amp;quot;channelName&amp;quot; : @&amp;quot;TheGreatBigMovie&amp;quot;: strUrl };   &lt;br /&gt;
    return channel;&lt;br /&gt;
}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objectivec&amp;quot;&amp;gt;    &lt;br /&gt;
- (NSDictionary *)loadDtvr{&lt;br /&gt;
    &lt;br /&gt;
    //Loading DTVR data  &lt;br /&gt;
    NSDictionary *dtvr = @{ @&amp;quot;adModel&amp;quot;:@&amp;quot;1&amp;quot; ,  &lt;br /&gt;
                            @&amp;quot;type&amp;quot;:@&amp;quot;content&amp;quot;,};  &lt;br /&gt;
    return dtvr;&lt;br /&gt;
}&lt;br /&gt;
    &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== iOS DTVR Step 4 - Basic Set of Events - Sample Playback ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv600&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 4 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv600&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== SDK Events/APIs =====&lt;br /&gt;
&amp;lt;!--[[File:appsdkTimeline-DTVR-V2.png|icon]]--&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;
&lt;br /&gt;
===== Configure API calls - loadMetadata =====&lt;br /&gt;
Use &amp;lt;code&amp;gt;loadMetadata&amp;lt;/code&amp;gt; to pass the metadata object created above. &lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Objective C = &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;[nielsenApi loadMetadata:(dtvr)];&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Swift = &amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;self.nielsenAppApi?.loadMetadata(dtvr)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Configure API calls - sendID3 =====&lt;br /&gt;
[[sendID3]] API is a Nielsen AppSDK receiver for timed metadata events (ID3 tags) provided through iOS’s NSNotificationCenter notification system. This API filters out Nielsen-specific ID3 tags from the system and uses them to create duration data. These ID3 tags are used by Nielsen SDK for DTVR measurement, and the stream that is played must contain ID3 tags and have these tags extracted and passed to SDK using the below procedure in order for DTVR measurement to occur. &lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Objective C = &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;[nielsenApi sendID3:extraString];&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Swift = &amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt; [nielsenApi sendID3:extraString];&amp;lt;/syntaxhighlight&amp;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;
Refer to [[iOS SDK API Reference#Retrieving ID3 Tags|Retrieving ID3 Tags]] section to know more details.&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;
As Apple has deprecated the use of [https://developer.apple.com/documentation/avfoundation/avplayeritem/1389602-timedmetadata?language=objc timedMetadata], we now recommend using [https://developer.apple.com/documentation/avfoundation/avplayeritemmetadataoutput?language=objc AVPlayerItemMetadataOutput] for extracting ID3 tags from the iOS Native Player.&lt;br /&gt;
&lt;br /&gt;
If any other player apart from the iOS native player is used, check and ensure that the player has the capability to extract metadata such as 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;
|Swift = &amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt; &lt;br /&gt;
        //First, ensure your class conforms to the AVPlayerItemMetadataOutputPushDelegate protocol.&lt;br /&gt;
           class YourClass: AVPlayerItemMetadataOutputPushDelegate { &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;
       // Then create an instance of AVPlayerItemMetadataOutput and add it to the player item&lt;br /&gt;
          let metadataOutput = AVPlayerItemMetadataOutput(identifiers: nil)&lt;br /&gt;
           playerItem.add(metadataOutput)&lt;br /&gt;
 &lt;br /&gt;
       // and set the delegate and a dispatch queue&lt;br /&gt;
           metadataOutput.setDelegate(self, queue: DispatchQueue.main)&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;
        // After that below callback function of AVPlayerItemMetadataOutputPushDelegate &lt;br /&gt;
        // protocol will be triggered whenever ID3 tag is received from stream. &lt;br /&gt;
          func metadataOutput(_ output: AVPlayerItemMetadataOutput, didOutputTimedMetadataGroups groups: [AVTimedMetadataGroup], from track: AVPlayerItemTrack?) {&lt;br /&gt;
    for group in groups {&lt;br /&gt;
        for item in group.items {&lt;br /&gt;
            // Handle the metadata item&lt;br /&gt;
            handleTimedMetadata(metadataItem: item)&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;
          // Then further metadata item can be handled like below &lt;br /&gt;
          func handleTimedMetadata(metadataItem: AVMetadataItem) {&lt;br /&gt;
    guard let key = metadataItem.key as? String,&lt;br /&gt;
          let extraString = metadataItem.extraAttributes?[AVMetadataExtraAttributeInfoKey] as? String else {&lt;br /&gt;
        return&lt;br /&gt;
    }&lt;br /&gt;
    // If the extra string(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.hasPrefix(&amp;quot;www.nielsen.com&amp;quot;) {&lt;br /&gt;
        DispatchQueue.global(qos: .default).async {&lt;br /&gt;
            self.nielsenApi?.sendID3(extraString)&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&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;
        //First, ensure your class conforms to the AVPlayerItemMetadataOutputPushDelegate protocol.&lt;br /&gt;
          @interface YourClass : NSObject &amp;lt;AVPlayerItemMetadataOutputPushDelegate&amp;gt; &lt;br /&gt;
&lt;br /&gt;
          @end&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;
        // Then create an instance of AVPlayerItemMetadataOutput and add it to the player item&lt;br /&gt;
          AVPlayerItemMetadataOutput *metadataOutput = [[AVPlayerItemMetadataOutput alloc] initWithIdentifiers:nil];&lt;br /&gt;
          [playerItem addOutput:metadataOutput];&lt;br /&gt;
&lt;br /&gt;
        // and set the delegate and a dispatch queue&lt;br /&gt;
          [metadataOutput setDelegate:self queue:dispatch_get_main_queue()];&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;
        // After that below callback function of AVPlayerItemMetadataOutputPushDelegate &lt;br /&gt;
        // protocol will be triggered whenever ID3 tag is received from stream.&lt;br /&gt;
           - (void)metadataOutput:(AVPlayerItemMetadataOutput *)output didOutputTimedMetadataGroups:(NSArray&amp;lt;AVTimedMetadataGroup *&amp;gt; *)groups fromPlayerItemTrack:(AVPlayerItemTrack *)track {&lt;br /&gt;
    for (AVTimedMetadataGroup *group in groups) {&lt;br /&gt;
        for (AVMetadataItem *item in group.items) {&lt;br /&gt;
            // Handle the metadata item&lt;br /&gt;
            [self handleTimedMetadata:item];&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;
        // Then further metadata item can be handled like below &lt;br /&gt;
          - (void)handleTimedMetadata:(AVMetadataItem *)item {&lt;br /&gt;
    NSString *key = (NSString *)item.key;&lt;br /&gt;
    NSString *extraString = item.extraAttributes[AVMetadataExtraAttributeInfoKey];&lt;br /&gt;
    // If the key is &amp;quot;PRIV&amp;quot; and the extra string starts with &amp;quot;www.nielsen.com&amp;quot;, send it to the Nielsen API&lt;br /&gt;
    if ([key isEqualToString:@&amp;quot;PRIV&amp;quot;] &amp;amp;&amp;amp; [extraString hasPrefix:@&amp;quot;www.nielsen.com&amp;quot;]) {&lt;br /&gt;
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{&lt;br /&gt;
            [self.nielsenApi sendID3:extraString];&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;
===== 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. &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 loadMetadata and sendID3 events to occur.&lt;br /&gt;
# '''Processing state''' – The SDK instance is processing playing information. For DTVR, the &amp;lt;code&amp;gt;'''loadMetadata''' &amp;lt;/code&amp;gt; call moves the SDK instance into this state. In this state, the SDK instance will be able to process sendID3 calls and measure content.&lt;br /&gt;
# '''Disabled state''' – The SDK instance is disabled.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Keep Going ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv900&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv900&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Congratulations, you've successfully integrated the iOS SDK in your app for a basic content playback scenario!&lt;br /&gt;
&lt;br /&gt;
You can add more content to see channel-change scenarios or continue to next steps below.&lt;br /&gt;
&lt;br /&gt;
View your application's debug logs and search for the term (AppSDK) to see messages emitted by Nielsen AppSDK during video playback.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Next Steps ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv1000&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv1000&amp;quot;&amp;gt;&lt;br /&gt;
====Going Live====&lt;br /&gt;
&lt;br /&gt;
In addition to the basic steps above, before going live developers need to handle app background/foreground events, make certain privacy disclosures, handle interruption events (stop, fast-forward, rewind), remove iOS simulator slices, and allow users to opt out of Nielsen measurement. More details can be found [[DTVR_iOS_SDK|here]], along with a more comprehensive reference for implementing DTVR measurement with AppSDK.&lt;br /&gt;
&lt;br /&gt;
Once the DTVR Tracking Code is added, Nielsen will validate the implementation. Following Nielsen testing, developers need to make a few updates to the initialization call to ensure that the app is being measured properly.&lt;br /&gt;
&lt;br /&gt;
#'''App ID''': Ensure that correct  is used during initialization '''PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'''&lt;br /&gt;
#'''Debug Logging''': Disable logging by changing initialization call to use @&amp;quot;nol_devDebug&amp;quot;:@&amp;quot;INFO&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;/div&gt;</summary>
		<author><name>NickParrucci</name></author>
	</entry>
	<entry>
		<id>https://nielsentest.mywikis.net/w/index.php?title=iOS_Step_By_Step&amp;diff=6464</id>
		<title>iOS Step By Step</title>
		<link rel="alternate" type="text/html" href="https://nielsentest.mywikis.net/w/index.php?title=iOS_Step_By_Step&amp;diff=6464"/>
		<updated>2023-07-27T13:24:32Z</updated>

		<summary type="html">&lt;p&gt;NickParrucci: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
__NOTOC__&lt;br /&gt;
&lt;br /&gt;
Provided below are step-by-step quick start guides for implementing Nielsen iOS SDK for DCR Static, DCR Video, and DTVR products. Click each section to get started. &lt;br /&gt;
&lt;br /&gt;
== &amp;amp;rarr; iOS DCR Static ==&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivision&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide DCR Static &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivision&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== iOS DCR Static Introduction ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisiona-&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide Intro &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisiona-&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Digital Content Ratings (DCR) Static product provides content consumption measurement in client mobile apps and webpages. This measurement includes insight into the total time a user spent on a webpage, how they navigated through the page via links, and many other data points.&lt;br /&gt;
This tutorial provides the steps to implement the DCR Static product in a sample iOS app. It includes:&lt;br /&gt;
&lt;br /&gt;
*SDK Initialization Call&lt;br /&gt;
*DCR Static Metadata: information about the sections being tracked&lt;br /&gt;
&lt;br /&gt;
By the end of this guide you will have the needed steps to integrate Nielsen's AppSDK in the background of your app.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== iOS DCR Static Step 1 - Obtain AppID ===&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisiona1&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 1 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisiona1&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To begin using the iOS SDK (AppSDK) you will need to obtain an Application ID (AppId)&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! !! Item !! Description !! Source&lt;br /&gt;
|-&lt;br /&gt;
|&amp;amp;#9989; || App ID (appid) || Unique ID assigned to the player/site and configured by product || Contact your Nielsen TAM&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The appid is a 37 character unique ID assigned to the player/site and configured by product and is required when creating a new instance of the AppSDK in the app.&lt;br /&gt;
&amp;lt;/br&amp;gt;Example: '''PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== iOS DCR Static Step 2 - SDK Initialization ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionc&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 2 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionc&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== How to obtain the NielsenAppApi.Framework ====&lt;br /&gt;
The Nielsen AppSDK can either be downloaded directly or can be integrated directly within an application through the use of CocoaPods. We recommend using the CocoaPods-based integration whenever possible to ensure you maintain the most recent changes and enhancements to the Nielsen libraries.&lt;br /&gt;
* [[Digital_Measurement_iOS_Artifactory_Guide|Select to obtain CocoaPods implementation guide]]&lt;br /&gt;
* [[Special:Downloads|Select to Download Directly]]&lt;br /&gt;
&lt;br /&gt;
==== Configuring Xcode Development Environment ====&lt;br /&gt;
Starting with SDK version 6.0.0.0, the Nielsen App SDK is compatible with Apple iOS versions 8.0 and above.  In addition, when using the dynamic framework,  all the required frameworks are linked automatically as the are needed.  More details can be found here: https://stackoverflow.com/questions/24902787/dont-we-need-to-link-framework-to-xcode-project-anymore&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': All communications between the SDK and the Census (Collection Facility) use HTTPS.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Download Framework ====&lt;br /&gt;
The first step is to download and copy the [[Special:Downloads|NielsenAppApi.framework]] bundle to the app project directory. (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
==== Add Framework ====&lt;br /&gt;
In the General tab for app configuration add NielsenAppApi.framework in the list of Embedded Binaries.  (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
==== Add Path ====&lt;br /&gt;
Add path to the NielsenAppApi.framework in the Framework Search Paths build setting.  (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
==== Import Framework ====&lt;br /&gt;
Add NielsenAppApi.framework module in the source file of your app:&lt;br /&gt;
&lt;br /&gt;
==== Using Swift ====&lt;br /&gt;
Add the following:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
import NielsenAppApi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using Objective-C ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang =&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
@import NielsenAppApi;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sample SDK Initialization Code ===&lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Swift  = &lt;br /&gt;
Swift 4.0 Example:&lt;br /&gt;
&amp;lt;code&amp;gt;NielsenInit.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
import Foundation&lt;br /&gt;
import NielsenAppApi&lt;br /&gt;
&lt;br /&gt;
class NielsenInit : NSObject {&lt;br /&gt;
    class func createNielsenApi(delegate: NielsenAppApiDelegate) -&amp;gt; NielsenAppApi?{&lt;br /&gt;
        &lt;br /&gt;
        let appInformation:[String: String] = [&lt;br /&gt;
            &amp;quot;appid&amp;quot;: &amp;quot;PDA7D5EE6-B1B8-4123-9277-2A788XXXXXXX&amp;quot;,&lt;br /&gt;
            &amp;quot;sfcode&amp;quot;: &amp;quot;dcr&amp;quot;,&lt;br /&gt;
            &amp;quot;nol_devDebug&amp;quot;: &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
        ]       &lt;br /&gt;
        return NielsenAppApi(appInfo:appInformation, delegate:delegate)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sample code using AVPlayer.&lt;br /&gt;
&amp;lt;code&amp;gt;LandingVC.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
import UIKit&lt;br /&gt;
import NielsenAppApi&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class LandingVC: UIViewController, NielsenAppApiDelegate {&lt;br /&gt;
    &lt;br /&gt;
    var nielsenMain : NielsenAppApi!&lt;br /&gt;
    var sdkMethods : SDKMethods!&lt;br /&gt;
    var data : [String : Any]!&lt;br /&gt;
&lt;br /&gt;
class ViewController: UIViewController, NielsenAppApiDelegate, AVPlayerViewControllerDelegate  {&lt;br /&gt;
&lt;br /&gt;
// your code//    &lt;br /&gt;
&lt;br /&gt;
  override func viewDidLoad() {&lt;br /&gt;
        super.viewDidLoad()&lt;br /&gt;
        //Getting the instance of NielsenApi&lt;br /&gt;
        self.nielsenApi = NielsenInit.createNielsenApi(delegate: self)&lt;br /&gt;
            }&lt;br /&gt;
  }&lt;br /&gt;
    override func viewDidAppear(_ animated: Bool) {      &lt;br /&gt;
        self.data = sdkMethods.loadStaticMaster()     // This is just an example of populating the metadata&lt;br /&gt;
        self.nielsenMain.loadMetadata(self.data)&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Objective C = &lt;br /&gt;
Initialize the Nielsen App object within the viewDidLoad view controller delegate method using initWithAppInfo:delegate:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;If App SDK is initialized using init or new methods, it will ignore the API calls resulting in no measurement. The SDK will not return any errors.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;    &lt;br /&gt;
#import &amp;quot;NielsenInit.h&amp;quot;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenEventTracker.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@implementation NielsenInit&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppApi *)createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate&lt;br /&gt;
{    &lt;br /&gt;
    //Initialising the NielsenEventTracker class by passing app information which returns the instance of NielsenEventTracker.&lt;br /&gt;
    &lt;br /&gt;
    NSDictionary *appInformation = @{ @&amp;quot;appid&amp;quot;: @&amp;quot;PDA7D5EE6-B1B8-4123-9277-2A788XXXXXXX&amp;quot;,&lt;br /&gt;
                            @&amp;quot;appversion&amp;quot;: @&amp;quot;1.0&amp;quot;,&lt;br /&gt;
                            @&amp;quot;sfcode&amp;quot;: @&amp;quot;dcr&amp;quot;,&lt;br /&gt;
                            @&amp;quot;nol_devDebug&amp;quot;: @&amp;quot;DEBUG&amp;quot;, };&lt;br /&gt;
    &lt;br /&gt;
    return [[NielsenAppApi alloc] initWithAppInfo:appInformation delegate:delegate];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following would be the &amp;lt;code&amp;gt;NielsenInit.h&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;Foundation/Foundation.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@class NielsenAppApi;&lt;br /&gt;
@protocol NielsenAppApiDelegate;&lt;br /&gt;
&lt;br /&gt;
@interface NielsenInit : NSObject&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppApi *)createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Sample Code:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
@implementation ViewController&lt;br /&gt;
&lt;br /&gt;
- (void)viewDidLoad {&lt;br /&gt;
    [super viewDidLoad];&lt;br /&gt;
        &lt;br /&gt;
    //Getting the instance of Nielsen SDK&lt;br /&gt;
    nielsenApi = [NielsenInit createNielsenAppApiWithDelegate:nil];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== iOS DCR Static Step 3 - Create/Load DCR Static Metadata Object ===&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisiond&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 3 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisiond&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Configure Metadata ====&lt;br /&gt;
Map the Nielsen keys to variables so that the content metadata is dynamically updated.&lt;br /&gt;
&lt;br /&gt;
The Nielsen reserved keys are:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Key !! Description !! Data Type !! Value !! Required?&lt;br /&gt;
|-&lt;br /&gt;
| type || asset type || fixed || &amp;lt;code&amp;gt;'static'&amp;lt;/code&amp;gt; || Yes&lt;br /&gt;
|-&lt;br /&gt;
| assetid || Unique ID for each article || dynamic || custom &amp;lt;br&amp;gt;(no [[Special Characters]]) || No&lt;br /&gt;
|-&lt;br /&gt;
| section || section of each site (e.g. section value should be first level in page URL: website.com/section). Limit to 25 unique values || dynamic || custom || Yes&lt;br /&gt;
|-&lt;br /&gt;
| segA || custom segment for reporting: Limit to 25 unique values across custom segments (segA + segB + segC) || dynamic || custom || No&lt;br /&gt;
|-&lt;br /&gt;
| segB || custom segment for reporting: Limit to 25 unique values across custom segments (segA + segB + segC) || dynamic || custom || No&lt;br /&gt;
|-&lt;br /&gt;
| segC || custom segment for reporting: Limit to 25 unique values across custom segments (segA + segB + segC) || dynamic || custom || No&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The values passed through the Nielsen keys will determine the breakouts that are seen in reporting. The custom segments (A, B &amp;amp; C) will roll into the sub-brand. To not use custom segments A, B and C, do not pass any value in these keys.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Configure API calls - loadMetadata ====&lt;br /&gt;
Use [[loadMetadata]] to pass 'content' [[Digital Measurement Metadata]]. The CMS data must be passed as a JSON object.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;    loadMetadata(JSONObject jsonMetadata);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Note: The [[loadMetadata]] call must have (&amp;quot;type&amp;quot;: &amp;quot;static&amp;quot;). &amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Call [[loadMetadata]] with JSON metadata as below.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;    new JSONObject()&lt;br /&gt;
        .put(&amp;quot;type&amp;quot;, &amp;quot;static&amp;quot;)&lt;br /&gt;
        .put(&amp;quot;section&amp;quot;, &amp;quot;siteSection&amp;quot;)&lt;br /&gt;
        .put(&amp;quot;assetid&amp;quot;, &amp;quot;vid345-67483&amp;quot;)&lt;br /&gt;
        .put(&amp;quot;segA&amp;quot;, &amp;quot;segmentA&amp;quot;)&lt;br /&gt;
        .put(&amp;quot;segB&amp;quot;, &amp;quot;segmentB&amp;quot;)&lt;br /&gt;
        .put(&amp;quot;segC&amp;quot;,&amp;quot;segmentC&amp;quot;)&lt;br /&gt;
    }&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As soon as this loadMetadata call is made, AppSDK will record a view event and start tracking the section/page time spent (AppSDK 9.1 and above).&lt;br /&gt;
&lt;br /&gt;
==== DCR Static Duration Measurement per Section/Page/Asset ====&lt;br /&gt;
If your Nielsen AppID is enabled for DCR Static duration measurement, a view event will be recorded and a timer will be started for each screen/page. Duration will be measured until a new page is loaded or the app is moved to the background. The event which triggers recognition of page view and timer start is the loadMetadata API call with a metadata object of type 'static'. Once a page is viewed and the timer has started, duration will be measured until a new page has loaded ''with associated loadMetadata call having a different '''section name''' from the previous page''. If a new loadMetadata call is made with the same '''section name''', it will be ignored - no new view will be recorded. If it is desired to have a new view event even though the metadata contains the same '''section name''' (example: single-page apps having several assedIDs but common section name), staticEnd API can be called between page views. For the purposes of this overview, staticend will not be used. See [[DCR_Static_iOS_SDK|this page]] for more information. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Keep Going ===&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisiong&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisiong&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Congratulations, you've successfully integrated the iOS SDK in your app!&lt;br /&gt;
&lt;br /&gt;
You can add static loadMetadata calls for more sections/pages in your app to see what happens when transitioning between sections.&lt;br /&gt;
&lt;br /&gt;
View your application's debug logs and search for the term (AppSDK) to see messages emitted by Nielsen AppSDK.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Next Steps ===&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisioni&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisioni&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now that you've integrated DCR Static for the AppSDK, what's next?&lt;br /&gt;
&lt;br /&gt;
====Going Live====&lt;br /&gt;
&lt;br /&gt;
In addition to the basic steps above, before going live developers need to handle app background/foreground events, make certain privacy disclosures, and allow users to opt out of Nielsen measurement. More details can be found [[DCR_Static_iOS_SDK|here]], along with a more comprehensive reference for implementing DCR Static measurement with AppSDK.&lt;br /&gt;
&lt;br /&gt;
Once the DCR Tracking Code is added, Nielsen will validate the implementation. Following Nielsen testing, developers need to make a few updates to the initialization call to ensure that the app is being measured properly.&lt;br /&gt;
&lt;br /&gt;
#'''App ID''': Ensure that correct  is used during initialization '''PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'''&lt;br /&gt;
#'''Debug Logging''': Disable logging by changing initialization call to use @&amp;quot;nol_devDebug&amp;quot;:@&amp;quot;INFO&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== &amp;amp;rarr; iOS DCR Video ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivision1&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide DCR Video &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivision1&amp;quot;&amp;gt;&lt;br /&gt;
==== iOS DCR Video Introduction ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv2-&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide Intro &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv2-&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Digital Content Ratings (DCR) Video product provides content consumption measurement in client mobile apps and webpages. This measurement includes insight into the total time a user spent watching the tracked content, video player events, and much more.&lt;br /&gt;
This example provides the steps to implement the DCR Video product in a sample iOS app. It includes:&lt;br /&gt;
&lt;br /&gt;
*SDK Initialization&lt;br /&gt;
*DCR Video Metadata: information about the content being tracked&lt;br /&gt;
*DCR Video Events/API calls&lt;br /&gt;
&lt;br /&gt;
By the end of this guide you will have the needed steps to integrate Nielsen's AppSDK in the background of your app.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== iOS DCR Video Step 1 - Obtain AppID ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv3&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 1 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv3&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To begin using the iOS AppSDK, you will need to obtain an Application ID (AppId)&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! !! Item !! Description !! Source&lt;br /&gt;
|-&lt;br /&gt;
|&amp;amp;#9989; || App ID (appid) || Unique ID assigned to the player/site and configured by product || Contact your Nielsen Representative&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The appid is a 37 character unique ID assigned to the player/site and configured by product and is required when creating a new instance of the AppSDK in the app.&lt;br /&gt;
&amp;lt;/br&amp;gt;Example: '''PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== iOS DCR Video Step 2 - SDK Initialization ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionc&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 2 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionc&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== How to obtain the NielsenAppApi.Framework =====&lt;br /&gt;
The Nielsen AppSDK can either be downloaded directly or can be integrated directly within an application through the use of CocoaPods. We recommend using the CocoaPods-based integration whenever possible to ensure you maintain the most recent changes and enhancements to the Nielsen libraries.&lt;br /&gt;
* [[Digital_Measurement_iOS_Artifactory_Guide|Select to obtain CocoaPods implementation guide]]&lt;br /&gt;
* [[Special:Downloads|Select to Download Directly]]&lt;br /&gt;
&lt;br /&gt;
===== Configuring Xcode Development Environment =====&lt;br /&gt;
Starting with SDK version 6.0.0.0, the Nielsen App SDK is compatible with Apple iOS versions 8.0 and above.  In addition, when using the dynamic framework,  all the required frameworks are linked automatically as the are needed.  More details can be found here: https://stackoverflow.com/questions/24902787/dont-we-need-to-link-framework-to-xcode-project-anymore&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': All communications between the SDK and the Census (Collection Facility) use HTTPS.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======= Download Framework =======&lt;br /&gt;
The first step is to download and copy the [[Special:Downloads|NielsenAppApi.framework]] bundle to the app project directory. (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
======= Add Framework =======&lt;br /&gt;
In the General tab for app configuration add NielsenAppApi.framework in the list of Embedded Binaries.  (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
======= Add Path =======&lt;br /&gt;
Add path to the NielsenAppApi.framework in the Framework Search Paths build setting.  (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
======= Import Framework =======&lt;br /&gt;
Add NielsenAppApi.framework module in the source file of your app:&lt;br /&gt;
&lt;br /&gt;
======= Using Swift =======&lt;br /&gt;
Add the following:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
import NielsenAppApi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======= Using Objective-C =======&lt;br /&gt;
&amp;lt;syntaxhighlight lang =&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
@import NielsenAppApi;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======= SDK Initialization =======&lt;br /&gt;
&lt;br /&gt;
The following table contains the list of arguments that can be passed via the AppInfo JSON schema.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter / Argument !! Description !! Source !! Required? !! Example&lt;br /&gt;
|--style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
| appid || Unique Nielsen ID for the application. The ID is a GUID data type. If you did not receive your App ID, let us know and we will provide you. || Nielsen-specified || Yes || PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&lt;br /&gt;
|--style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
| nol_devDebug || Enables Nielsen console logging. Only required for testing &amp;lt;br&amp;gt;&lt;br /&gt;
|| Nielsen-specified || Optional || DEBUG&lt;br /&gt;
|}&lt;br /&gt;
==== Debug flag for development environment ====&lt;br /&gt;
Player application developers / integrators can use Debug flag to check whether an App SDK API call made is successful. To activate the Debug flag,&lt;br /&gt;
Pass the argument &amp;lt;code&amp;gt;@&amp;quot;nol_devDebug&amp;quot;:@&amp;quot;DEBUG&amp;quot;&amp;lt;/code&amp;gt;, in the JSON string . &lt;br /&gt;
&lt;br /&gt;
Once the flag is active, it logs each API call made and the data passed. The log created by this flag is minimal.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': DO NOT activate the Debug flag in a production environment.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Swift Example ===&lt;br /&gt;
==== Sample SDK Initialization Code ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;NielsenInit.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class NielsenInit: NSObject {&lt;br /&gt;
    class func createNielsenAppApi(delegate: NielsenAppApiDelegate) -&amp;gt; NielsenAppApi?{&lt;br /&gt;
    let appInformation:[String: String] = [&lt;br /&gt;
           &amp;quot;appid&amp;quot;: &amp;quot;PE392366B-F2C1-4BC4-AB62-A7DAFDCXXXX&amp;quot;,&lt;br /&gt;
           &amp;quot;nol_devDebug&amp;quot;: &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
        ]&lt;br /&gt;
        return NielsenAppApi(appInfo:appInformation, delegate:delegate)}}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;ViewController.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class ViewController: UIViewController, NielsenAppApiDelegate, AVPictureInPictureControllerDelegate, CLLocationManagerDelegate  {&lt;br /&gt;
&lt;br /&gt;
    let avPlayerViewController = AVPlayerViewController()&lt;br /&gt;
    var avPlayer:AVPlayer?&lt;br /&gt;
    var nielsenAppApi: NielsenAppApi!&lt;br /&gt;
&lt;br /&gt;
  override func viewDidLoad() {&lt;br /&gt;
        super.viewDidLoad()&lt;br /&gt;
        self.nielsenAppApi = NielsenInit.createNielsenAppApi(delegate: self)&lt;br /&gt;
        NSLog(&amp;quot;Nielsen SDK initialized&amp;quot;)&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Objective C ===&lt;br /&gt;
==== Sample SDK Initialization Code ====&lt;br /&gt;
Initialize the Nielsen App object within the viewDidLoad view controller delegate method using initWithAppInfo:delegate:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;If App SDK is initialized using init or new methods, it will ignore the API calls resulting in no measurement. The SDK will not return any errors.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;quot;NlsAppApiFactory.h&amp;quot;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenAppApi.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@implementation NlsAppApiFactory&lt;br /&gt;
+ (NielsenAppApi *)createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
{&lt;br /&gt;
    NSDictionary *appInformation = @{&lt;br /&gt;
                                     @&amp;quot;appid&amp;quot;: &amp;quot;PE392366B-F2C1-4BC4-AB62-A7DAFDC51XXX&amp;quot;,&lt;br /&gt;
                                     @&amp;quot;nol_devDebug&amp;quot;: @&amp;quot;DEBUG&amp;quot;&lt;br /&gt;
                                     };&lt;br /&gt;
    return [[NielsenAppApi alloc] initWithAppInfo:appInformation delegate:delegate];&lt;br /&gt;
}&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following would be the &amp;lt;code&amp;gt;NlsAppApiFactory.h&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;Foundation/Foundation.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@class NielsenAppApi;&lt;br /&gt;
@protocol NielsenAppApiDeligate;&lt;br /&gt;
@interface NlsAppApiFactory : NSObject&lt;br /&gt;
+ (NielsenAppAPI *) createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
@end&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
The following might be in the &amp;lt;code&amp;gt;Viewcontroller.m&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
@implementation ViewController&lt;br /&gt;
&lt;br /&gt;
- (void)viewDidLoad {&lt;br /&gt;
    [super viewDidLoad];&lt;br /&gt;
    &lt;br /&gt;
    //Setting background image&lt;br /&gt;
    UIImage *backgroundImage = [UIImage imageNamed:@&amp;quot;new_ios_bg.png&amp;quot;];&lt;br /&gt;
    UIImageView *backgroundImageView=[[UIImageView alloc]initWithFrame:self.view.frame];&lt;br /&gt;
    backgroundImageView.image=backgroundImage;&lt;br /&gt;
    [self.view insertSubview:backgroundImageView atIndex:0];&lt;br /&gt;
    &lt;br /&gt;
    //Mark: In NielsenInit class we are initialising the Nielsen SDK.&lt;br /&gt;
    &lt;br /&gt;
    //Getting the instance of Nielsen SDK&lt;br /&gt;
    nielsenApi = [NielsenInit createNielsenAppApiWithDelegate:nil];&lt;br /&gt;
}&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== iOS DCR Video Step 3 - Create DCR Video Content Metadata Object ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv5&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 3 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv5&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Configure Metadata =====&lt;br /&gt;
The SDK methods handle 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 Nielsen Key names (e.g. appid, program) 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;br&amp;gt;&lt;br /&gt;
===== Create channelName Metadata =====&lt;br /&gt;
channelName 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;
|--style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
! Key !! Description !!	Values	 !! Required&lt;br /&gt;
|--style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
| channelName	|| Any string representing the channel/stream	|| custom	|| ✓&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== Create Content Metadata =====&lt;br /&gt;
Content metadata should remain constant throughout the entirety of an episode/clip including when ads play.&lt;br /&gt;
&amp;lt;blockquote&amp;gt; program and title metadata values should be passed to SDK as UTF-8 strings. &amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;height: 45em; overflow-y:auto;&amp;quot;&amp;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'''!!'''Provider'''&lt;br /&gt;
|-&lt;br /&gt;
| type || Type of asset ||For Video use: &amp;lt;code&amp;gt;content&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt; For Static or text &amp;lt;code&amp;gt;static&amp;lt;/code&amp;gt; || Yes || Nielsen&lt;br /&gt;
|-style=&amp;quot;background-color:#e9f9fa;&amp;quot;&lt;br /&gt;
| assetid || Unique ID assigned to asset &amp;lt;br&amp;gt; Note: Refrain from using the following special characters [[Special_Characters|(Special Characters)]]. || Examples: &amp;lt;br&amp;gt; &amp;lt;code&amp;gt;BBT345a234 &amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; &amp;lt;code&amp;gt;CBSs5e234F2021&amp;lt;/code&amp;gt;  || Yes || Client &lt;br /&gt;
|-&lt;br /&gt;
| program ||Complete program or movie title &amp;lt;br&amp;gt; (no abbreviations or shorthand) &amp;lt;br&amp;gt; Note: there is a 25 character limit.  ||&amp;lt;code&amp;gt; The Big Bang Theory&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; &amp;lt;code&amp;gt; TheBigBangTheory&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt;&amp;lt;code&amp;gt; The Dark Knight&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt;&amp;lt;code&amp;gt; TheDarkKnight&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; || Yes || Client &lt;br /&gt;
|-style=&amp;quot;background-color:#e9f9fa;&amp;quot;&lt;br /&gt;
| title ||Episode title with season and episode number (40 character limit) &amp;lt;br&amp;gt; (Formats accepted: S01E03, S1E3, S1 E3). || Examples: &amp;lt;br&amp;gt; &amp;lt;code&amp;gt;The Pants Alternative S03E18&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; &amp;lt;code&amp;gt;The Pants Alternative S3E18&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; &amp;lt;code&amp;gt;The Pants Alternative S3 E18&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; Can also accept: &amp;lt;code&amp;gt; S3E18&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; Not Valid: &amp;lt;code&amp;gt; 318 &amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt; 0318 &amp;lt;/code&amp;gt;|| Yes || Client &lt;br /&gt;
|-&lt;br /&gt;
| crossId1 || Gracenote TMS ID (If available) should be passed for all telecasted content for clients using the Gracenote solution for proper matching purposes. &amp;lt;br&amp;gt;Note: The TMS ID will be a 14 character string. Normally leading with 2 alpha characerts ('EP', 'MV', 'SH' or 'SP'), followed by 12 numbers.&lt;br /&gt;
|| The TMS ID will be a 14 character string. &amp;lt;br&amp;gt; Normally being with  'EV,' 'EP', 'SH', 'SP', or 'MV' &amp;lt;br&amp;gt; Followed by 12 numbers after the initial two letter prefix. &amp;lt;br&amp;gt; &amp;lt;br&amp;gt; The Giant Morning Show: &amp;lt;code&amp;gt;SH009311820022&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; The Pants Alternative Episode : &amp;lt;code&amp;gt;EP009311820061&amp;lt;/code&amp;gt; || Optional || Nielsen&lt;br /&gt;
|-style=&amp;quot;background-color:#e9f9fa;&amp;quot;&lt;br /&gt;
| crossId2 || Populated by content distributor to contribute viewing from that distributor to the given content originator. || For a full list of acceptable values, please contact your Nielsen reprentative. || Yes, for distributors || Nielsen&lt;br /&gt;
|-&lt;br /&gt;
| length || Length of content in seconds&amp;lt;br&amp;gt;Note: Integers and decimals are acceptable values are acceptable for the length parameter. || Examples:&lt;br /&gt;
&amp;lt;small&amp;gt;For standard VOD content - &amp;lt;code&amp;gt;300&amp;lt;/code&amp;gt; to represent 5 minutes, &amp;lt;code&amp;gt;1320&amp;lt;/code&amp;gt; to represent 22 minutes, etc.&lt;br /&gt;
&amp;lt;br&amp;gt;If DAI live stream of a discrete program (Live Event/Sporting Event), pass length of content. See example for standard VOD content above.&lt;br /&gt;
&amp;lt;br&amp;gt;If unknown DAI live steam, pass a value of &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;.&amp;lt;/small&amp;gt; &lt;br /&gt;
|| Yes || Client &lt;br /&gt;
|-style=&amp;quot;background-color:#e9f9fa;&amp;quot;&lt;br /&gt;
| airdate ||Original broadcast or release date for the program &amp;lt;br&amp;gt;For USA, date should be EST &amp;lt;br&amp;gt; Outside USA, date should be local time.&amp;lt;br&amp;gt;If not applicable or available, original broadcast or release date for the Program. || Acceptable Formats:&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;YYYY-MM-DDTHH:MI:SS&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;YYYY-MM-DDHH:MI:SS&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;YYYY-MM-DDTHH:MI:SS+xx:xx&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;YYYY-MM-DDTHH:MI:SS-xx:xx&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;YYYYMMDDHH:MI:SS&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;YYYYMMDD HH:MI:SS&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;MM-DD-YYYY&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;MM/DD/YYYY&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;YYYYMMDD&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; || Yes || Client &lt;br /&gt;
|-&lt;br /&gt;
| isfullepisode || Full episode flag to identify differences between long form content. || &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;- full episode, &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt;- non full episode(clip,teaser,promo,etc.)&lt;br /&gt;
&amp;lt;small&amp;gt;Also accept: &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;lf&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;yes&amp;lt;/code&amp;gt;- longform&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;sf&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;no&amp;lt;/code&amp;gt;- shortform&lt;br /&gt;
|| Yes || Nielsen&lt;br /&gt;
|-style=&amp;quot;background-color:#e9f9fa;&amp;quot;&lt;br /&gt;
| adloadtype || &amp;lt;big&amp;gt;&amp;lt;small&amp;gt;Type of ad load: &lt;br /&gt;
&amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; Linear – matches TV ad load&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;2&amp;lt;/code&amp;gt; Dynamic – Dynamic Ad Insertion (DAI)&amp;lt;/small&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
|| &amp;lt;code&amp;gt;2&amp;lt;/code&amp;gt; - DCR measures content with dynamic ads || Yes || Nielsen&lt;br /&gt;
|-&lt;br /&gt;
| segB || One of two custom segment for the clients granular reporting within a brand. || Examples:&amp;lt;br&amp;gt;Genre - &amp;lt;code&amp;gt;horror&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;comedy&amp;lt;/code&amp;gt;, etc.&amp;lt;br&amp;gt;Timeslot - &amp;lt;code&amp;gt;primetime&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;daytime&amp;lt;/code&amp;gt;, etc.&amp;lt;br&amp;gt;News type - &amp;lt;code&amp;gt;breakingnews&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;weather&amp;lt;/code&amp;gt;, etc. || Optional || Client &lt;br /&gt;
|-style=&amp;quot;background-color:#e9f9fa;&amp;quot;&lt;br /&gt;
| segC || One of two custom segment for the clients granular reporting within a brand. || Examples:&amp;lt;br&amp;gt;Genre - &amp;lt;code&amp;gt;horror&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;comedy&amp;lt;/code&amp;gt;, etc.&amp;lt;br&amp;gt;Timeslot - &amp;lt;code&amp;gt;primetime&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;daytime&amp;lt;/code&amp;gt;, etc.&amp;lt;br&amp;gt;News type - &amp;lt;code&amp;gt;breakingnews&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;weather&amp;lt;/code&amp;gt;, etc. || Optional || Client &lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Custom segments (segB and segC) can be used to aggregate video and/or static content within a single Brand to receive more granular reports within a brand.&lt;br /&gt;
&lt;br /&gt;
Examples regarding usage of segments within SDK:&lt;br /&gt;
* All comedy clips and stories for a Brand rolled into a &amp;quot;Comedy&amp;quot; segment&lt;br /&gt;
* genre grouping content by Comedy vs. Drama&lt;br /&gt;
* group related Text + Video content - i.e. for a show that has a lot of - static pages associated with it&lt;br /&gt;
* packaging based on how clients sell inventory&lt;br /&gt;
* grouping related types of content either by genre, category or platform.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Metadata Example =====&lt;br /&gt;
&amp;lt;code&amp;gt;Swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&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;program&amp;quot;: &amp;quot;The Big Bang Theory&amp;quot;,&lt;br /&gt;
    &amp;quot;title&amp;quot;: &amp;quot;The Pants Alternative S03E18&amp;quot;,  //Formats accepted: S01E03, S1E3, S1 E3&lt;br /&gt;
    &amp;quot;crossId1&amp;quot;: &amp;quot;EP009311820061&amp;quot;, //optional&lt;br /&gt;
    &amp;quot;crossId2&amp;quot;: &amp;quot;Content Originator&amp;quot;, //optional&lt;br /&gt;
    &amp;quot;length&amp;quot;: &amp;quot;3600&amp;quot;,&lt;br /&gt;
    &amp;quot;airdate&amp;quot;: &amp;quot;2022-03-21T10:05:00&amp;quot;, &lt;br /&gt;
    &amp;quot;isfullepisode&amp;quot;: &amp;quot;Yes&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;
];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;Objective-C&amp;lt;/code&amp;gt;    &lt;br /&gt;
&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;program&amp;quot;: @ &amp;quot;The Big Bang Theory&amp;quot;,&lt;br /&gt;
    @ &amp;quot;title&amp;quot;: @ &amp;quot;The Pants Alternative S03E18&amp;quot;, //Formats accepted: S01E03, S1E3, S1 E3&lt;br /&gt;
    @ &amp;quot;crossId1&amp;quot;: @ &amp;quot;EP009311820061&amp;quot;, //optional&lt;br /&gt;
    @ &amp;quot;crossId2&amp;quot;: @ &amp;quot;Content Originator&amp;quot;, //optional&lt;br /&gt;
    @ &amp;quot;length&amp;quot;: @ &amp;quot;3600&amp;quot;,&lt;br /&gt;
    @ &amp;quot;airdate&amp;quot;: @ &amp;quot;2022-03-21T10:05:00&amp;quot;,&lt;br /&gt;
    @ &amp;quot;isfullepisode&amp;quot;: @ &amp;quot;y&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;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== iOS DCR Video Step 4 - Basic Set of Events - Sample Playback ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv6&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 4 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv6&amp;quot;&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;
| '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;
| 'playheadPosition'	|| 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: 'PlayheadPosition' 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 '''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 content or Ad playback is interrupted and at the end of each Ad. &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. &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;'''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;
==== Sample Use Case: 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 [[playheadPosition|playheadPosition()]] 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;
|-style=&amp;quot;background-color:#d8f5d7;&amp;quot;&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;
|-style=&amp;quot;background-color:#d8f5d7;&amp;quot;&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;
|- style=&amp;quot;background-color:#d8f5d7;&amp;quot;&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;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Keep Going ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv9&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv9&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Congratulations, you've successfully integrated the iOS SDK in your app for a basic content playback scenario!&lt;br /&gt;
&lt;br /&gt;
You can add more content to see channel-change scenarios or continue to next steps below.&lt;br /&gt;
&lt;br /&gt;
View your application's debug logs and search for the term (AppSDK) to see messages emitted by Nielsen AppSDK during video playback.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Next Steps ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv10&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv10&amp;quot;&amp;gt;&lt;br /&gt;
====Going Live====&lt;br /&gt;
&lt;br /&gt;
In addition to the basic steps above, before going live developers need to handle app background/foreground events, make certain privacy disclosures, handle interruption events (stop, fast-forward, rewind), remove iOS simulator slices, and allow users to opt out of Nielsen measurement. More details can be found [[DCR_Video_iOS_SDK|here]], along with a more comprehensive reference for implementing DCR Video measurement with AppSDK.&lt;br /&gt;
&lt;br /&gt;
Once the DCR Tracking Code is added, Nielsen will validate the implementation. Following Nielsen testing, developers need to make a few updates to the initialization call to ensure that the app is being measured properly.&lt;br /&gt;
&lt;br /&gt;
#'''App ID''': Ensure that correct  is used during initialization '''PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'''&lt;br /&gt;
#'''Debug Logging''': Disable logging by changing initialization call to use @&amp;quot;nol_devDebug&amp;quot;:@&amp;quot;INFO&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== &amp;amp;rarr; iOS DTVR (coming soon) ==&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivision100&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide iOS DTVR &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivision100&amp;quot;&amp;gt;&lt;br /&gt;
==== iOS DTVR Introduction ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv200-&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide Intro &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv200-&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Nielsen DTVR (Digital TV Ratings) product provides content consumption measurement in client mobile apps and webpages. This measurement includes insight into the total time a user spent watching the tracked content, video player events, and much more.&lt;br /&gt;
This example provides the steps to implement the DTVR product in a sample iOS app using Nielsen AppSDK. It includes:&lt;br /&gt;
&lt;br /&gt;
*SDK Initialization&lt;br /&gt;
*DTVR Video Metadata: information about the content being tracked&lt;br /&gt;
*DTVR Video Events/API calls&lt;br /&gt;
*Extracting ID3 tags from the video stream and passing to AppSDK for measurement&lt;br /&gt;
&lt;br /&gt;
By the end of this guide you will have the needed steps to integrate Nielsen's AppSDK in the background of your app for DTVR measurement.&lt;br /&gt;
&lt;br /&gt;
'''NOTE: video streams must have Nielsen ID3 tags embedded in order to be measured using the DTVR product. See the section in this guide &amp;quot;Extracting ID3 Tags&amp;quot; or contact your Nielsen representative for more information.'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== iOS DTVR Step 1 - Obtain AppID ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv300&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 1 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv300&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To begin using the iOS AppSDK, you will need to obtain an Application ID (AppId)&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! !! Item !! Description !! Source&lt;br /&gt;
|-&lt;br /&gt;
|&amp;amp;#9989; || App ID (appid) || Unique ID assigned to the player/site and configured by product || Contact your Nielsen Representative&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The appid is a 37 character unique ID assigned to the player/site and configured by product and is required when creating a new instance of the AppSDK in the app.&lt;br /&gt;
&amp;lt;/br&amp;gt;Example: '''PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== iOS DTVR Step 2 - SDK Initialization ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivision400&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 2 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivision400&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== How to obtain the NielsenAppApi.Framework =====&lt;br /&gt;
The Nielsen AppSDK can either be downloaded directly or can be integrated directly within an application through the use of CocoaPods. We recommend using the CocoaPods-based integration whenever possible to ensure you maintain the most recent changes and enhancements to the Nielsen libraries.&lt;br /&gt;
* [[Digital_Measurement_iOS_Artifactory_Guide|Select to obtain CocoaPods implementation guide]]&lt;br /&gt;
* [[Special:Downloads|Select to Download Directly]]&lt;br /&gt;
&lt;br /&gt;
===== Configuring Xcode Development Environment =====&lt;br /&gt;
Starting with SDK version 6.0.0.0, the Nielsen App SDK is compatible with Apple iOS versions 8.0 and above.  In addition, when using the dynamic framework,  all the required frameworks are linked automatically as the are needed.  More details can be found here: https://stackoverflow.com/questions/24902787/dont-we-need-to-link-framework-to-xcode-project-anymore&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': All communications between the SDK and the Census (Collection Facility) use HTTPS.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======= Download Framework =======&lt;br /&gt;
The first step is to download and copy the [[Special:Downloads|NielsenAppApi.framework]] bundle to the app project directory. (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
======= Add Framework =======&lt;br /&gt;
In the General tab for app configuration add NielsenAppApi.framework in the list of Embedded Binaries.  (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
======= Add Path =======&lt;br /&gt;
Add path to the NielsenAppApi.framework in the Framework Search Paths build setting.  (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
======= Import Framework =======&lt;br /&gt;
Add NielsenAppApi.framework module in the source file of your app:&lt;br /&gt;
&lt;br /&gt;
======= Using Swift =======&lt;br /&gt;
Add the following:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
import NielsenAppApi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======= Using Objective-C =======&lt;br /&gt;
&amp;lt;syntaxhighlight lang =&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
@import NielsenAppApi;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======= SDK Initialization =======&lt;br /&gt;
&lt;br /&gt;
The following table contains the list of arguments that can be passed via the AppInfo JSON schema.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter / Argument !! Description !! Source !! Required? !! Example&lt;br /&gt;
|--style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
| appid || Unique Nielsen ID for the application. The ID is a GUID data type. If you did not receive your App ID, let us know and we will provide you. || Nielsen-specified || Yes || PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&lt;br /&gt;
|--style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
| nol_devDebug || Enables Nielsen console logging. Only required for testing &amp;lt;br&amp;gt;&lt;br /&gt;
|| Nielsen-specified || Optional || DEBUG&lt;br /&gt;
|}&lt;br /&gt;
==== Debug flag for development environment ====&lt;br /&gt;
Player application developers / integrators can use Debug flag to check whether an App SDK API call made is successful. To activate the Debug flag,&lt;br /&gt;
Pass the argument &amp;lt;code&amp;gt;@&amp;quot;nol_devDebug&amp;quot;:@&amp;quot;DEBUG&amp;quot;&amp;lt;/code&amp;gt;, in the JSON string . &lt;br /&gt;
&lt;br /&gt;
Once the flag is active, it logs each API call made and the data passed. The log created by this flag is minimal.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': DO NOT activate the Debug flag in a production environment.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Swift Example ===&lt;br /&gt;
==== Sample SDK Initialization Code ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;NielsenInit.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class NielsenInit: NSObject {&lt;br /&gt;
    class func createNielsenAppApi(delegate: NielsenAppApiDelegate) -&amp;gt; NielsenAppApi?{&lt;br /&gt;
    let appInformation:[String: String] = [&lt;br /&gt;
           &amp;quot;appid&amp;quot;: &amp;quot;PE392366B-F2C1-4BC4-AB62-A7DAFDCXXXX&amp;quot;,&lt;br /&gt;
           &amp;quot;nol_devDebug&amp;quot;: &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
        ]&lt;br /&gt;
        return NielsenAppApi(appInfo:appInformation, delegate:delegate)}}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;ViewController.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class ViewController: UIViewController, NielsenAppApiDelegate, AVPictureInPictureControllerDelegate, CLLocationManagerDelegate  {&lt;br /&gt;
&lt;br /&gt;
    let avPlayerViewController = AVPlayerViewController()&lt;br /&gt;
    var avPlayer:AVPlayer?&lt;br /&gt;
    var nielsenAppApi: NielsenAppApi!&lt;br /&gt;
&lt;br /&gt;
  override func viewDidLoad() {&lt;br /&gt;
        super.viewDidLoad()&lt;br /&gt;
        self.nielsenAppApi = NielsenInit.createNielsenAppApi(delegate: self)&lt;br /&gt;
        NSLog(&amp;quot;Nielsen SDK initialized&amp;quot;)&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Objective C ===&lt;br /&gt;
==== Sample SDK Initialization Code ====&lt;br /&gt;
Initialize the Nielsen App object within the viewDidLoad view controller delegate method using initWithAppInfo:delegate:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;If App SDK is initialized using init or new methods, it will ignore the API calls resulting in no measurement. The SDK will not return any errors.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;quot;NlsAppApiFactory.h&amp;quot;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenAppApi.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@implementation NlsAppApiFactory&lt;br /&gt;
+ (NielsenAppApi *)createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
{&lt;br /&gt;
    NSDictionary *appInformation = @{&lt;br /&gt;
                                     @&amp;quot;appid&amp;quot;: &amp;quot;PE392366B-F2C1-4BC4-AB62-A7DAFDC51XXX&amp;quot;,&lt;br /&gt;
                                     @&amp;quot;nol_devDebug&amp;quot;: @&amp;quot;DEBUG&amp;quot;&lt;br /&gt;
                                     };&lt;br /&gt;
    return [[NielsenAppApi alloc] initWithAppInfo:appInformation delegate:delegate];&lt;br /&gt;
}&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following would be the &amp;lt;code&amp;gt;NlsAppApiFactory.h&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;Foundation/Foundation.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@class NielsenAppApi;&lt;br /&gt;
@protocol NielsenAppApiDeligate;&lt;br /&gt;
@interface NlsAppApiFactory : NSObject&lt;br /&gt;
+ (NielsenAppAPI *) createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
@end&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
The following might be in the &amp;lt;code&amp;gt;Viewcontroller.m&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
@implementation ViewController&lt;br /&gt;
&lt;br /&gt;
- (void)viewDidLoad {&lt;br /&gt;
    [super viewDidLoad];&lt;br /&gt;
    &lt;br /&gt;
    //Setting background image&lt;br /&gt;
    UIImage *backgroundImage = [UIImage imageNamed:@&amp;quot;new_ios_bg.png&amp;quot;];&lt;br /&gt;
    UIImageView *backgroundImageView=[[UIImageView alloc]initWithFrame:self.view.frame];&lt;br /&gt;
    backgroundImageView.image=backgroundImage;&lt;br /&gt;
    [self.view insertSubview:backgroundImageView atIndex:0];&lt;br /&gt;
    &lt;br /&gt;
    //Mark: In NielsenInit class we are initialising the Nielsen SDK.&lt;br /&gt;
    &lt;br /&gt;
    //Getting the instance of Nielsen SDK&lt;br /&gt;
    nielsenApi = [NielsenInit createNielsenAppApiWithDelegate:nil];&lt;br /&gt;
}&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== iOS DTVR Step 3 - Create DTVR Content Metadata Object ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv500&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 3 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv500&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Configure Metadata =====&lt;br /&gt;
Content metadata should remain constant throughout the completion of an episode or live stream.&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 for DTVR      || ✓&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
- (NSDictionary *)loadChannelInfo&lt;br /&gt;
{&lt;br /&gt;
    //Loading Channel Info.    &lt;br /&gt;
    NSString *strUrl = self.url.absoluteString;  &lt;br /&gt;
    NSDictionary *channel = @{  @&amp;quot;channelName&amp;quot; : @&amp;quot;TheGreatBigMovie&amp;quot;: strUrl };   &lt;br /&gt;
    return channel;&lt;br /&gt;
}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objectivec&amp;quot;&amp;gt;    &lt;br /&gt;
- (NSDictionary *)loadDtvr{&lt;br /&gt;
    &lt;br /&gt;
    //Loading DTVR data  &lt;br /&gt;
    NSDictionary *dtvr = @{ @&amp;quot;adModel&amp;quot;:@&amp;quot;1&amp;quot; ,  &lt;br /&gt;
                            @&amp;quot;type&amp;quot;:@&amp;quot;content&amp;quot;,};  &lt;br /&gt;
    return dtvr;&lt;br /&gt;
}&lt;br /&gt;
    &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== iOS DTVR Step 4 - Basic Set of Events - Sample Playback ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv600&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 4 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv600&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== SDK Events/APIs =====&lt;br /&gt;
&amp;lt;!--[[File:appsdkTimeline-DTVR-V2.png|icon]]--&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;
&lt;br /&gt;
===== Configure API calls - loadMetadata =====&lt;br /&gt;
Use &amp;lt;code&amp;gt;loadMetadata&amp;lt;/code&amp;gt; to pass the metadata object created above. &lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Objective C = &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;[nielsenApi loadMetadata:(dtvr)];&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Swift = &amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;self.nielsenAppApi?.loadMetadata(dtvr)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Configure API calls - sendID3 =====&lt;br /&gt;
[[sendID3]] API is a Nielsen AppSDK receiver for timed metadata events (ID3 tags) provided through iOS’s NSNotificationCenter notification system. This API filters out Nielsen-specific ID3 tags from the system and uses them to create duration data. These ID3 tags are used by Nielsen SDK for DTVR measurement, and the stream that is played must contain ID3 tags and have these tags extracted and passed to SDK using the below procedure in order for DTVR measurement to occur. &lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Objective C = &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;[nielsenApi sendID3:extraString];&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Swift = &amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt; [nielsenApi sendID3:extraString];&amp;lt;/syntaxhighlight&amp;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;
Refer to [[iOS SDK API Reference#Retrieving ID3 Tags|Retrieving ID3 Tags]] section to know more details.&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;
As Apple has deprecated the use of [https://developer.apple.com/documentation/avfoundation/avplayeritem/1389602-timedmetadata?language=objc timedMetadata], we now recommend using [https://developer.apple.com/documentation/avfoundation/avplayeritemmetadataoutput?language=objc AVPlayerItemMetadataOutput] for extracting ID3 tags from the iOS Native Player.&lt;br /&gt;
&lt;br /&gt;
If any other player apart from the iOS native player is used, check and ensure that the player has the capability to extract metadata such as 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;
|Swift = &amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt; &lt;br /&gt;
        //First, ensure your class conforms to the AVPlayerItemMetadataOutputPushDelegate protocol.&lt;br /&gt;
           class YourClass: AVPlayerItemMetadataOutputPushDelegate { &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;
       // Then create an instance of AVPlayerItemMetadataOutput and add it to the player item&lt;br /&gt;
          let metadataOutput = AVPlayerItemMetadataOutput(identifiers: nil)&lt;br /&gt;
           playerItem.add(metadataOutput)&lt;br /&gt;
 &lt;br /&gt;
       // and set the delegate and a dispatch queue&lt;br /&gt;
           metadataOutput.setDelegate(self, queue: DispatchQueue.main)&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;
        // After that below callback function of AVPlayerItemMetadataOutputPushDelegate &lt;br /&gt;
        // protocol will be triggered whenever ID3 tag is received from stream. &lt;br /&gt;
          func metadataOutput(_ output: AVPlayerItemMetadataOutput, didOutputTimedMetadataGroups groups: [AVTimedMetadataGroup], from track: AVPlayerItemTrack?) {&lt;br /&gt;
    for group in groups {&lt;br /&gt;
        for item in group.items {&lt;br /&gt;
            // Handle the metadata item&lt;br /&gt;
            handleTimedMetadata(metadataItem: item)&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;
          // Then further metadata item can be handled like below &lt;br /&gt;
          func handleTimedMetadata(metadataItem: AVMetadataItem) {&lt;br /&gt;
    guard let key = metadataItem.key as? String,&lt;br /&gt;
          let extraString = metadataItem.extraAttributes?[AVMetadataExtraAttributeInfoKey] as? String else {&lt;br /&gt;
        return&lt;br /&gt;
    }&lt;br /&gt;
    // If the extra string(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.hasPrefix(&amp;quot;www.nielsen.com&amp;quot;) {&lt;br /&gt;
        DispatchQueue.global(qos: .default).async {&lt;br /&gt;
            self.nielsenApi?.sendID3(extraString)&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&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;
        //First, ensure your class conforms to the AVPlayerItemMetadataOutputPushDelegate protocol.&lt;br /&gt;
          @interface YourClass : NSObject &amp;lt;AVPlayerItemMetadataOutputPushDelegate&amp;gt; &lt;br /&gt;
&lt;br /&gt;
          @end&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;
        // Then create an instance of AVPlayerItemMetadataOutput and add it to the player item&lt;br /&gt;
          AVPlayerItemMetadataOutput *metadataOutput = [[AVPlayerItemMetadataOutput alloc] initWithIdentifiers:nil];&lt;br /&gt;
          [playerItem addOutput:metadataOutput];&lt;br /&gt;
&lt;br /&gt;
        // and set the delegate and a dispatch queue&lt;br /&gt;
          [metadataOutput setDelegate:self queue:dispatch_get_main_queue()];&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;
        // After that below callback function of AVPlayerItemMetadataOutputPushDelegate &lt;br /&gt;
        // protocol will be triggered whenever ID3 tag is received from stream.&lt;br /&gt;
           - (void)metadataOutput:(AVPlayerItemMetadataOutput *)output didOutputTimedMetadataGroups:(NSArray&amp;lt;AVTimedMetadataGroup *&amp;gt; *)groups fromPlayerItemTrack:(AVPlayerItemTrack *)track {&lt;br /&gt;
    for (AVTimedMetadataGroup *group in groups) {&lt;br /&gt;
        for (AVMetadataItem *item in group.items) {&lt;br /&gt;
            // Handle the metadata item&lt;br /&gt;
            [self handleTimedMetadata:item];&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;
        // Then further metadata item can be handled like below &lt;br /&gt;
          - (void)handleTimedMetadata:(AVMetadataItem *)item {&lt;br /&gt;
    NSString *key = (NSString *)item.key;&lt;br /&gt;
    NSString *extraString = item.extraAttributes[AVMetadataExtraAttributeInfoKey];&lt;br /&gt;
    // If the key is &amp;quot;PRIV&amp;quot; and the extra string starts with &amp;quot;www.nielsen.com&amp;quot;, send it to the Nielsen API&lt;br /&gt;
    if ([key isEqualToString:@&amp;quot;PRIV&amp;quot;] &amp;amp;&amp;amp; [extraString hasPrefix:@&amp;quot;www.nielsen.com&amp;quot;]) {&lt;br /&gt;
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{&lt;br /&gt;
            [self.nielsenApi sendID3:extraString];&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;
===== 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. &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 loadMetadata and sendID3 events to occur.&lt;br /&gt;
# '''Processing state''' – The SDK instance is processing playing information. For DTVR, the &amp;lt;code&amp;gt;'''loadMetadata''' &amp;lt;/code&amp;gt; call moves the SDK instance into this state. In this state, the SDK instance will be able to process sendID3 calls and measure content.&lt;br /&gt;
# '''Disabled state''' – The SDK instance is disabled.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Keep Going ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv900&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv900&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Congratulations, you've successfully integrated the iOS SDK in your app for a basic content playback scenario!&lt;br /&gt;
&lt;br /&gt;
You can add more content to see channel-change scenarios or continue to next steps below.&lt;br /&gt;
&lt;br /&gt;
View your application's debug logs and search for the term (AppSDK) to see messages emitted by Nielsen AppSDK during video playback.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Next Steps ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv1000&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv1000&amp;quot;&amp;gt;&lt;br /&gt;
====Going Live====&lt;br /&gt;
&lt;br /&gt;
In addition to the basic steps above, before going live developers need to handle app background/foreground events, make certain privacy disclosures, handle interruption events (stop, fast-forward, rewind), remove iOS simulator slices, and allow users to opt out of Nielsen measurement. More details can be found [[DTVR_iOS_SDK|here]], along with a more comprehensive reference for implementing DTVR measurement with AppSDK.&lt;br /&gt;
&lt;br /&gt;
Once the DTVR Tracking Code is added, Nielsen will validate the implementation. Following Nielsen testing, developers need to make a few updates to the initialization call to ensure that the app is being measured properly.&lt;br /&gt;
&lt;br /&gt;
#'''App ID''': Ensure that correct  is used during initialization '''PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'''&lt;br /&gt;
#'''Debug Logging''': Disable logging by changing initialization call to use @&amp;quot;nol_devDebug&amp;quot;:@&amp;quot;INFO&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>NickParrucci</name></author>
	</entry>
	<entry>
		<id>https://nielsentest.mywikis.net/w/index.php?title=Android_Step_By_Step&amp;diff=6463</id>
		<title>Android Step By Step</title>
		<link rel="alternate" type="text/html" href="https://nielsentest.mywikis.net/w/index.php?title=Android_Step_By_Step&amp;diff=6463"/>
		<updated>2023-07-27T13:14:43Z</updated>

		<summary type="html">&lt;p&gt;NickParrucci: /* Going Live */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
__NOTOC__&lt;br /&gt;
&lt;br /&gt;
Provided below are step-by-step quick start guides for implementing Nielsen Android SDK for DCR Static, DCR Video, and DTVR products. Click each section to get started. &lt;br /&gt;
&lt;br /&gt;
== &amp;amp;rarr; Android DCR Static ==&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivision&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide DCR Static &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivision&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Android DCR Static Introduction ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivision1&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide Intro &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivision1&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Digital Content Ratings (DCR) Static product provides content consumption measurement on client webpages. This measurement includes insight into the total time a user spent on a webpage, how they navigated through the page via links, and many other data points.&lt;br /&gt;
This tutorial provides the steps to implement the DCR Static product in a sample Android app. It includes:&lt;br /&gt;
&lt;br /&gt;
*SDK Initialization Call&lt;br /&gt;
*DCR Static Metadata: information about the sections being tracked&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
By the end of this guide you will have the needed steps to integrate Nielsen's AppSDK in the background of your app.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Android DCR Static Step 1 - Obtain AppID ===&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivision2&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 1 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivision2&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To begin using the Android SDK (AppSDK) you will need to obtain an Application ID (AppId)&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! !! Item !! Description !! Source&lt;br /&gt;
|-&lt;br /&gt;
|&amp;amp;#9989; || App ID (appid) || Unique ID assigned to the player/site and configured by product || Contact your Nielsen TAM&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The appid is a 37 character unique ID assigned to the player/site and configured by product and is required when creating a new instance of the AppSDK in the app.&lt;br /&gt;
&amp;lt;/br&amp;gt;Example: '''PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Android DCR Static Step 2 - SDK Initialization ===&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivision3&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 2 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivision3&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== How to obtain the NielsenAppApi ====&lt;br /&gt;
The Nielsen AppSDK can either be downloaded directly or can be integrated into an application through the use of Gradle. We recommend using the Gradle-based integration whenever possible to ensure you maintain the most recent changes and enhancements to the Nielsen libraries.&lt;br /&gt;
* [[Digital_Measurement_Android_Artifactory_Guide|Select to obtain Gradle implementation guide]]&lt;br /&gt;
* [[Special:Downloads|Select to Download Directly]]&lt;br /&gt;
&lt;br /&gt;
==== SDK Initialization ====&lt;br /&gt;
&lt;br /&gt;
The following table contains the list of arguments that can be passed via the AppInfo JSON schema.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter / Argument !! Description !! Source !! Required? !! Example&lt;br /&gt;
|-&lt;br /&gt;
| appid || Unique Nielsen ID for the application. The ID is a GUID data type. If you did not receive your App ID, let us know and we will provide you. || Nielsen-specified || Yes || PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&lt;br /&gt;
|-&lt;br /&gt;
| nol_devDebug || Enables Nielsen console logging. Only required for testing&lt;br /&gt;
|| Nielsen-specified || Optional || &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Debug flag for development environment ====&lt;br /&gt;
Player application developers / integrators can use Debug flag to check whether an App SDK API call made is successful. To activate the Debug flag,&lt;br /&gt;
Pass the argument &amp;lt;code&amp;gt;@&amp;quot;nol_devDebug&amp;quot;:@&amp;quot;INFO&amp;quot;&amp;lt;/code&amp;gt;, in the JSON string . The permitted values are:&lt;br /&gt;
&lt;br /&gt;
* '''INFO''': Displays the API calls and the input data from the application (validate player name, app ID, etc.). It can be used as certification Aid.&lt;br /&gt;
* '''WARN''': Indicates potential integration / configuration errors or SDK issues.&lt;br /&gt;
* '''ERROR''': Indicates important integration errors or non-recoverable SDK issues.&lt;br /&gt;
* '''DEBUG''': Debug logs, used by the developers to debug more complex issues.&lt;br /&gt;
&lt;br /&gt;
Once the flag is active, it logs each API call made and the data passed. The log created by this flag is minimal.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': DO NOT activate the Debug flag in a production environment.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Sample SDK Initialization Code ====&lt;br /&gt;
&lt;br /&gt;
'''Initialization of App SDK object through a JSON object'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;try&lt;br /&gt;
{&lt;br /&gt;
  // Prepare AppSdk configuration object (JSONObject)&lt;br /&gt;
  JSONObject appSdkConfig = new JSONObject()&lt;br /&gt;
          .put(&amp;quot;appid&amp;quot;, &amp;quot;PDA7D5EE6-B1B8-XXXX-XXXX-2A788BCXXXCA&amp;quot;)&lt;br /&gt;
          .put(&amp;quot;nol_devDebug&amp;quot;, &amp;quot;DEBUG&amp;quot;); // only for debug builds&lt;br /&gt;
&lt;br /&gt;
// Pass appSdkConfig to the AppSdk constructor&lt;br /&gt;
mAppSdk = new AppSdk(appContext, appSdkConfig, appSdkListener);&lt;br /&gt;
}&lt;br /&gt;
catch (JSONException e)&lt;br /&gt;
{&lt;br /&gt;
  Log.e(TAG, &amp;quot;Couldn’t prepare JSONObject for appSdkConfig&amp;quot;, e);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Here, &amp;lt;code&amp;gt;appContext&amp;lt;/code&amp;gt; is the App context object and &amp;lt;code&amp;gt;appSdkConfig&amp;lt;/code&amp;gt; is JSON object for holding the parameters (&amp;lt;code&amp;gt;appid&amp;lt;/code&amp;gt;) the App passes to the Nielsen App SDK via a JSON string. The appid is obtained from Nielsen operational support and is unique to the app.&lt;br /&gt;
&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;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Android DCR Static Step 3 - Create/Load DCR Static Metadata Object ===&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivision4&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 3 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivision4&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Configure Metadata ====&lt;br /&gt;
Map the Nielsen keys to variables so that the content metadata is dynamically updated.&lt;br /&gt;
&lt;br /&gt;
The Nielsen reserved keys are:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Key !! Description !! Data Type !! Value !! Required?&lt;br /&gt;
|-&lt;br /&gt;
| type || asset type || fixed || &amp;lt;code&amp;gt;'static'&amp;lt;/code&amp;gt; || Yes&lt;br /&gt;
|-&lt;br /&gt;
| assetid || Unique ID for each article || dynamic || custom &amp;lt;br&amp;gt;(no [[Special Characters]]) || No&lt;br /&gt;
|-&lt;br /&gt;
| section || section of each site (e.g. section value should be first level in page URL: website.com/section). Limit to 25 unique values || dynamic || custom || Yes&lt;br /&gt;
|-&lt;br /&gt;
| segA || custom segment for reporting: Limit to 25 unique values across custom segments (segA + segB + segC) || dynamic || custom || No&lt;br /&gt;
|-&lt;br /&gt;
| segB || custom segment for reporting: Limit to 25 unique values across custom segments (segA + segB + segC) || dynamic || custom || No&lt;br /&gt;
|-&lt;br /&gt;
| segC || custom segment for reporting: Limit to 25 unique values across custom segments (segA + segB + segC) || dynamic || custom || No&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The values passed through the Nielsen keys will determine the breakouts that are seen in reporting. The custom segments (A, B &amp;amp; C) will roll into the sub-brand. To not use custom segments A, B and C, do not pass any value in these keys.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Configure API calls - loadMetadata ====&lt;br /&gt;
Use [[loadMetadata]] to pass 'content' [[Digital Measurement Metadata]]. The CMS data must be passed as a JSON object.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;    loadMetadata(JSONObject jsonMetadata);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Refer to [[Digital Measurement Metadata]] for the list of parameters to be passed in the JSON object.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Note: The [[loadMetadata]] call must have (&amp;quot;type&amp;quot;: &amp;quot;static&amp;quot;). &amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Call [[loadMetadata]] with JSON metadata as below.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;    new JSONObject()&lt;br /&gt;
        .put(&amp;quot;type&amp;quot;, &amp;quot;static&amp;quot;)&lt;br /&gt;
        .put(&amp;quot;section&amp;quot;, &amp;quot;siteSection&amp;quot;)&lt;br /&gt;
        .put(&amp;quot;assetid&amp;quot;, &amp;quot;vid345-67483&amp;quot;)&lt;br /&gt;
        .put(&amp;quot;segA&amp;quot;, &amp;quot;segmentA&amp;quot;)&lt;br /&gt;
        .put(&amp;quot;segB&amp;quot;, &amp;quot;segmentB&amp;quot;)&lt;br /&gt;
        .put(&amp;quot;segC&amp;quot;,&amp;quot;segmentC&amp;quot;)&lt;br /&gt;
    }&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As soon as this loadMetadata call is made, AppSDK will record a view event and start tracking the section/page time spent (AppSDK 9.1 and above).&lt;br /&gt;
&lt;br /&gt;
==== DCR Static Duration Measurement per Section/Page/Asset ====&lt;br /&gt;
If your Nielsen AppID is enabled for DCR Static duration measurement, a view event will be recorded and a timer will be started for each screen/page. Duration will be measured until a new page is loaded or the app is moved to the background. The event which triggers recognition of page view and timer start is the loadMetadata API call with a metadata object of type 'static'. Once a page is viewed and the timer has started, duration will be measured until a new page has loaded ''with associated loadMetadata call having a different '''section name''' from the previous page''. If a new loadMetadata call is made with the same '''section name''', it will be ignored - no new view will be recorded. If it is desired to have a new view event even though the metadata contains the same '''section name''' (example: single-page apps having several assedIDs but common section name), staticEnd API can be called between page views. For the purposes of this overview, staticend will not be used. See [[DCR_Static_Android_SDK|this page]] for more information. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Keep Going ===&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivision5&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivision5&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Congratulations, you've successfully integrated the Android SDK in your app!&lt;br /&gt;
&lt;br /&gt;
You can add static loadMetadata calls for more sections/pages in your app to see what happens when transitioning between sections.&lt;br /&gt;
&lt;br /&gt;
View your application's debug logs and search for the term (AppSDK) to see messages emitted by Nielsen AppSDK.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Next Steps ===&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivision6&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivision6&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now that you've integrated DCR Static for the AppSDK, what's next?&lt;br /&gt;
&lt;br /&gt;
====Going Live====&lt;br /&gt;
&lt;br /&gt;
In addition to the basic steps above, before going live developers need to handle app background/foreground events, make certain privacy disclosures, and allow users to opt out of Nielsen measurement. More details can be found [[DCR_Static_Android_SDK|here]], along with a more comprehensive reference for implementing DCR Static measurement with AppSDK.&lt;br /&gt;
&lt;br /&gt;
Once the DCR Tracking Code is added, Nielsen will validate the implementation. Following Nielsen testing, developers need to make a few updates to the initialization call to ensure that the app is being measured properly.&lt;br /&gt;
&lt;br /&gt;
#'''App ID''': Ensure that correct  is used during initialization '''PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'''&lt;br /&gt;
#'''Debug Logging''': Disable logging by changing initialization call to use @&amp;quot;nol_devDebug&amp;quot;:@&amp;quot;INFO&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== &amp;amp;rarr; Android DCR Video ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivision7&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide DCR Video &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivision7&amp;quot;&amp;gt;&lt;br /&gt;
==== Android DCR Video Introduction ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv8&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide Intro &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Digital Content Ratings (DCR) Video product provides content consumption measurement on client webpages. This measurement includes insight into the total time a user spent watching the tracked content, video player events, and much more.&lt;br /&gt;
This example provides the steps to implement the DCR Video product in a sample Android app. It includes:&lt;br /&gt;
&lt;br /&gt;
*SDK Initialization&lt;br /&gt;
*DCR Video Metadata: information about the content being tracked&lt;br /&gt;
*DCR Video Events/API calls&lt;br /&gt;
&lt;br /&gt;
By the end of this guide you will have the needed steps to integrate Nielsen's AppSDK in the background of your app.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Android DCR Video Step 1 - Obtain AppID ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv9&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 1 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv9&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To begin using the Android AppSDK, you will need to obtain an Application ID (AppId)&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! !! Item !! Description !! Source&lt;br /&gt;
|-&lt;br /&gt;
|&amp;amp;#9989; || App ID (appid) || Unique ID assigned to the player/site and configured by product || Contact your Nielsen Representative&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The appid is a 37 character unique ID assigned to the player/site and configured by product and is required when creating a new instance of the AppSDK in the app.&lt;br /&gt;
&amp;lt;/br&amp;gt;Example: '''PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Android DCR Video Step 2 - SDK Initialization ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivision10&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 2 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivision10&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Setting up your  Development Environment  =====&lt;br /&gt;
===== Configuring Android Development Environment =====&lt;br /&gt;
*The Nielsen App SDK (located in the [https://engineeringportal.nielsen.com/docs/Special:Downloads Downloads section] of the website) class is the primary application interface to the Nielsen App SDK on Android.&lt;br /&gt;
*The Nielsen App SDK class is defined as the only public class belonging to the com.nielsen.app.sdk package.&lt;br /&gt;
*The Nielsen App SDK can also be added via [https://engineeringportal.nielsen.com/docs/Digital_Measurement_Android_Artifactory_Guide Artifact Repository].&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;
&lt;br /&gt;
Once SDK is downloaded ensure to unzip the Nielsen SDK and copy the AppSdk.jar in your app (Android Studio) libs folder, then right click the AppSdk.jar and select '''Add As Library'''.&lt;br /&gt;
Ensure the AppSdk.jar file is added in 'build.gradle (App Level) file.&lt;br /&gt;
* App SDK 1.2 provides support for x86, mips, and armeabi-7a architecture.&lt;br /&gt;
&lt;br /&gt;
===== Google Play Services =====&lt;br /&gt;
Add the Google Play Services in the project,&lt;br /&gt;
Steps: Android Studio -&amp;gt; File -&amp;gt; Project Structure -&amp;gt;(In module selection) select App -&amp;gt; Dependencies (tab) -&amp;gt; Click &amp;quot;+&amp;quot; button and search for &amp;lt;code&amp;gt;&amp;quot;*play-services*&amp;quot;&amp;lt;/code&amp;gt;.  Then select the most recent version of the play-services Artifact.&lt;br /&gt;
Ensure it is added in build.gradle (App level) file&lt;br /&gt;
&lt;br /&gt;
===== Google AD ID Permissions =====&lt;br /&gt;
The following is required if target API level is set to 31 (Android 12) with the Ad Version of the Nielsen SDK.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;uses-permission android:name=&amp;quot;com.google.android.gms.permission.AD_ID&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;
====== Manifest File ====== &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;&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 runtime permissions in Android versions, please visit [https://developer.android.com/training/permissions/requesting.html].   &lt;br /&gt;
&lt;br /&gt;
* In &amp;lt;code&amp;gt;AndroidManifest.xml &amp;lt;/code&amp;gt;under &amp;lt;code&amp;gt;&amp;lt;application&amp;gt;&amp;lt;/code&amp;gt; add the following metadata&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&amp;lt;meta-data &lt;br /&gt;
android:name=&amp;quot;com.google.android.gms.version&amp;quot; &lt;br /&gt;
android:value=&amp;quot;@integer/google_play_services_version&amp;quot;/&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&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;
&lt;br /&gt;
===== Library =====&lt;br /&gt;
Nielsen App SDK uses the following packages/classes from the Google Play service.&lt;br /&gt;
* google-play-services_lib&lt;br /&gt;
&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;
===== SDK Initialization =====&lt;br /&gt;
&lt;br /&gt;
The following table contains the list of arguments that can be passed via the AppInfo JSON schema.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter / Argument !! Description !! Source !! Required? !! Example&lt;br /&gt;
|-&lt;br /&gt;
| appid || Unique Nielsen ID for the application. The ID is a GUID data type. If you did not receive your App ID, let us know and we will provide you. || Nielsen-specified || Yes || PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&lt;br /&gt;
|-&lt;br /&gt;
| nol_devDebug || Enables Nielsen console logging. Only required for testing&lt;br /&gt;
|| Nielsen-specified || Optional || &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
== Debug flag for development environment ==&lt;br /&gt;
Player application developers / integrators can use Debug flag to check whether an App SDK API call made is successful. To activate the Debug flag,&lt;br /&gt;
Pass the argument &amp;lt;code&amp;gt;@&amp;quot;nol_devDebug&amp;quot;:@&amp;quot;DEBUG&amp;quot;&amp;lt;/code&amp;gt;, in the JSON string . The permitted values are:&lt;br /&gt;
&lt;br /&gt;
* '''INFO''': Displays the API calls and the input data from the application (validate player name, app ID, etc.). It can be used as certification Aid.&lt;br /&gt;
* '''WARN''': Indicates potential integration / configuration errors or SDK issues.&lt;br /&gt;
* '''ERROR''': Indicates important integration errors or non-recoverable SDK issues.&lt;br /&gt;
* '''DEBUG''': Debug logs, used by the developers to debug more complex issues.&lt;br /&gt;
&lt;br /&gt;
Once the flag is active, it logs each API call made and the data passed. The log created by this flag is minimal.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': DO NOT activate the Debug flag in a production environment.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Sample SDK Initialization Code ====&lt;br /&gt;
&lt;br /&gt;
'''Initialization of App SDK object through a JSON object'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;try&lt;br /&gt;
{&lt;br /&gt;
  // Prepare AppSdk configuration object (JSONObject)&lt;br /&gt;
  JSONObject appSdkConfig = new JSONObject()&lt;br /&gt;
          .put(&amp;quot;appid&amp;quot;, &amp;quot;PDA7D5EE6-B1B8-XXXX-XXXX-2A788BCXXXCA&amp;quot;)&lt;br /&gt;
          .put(&amp;quot;nol_devDebug&amp;quot;, &amp;quot;DEBUG&amp;quot;); // only for debug builds&lt;br /&gt;
&lt;br /&gt;
// Pass appSdkConfig to the AppSdk constructor&lt;br /&gt;
mAppSdk = new AppSdk(appContext, appSdkConfig, appSdkListener);&lt;br /&gt;
}&lt;br /&gt;
catch (JSONException e)&lt;br /&gt;
{&lt;br /&gt;
  Log.e(TAG, &amp;quot;Couldn’t prepare JSONObject for appSdkConfig&amp;quot;, e);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Here, &amp;lt;code&amp;gt;appContext&amp;lt;/code&amp;gt; is the App context object and &amp;lt;code&amp;gt;appSdkConfig&amp;lt;/code&amp;gt; is JSON object for holding the parameters (&amp;lt;code&amp;gt;appid&amp;lt;/code&amp;gt;) the App passes to the Nielsen App SDK via a JSON string. The appid is obtained from Nielsen operational support and is unique to the app.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The integration of Nielsen App SDK will depend on type of client app.&amp;lt;br /&amp;gt;&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;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Android DCR Video Step 3 - Create DCR Video Content Metadata Object ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv11&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 3 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv11&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Handling JSON Metadata =====&lt;br /&gt;
The SDK methods handle 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.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
! '''Keys''' !! '''Description''' !! '''Values''' !! '''Required'''!!'''Provider'''&lt;br /&gt;
|-&lt;br /&gt;
| type || Type of asset ||For Video use: &amp;lt;code&amp;gt;content&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt; For Static or text &amp;lt;code&amp;gt;static&amp;lt;/code&amp;gt; || Yes || Nielsen&lt;br /&gt;
|-style=&amp;quot;background-color:#e9f9fa;&amp;quot;&lt;br /&gt;
| assetid || Unique ID assigned to asset &amp;lt;br&amp;gt; Note: Refrain from using the following special characters [[Special_Characters|(Special Characters)]]. || Examples: &amp;lt;br&amp;gt; &amp;lt;code&amp;gt;BBT345a234 &amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; &amp;lt;code&amp;gt;CBSs5e234F2021&amp;lt;/code&amp;gt;  || Yes || Client &lt;br /&gt;
|-&lt;br /&gt;
| program ||Complete program or movie title &amp;lt;br&amp;gt; (no abbreviations or shorthand) &amp;lt;br&amp;gt; Note: there is a 25 character limit.  ||&amp;lt;code&amp;gt; The Big Bang Theory&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; &amp;lt;code&amp;gt; TheBigBangTheory&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt;&amp;lt;code&amp;gt; The Dark Knight&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt;&amp;lt;code&amp;gt; TheDarkKnight&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; || Yes || Client &lt;br /&gt;
|-style=&amp;quot;background-color:#e9f9fa;&amp;quot;&lt;br /&gt;
| title ||Episode title with season and episode number (40 character limit) &amp;lt;br&amp;gt; (Formats accepted: S01E03, S1E3, S1 E3). || Examples: &amp;lt;br&amp;gt; &amp;lt;code&amp;gt;The Pants Alternative S03E18&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; &amp;lt;code&amp;gt;The Pants Alternative S3E18&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; &amp;lt;code&amp;gt;The Pants Alternative S3 E18&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; Can also accept: &amp;lt;code&amp;gt; S3E18&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; Not Valid: &amp;lt;code&amp;gt; 318 &amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt; 0318 &amp;lt;/code&amp;gt;|| Yes || Client &lt;br /&gt;
|-&lt;br /&gt;
| crossId1 || Gracenote TMS ID (If available) should be passed for all telecasted content for clients using the Gracenote solution for proper matching purposes. &amp;lt;br&amp;gt;Note: The TMS ID will be a 14 character string. Normally leading with 2 alpha characerts ('EP', 'MV', 'SH' or 'SP'), followed by 12 numbers.&lt;br /&gt;
|| The TMS ID will be a 14 character string. &amp;lt;br&amp;gt; Normally being with  'EV,' 'EP', 'SH', 'SP', or 'MV' &amp;lt;br&amp;gt; Followed by 12 numbers after the initial two letter prefix. &amp;lt;br&amp;gt; &amp;lt;br&amp;gt; The Giant Morning Show: &amp;lt;code&amp;gt;SH009311820022&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; The Pants Alternative Episode : &amp;lt;code&amp;gt;EP009311820061&amp;lt;/code&amp;gt; || Optional || Nielsen&lt;br /&gt;
|-style=&amp;quot;background-color:#e9f9fa;&amp;quot;&lt;br /&gt;
| crossId2 || Populated by content distributor to contribute viewing from that distributor to the given content originator. || Custom&amp;lt;br&amp;gt;For a full list of acceptable values, please contact your Nielsen reprentative. || Yes, for distributors || Nielsen&lt;br /&gt;
|-&lt;br /&gt;
| length || Length of content in seconds&amp;lt;br&amp;gt;Note: Integers and decimals are acceptable values are acceptable for the length parameter. || Examples:&lt;br /&gt;
&amp;lt;small&amp;gt;For standard VOD content - &amp;lt;code&amp;gt;300&amp;lt;/code&amp;gt; to represent 5 minutes, &amp;lt;code&amp;gt;1320&amp;lt;/code&amp;gt; to represent 22 minutes, etc.&lt;br /&gt;
&amp;lt;br&amp;gt;If DAI live stream of a discrete program (Live Event/Sporting Event), pass length of content. See example for standard VOD content above.&lt;br /&gt;
&amp;lt;br&amp;gt;If unknown DAI live steam, pass a value of &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;.&amp;lt;/small&amp;gt; &lt;br /&gt;
|| Yes || Client &lt;br /&gt;
|-style=&amp;quot;background-color:#e9f9fa;&amp;quot;&lt;br /&gt;
| airdate ||Original broadcast or release date for the program &amp;lt;br&amp;gt;For USA, date should be EST &amp;lt;br&amp;gt; Outside USA, date should be local time.&amp;lt;br&amp;gt;If not applicable or available, original broadcast or release date for the Program. || Acceptable Formats:&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;YYYY-MM-DDTHH:MI:SS&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;YYYY-MM-DDHH:MI:SS&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;YYYY-MM-DDTHH:MI:SS+xx:xx&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;YYYY-MM-DDTHH:MI:SS-xx:xx&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;YYYYMMDDHH:MI:SS&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;YYYYMMDD HH:MI:SS&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;MM-DD-YYYY&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;MM/DD/YYYY&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;YYYYMMDD&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; || Yes || Client &lt;br /&gt;
|-&lt;br /&gt;
| isfullepisode || Full episode flag to identify differences between long form content. || &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;- full episode, &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt;- non full episode(clip,teaser,promo,etc.)&lt;br /&gt;
&amp;lt;small&amp;gt;Also accept: &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;lf&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;yes&amp;lt;/code&amp;gt;- longform&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;sf&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;no&amp;lt;/code&amp;gt;- shortform&lt;br /&gt;
|| Yes || Nielsen&lt;br /&gt;
|-style=&amp;quot;background-color:#e9f9fa;&amp;quot;&lt;br /&gt;
| adloadtype || &amp;lt;big&amp;gt;&amp;lt;small&amp;gt;Type of ad load: &lt;br /&gt;
&amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; Linear – matches TV ad load&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;2&amp;lt;/code&amp;gt; Dynamic – Dynamic Ad Insertion (DAI)&amp;lt;/small&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
|| &amp;lt;code&amp;gt;2&amp;lt;/code&amp;gt; - DCR measures content with dynamic ads || Yes || Nielsen&lt;br /&gt;
|-&lt;br /&gt;
| segB || One of two custom segment for the clients granular reporting within a brand. || Examples:&amp;lt;br&amp;gt;Genre - &amp;lt;code&amp;gt;horror&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;comedy&amp;lt;/code&amp;gt;, etc.&amp;lt;br&amp;gt;Timeslot - &amp;lt;code&amp;gt;primetime&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;daytime&amp;lt;/code&amp;gt;, etc.&amp;lt;br&amp;gt;News type - &amp;lt;code&amp;gt;breakingnews&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;weather&amp;lt;/code&amp;gt;, etc. || Optional || Client &lt;br /&gt;
|-style=&amp;quot;background-color:#e9f9fa;&amp;quot;&lt;br /&gt;
| segC || One of two custom segment for the clients granular reporting within a brand. || Examples:&amp;lt;br&amp;gt;Genre - &amp;lt;code&amp;gt;horror&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;comedy&amp;lt;/code&amp;gt;, etc.&amp;lt;br&amp;gt;Timeslot - &amp;lt;code&amp;gt;primetime&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;daytime&amp;lt;/code&amp;gt;, etc.&amp;lt;br&amp;gt;News type - &amp;lt;code&amp;gt;breakingnews&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;weather&amp;lt;/code&amp;gt;, etc. || Optional || Client &lt;br /&gt;
|}&lt;br /&gt;
Custom segments (segB and segC) can be used to aggregate video and/or static content within a single Brand to receive more granular reports within a brand.&lt;br /&gt;
&lt;br /&gt;
Examples regarding usage of segments within SDK:&lt;br /&gt;
* All comedy clips and stories for a Brand rolled into a &amp;quot;Comedy&amp;quot; segment&lt;br /&gt;
* genre grouping content by Comedy vs. Drama&lt;br /&gt;
* group related Text + Video content - i.e. for a show that has a lot of - static pages associated with it&lt;br /&gt;
* packaging based on how clients sell inventory&lt;br /&gt;
* grouping related types of content either by genre, category or platform.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Android DCR Video Step 4 - Basic Set of Events - Sample Playback ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv12&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 4 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv12&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Configure API Calls =====&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;
&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;
==== Sample Use Case: 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;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Keep Going ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv13&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv13&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Congratulations, you've successfully integrated the Android SDK in your app for a basic content playback scenario!&lt;br /&gt;
&lt;br /&gt;
You can add more content to see channel-change scenarios or continue to next steps below.&lt;br /&gt;
&lt;br /&gt;
View your application's debug logs and search for the term (AppSDK) to see messages emitted by Nielsen AppSDK during video playback.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Next Steps ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv14&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv14&amp;quot;&amp;gt;&lt;br /&gt;
====Going Live====&lt;br /&gt;
&lt;br /&gt;
In addition to the basic steps above, before going live developers need to handle app background/foreground events, make certain privacy disclosures, handle interruption events (stop, fast-forward, rewind), and allow users to opt out of Nielsen measurement. More details can be found [[DCR_Video_Android_SDK|here]], along with a more comprehensive reference for implementing DCR Video measurement with AppSDK.&lt;br /&gt;
&lt;br /&gt;
Once the DCR Tracking Code is added, Nielsen will validate the implementation. Following Nielsen testing, developers need to make a few updates to the initialization call to ensure that the app is being measured properly.&lt;br /&gt;
&lt;br /&gt;
#'''App ID''': Ensure that correct  is used during initialization '''PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'''&lt;br /&gt;
#'''Debug Logging''': Disable logging by changing initialization call to use @&amp;quot;nol_devDebug&amp;quot;:@&amp;quot;INFO&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== &amp;amp;rarr; Android DTVR (coming soon) ==&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivision100&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide Android DTVR &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivision100&amp;quot;&amp;gt;&lt;br /&gt;
==== Android DTVR Introduction ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv200-&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide Intro &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv200-&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Nielsen DTVR (Digital TV Ratings) product provides content consumption measurement in client mobile apps and webpages. This measurement includes insight into the total time a user spent watching the tracked content, video player events, and much more.&lt;br /&gt;
This example provides the steps to implement the DTVR product in a sample Android app using Nielsen AppSDK. It includes:&lt;br /&gt;
&lt;br /&gt;
*SDK Initialization&lt;br /&gt;
*DTVR Video Metadata: information about the content being tracked&lt;br /&gt;
*DTVR Video Events/API calls&lt;br /&gt;
*Extracting ID3 tags from the video stream and passing to AppSDK for measurement&lt;br /&gt;
&lt;br /&gt;
By the end of this guide you will have the needed steps to integrate Nielsen's AppSDK in the background of your app for DTVR measurement.&lt;br /&gt;
&lt;br /&gt;
'''NOTE: video streams must have Nielsen ID3 tags embedded in order to be measured using the DTVR product. See the section in this guide &amp;quot;Extracting ID3 Tags&amp;quot; or contact your Nielsen representative for more information.'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Android DTVR Step 1 - Obtain AppID ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv300&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 1 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv300&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To begin using the Android AppSDK, you will need to obtain an Application ID (AppId)&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! !! Item !! Description !! Source&lt;br /&gt;
|-&lt;br /&gt;
|&amp;amp;#9989; || App ID (appid) || Unique ID assigned to the player/site and configured by product || Contact your Nielsen Representative&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The appid is a 37 character unique ID assigned to the player/site and configured by product and is required when creating a new instance of the AppSDK in the app.&lt;br /&gt;
&amp;lt;/br&amp;gt;Example: '''PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Android DTVR Step 2 - SDK Initialization ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivision400&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 2 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivision400&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Configuring Android Development Environment =====&lt;br /&gt;
*The Nielsen App SDK (located in the [https://engineeringportal.nielsen.com/docs/Special:Downloads Downloads section] of the website) class is the primary application interface to the Nielsen App SDK on Android.&lt;br /&gt;
*The Nielsen App SDK class is defined as the only public class belonging to the com.nielsen.app.sdk package.&lt;br /&gt;
*The Nielsen App SDK can also be added via [https://engineeringportal.nielsen.com/docs/Digital_Measurement_Android_Artifactory_Guide Artifact Repository].&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;
&lt;br /&gt;
Once SDK is downloaded ensure to unzip the Nielsen SDK and copy the AppSdk.jar in your app (Android Studio) libs folder, then right click the AppSdk.jar and select '''Add As Library'''.&lt;br /&gt;
Ensure the AppSdk.jar file is added in 'build.gradle (App Level) file.&lt;br /&gt;
* App SDK 1.2 provides support for x86, mips, and armeabi-7a architecture.&lt;br /&gt;
&lt;br /&gt;
===== Google Play Services =====&lt;br /&gt;
Add the Google Play Services in the project,&lt;br /&gt;
Steps: Android Studio -&amp;gt; File -&amp;gt; Project Structure -&amp;gt;(In module selection) select App -&amp;gt; Dependencies (tab) -&amp;gt; Click &amp;quot;+&amp;quot; button and search for &amp;lt;code&amp;gt;&amp;quot;*play-services*&amp;quot;&amp;lt;/code&amp;gt;.  Then select the most recent version of the play-services Artifact.&lt;br /&gt;
Ensure it is added in build.gradle (App level) file&lt;br /&gt;
&lt;br /&gt;
===== Google AD ID Permissions =====&lt;br /&gt;
The following is required if target API level is set to 31 (Android 12) with the Ad Version of the Nielsen SDK.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;uses-permission android:name=&amp;quot;com.google.android.gms.permission.AD_ID&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;
====== Manifest File ====== &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;&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 runtime permissions in Android versions, please visit [https://developer.android.com/training/permissions/requesting.html].   &lt;br /&gt;
&lt;br /&gt;
* In &amp;lt;code&amp;gt;AndroidManifest.xml &amp;lt;/code&amp;gt;under &amp;lt;code&amp;gt;&amp;lt;application&amp;gt;&amp;lt;/code&amp;gt; add the following metadata&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&amp;lt;meta-data &lt;br /&gt;
android:name=&amp;quot;com.google.android.gms.version&amp;quot; &lt;br /&gt;
android:value=&amp;quot;@integer/google_play_services_version&amp;quot;/&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&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;
&lt;br /&gt;
===== Library =====&lt;br /&gt;
Nielsen App SDK uses the following packages/classes from the Google Play service.&lt;br /&gt;
* google-play-services_lib&lt;br /&gt;
&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;
===== SDK Initialization =====&lt;br /&gt;
&lt;br /&gt;
The following table contains the list of arguments that can be passed via the AppInfo JSON schema.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter / Argument !! Description !! Source !! Required? !! Example&lt;br /&gt;
|-&lt;br /&gt;
| appid || Unique Nielsen ID for the application. The ID is a GUID data type. If you did not receive your App ID, let us know and we will provide you. || Nielsen-specified || Yes || PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&lt;br /&gt;
|-&lt;br /&gt;
| nol_devDebug || Enables Nielsen console logging. Only required for testing&lt;br /&gt;
|| Nielsen-specified || Optional || &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Debug flag for development environment ==&lt;br /&gt;
Player application developers / integrators can use Debug flag to check whether an App SDK API call made is successful. To activate the Debug flag,&lt;br /&gt;
Pass the argument &amp;lt;code&amp;gt;@&amp;quot;nol_devDebug&amp;quot;:@&amp;quot;DEBUG&amp;quot;&amp;lt;/code&amp;gt;, in the JSON string . The permitted values are:&lt;br /&gt;
&lt;br /&gt;
* '''INFO''': Displays the API calls and the input data from the application (validate player name, app ID, etc.). It can be used as certification Aid.&lt;br /&gt;
* '''WARN''': Indicates potential integration / configuration errors or SDK issues.&lt;br /&gt;
* '''ERROR''': Indicates important integration errors or non-recoverable SDK issues.&lt;br /&gt;
* '''DEBUG''': Debug logs, used by the developers to debug more complex issues.&lt;br /&gt;
&lt;br /&gt;
Once the flag is active, it logs each API call made and the data passed. The log created by this flag is minimal.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': DO NOT activate the Debug flag in a production environment.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Sample SDK Initialization Code ====&lt;br /&gt;
&lt;br /&gt;
'''Initialization of App SDK object through a JSON object'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;try&lt;br /&gt;
{&lt;br /&gt;
  // Prepare AppSdk configuration object (JSONObject)&lt;br /&gt;
  JSONObject appSdkConfig = new JSONObject()&lt;br /&gt;
          .put(&amp;quot;appid&amp;quot;, &amp;quot;PDA7D5EE6-B1B8-XXXX-XXXX-2A788BCXXXCA&amp;quot;)&lt;br /&gt;
          .put(&amp;quot;nol_devDebug&amp;quot;, &amp;quot;DEBUG&amp;quot;); // only for debug builds&lt;br /&gt;
&lt;br /&gt;
// Pass appSdkConfig to the AppSdk constructor&lt;br /&gt;
mAppSdk = new AppSdk(appContext, appSdkConfig, appSdkListener);&lt;br /&gt;
}&lt;br /&gt;
catch (JSONException e)&lt;br /&gt;
{&lt;br /&gt;
  Log.e(TAG, &amp;quot;Couldn’t prepare JSONObject for appSdkConfig&amp;quot;, e);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Here, &amp;lt;code&amp;gt;appContext&amp;lt;/code&amp;gt; is the App context object and &amp;lt;code&amp;gt;appSdkConfig&amp;lt;/code&amp;gt; is JSON object for holding the parameters (&amp;lt;code&amp;gt;appid&amp;lt;/code&amp;gt;) the App passes to the Nielsen App SDK via a JSON string. The appid is obtained from Nielsen operational support and is unique to the app.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The integration of Nielsen App SDK will depend on type of client app.&amp;lt;br /&amp;gt;&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;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Android DTVR Step 3 - Create DTVR Content Metadata Object ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv500&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 3 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv500&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Configure Metadata =====&lt;br /&gt;
Content metadata should remain constant throughout the completion of an episode or live stream.&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      || ✓&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
------------------------&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;   &lt;br /&gt;
    public JSONObject loadDtvr() {&lt;br /&gt;
     try {&lt;br /&gt;
            dtvrdata = new JSONObject()&lt;br /&gt;
                    .put( &amp;quot;type&amp;quot;,&amp;quot;content&amp;quot;)&lt;br /&gt;
                    .put(&amp;quot;adModel&amp;quot;, &amp;quot;1&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        return dtvrdata;&lt;br /&gt;
    }&lt;br /&gt;
    &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Android DTVR Step 4 - Basic Set of Events - Sample Playback ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv600&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 4 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv600&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== SDK Events/APIs =====&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;
&lt;br /&gt;
===== Configure API calls - loadMetadata =====&lt;br /&gt;
Use &amp;lt;code&amp;gt;loadMetadata&amp;lt;/code&amp;gt; to pass the metadata object created above. &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt; appSdk.loadMetadata(dtvrdata);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Configure API calls - sendID3 =====&lt;br /&gt;
[[sendID3]] API is a receiver for timed metadata events (ID3 tags. This API filters out Nielsen-specific ID3 tags from the system and buffers the data for transfer to Nielsen’s collection facility.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt; //Sending ID3 tag to SDK.&lt;br /&gt;
appSdk.sendID3(id3String);&amp;lt;/syntaxhighlight&amp;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;
Refer to [[Android SDK API Reference#Retrieving ID3 Tags|Retrieving ID3 Tags]] section to know more details.&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;
=====  Examples of extracting ID3 tags fromAndroid 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 mediaPlayer, TimedMetaData timedMetaData) {&lt;br /&gt;
&lt;br /&gt;
        if(timedMetaData != null &amp;amp;&amp;amp; timedMetaData.getMetaData() != null &amp;amp;&amp;amp; mMediaPlayer.isPlaying()){&lt;br /&gt;
&lt;br /&gt;
            //getting metadata.&lt;br /&gt;
            String iD3Payload = new String(timedMetaData.getMetaData(), StandardCharsets.UTF_8);&lt;br /&gt;
&lt;br /&gt;
            //If tag metadata contains &amp;quot;www.nielsen.com&amp;quot;, then only sending to SDK&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;
                //getting index&lt;br /&gt;
                int index = iD3Payload.indexOf(&amp;quot;www.nielsen.com&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
                //getting substring as ID3 tag will be of 249 characters&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;
&lt;br /&gt;
                //Sending ID3 tag to SDK.&lt;br /&gt;
                appSdk.sendID3(id3String);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/syntaxhighlight&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. &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 loadMetadata and sendID3 events to occur.&lt;br /&gt;
# '''Processing state''' – The SDK instance is processing playing information. The &amp;lt;code&amp;gt;'''loadMetadata'''&amp;lt;/code&amp;gt; call moves the SDK instance into this state. In this state, the SDK instance will be able to process sendID3 calls and measure content.&lt;br /&gt;
# '''Disabled state''' – The SDK instance is disabled.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Keep Going ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv900&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv900&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Congratulations, you've successfully integrated the Android SDK in your app for a basic content playback scenario!&lt;br /&gt;
&lt;br /&gt;
You can add more content to see channel-change scenarios or continue to next steps below.&lt;br /&gt;
&lt;br /&gt;
View your application's debug logs and search for the term (AppSDK) to see messages emitted by Nielsen AppSDK during video playback.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Next Steps ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv1000&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv1000&amp;quot;&amp;gt;&lt;br /&gt;
====Going Live====&lt;br /&gt;
&lt;br /&gt;
In addition to the basic steps above, before going live developers need to handle app background/foreground events, make certain privacy disclosures, handle interruption events (stop, fast-forward, rewind), and allow users to opt out of Nielsen measurement. More details can be found [[DTVR_Android_SDK|here]], along with a more comprehensive reference for implementing DTVR measurement with AppSDK.&lt;br /&gt;
&lt;br /&gt;
Once the DTVR Tracking Code is added, Nielsen will validate the implementation. Following Nielsen testing, developers need to make a few updates to the initialization call to ensure that the app is being measured properly.&lt;br /&gt;
&lt;br /&gt;
#'''App ID''': Ensure that correct  is used during initialization '''PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'''&lt;br /&gt;
#'''Debug Logging''': Disable logging by changing initialization call to use @&amp;quot;nol_devDebug&amp;quot;:@&amp;quot;INFO&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>NickParrucci</name></author>
	</entry>
	<entry>
		<id>https://nielsentest.mywikis.net/w/index.php?title=Android_Step_By_Step&amp;diff=6462</id>
		<title>Android Step By Step</title>
		<link rel="alternate" type="text/html" href="https://nielsentest.mywikis.net/w/index.php?title=Android_Step_By_Step&amp;diff=6462"/>
		<updated>2023-07-27T13:13:17Z</updated>

		<summary type="html">&lt;p&gt;NickParrucci: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
__NOTOC__&lt;br /&gt;
&lt;br /&gt;
Provided below are step-by-step quick start guides for implementing Nielsen Android SDK for DCR Static, DCR Video, and DTVR products. Click each section to get started. &lt;br /&gt;
&lt;br /&gt;
== &amp;amp;rarr; Android DCR Static ==&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivision&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide DCR Static &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivision&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Android DCR Static Introduction ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivision1&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide Intro &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivision1&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Digital Content Ratings (DCR) Static product provides content consumption measurement on client webpages. This measurement includes insight into the total time a user spent on a webpage, how they navigated through the page via links, and many other data points.&lt;br /&gt;
This tutorial provides the steps to implement the DCR Static product in a sample Android app. It includes:&lt;br /&gt;
&lt;br /&gt;
*SDK Initialization Call&lt;br /&gt;
*DCR Static Metadata: information about the sections being tracked&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
By the end of this guide you will have the needed steps to integrate Nielsen's AppSDK in the background of your app.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Android DCR Static Step 1 - Obtain AppID ===&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivision2&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 1 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivision2&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To begin using the Android SDK (AppSDK) you will need to obtain an Application ID (AppId)&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! !! Item !! Description !! Source&lt;br /&gt;
|-&lt;br /&gt;
|&amp;amp;#9989; || App ID (appid) || Unique ID assigned to the player/site and configured by product || Contact your Nielsen TAM&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The appid is a 37 character unique ID assigned to the player/site and configured by product and is required when creating a new instance of the AppSDK in the app.&lt;br /&gt;
&amp;lt;/br&amp;gt;Example: '''PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Android DCR Static Step 2 - SDK Initialization ===&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivision3&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 2 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivision3&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== How to obtain the NielsenAppApi ====&lt;br /&gt;
The Nielsen AppSDK can either be downloaded directly or can be integrated into an application through the use of Gradle. We recommend using the Gradle-based integration whenever possible to ensure you maintain the most recent changes and enhancements to the Nielsen libraries.&lt;br /&gt;
* [[Digital_Measurement_Android_Artifactory_Guide|Select to obtain Gradle implementation guide]]&lt;br /&gt;
* [[Special:Downloads|Select to Download Directly]]&lt;br /&gt;
&lt;br /&gt;
==== SDK Initialization ====&lt;br /&gt;
&lt;br /&gt;
The following table contains the list of arguments that can be passed via the AppInfo JSON schema.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter / Argument !! Description !! Source !! Required? !! Example&lt;br /&gt;
|-&lt;br /&gt;
| appid || Unique Nielsen ID for the application. The ID is a GUID data type. If you did not receive your App ID, let us know and we will provide you. || Nielsen-specified || Yes || PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&lt;br /&gt;
|-&lt;br /&gt;
| nol_devDebug || Enables Nielsen console logging. Only required for testing&lt;br /&gt;
|| Nielsen-specified || Optional || &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Debug flag for development environment ====&lt;br /&gt;
Player application developers / integrators can use Debug flag to check whether an App SDK API call made is successful. To activate the Debug flag,&lt;br /&gt;
Pass the argument &amp;lt;code&amp;gt;@&amp;quot;nol_devDebug&amp;quot;:@&amp;quot;INFO&amp;quot;&amp;lt;/code&amp;gt;, in the JSON string . The permitted values are:&lt;br /&gt;
&lt;br /&gt;
* '''INFO''': Displays the API calls and the input data from the application (validate player name, app ID, etc.). It can be used as certification Aid.&lt;br /&gt;
* '''WARN''': Indicates potential integration / configuration errors or SDK issues.&lt;br /&gt;
* '''ERROR''': Indicates important integration errors or non-recoverable SDK issues.&lt;br /&gt;
* '''DEBUG''': Debug logs, used by the developers to debug more complex issues.&lt;br /&gt;
&lt;br /&gt;
Once the flag is active, it logs each API call made and the data passed. The log created by this flag is minimal.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': DO NOT activate the Debug flag in a production environment.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Sample SDK Initialization Code ====&lt;br /&gt;
&lt;br /&gt;
'''Initialization of App SDK object through a JSON object'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;try&lt;br /&gt;
{&lt;br /&gt;
  // Prepare AppSdk configuration object (JSONObject)&lt;br /&gt;
  JSONObject appSdkConfig = new JSONObject()&lt;br /&gt;
          .put(&amp;quot;appid&amp;quot;, &amp;quot;PDA7D5EE6-B1B8-XXXX-XXXX-2A788BCXXXCA&amp;quot;)&lt;br /&gt;
          .put(&amp;quot;nol_devDebug&amp;quot;, &amp;quot;DEBUG&amp;quot;); // only for debug builds&lt;br /&gt;
&lt;br /&gt;
// Pass appSdkConfig to the AppSdk constructor&lt;br /&gt;
mAppSdk = new AppSdk(appContext, appSdkConfig, appSdkListener);&lt;br /&gt;
}&lt;br /&gt;
catch (JSONException e)&lt;br /&gt;
{&lt;br /&gt;
  Log.e(TAG, &amp;quot;Couldn’t prepare JSONObject for appSdkConfig&amp;quot;, e);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Here, &amp;lt;code&amp;gt;appContext&amp;lt;/code&amp;gt; is the App context object and &amp;lt;code&amp;gt;appSdkConfig&amp;lt;/code&amp;gt; is JSON object for holding the parameters (&amp;lt;code&amp;gt;appid&amp;lt;/code&amp;gt;) the App passes to the Nielsen App SDK via a JSON string. The appid is obtained from Nielsen operational support and is unique to the app.&lt;br /&gt;
&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;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Android DCR Static Step 3 - Create/Load DCR Static Metadata Object ===&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivision4&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 3 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivision4&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Configure Metadata ====&lt;br /&gt;
Map the Nielsen keys to variables so that the content metadata is dynamically updated.&lt;br /&gt;
&lt;br /&gt;
The Nielsen reserved keys are:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Key !! Description !! Data Type !! Value !! Required?&lt;br /&gt;
|-&lt;br /&gt;
| type || asset type || fixed || &amp;lt;code&amp;gt;'static'&amp;lt;/code&amp;gt; || Yes&lt;br /&gt;
|-&lt;br /&gt;
| assetid || Unique ID for each article || dynamic || custom &amp;lt;br&amp;gt;(no [[Special Characters]]) || No&lt;br /&gt;
|-&lt;br /&gt;
| section || section of each site (e.g. section value should be first level in page URL: website.com/section). Limit to 25 unique values || dynamic || custom || Yes&lt;br /&gt;
|-&lt;br /&gt;
| segA || custom segment for reporting: Limit to 25 unique values across custom segments (segA + segB + segC) || dynamic || custom || No&lt;br /&gt;
|-&lt;br /&gt;
| segB || custom segment for reporting: Limit to 25 unique values across custom segments (segA + segB + segC) || dynamic || custom || No&lt;br /&gt;
|-&lt;br /&gt;
| segC || custom segment for reporting: Limit to 25 unique values across custom segments (segA + segB + segC) || dynamic || custom || No&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The values passed through the Nielsen keys will determine the breakouts that are seen in reporting. The custom segments (A, B &amp;amp; C) will roll into the sub-brand. To not use custom segments A, B and C, do not pass any value in these keys.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Configure API calls - loadMetadata ====&lt;br /&gt;
Use [[loadMetadata]] to pass 'content' [[Digital Measurement Metadata]]. The CMS data must be passed as a JSON object.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;    loadMetadata(JSONObject jsonMetadata);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Refer to [[Digital Measurement Metadata]] for the list of parameters to be passed in the JSON object.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Note: The [[loadMetadata]] call must have (&amp;quot;type&amp;quot;: &amp;quot;static&amp;quot;). &amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Call [[loadMetadata]] with JSON metadata as below.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;    new JSONObject()&lt;br /&gt;
        .put(&amp;quot;type&amp;quot;, &amp;quot;static&amp;quot;)&lt;br /&gt;
        .put(&amp;quot;section&amp;quot;, &amp;quot;siteSection&amp;quot;)&lt;br /&gt;
        .put(&amp;quot;assetid&amp;quot;, &amp;quot;vid345-67483&amp;quot;)&lt;br /&gt;
        .put(&amp;quot;segA&amp;quot;, &amp;quot;segmentA&amp;quot;)&lt;br /&gt;
        .put(&amp;quot;segB&amp;quot;, &amp;quot;segmentB&amp;quot;)&lt;br /&gt;
        .put(&amp;quot;segC&amp;quot;,&amp;quot;segmentC&amp;quot;)&lt;br /&gt;
    }&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As soon as this loadMetadata call is made, AppSDK will record a view event and start tracking the section/page time spent (AppSDK 9.1 and above).&lt;br /&gt;
&lt;br /&gt;
==== DCR Static Duration Measurement per Section/Page/Asset ====&lt;br /&gt;
If your Nielsen AppID is enabled for DCR Static duration measurement, a view event will be recorded and a timer will be started for each screen/page. Duration will be measured until a new page is loaded or the app is moved to the background. The event which triggers recognition of page view and timer start is the loadMetadata API call with a metadata object of type 'static'. Once a page is viewed and the timer has started, duration will be measured until a new page has loaded ''with associated loadMetadata call having a different '''section name''' from the previous page''. If a new loadMetadata call is made with the same '''section name''', it will be ignored - no new view will be recorded. If it is desired to have a new view event even though the metadata contains the same '''section name''' (example: single-page apps having several assedIDs but common section name), staticEnd API can be called between page views. For the purposes of this overview, staticend will not be used. See [[DCR_Static_Android_SDK|this page]] for more information. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Keep Going ===&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivision5&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivision5&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Congratulations, you've successfully integrated the Android SDK in your app!&lt;br /&gt;
&lt;br /&gt;
You can add static loadMetadata calls for more sections/pages in your app to see what happens when transitioning between sections.&lt;br /&gt;
&lt;br /&gt;
View your application's debug logs and search for the term (AppSDK) to see messages emitted by Nielsen AppSDK.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Next Steps ===&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivision6&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivision6&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now that you've integrated DCR Static for the AppSDK, what's next?&lt;br /&gt;
&lt;br /&gt;
====Going Live====&lt;br /&gt;
&lt;br /&gt;
In addition to the basic steps above, before going live developers need to handle app background/foreground events, make certain privacy disclosures, and allow users to opt out of Nielsen measurement. More details can be found [[DCR_Static_Android_SDK|here]], along with a more comprehensive reference for implementing DCR Static measurement with AppSDK.&lt;br /&gt;
&lt;br /&gt;
Once the DCR Tracking Code is added, Nielsen will validate the implementation. Following Nielsen testing, developers need to make a few updates to the initialization call to ensure that the app is being measured properly.&lt;br /&gt;
&lt;br /&gt;
#'''App ID''': Ensure that correct  is used during initialization '''PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'''&lt;br /&gt;
#'''Debug Logging''': Disable logging by changing initialization call to use @&amp;quot;nol_devDebug&amp;quot;:@&amp;quot;INFO&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== &amp;amp;rarr; Android DCR Video ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivision7&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide DCR Video &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivision7&amp;quot;&amp;gt;&lt;br /&gt;
==== Android DCR Video Introduction ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv8&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide Intro &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv8&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Digital Content Ratings (DCR) Video product provides content consumption measurement on client webpages. This measurement includes insight into the total time a user spent watching the tracked content, video player events, and much more.&lt;br /&gt;
This example provides the steps to implement the DCR Video product in a sample Android app. It includes:&lt;br /&gt;
&lt;br /&gt;
*SDK Initialization&lt;br /&gt;
*DCR Video Metadata: information about the content being tracked&lt;br /&gt;
*DCR Video Events/API calls&lt;br /&gt;
&lt;br /&gt;
By the end of this guide you will have the needed steps to integrate Nielsen's AppSDK in the background of your app.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Android DCR Video Step 1 - Obtain AppID ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv9&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 1 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv9&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To begin using the Android AppSDK, you will need to obtain an Application ID (AppId)&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! !! Item !! Description !! Source&lt;br /&gt;
|-&lt;br /&gt;
|&amp;amp;#9989; || App ID (appid) || Unique ID assigned to the player/site and configured by product || Contact your Nielsen Representative&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The appid is a 37 character unique ID assigned to the player/site and configured by product and is required when creating a new instance of the AppSDK in the app.&lt;br /&gt;
&amp;lt;/br&amp;gt;Example: '''PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Android DCR Video Step 2 - SDK Initialization ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivision10&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 2 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivision10&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Setting up your  Development Environment  =====&lt;br /&gt;
===== Configuring Android Development Environment =====&lt;br /&gt;
*The Nielsen App SDK (located in the [https://engineeringportal.nielsen.com/docs/Special:Downloads Downloads section] of the website) class is the primary application interface to the Nielsen App SDK on Android.&lt;br /&gt;
*The Nielsen App SDK class is defined as the only public class belonging to the com.nielsen.app.sdk package.&lt;br /&gt;
*The Nielsen App SDK can also be added via [https://engineeringportal.nielsen.com/docs/Digital_Measurement_Android_Artifactory_Guide Artifact Repository].&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;
&lt;br /&gt;
Once SDK is downloaded ensure to unzip the Nielsen SDK and copy the AppSdk.jar in your app (Android Studio) libs folder, then right click the AppSdk.jar and select '''Add As Library'''.&lt;br /&gt;
Ensure the AppSdk.jar file is added in 'build.gradle (App Level) file.&lt;br /&gt;
* App SDK 1.2 provides support for x86, mips, and armeabi-7a architecture.&lt;br /&gt;
&lt;br /&gt;
===== Google Play Services =====&lt;br /&gt;
Add the Google Play Services in the project,&lt;br /&gt;
Steps: Android Studio -&amp;gt; File -&amp;gt; Project Structure -&amp;gt;(In module selection) select App -&amp;gt; Dependencies (tab) -&amp;gt; Click &amp;quot;+&amp;quot; button and search for &amp;lt;code&amp;gt;&amp;quot;*play-services*&amp;quot;&amp;lt;/code&amp;gt;.  Then select the most recent version of the play-services Artifact.&lt;br /&gt;
Ensure it is added in build.gradle (App level) file&lt;br /&gt;
&lt;br /&gt;
===== Google AD ID Permissions =====&lt;br /&gt;
The following is required if target API level is set to 31 (Android 12) with the Ad Version of the Nielsen SDK.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;uses-permission android:name=&amp;quot;com.google.android.gms.permission.AD_ID&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;
====== Manifest File ====== &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;&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 runtime permissions in Android versions, please visit [https://developer.android.com/training/permissions/requesting.html].   &lt;br /&gt;
&lt;br /&gt;
* In &amp;lt;code&amp;gt;AndroidManifest.xml &amp;lt;/code&amp;gt;under &amp;lt;code&amp;gt;&amp;lt;application&amp;gt;&amp;lt;/code&amp;gt; add the following metadata&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&amp;lt;meta-data &lt;br /&gt;
android:name=&amp;quot;com.google.android.gms.version&amp;quot; &lt;br /&gt;
android:value=&amp;quot;@integer/google_play_services_version&amp;quot;/&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&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;
&lt;br /&gt;
===== Library =====&lt;br /&gt;
Nielsen App SDK uses the following packages/classes from the Google Play service.&lt;br /&gt;
* google-play-services_lib&lt;br /&gt;
&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;
===== SDK Initialization =====&lt;br /&gt;
&lt;br /&gt;
The following table contains the list of arguments that can be passed via the AppInfo JSON schema.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter / Argument !! Description !! Source !! Required? !! Example&lt;br /&gt;
|-&lt;br /&gt;
| appid || Unique Nielsen ID for the application. The ID is a GUID data type. If you did not receive your App ID, let us know and we will provide you. || Nielsen-specified || Yes || PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&lt;br /&gt;
|-&lt;br /&gt;
| nol_devDebug || Enables Nielsen console logging. Only required for testing&lt;br /&gt;
|| Nielsen-specified || Optional || &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
== Debug flag for development environment ==&lt;br /&gt;
Player application developers / integrators can use Debug flag to check whether an App SDK API call made is successful. To activate the Debug flag,&lt;br /&gt;
Pass the argument &amp;lt;code&amp;gt;@&amp;quot;nol_devDebug&amp;quot;:@&amp;quot;DEBUG&amp;quot;&amp;lt;/code&amp;gt;, in the JSON string . The permitted values are:&lt;br /&gt;
&lt;br /&gt;
* '''INFO''': Displays the API calls and the input data from the application (validate player name, app ID, etc.). It can be used as certification Aid.&lt;br /&gt;
* '''WARN''': Indicates potential integration / configuration errors or SDK issues.&lt;br /&gt;
* '''ERROR''': Indicates important integration errors or non-recoverable SDK issues.&lt;br /&gt;
* '''DEBUG''': Debug logs, used by the developers to debug more complex issues.&lt;br /&gt;
&lt;br /&gt;
Once the flag is active, it logs each API call made and the data passed. The log created by this flag is minimal.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': DO NOT activate the Debug flag in a production environment.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Sample SDK Initialization Code ====&lt;br /&gt;
&lt;br /&gt;
'''Initialization of App SDK object through a JSON object'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;try&lt;br /&gt;
{&lt;br /&gt;
  // Prepare AppSdk configuration object (JSONObject)&lt;br /&gt;
  JSONObject appSdkConfig = new JSONObject()&lt;br /&gt;
          .put(&amp;quot;appid&amp;quot;, &amp;quot;PDA7D5EE6-B1B8-XXXX-XXXX-2A788BCXXXCA&amp;quot;)&lt;br /&gt;
          .put(&amp;quot;nol_devDebug&amp;quot;, &amp;quot;DEBUG&amp;quot;); // only for debug builds&lt;br /&gt;
&lt;br /&gt;
// Pass appSdkConfig to the AppSdk constructor&lt;br /&gt;
mAppSdk = new AppSdk(appContext, appSdkConfig, appSdkListener);&lt;br /&gt;
}&lt;br /&gt;
catch (JSONException e)&lt;br /&gt;
{&lt;br /&gt;
  Log.e(TAG, &amp;quot;Couldn’t prepare JSONObject for appSdkConfig&amp;quot;, e);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Here, &amp;lt;code&amp;gt;appContext&amp;lt;/code&amp;gt; is the App context object and &amp;lt;code&amp;gt;appSdkConfig&amp;lt;/code&amp;gt; is JSON object for holding the parameters (&amp;lt;code&amp;gt;appid&amp;lt;/code&amp;gt;) the App passes to the Nielsen App SDK via a JSON string. The appid is obtained from Nielsen operational support and is unique to the app.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The integration of Nielsen App SDK will depend on type of client app.&amp;lt;br /&amp;gt;&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;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Android DCR Video Step 3 - Create DCR Video Content Metadata Object ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv11&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 3 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv11&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Handling JSON Metadata =====&lt;br /&gt;
The SDK methods handle 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.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
! '''Keys''' !! '''Description''' !! '''Values''' !! '''Required'''!!'''Provider'''&lt;br /&gt;
|-&lt;br /&gt;
| type || Type of asset ||For Video use: &amp;lt;code&amp;gt;content&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt; For Static or text &amp;lt;code&amp;gt;static&amp;lt;/code&amp;gt; || Yes || Nielsen&lt;br /&gt;
|-style=&amp;quot;background-color:#e9f9fa;&amp;quot;&lt;br /&gt;
| assetid || Unique ID assigned to asset &amp;lt;br&amp;gt; Note: Refrain from using the following special characters [[Special_Characters|(Special Characters)]]. || Examples: &amp;lt;br&amp;gt; &amp;lt;code&amp;gt;BBT345a234 &amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; &amp;lt;code&amp;gt;CBSs5e234F2021&amp;lt;/code&amp;gt;  || Yes || Client &lt;br /&gt;
|-&lt;br /&gt;
| program ||Complete program or movie title &amp;lt;br&amp;gt; (no abbreviations or shorthand) &amp;lt;br&amp;gt; Note: there is a 25 character limit.  ||&amp;lt;code&amp;gt; The Big Bang Theory&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; &amp;lt;code&amp;gt; TheBigBangTheory&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt;&amp;lt;code&amp;gt; The Dark Knight&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt;&amp;lt;code&amp;gt; TheDarkKnight&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; || Yes || Client &lt;br /&gt;
|-style=&amp;quot;background-color:#e9f9fa;&amp;quot;&lt;br /&gt;
| title ||Episode title with season and episode number (40 character limit) &amp;lt;br&amp;gt; (Formats accepted: S01E03, S1E3, S1 E3). || Examples: &amp;lt;br&amp;gt; &amp;lt;code&amp;gt;The Pants Alternative S03E18&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; &amp;lt;code&amp;gt;The Pants Alternative S3E18&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; &amp;lt;code&amp;gt;The Pants Alternative S3 E18&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; Can also accept: &amp;lt;code&amp;gt; S3E18&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; Not Valid: &amp;lt;code&amp;gt; 318 &amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt; 0318 &amp;lt;/code&amp;gt;|| Yes || Client &lt;br /&gt;
|-&lt;br /&gt;
| crossId1 || Gracenote TMS ID (If available) should be passed for all telecasted content for clients using the Gracenote solution for proper matching purposes. &amp;lt;br&amp;gt;Note: The TMS ID will be a 14 character string. Normally leading with 2 alpha characerts ('EP', 'MV', 'SH' or 'SP'), followed by 12 numbers.&lt;br /&gt;
|| The TMS ID will be a 14 character string. &amp;lt;br&amp;gt; Normally being with  'EV,' 'EP', 'SH', 'SP', or 'MV' &amp;lt;br&amp;gt; Followed by 12 numbers after the initial two letter prefix. &amp;lt;br&amp;gt; &amp;lt;br&amp;gt; The Giant Morning Show: &amp;lt;code&amp;gt;SH009311820022&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; The Pants Alternative Episode : &amp;lt;code&amp;gt;EP009311820061&amp;lt;/code&amp;gt; || Optional || Nielsen&lt;br /&gt;
|-style=&amp;quot;background-color:#e9f9fa;&amp;quot;&lt;br /&gt;
| crossId2 || Populated by content distributor to contribute viewing from that distributor to the given content originator. || Custom&amp;lt;br&amp;gt;For a full list of acceptable values, please contact your Nielsen reprentative. || Yes, for distributors || Nielsen&lt;br /&gt;
|-&lt;br /&gt;
| length || Length of content in seconds&amp;lt;br&amp;gt;Note: Integers and decimals are acceptable values are acceptable for the length parameter. || Examples:&lt;br /&gt;
&amp;lt;small&amp;gt;For standard VOD content - &amp;lt;code&amp;gt;300&amp;lt;/code&amp;gt; to represent 5 minutes, &amp;lt;code&amp;gt;1320&amp;lt;/code&amp;gt; to represent 22 minutes, etc.&lt;br /&gt;
&amp;lt;br&amp;gt;If DAI live stream of a discrete program (Live Event/Sporting Event), pass length of content. See example for standard VOD content above.&lt;br /&gt;
&amp;lt;br&amp;gt;If unknown DAI live steam, pass a value of &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;.&amp;lt;/small&amp;gt; &lt;br /&gt;
|| Yes || Client &lt;br /&gt;
|-style=&amp;quot;background-color:#e9f9fa;&amp;quot;&lt;br /&gt;
| airdate ||Original broadcast or release date for the program &amp;lt;br&amp;gt;For USA, date should be EST &amp;lt;br&amp;gt; Outside USA, date should be local time.&amp;lt;br&amp;gt;If not applicable or available, original broadcast or release date for the Program. || Acceptable Formats:&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;YYYY-MM-DDTHH:MI:SS&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;YYYY-MM-DDHH:MI:SS&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;YYYY-MM-DDTHH:MI:SS+xx:xx&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;YYYY-MM-DDTHH:MI:SS-xx:xx&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;YYYYMMDDHH:MI:SS&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;YYYYMMDD HH:MI:SS&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;MM-DD-YYYY&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;MM/DD/YYYY&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;YYYYMMDD&amp;lt;/code&amp;gt;&amp;lt;/big&amp;gt; || Yes || Client &lt;br /&gt;
|-&lt;br /&gt;
| isfullepisode || Full episode flag to identify differences between long form content. || &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;- full episode, &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt;- non full episode(clip,teaser,promo,etc.)&lt;br /&gt;
&amp;lt;small&amp;gt;Also accept: &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;lf&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;yes&amp;lt;/code&amp;gt;- longform&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;sf&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;no&amp;lt;/code&amp;gt;- shortform&lt;br /&gt;
|| Yes || Nielsen&lt;br /&gt;
|-style=&amp;quot;background-color:#e9f9fa;&amp;quot;&lt;br /&gt;
| adloadtype || &amp;lt;big&amp;gt;&amp;lt;small&amp;gt;Type of ad load: &lt;br /&gt;
&amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; Linear – matches TV ad load&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;2&amp;lt;/code&amp;gt; Dynamic – Dynamic Ad Insertion (DAI)&amp;lt;/small&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
|| &amp;lt;code&amp;gt;2&amp;lt;/code&amp;gt; - DCR measures content with dynamic ads || Yes || Nielsen&lt;br /&gt;
|-&lt;br /&gt;
| segB || One of two custom segment for the clients granular reporting within a brand. || Examples:&amp;lt;br&amp;gt;Genre - &amp;lt;code&amp;gt;horror&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;comedy&amp;lt;/code&amp;gt;, etc.&amp;lt;br&amp;gt;Timeslot - &amp;lt;code&amp;gt;primetime&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;daytime&amp;lt;/code&amp;gt;, etc.&amp;lt;br&amp;gt;News type - &amp;lt;code&amp;gt;breakingnews&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;weather&amp;lt;/code&amp;gt;, etc. || Optional || Client &lt;br /&gt;
|-style=&amp;quot;background-color:#e9f9fa;&amp;quot;&lt;br /&gt;
| segC || One of two custom segment for the clients granular reporting within a brand. || Examples:&amp;lt;br&amp;gt;Genre - &amp;lt;code&amp;gt;horror&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;comedy&amp;lt;/code&amp;gt;, etc.&amp;lt;br&amp;gt;Timeslot - &amp;lt;code&amp;gt;primetime&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;daytime&amp;lt;/code&amp;gt;, etc.&amp;lt;br&amp;gt;News type - &amp;lt;code&amp;gt;breakingnews&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;weather&amp;lt;/code&amp;gt;, etc. || Optional || Client &lt;br /&gt;
|}&lt;br /&gt;
Custom segments (segB and segC) can be used to aggregate video and/or static content within a single Brand to receive more granular reports within a brand.&lt;br /&gt;
&lt;br /&gt;
Examples regarding usage of segments within SDK:&lt;br /&gt;
* All comedy clips and stories for a Brand rolled into a &amp;quot;Comedy&amp;quot; segment&lt;br /&gt;
* genre grouping content by Comedy vs. Drama&lt;br /&gt;
* group related Text + Video content - i.e. for a show that has a lot of - static pages associated with it&lt;br /&gt;
* packaging based on how clients sell inventory&lt;br /&gt;
* grouping related types of content either by genre, category or platform.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Android DCR Video Step 4 - Basic Set of Events - Sample Playback ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv12&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 4 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv12&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Configure API Calls =====&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;
&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;
==== Sample Use Case: 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;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Keep Going ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv13&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv13&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Congratulations, you've successfully integrated the Android SDK in your app for a basic content playback scenario!&lt;br /&gt;
&lt;br /&gt;
You can add more content to see channel-change scenarios or continue to next steps below.&lt;br /&gt;
&lt;br /&gt;
View your application's debug logs and search for the term (AppSDK) to see messages emitted by Nielsen AppSDK during video playback.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Next Steps ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv14&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv14&amp;quot;&amp;gt;&lt;br /&gt;
====Going Live====&lt;br /&gt;
&lt;br /&gt;
In addition to the basic steps above, before going live developers need to handle app background/foreground events, make certain privacy disclosures, handle interruption events (stop, fast-forward, rewind), and allow users to opt out of Nielsen measurement. More details can be found [[DCR_Video_iOS_SDK|here]], along with a more comprehensive reference for implementing DCR Video measurement with AppSDK.&lt;br /&gt;
&lt;br /&gt;
Once the DCR Tracking Code is added, Nielsen will validate the implementation. Following Nielsen testing, developers need to make a few updates to the initialization call to ensure that the app is being measured properly.&lt;br /&gt;
&lt;br /&gt;
#'''App ID''': Ensure that correct  is used during initialization '''PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'''&lt;br /&gt;
#'''Debug Logging''': Disable logging by changing initialization call to use @&amp;quot;nol_devDebug&amp;quot;:@&amp;quot;INFO&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== &amp;amp;rarr; Android DTVR (coming soon) ==&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivision100&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide Android DTVR &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivision100&amp;quot;&amp;gt;&lt;br /&gt;
==== Android DTVR Introduction ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv200-&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide Intro &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv200-&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Nielsen DTVR (Digital TV Ratings) product provides content consumption measurement in client mobile apps and webpages. This measurement includes insight into the total time a user spent watching the tracked content, video player events, and much more.&lt;br /&gt;
This example provides the steps to implement the DTVR product in a sample Android app using Nielsen AppSDK. It includes:&lt;br /&gt;
&lt;br /&gt;
*SDK Initialization&lt;br /&gt;
*DTVR Video Metadata: information about the content being tracked&lt;br /&gt;
*DTVR Video Events/API calls&lt;br /&gt;
*Extracting ID3 tags from the video stream and passing to AppSDK for measurement&lt;br /&gt;
&lt;br /&gt;
By the end of this guide you will have the needed steps to integrate Nielsen's AppSDK in the background of your app for DTVR measurement.&lt;br /&gt;
&lt;br /&gt;
'''NOTE: video streams must have Nielsen ID3 tags embedded in order to be measured using the DTVR product. See the section in this guide &amp;quot;Extracting ID3 Tags&amp;quot; or contact your Nielsen representative for more information.'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Android DTVR Step 1 - Obtain AppID ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv300&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 1 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv300&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To begin using the Android AppSDK, you will need to obtain an Application ID (AppId)&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! !! Item !! Description !! Source&lt;br /&gt;
|-&lt;br /&gt;
|&amp;amp;#9989; || App ID (appid) || Unique ID assigned to the player/site and configured by product || Contact your Nielsen Representative&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The appid is a 37 character unique ID assigned to the player/site and configured by product and is required when creating a new instance of the AppSDK in the app.&lt;br /&gt;
&amp;lt;/br&amp;gt;Example: '''PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Android DTVR Step 2 - SDK Initialization ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivision400&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 2 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivision400&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Configuring Android Development Environment =====&lt;br /&gt;
*The Nielsen App SDK (located in the [https://engineeringportal.nielsen.com/docs/Special:Downloads Downloads section] of the website) class is the primary application interface to the Nielsen App SDK on Android.&lt;br /&gt;
*The Nielsen App SDK class is defined as the only public class belonging to the com.nielsen.app.sdk package.&lt;br /&gt;
*The Nielsen App SDK can also be added via [https://engineeringportal.nielsen.com/docs/Digital_Measurement_Android_Artifactory_Guide Artifact Repository].&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;
&lt;br /&gt;
Once SDK is downloaded ensure to unzip the Nielsen SDK and copy the AppSdk.jar in your app (Android Studio) libs folder, then right click the AppSdk.jar and select '''Add As Library'''.&lt;br /&gt;
Ensure the AppSdk.jar file is added in 'build.gradle (App Level) file.&lt;br /&gt;
* App SDK 1.2 provides support for x86, mips, and armeabi-7a architecture.&lt;br /&gt;
&lt;br /&gt;
===== Google Play Services =====&lt;br /&gt;
Add the Google Play Services in the project,&lt;br /&gt;
Steps: Android Studio -&amp;gt; File -&amp;gt; Project Structure -&amp;gt;(In module selection) select App -&amp;gt; Dependencies (tab) -&amp;gt; Click &amp;quot;+&amp;quot; button and search for &amp;lt;code&amp;gt;&amp;quot;*play-services*&amp;quot;&amp;lt;/code&amp;gt;.  Then select the most recent version of the play-services Artifact.&lt;br /&gt;
Ensure it is added in build.gradle (App level) file&lt;br /&gt;
&lt;br /&gt;
===== Google AD ID Permissions =====&lt;br /&gt;
The following is required if target API level is set to 31 (Android 12) with the Ad Version of the Nielsen SDK.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;uses-permission android:name=&amp;quot;com.google.android.gms.permission.AD_ID&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;
====== Manifest File ====== &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;&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 runtime permissions in Android versions, please visit [https://developer.android.com/training/permissions/requesting.html].   &lt;br /&gt;
&lt;br /&gt;
* In &amp;lt;code&amp;gt;AndroidManifest.xml &amp;lt;/code&amp;gt;under &amp;lt;code&amp;gt;&amp;lt;application&amp;gt;&amp;lt;/code&amp;gt; add the following metadata&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&amp;lt;meta-data &lt;br /&gt;
android:name=&amp;quot;com.google.android.gms.version&amp;quot; &lt;br /&gt;
android:value=&amp;quot;@integer/google_play_services_version&amp;quot;/&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&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;
&lt;br /&gt;
===== Library =====&lt;br /&gt;
Nielsen App SDK uses the following packages/classes from the Google Play service.&lt;br /&gt;
* google-play-services_lib&lt;br /&gt;
&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;
===== SDK Initialization =====&lt;br /&gt;
&lt;br /&gt;
The following table contains the list of arguments that can be passed via the AppInfo JSON schema.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter / Argument !! Description !! Source !! Required? !! Example&lt;br /&gt;
|-&lt;br /&gt;
| appid || Unique Nielsen ID for the application. The ID is a GUID data type. If you did not receive your App ID, let us know and we will provide you. || Nielsen-specified || Yes || PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&lt;br /&gt;
|-&lt;br /&gt;
| nol_devDebug || Enables Nielsen console logging. Only required for testing&lt;br /&gt;
|| Nielsen-specified || Optional || &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Debug flag for development environment ==&lt;br /&gt;
Player application developers / integrators can use Debug flag to check whether an App SDK API call made is successful. To activate the Debug flag,&lt;br /&gt;
Pass the argument &amp;lt;code&amp;gt;@&amp;quot;nol_devDebug&amp;quot;:@&amp;quot;DEBUG&amp;quot;&amp;lt;/code&amp;gt;, in the JSON string . The permitted values are:&lt;br /&gt;
&lt;br /&gt;
* '''INFO''': Displays the API calls and the input data from the application (validate player name, app ID, etc.). It can be used as certification Aid.&lt;br /&gt;
* '''WARN''': Indicates potential integration / configuration errors or SDK issues.&lt;br /&gt;
* '''ERROR''': Indicates important integration errors or non-recoverable SDK issues.&lt;br /&gt;
* '''DEBUG''': Debug logs, used by the developers to debug more complex issues.&lt;br /&gt;
&lt;br /&gt;
Once the flag is active, it logs each API call made and the data passed. The log created by this flag is minimal.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': DO NOT activate the Debug flag in a production environment.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Sample SDK Initialization Code ====&lt;br /&gt;
&lt;br /&gt;
'''Initialization of App SDK object through a JSON object'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;try&lt;br /&gt;
{&lt;br /&gt;
  // Prepare AppSdk configuration object (JSONObject)&lt;br /&gt;
  JSONObject appSdkConfig = new JSONObject()&lt;br /&gt;
          .put(&amp;quot;appid&amp;quot;, &amp;quot;PDA7D5EE6-B1B8-XXXX-XXXX-2A788BCXXXCA&amp;quot;)&lt;br /&gt;
          .put(&amp;quot;nol_devDebug&amp;quot;, &amp;quot;DEBUG&amp;quot;); // only for debug builds&lt;br /&gt;
&lt;br /&gt;
// Pass appSdkConfig to the AppSdk constructor&lt;br /&gt;
mAppSdk = new AppSdk(appContext, appSdkConfig, appSdkListener);&lt;br /&gt;
}&lt;br /&gt;
catch (JSONException e)&lt;br /&gt;
{&lt;br /&gt;
  Log.e(TAG, &amp;quot;Couldn’t prepare JSONObject for appSdkConfig&amp;quot;, e);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Here, &amp;lt;code&amp;gt;appContext&amp;lt;/code&amp;gt; is the App context object and &amp;lt;code&amp;gt;appSdkConfig&amp;lt;/code&amp;gt; is JSON object for holding the parameters (&amp;lt;code&amp;gt;appid&amp;lt;/code&amp;gt;) the App passes to the Nielsen App SDK via a JSON string. The appid is obtained from Nielsen operational support and is unique to the app.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The integration of Nielsen App SDK will depend on type of client app.&amp;lt;br /&amp;gt;&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;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Android DTVR Step 3 - Create DTVR Content Metadata Object ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv500&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 3 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv500&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Configure Metadata =====&lt;br /&gt;
Content metadata should remain constant throughout the completion of an episode or live stream.&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      || ✓&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
------------------------&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;   &lt;br /&gt;
    public JSONObject loadDtvr() {&lt;br /&gt;
     try {&lt;br /&gt;
            dtvrdata = new JSONObject()&lt;br /&gt;
                    .put( &amp;quot;type&amp;quot;,&amp;quot;content&amp;quot;)&lt;br /&gt;
                    .put(&amp;quot;adModel&amp;quot;, &amp;quot;1&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        return dtvrdata;&lt;br /&gt;
    }&lt;br /&gt;
    &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Android DTVR Step 4 - Basic Set of Events - Sample Playback ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv600&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide step 4 &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv600&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== SDK Events/APIs =====&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;
&lt;br /&gt;
===== Configure API calls - loadMetadata =====&lt;br /&gt;
Use &amp;lt;code&amp;gt;loadMetadata&amp;lt;/code&amp;gt; to pass the metadata object created above. &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt; appSdk.loadMetadata(dtvrdata);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Configure API calls - sendID3 =====&lt;br /&gt;
[[sendID3]] API is a receiver for timed metadata events (ID3 tags. This API filters out Nielsen-specific ID3 tags from the system and buffers the data for transfer to Nielsen’s collection facility.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt; //Sending ID3 tag to SDK.&lt;br /&gt;
appSdk.sendID3(id3String);&amp;lt;/syntaxhighlight&amp;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;
Refer to [[Android SDK API Reference#Retrieving ID3 Tags|Retrieving ID3 Tags]] section to know more details.&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;
=====  Examples of extracting ID3 tags fromAndroid 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 mediaPlayer, TimedMetaData timedMetaData) {&lt;br /&gt;
&lt;br /&gt;
        if(timedMetaData != null &amp;amp;&amp;amp; timedMetaData.getMetaData() != null &amp;amp;&amp;amp; mMediaPlayer.isPlaying()){&lt;br /&gt;
&lt;br /&gt;
            //getting metadata.&lt;br /&gt;
            String iD3Payload = new String(timedMetaData.getMetaData(), StandardCharsets.UTF_8);&lt;br /&gt;
&lt;br /&gt;
            //If tag metadata contains &amp;quot;www.nielsen.com&amp;quot;, then only sending to SDK&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;
                //getting index&lt;br /&gt;
                int index = iD3Payload.indexOf(&amp;quot;www.nielsen.com&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
                //getting substring as ID3 tag will be of 249 characters&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;
&lt;br /&gt;
                //Sending ID3 tag to SDK.&lt;br /&gt;
                appSdk.sendID3(id3String);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/syntaxhighlight&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. &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 loadMetadata and sendID3 events to occur.&lt;br /&gt;
# '''Processing state''' – The SDK instance is processing playing information. The &amp;lt;code&amp;gt;'''loadMetadata'''&amp;lt;/code&amp;gt; call moves the SDK instance into this state. In this state, the SDK instance will be able to process sendID3 calls and measure content.&lt;br /&gt;
# '''Disabled state''' – The SDK instance is disabled.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Keep Going ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv900&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv900&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Congratulations, you've successfully integrated the Android SDK in your app for a basic content playback scenario!&lt;br /&gt;
&lt;br /&gt;
You can add more content to see channel-change scenarios or continue to next steps below.&lt;br /&gt;
&lt;br /&gt;
View your application's debug logs and search for the term (AppSDK) to see messages emitted by Nielsen AppSDK during video playback.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Next Steps ====&lt;br /&gt;
&amp;lt;span class=&amp;quot;mw-customtoggle-myDivisionv1000&amp;quot; style=&amp;quot;color: cornflowerblue&amp;quot;&amp;gt; Show/hide &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-myDivisionv1000&amp;quot;&amp;gt;&lt;br /&gt;
====Going Live====&lt;br /&gt;
&lt;br /&gt;
In addition to the basic steps above, before going live developers need to handle app background/foreground events, make certain privacy disclosures, handle interruption events (stop, fast-forward, rewind), and allow users to opt out of Nielsen measurement. More details can be found [[DTVR_Android_SDK|here]], along with a more comprehensive reference for implementing DTVR measurement with AppSDK.&lt;br /&gt;
&lt;br /&gt;
Once the DTVR Tracking Code is added, Nielsen will validate the implementation. Following Nielsen testing, developers need to make a few updates to the initialization call to ensure that the app is being measured properly.&lt;br /&gt;
&lt;br /&gt;
#'''App ID''': Ensure that correct  is used during initialization '''PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'''&lt;br /&gt;
#'''Debug Logging''': Disable logging by changing initialization call to use @&amp;quot;nol_devDebug&amp;quot;:@&amp;quot;INFO&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>NickParrucci</name></author>
	</entry>
	<entry>
		<id>https://nielsentest.mywikis.net/w/index.php?title=DCR_Italy_Static_iOS_SDK&amp;diff=6461</id>
		<title>DCR Italy Static iOS SDK</title>
		<link rel="alternate" type="text/html" href="https://nielsentest.mywikis.net/w/index.php?title=DCR_Italy_Static_iOS_SDK&amp;diff=6461"/>
		<updated>2023-07-20T12:16:40Z</updated>

		<summary type="html">&lt;p&gt;NickParrucci: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|International DCR}}  {{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]]), [[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;
== Prerequisites ==&lt;br /&gt;
This Guide is for the Implementation of Static Measurement. For implementation of Video, please refer to the [[DCR Italy Video iOS SDK |iOS DCR Video Implementation Guide.]]&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: 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. || Provided by 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;
 || '''sfcode''' || Unique identifier for the environment that the SDK should point to || Provided by Nielsen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
If need App ID(s) or our SDKs, feel free to reach out to us and we will be happy to help you get started.&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;
=== Notes for WebView Contents ===&lt;br /&gt;
&amp;lt;code&amp;gt;Please note that if within your APP user can surf '''static contents''' recalled from your website the [[DCR_Italy_Static_Browser_SDK|browser static SDK]] have to inhibit from this pages.&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==  Implementation ==&lt;br /&gt;
This guide covers implementation steps for iOS using Xcode to enable '''Static Measurement''' within you APP.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;If you are building an app for the 'kids category' please review the [[DCR_Italy_Static_iOS_SDK#Special_Note_Regarding_Apps_in_the_Kids_Category|Opt Out Requirement.]]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== How to obtain the NielsenAppApi.Framework ===&lt;br /&gt;
The Nielsen AppSDK can either be downloaded directly or can be integrated directly within an application through the use of CocoaPods. We recommend using the CocoaPods-based integration whenever possible to ensure you maintain the most recent changes and enhancements to the Nielsen libraries.&lt;br /&gt;
* [[Digital_Measurement_iOS_Artifactory_Guide|Select to obtain CocoaPods implementation guide]]&lt;br /&gt;
* [[Special:Downloads|Select to Download Directly]]&lt;br /&gt;
* [[DCR_Video_iOS_SDK_xcframework|Using the XCFramework bundle]]&lt;br /&gt;
&lt;br /&gt;
== Special Notes regarding iOS14 ==&lt;br /&gt;
=== Permission to Track === &lt;br /&gt;
&lt;br /&gt;
Apple recently released a new policy on consent requirements, that require the user's permission, to track them using their device's advertising identifier (IDFA).  To request the user's permission, use the AppTrackingTransparency framework. &lt;br /&gt;
&lt;br /&gt;
For more information, see:&lt;br /&gt;
* [https://developer.apple.com/documentation/apptrackingtransparency App Tracking Transparency]&lt;br /&gt;
* [https://developer.apple.com/design/human-interface-guidelines/ios/app-architecture/requesting-permission/ Human Interface Guidelines]&lt;br /&gt;
* [https://developer.apple.com/documentation/adsupport AdSupport Framework]&lt;br /&gt;
&lt;br /&gt;
More detailed information on how the Nielsen SDK versions work with the AppTrackingTransparency framework is located on our [[ DCR Video iOS14 Migration|DCR Video iOS14 Migration]] page.&lt;br /&gt;
&lt;br /&gt;
== Setting up your  Development Environment  ==&lt;br /&gt;
Prior to SDK Version 6.2.0.0 the  IOS framework has been distributed as a static library packaged into framework bundle format. Apple recommends to use dynamic framework, it has some benefits over static libraries like less executable file size of an app, faster startup time and native support in xCode IDE. Nielsen AppSDK has been transformed into dynamic framework in this release ([[iOS_Static_Framework_Setup|static framework]] is still available).&lt;br /&gt;
&lt;br /&gt;
If migrating from the static library to this new dynamic framework, once implemented, unless your specific application requires, you can remove the following Frameworks that were once required:&amp;lt;code&amp;gt; [AdSupport, JavascriptCore, SystemConfiguration, Security, AVFoundation, libc++] &amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The '''Dynamic framework''' is created as a fat framework. It means that it contains slices required for devices (armv7, arm64) as well as slices required for simulators (i386, x86_64). Simulator slices are needed to let clients build and debug their app on the simulators, but they should be removed before sending the app to the AppStore. The example of the shell script that should be added as a Run Script phase in the application can be [[DCR_Video_iOS_SDK#Removing_Simulators_.28Dynamic_Framework_Only.29|found below]].&lt;br /&gt;
&lt;br /&gt;
'''[[DCR_Video_iOS_SDK_xcframework|XCFramework]]''' is solution for the problems described above Apple recommends to use XCFrameworks. In XCFramework, we no longer build a single framework with multiple architectures. Instead, we build one small framework for each combination of architecture and target and store it in its own folder. The top-level XCFramework folder have folders like ios-arm64, ios-arm64-simulator, etc. Each of these folders is its own framework, complete with headers, modules, and binary.&lt;br /&gt;
&lt;br /&gt;
=== Configuring Xcode Development Environment ===&lt;br /&gt;
Starting with SDK version 6.0.0.0, the Nielsen App SDK is compatible with Apple iOS versions 8.0 and above.  In addition, when using the dynamic framework,  all the required frameworks are linked automatically as the are needed.  More details can be found here: https://stackoverflow.com/questions/24902787/dont-we-need-to-link-framework-to-xcode-project-anymore&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': All communications between the SDK and the Census (Collection Facility) use HTTPS.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Special Note for Static Framework ===&lt;br /&gt;
Starting from 8.2.0.0 release framework is build from the mixed (swift + objc) source code.&lt;br /&gt;
If [[iOS_Static_Framework_Setup|static (xc)framework is integrated additional settings]] should be applied to fix build or runtime issues.&lt;br /&gt;
&lt;br /&gt;
=== Download Framework ===&lt;br /&gt;
The first step is to download and copy the [[Special:Downloads|NielsenAppApi.framework]] bundle to the app project directory. (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
=== Add Framework ===&lt;br /&gt;
In the General tab for app configuration add NielsenAppApi.framework in the list of Embedded Binaries.  (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
=== Add Path ===&lt;br /&gt;
Add path to the NielsenAppApi.framework in the Framework Search Paths build setting.  (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
=== Import Framework ===&lt;br /&gt;
Add NielsenAppApi.framework module in the source file of your app:&lt;br /&gt;
&lt;br /&gt;
==== Using Swift ====&lt;br /&gt;
Add the following:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
import NielsenAppApi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using Objective-C ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang =&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
@import NielsenAppApi;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== xCode 12 building errors ====&lt;br /&gt;
Developers who uses &amp;quot;fat&amp;quot; framework in their apps started reporting the following error that they get building the app in xCode 12.3+:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Building for iOS Simulator, but the linked and embedded framework 'MyFramework.framework' was built for iOS + iOS Simulator.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
The binary framework contains different code for the same architecture in multiple places, and Xcode doesn’t know how to handle it. There is workaround that people recommend to use in such cases:&lt;br /&gt;
* https://stackoverflow.com/questions/63267897/building-for-ios-simulator-but-the-linked-framework-framework-was-built&lt;br /&gt;
* https://stackoverflow.com/questions/63932158/xcode12-issus-ld-building-for-ios-simulator-but-linking-in-object-file-built&lt;br /&gt;
&lt;br /&gt;
==== IPA processing failure ====&lt;br /&gt;
&amp;lt;code&amp;gt;Assertion failed: Expected 4 archs in otool output:&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The error above is due to the &amp;quot;fat&amp;quot; (simulator+device) framework which will not appear if you have not enabled Bitcode.  To build your app with full Bitcode support, it is recommended that you use a [[DCR_Video_iOS_SDK_xcframework|XCFramework]] to avoid the 4 archs in otool output message.&lt;br /&gt;
&lt;br /&gt;
== SDK Initialization ==&lt;br /&gt;
The latest version of the Nielsen App SDK allows instantiating multiple instances of the SDK object, which can be used simultaneously without any issue. The sharedInstance API that creates a singleton object was deprecated prior to version 5.1.1. [[Dual_Instances_of_SDK|(Click here for an example of multiple instances)]]&lt;br /&gt;
&lt;br /&gt;
The following table contains the list of arguments that can be passed via the AppInfo JSON schema.&lt;br /&gt;
*The appid is provided by the Nielsen Technical Account Manager (TAM). The appid is a GUID data type and is specific to the application.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter / Argument !! Description !! Source !! Required? !! Example&lt;br /&gt;
|-&lt;br /&gt;
| appid || Unique Nielsen ID for the application. The ID is a GUID data type. If you did not receive your App ID, let us know and we will provide you. || Nielsen-specified || Yes || PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&lt;br /&gt;
|-&lt;br /&gt;
| appname || Name of the application&lt;br /&gt;
|| Client-defined || Yes || &amp;quot;Nielsen Sample App&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| appversion || Current version of the app used&lt;br /&gt;
|| Client-defined || Yes || &amp;quot;1.0.2&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| sfcode || Nielsen collection facility to which the SDK should connect.&lt;br /&gt;
Italian Clients:&lt;br /&gt;
*&amp;quot;it&amp;quot;&lt;br /&gt;
|| Nielsen-specified || Yes || &amp;quot;it&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| nol_devDebug || Enables Nielsen console logging. Only required for testing&lt;br /&gt;
|| Nielsen-specified || Yes for Debugging / Testing App || &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Debug flag for development environment ==&lt;br /&gt;
Player application developers / integrators can use Debug flag to check whether an App SDK API call made is successful. To activate the Debug flag,&lt;br /&gt;
Pass the argument &amp;lt;code&amp;gt;@&amp;quot;nol_devDebug&amp;quot;:@&amp;quot;DEBUG&amp;quot;&amp;lt;/code&amp;gt;, in the JSON string . The permitted values are:&lt;br /&gt;
&lt;br /&gt;
* '''INFO''': Displays the API calls and the input data from the application (validate player name, app ID, etc.). It can be used as certification Aid.&lt;br /&gt;
* '''WARN''': Indicates potential integration / configuration errors or SDK issues.&lt;br /&gt;
* '''ERROR''': Indicates important integration errors or non-recoverable SDK issues.&lt;br /&gt;
* '''DEBUG''': Debug logs, used by the developers to debug more complex issues.&lt;br /&gt;
&lt;br /&gt;
Once the flag is active, it logs each API call made and the data passed. The log created by this flag is minimal.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': Activate the Debug flag in a Test environment.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sample SDK Initialization Code ===&lt;br /&gt;
==== App tracking transparency framework ====&lt;br /&gt;
&lt;br /&gt;
To display the App Tracking Transparency authorization request for accessing the IDFA, update your &amp;lt;code&amp;gt;info.plist&amp;lt;/code&amp;gt; to add the &amp;lt;code&amp;gt;NSUserTrackingUsageDescription&amp;lt;/code&amp;gt; key with a custom message describing your usage. Below is an example description text:&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;key&amp;gt;NSUserTrackingUsageDescription&amp;lt;/key&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;string&amp;gt;This identifier will be used to deliver personalized ads to you.&amp;lt;/string&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The system automatically generates the prompt’s title, which includes the name of your app, then the usage description appears as part of the App Tracking&lt;br /&gt;
&lt;br /&gt;
To present the authorization request, call requestTrackingAuthorizationWithCompletionHandler.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Please NOTE: It is important to initialize the NielsenSDK after the ATTrackingManager has Authorized usage.  When the SDK initializes, it checks the status of the ATTrackingManager.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can find an example in the file [[Special:Downloads|Global iOS SDK Download]] from the '''SDK Downloads''' section, folder name NielsenSampleVideoPlayer.&lt;br /&gt;
&lt;br /&gt;
====Swift 4.0 Example:====&lt;br /&gt;
&amp;lt;code&amp;gt;NielsenInit.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
import Foundation&lt;br /&gt;
import NielsenAppApi&lt;br /&gt;
&lt;br /&gt;
class NielsenInit : NSObject {&lt;br /&gt;
    class func createNielsenApi(delegate: NielsenAppApiDelegate) -&amp;gt; NielsenAppApi?{&lt;br /&gt;
        &lt;br /&gt;
        let appInformation:[String: String] = [&lt;br /&gt;
            &amp;quot;appid&amp;quot;: &amp;quot;PDA7D5EE6-B1B8-4123-9277-2A788XXXXXXX&amp;quot;,&lt;br /&gt;
            &amp;quot;appversion&amp;quot;: &amp;quot;1.0.2&amp;quot;,&lt;br /&gt;
            &amp;quot;appname&amp;quot;: &amp;quot;Nielsen Sample App&amp;quot;,&lt;br /&gt;
            &amp;quot;sfcode&amp;quot;: &amp;quot;it&amp;quot;,&lt;br /&gt;
            &amp;quot;nol_devDebug&amp;quot;: &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
        ]       &lt;br /&gt;
        return NielsenAppApi(appInfo:appInformation, delegate:delegate)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Sample code using AVPlayer===&lt;br /&gt;
&amp;lt;code&amp;gt;LandingVC.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
import UIKit&lt;br /&gt;
import NielsenAppApi&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class LandingVC: UIViewController, NielsenAppApiDelegate {&lt;br /&gt;
    &lt;br /&gt;
    var nielsenMain : NielsenAppApi!&lt;br /&gt;
    var sdkMethods : SDKMethods!&lt;br /&gt;
    var data : [String : Any]!&lt;br /&gt;
&lt;br /&gt;
class ViewController: UIViewController, NielsenAppApiDelegate, AVPlayerViewControllerDelegate  {&lt;br /&gt;
&lt;br /&gt;
// your code//    &lt;br /&gt;
&lt;br /&gt;
  override func viewDidLoad() {&lt;br /&gt;
        super.viewDidLoad()&lt;br /&gt;
        //Getting the instance of NielsenApi&lt;br /&gt;
        self.nielsenApi = NielsenInit.createNielsenApi(delegate: self)&lt;br /&gt;
            }&lt;br /&gt;
  }&lt;br /&gt;
    override func viewDidAppear(_ animated: Bool) {      &lt;br /&gt;
        self.data = sdkMethods.loadStaticMaster()     // This is just an example of populating the metadata&lt;br /&gt;
        self.nielsenMain.loadMetadata(self.data)&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Objective C ==== &lt;br /&gt;
Initialize the Nielsen App object within the viewDidLoad view controller delegate method using initWithAppInfo:delegate:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;If App SDK is initialized using init or new methods, it will ignore the API calls resulting in no measurement. The SDK will not return any errors.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;    &lt;br /&gt;
#import &amp;quot;NlsAppApiFactory.h&amp;quot;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenAppApi.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@implementation NlsAppApiFactory&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppApi *)createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
{&lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
    NSDictionary *appInformation = @{ &lt;br /&gt;
                                     @&amp;quot;appid&amp;quot;: &amp;quot;PDA7D5EE6-B1B8-4123-9277-2A788XXXXXXX&amp;quot;,&lt;br /&gt;
                                     @&amp;quot;appversion&amp;quot;: &amp;quot;1.0.2&amp;quot;,&lt;br /&gt;
                                     @&amp;quot;appname&amp;quot;: &amp;quot;Nielsen Sample App&amp;quot;,&lt;br /&gt;
                                     @&amp;quot;sfcode&amp;quot;: &amp;quot;it&amp;quot;,&lt;br /&gt;
                                     @&amp;quot;nol_devDebug&amp;quot;: @&amp;quot;DEBUG&amp;quot;&lt;br /&gt;
                                    };&lt;br /&gt;
    &lt;br /&gt;
    return [[NielsenAppApi alloc] initWithAppInfo:appInformation delegate:delegate];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following would be the &amp;lt;code&amp;gt;NlsAppApiFactory.h&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;Foundation/Foundation.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@class NielsenAppApi;&lt;br /&gt;
@protocol NielsenAppApiDelegate;&lt;br /&gt;
&lt;br /&gt;
@interface NlsAppApiFactory : NSObject &lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppAPI *) createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sample Code: ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
@implementation ViewController&lt;br /&gt;
&lt;br /&gt;
- (void)viewDidLoad {&lt;br /&gt;
    [super viewDidLoad];&lt;br /&gt;
        &lt;br /&gt;
    //Getting the instance of Nielsen SDK&lt;br /&gt;
    nielsenApi = [NlsAppApiFactory createNielsenAppApiWithDelegate:nil];&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&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, please review the [[APP SDK Event Codes|App SDK Event Code]] Reference page.&lt;br /&gt;
&lt;br /&gt;
== Populate and Pass Metadata Object ==&lt;br /&gt;
The Nielsen SDK is able to monitor Application launch events and how long your app has been running.  Once the Nielsen SDK has been Initialized, pass &amp;lt;code&amp;gt;&amp;quot;type&amp;quot;:'static'&amp;lt;/code&amp;gt; as a JSON object via loadMetadata.&lt;br /&gt;
&lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Swift = &amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
        let staticMetadata = [&lt;br /&gt;
            &amp;quot;type&amp;quot;: &amp;quot;static&amp;quot;,&lt;br /&gt;
            &amp;quot;assetid&amp;quot;: &amp;quot;HomePage&amp;quot;,&lt;br /&gt;
            &amp;quot;section&amp;quot;: &amp;quot;Home_EntityName_iOS&amp;quot;&lt;br /&gt;
        ];&lt;br /&gt;
         self.nielsenAppApi?.loadMetadata(staticMetadata)&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 *staticMetadata = @&lt;br /&gt;
    {&lt;br /&gt;
        &amp;quot;type&amp;quot;: &amp;quot;static&amp;quot;,&lt;br /&gt;
        &amp;quot;assetid&amp;quot;: &amp;quot;HomePage&amp;quot;,&lt;br /&gt;
        &amp;quot;section&amp;quot;: &amp;quot;Home_EntityName_iOS&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
[nielsenApi loadMetadata:(staticMetadata)];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
The above code would be inserted only for the &amp;quot;home section&amp;quot; within your app.&lt;br /&gt;
&lt;br /&gt;
=== Nielsen SDK Metadata ===&lt;br /&gt;
The following table defines the staticMetadata reserved keys:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Key !! Description !! Data Type !! Value !! Required?&lt;br /&gt;
|-&lt;br /&gt;
| type || asset type || fixed || &amp;lt;code&amp;gt;'static'&amp;lt;/code&amp;gt; || Yes&lt;br /&gt;
|-&lt;br /&gt;
| assetid || Unique ID for each article. For the Italian Market only the home page/ landing page must be tagged || dynamic || custom (no [[Special Characters|Special Characters]]) || Yes&lt;br /&gt;
|-&lt;br /&gt;
| section || section of the App to be measured &amp;lt;/br&amp;gt; EntityName = brand name or sub-brand name|| dynamic || &amp;lt;code&amp;gt;Home_EntityName_iOS&amp;lt;/code&amp;gt; for iOS App  || Yes&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Handling Foreground and Background states ==&lt;br /&gt;
For iOS, background/foreground detection is handled by the app lifecylce APIs which are provided by [https://developer.apple.com/library/content/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/TheAppLifeCycle/TheAppLifeCycle.html Apple:]&lt;br /&gt;
&lt;br /&gt;
Foreground/Background state measurement is a requirement of Nielsen AppSDK implementation which is especially crucial for static measurement.&lt;br /&gt;
&lt;br /&gt;
== Privacy and Opt-Out ==&lt;br /&gt;
There are two primary methods for implementing user Opt-out preferences:&lt;br /&gt;
&lt;br /&gt;
*[[DCR_Italy_Static_iOS_SDK#OS-level_Opt-out|OS-level Opt-out]] - managed by AppTracking or Limit Ad Tracking setting on device (preferred approach).&lt;br /&gt;
*[[DCR_Italy_Static_iOS_SDK#User_Choice|User Choice]] - Direct call to SDK. Can be used without the Ad Framework&lt;br /&gt;
&lt;br /&gt;
=== Special Note Regarding Apps in the Kids Category ===&lt;br /&gt;
If you are building an app that will be listed in the Kids Category:&lt;br /&gt;
&lt;br /&gt;
Ensure that you are using the [https://nielsendownloads-green.digitalengsdk.com/digital/Nielsen-iOS-App-SDK-GlobalNoId_latest.zip NoID version:] of the Nielsen SDK Framework. Also, you can use the [[Digital_Measurement_iOS_Artifactory_Guide|Artifactory method.]]&lt;br /&gt;
Immediately following the initialization of the Nielsen SDK ensure you call the userOptOut API with Opt out selection:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;NielsenAppApi?.userOptOut(&amp;quot;nielsenappsdk://1&amp;quot;); // User opt-outv&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== OS-level Opt-out ===&lt;br /&gt;
''OS-level Opt-out'' method available on Nielsen iOS&lt;br /&gt;
&lt;br /&gt;
The Nielsen SDK automatically leverages the iOS's '''Limit Ad Tracking''' or '''AppTracking''' setting.&lt;br /&gt;
&lt;br /&gt;
*If the User's device is running &amp;lt; iOS 13.x, the Nielsen SDK will check the status of '''Limit Ad Tracking'''.&lt;br /&gt;
*iOS14 modifies the way Apple manages the collection of a User's Opt-In status through '''AppTracking'''. Starting with Version 8.x+, the Nielsen App SDK will check the iOS version during initialization. If the device is running iOS12 or iOS13, the Limit Ad Tracking setting is requested. If iOS14.x +, then AppTracking is utilized.&lt;br /&gt;
&lt;br /&gt;
==== Get the latest Nielsen opt-out URL ====&lt;br /&gt;
&lt;br /&gt;
*Get the current Nielsen opt-out URL via [[optOutURL|optOutURL]]&lt;br /&gt;
*Display a WebView element whose loadUrl is set to the value obtained from [[optOutURL|optOutURL]]&lt;br /&gt;
&lt;br /&gt;
==== Webview Example ====&lt;br /&gt;
The below code is an example of displaying the Nielsen Privacy page to the user.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
import UIKit&lt;br /&gt;
import WebKit&lt;br /&gt;
import NielsenAppApi&lt;br /&gt;
&lt;br /&gt;
class OptOutVC: UIViewController, NielsenAppApiDelegate, WKNavigationDelegate {&lt;br /&gt;
    var webView: WKWebView!&lt;br /&gt;
    var nielsenApi: NielsenAppApi!&lt;br /&gt;
    &lt;br /&gt;
    override func loadView() {&lt;br /&gt;
        webView = WKWebView()&lt;br /&gt;
        webView.navigationDelegate = self&lt;br /&gt;
        view = webView  }&lt;br /&gt;
    &lt;br /&gt;
    override func viewDidLoad() {&lt;br /&gt;
        super.viewDidLoad()&lt;br /&gt;
        self.view.backgroundColor = UIColor(patternImage: UIImage(named: &amp;quot;new_ios_bg.png&amp;quot;)!) &lt;br /&gt;
        self.nielsenApi = NielsenInit.createNielsenApi(delegate: self)  //create an instance &lt;br /&gt;
        &lt;br /&gt;
        if let appApi = self.nielsenApi {&lt;br /&gt;
            //Getting the optPut URL from SDK&lt;br /&gt;
            if let url = URL(string: appApi.optOutURL) { //query the nielsensdk for the current privacy page&lt;br /&gt;
                webView.load(URLRequest(url: url))&lt;br /&gt;
                webView.allowsBackForwardNavigationGestures = true&lt;br /&gt;
            }}}}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== User Choice ===&lt;br /&gt;
The User Choice method can be used without the Ad Framework, or in situations where the publisher does not wish to use the [https://developer.apple.com/documentation/apptrackingtransparency App Tracking Transparency Framework.]&lt;br /&gt;
&lt;br /&gt;
==== The User Choice opt-out method works as follows: ====&lt;br /&gt;
&lt;br /&gt;
*Get the Nielsen opt-out URL via [[optOutURL|optOutURL]]&lt;br /&gt;
*Display a WebView element whose loadUrl is set to the value obtained from [[optOutURL|optOutURL]]&lt;br /&gt;
*Detect if the WebView URL changes to a special URL that indicates Opt-in, or Opt-out and close the WebView&lt;br /&gt;
**Opt-out if the WebView URL = &amp;lt;code&amp;gt;nielsenappsdk://1&amp;lt;/code&amp;gt;&lt;br /&gt;
**Opt-in if the WebView URL = &amp;lt;code&amp;gt;nielsenappsdk://0&amp;lt;/code&amp;gt;&lt;br /&gt;
*Pass the detected URL to the [[userOptOut|userOptOut]] function&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;NielsenAppApi?.userOptOut(&amp;quot;nielsenappsdk://1&amp;quot;); // User opt-out &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Opt-out example code ====&lt;br /&gt;
===== Objective-C =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)&lt;br /&gt;
navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {&lt;br /&gt;
&lt;br /&gt;
    NSURLRequest *request = [navigationAction request];&lt;br /&gt;
    NSString *url = [[request URL]absoluteString];&lt;br /&gt;
    &lt;br /&gt;
    if([url isEqualToString:self.NIELSEN_URL_OPT_OUT] || [url isEqualToString:self.NIELSEN_URL_OPT_IN]){&lt;br /&gt;
        [self.nielsenApi userOptOut:url];&lt;br /&gt;
        decisionHandler(WKNavigationActionPolicyAllow);&lt;br /&gt;
    }else{&lt;br /&gt;
        decisionHandler(WKNavigationActionPolicyCancel);&lt;br /&gt;
    }        &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Swift =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
var webView: WKWebView!&lt;br /&gt;
var NIELSEN_URL_OPT_OUT : String = &amp;quot;nielsenappsdk://1&amp;quot;&lt;br /&gt;
var NIELSEN_URL_OPT_IN : String = &amp;quot;nielsenappsdk://0&amp;quot;&lt;br /&gt;
&lt;br /&gt;
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, &lt;br /&gt;
decisionHandler: @escaping (WKNavigationActionPolicy) -&amp;gt; Void) {&lt;br /&gt;
&lt;br /&gt;
       let urlStr = navigationAction.request.url?.absoluteString&lt;br /&gt;
&lt;br /&gt;
        if(urlStr == NIELSEN_URL_OPT_OUT || urlStr == NIELSEN_URL_OPT_IN){&lt;br /&gt;
            let appApi = self.nielsenApi&lt;br /&gt;
            appApi?.userOptOut(urlStr)&lt;br /&gt;
            decisionHandler(.allow)&lt;br /&gt;
&lt;br /&gt;
        }else{&lt;br /&gt;
           decisionHandler(.cancel)&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Retrieve current Opt-Out preference ===&lt;br /&gt;
Whether the user is opted out via OS-level Opt-out or via User Choice Opt-out, the current Opt-Out status as detected by the SDK is available via the optOutStatus property in the Nielsen SDK API&lt;br /&gt;
&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;
In addition, the following text must be included in your app store description.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Si prega di notare che questa app include il software di misurazione proprietario di Nielsen che contribuisce alla ricerca di mercato. Per ulteriori informazioni, si prega di consultare il seguente link [https://global.nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/?lang=it https://global.nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/?lang=it]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Going Live ==&lt;br /&gt;
Following Nielsen testing, users need to make one update to the initialization call to ensure that the site is being measured properly.&lt;br /&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:&lt;br /&gt;
&lt;br /&gt;
=== iOS Example: ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class NielsenInit: NSObject {&lt;br /&gt;
    class func createNielsenAppApi(delegate: NielsenAppApiDelegate) -&amp;gt; NielsenAppApi?{&lt;br /&gt;
    let appInformation:[String: String] = [&lt;br /&gt;
            &amp;quot;appid&amp;quot;: &amp;quot;PDA7D5EE6-B1B8-4123-9277-2A788XXXXXXX&amp;quot;,&lt;br /&gt;
            &amp;quot;appversion&amp;quot;: &amp;quot;1.0.2&amp;quot;,&lt;br /&gt;
            &amp;quot;appname&amp;quot;: &amp;quot;Nielsen Sample App&amp;quot;,&lt;br /&gt;
            &amp;quot;sfcode&amp;quot;: &amp;quot;it&amp;quot;&lt;br /&gt;
            // Remove Flag:   &amp;quot;nol_devDebug&amp;quot;: &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
        ]&lt;br /&gt;
        return NielsenAppApi(appInfo:appInformation, delegate:delegate)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sample Applications ==&lt;br /&gt;
You can find some examples in the file [[Special:Downloads|Global iOS SDK Download]] from the '''SDK Downloads''' section&lt;/div&gt;</summary>
		<author><name>NickParrucci</name></author>
	</entry>
	<entry>
		<id>https://nielsentest.mywikis.net/w/index.php?title=DCR_Italy_Video_iOS_SDK&amp;diff=6460</id>
		<title>DCR Italy Video iOS SDK</title>
		<link rel="alternate" type="text/html" href="https://nielsentest.mywikis.net/w/index.php?title=DCR_Italy_Video_iOS_SDK&amp;diff=6460"/>
		<updated>2023-07-20T12:16:06Z</updated>

		<summary type="html">&lt;p&gt;NickParrucci: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|International DCR}}  {{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 page / sub section in the application.&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: 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. || Provided by 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;
 || '''sfcode''' || Unique identifier for the environment that the SDK should point to || Provided by Nielsen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
If need App ID(s) or our SDKs, feel free to reach out to us and we will be happy to help you get started.&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;
=== Notes for WebView Contents ===&lt;br /&gt;
&amp;lt;code&amp;gt;Please note that if within your APP user can surf '''static contents''' recalled from your website the [[DCR_Italy_Static_Browser_SDK|browser static SDK]] have to inhibit from this pages.&amp;lt;/code&amp;gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==  Implementation ==&lt;br /&gt;
This guide covers implementation steps for iOS using Xcode utilizing the Standard Nielsen SDK for DCR.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;If you are building an app for the 'kids category' please review the [[DCR_Italy_Video_iOS_SDK#Special_Note_Regarding_Apps_in_the_Kids_Category|Opt Out Requirement.]]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== How to obtain the NielsenAppApi.Framework ===&lt;br /&gt;
The Nielsen AppSDK can either be downloaded directly or can be integrated directly within an application through the use of CocoaPods. We recommend using the CocoaPods-based integration whenever possible to ensure you maintain the most recent changes and enhancements to the Nielsen libraries.&lt;br /&gt;
* [[Digital_Measurement_iOS_Artifactory_Guide|Select to obtain CocoaPods implementation guide]]&lt;br /&gt;
* [[Special:Downloads|Select to Download Directly]]&lt;br /&gt;
* [[DCR_Video_iOS_SDK_xcframework|Using the XCFramework bundle]]&lt;br /&gt;
&lt;br /&gt;
== Special Notes regarding iOS14 ==&lt;br /&gt;
=== Permission to Track === &lt;br /&gt;
&lt;br /&gt;
Apple recently released a new policy on consent requirements, that require the user's permission, to track them using their device's advertising identifier (IDFA).  To request the user's permission, use the AppTrackingTransparency framework. &lt;br /&gt;
&lt;br /&gt;
For more information, see:&lt;br /&gt;
* [https://developer.apple.com/documentation/apptrackingtransparency App Tracking Transparency]&lt;br /&gt;
* [https://developer.apple.com/design/human-interface-guidelines/ios/app-architecture/requesting-permission/ Human Interface Guidelines]&lt;br /&gt;
* [https://developer.apple.com/documentation/adsupport AdSupport Framework]&lt;br /&gt;
&lt;br /&gt;
More detailed information on how the Nielsen SDK versions work with the AppTrackingTransparency framework is located on our [[ DCR Video iOS14 Migration|DCR Video iOS14 Migration]] page.&lt;br /&gt;
&lt;br /&gt;
== Setting up your  Development Environment  ==&lt;br /&gt;
Prior to SDK Version 6.2.0.0 the  IOS framework has been distributed as a static library packaged into framework bundle format. Apple recommends to use dynamic framework, it has some benefits over static libraries like less executable file size of an app, faster startup time and native support in xCode IDE. Nielsen AppSDK has been transformed into dynamic framework in this release ([[iOS_Static_Framework_Setup|static framework]] is still available).&lt;br /&gt;
&lt;br /&gt;
If migrating from the static library to this new dynamic framework, once implemented, unless your specific application requires, you can remove the following Frameworks that were once required:&amp;lt;code&amp;gt; [AdSupport, JavascriptCore, SystemConfiguration, Security, AVFoundation, libc++] &amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The '''Dynamic framework''' is created as a fat framework. It means that it contains slices required for devices (armv7, arm64) as well as slices required for simulators (i386, x86_64). Simulator slices are needed to let clients build and debug their app on the simulators, but they should be removed before sending the app to the AppStore. The example of the shell script that should be added as a Run Script phase in the application can be [[DCR_Video_iOS_SDK#Removing_Simulators_.28Dynamic_Framework_Only.29|found below]].&lt;br /&gt;
&lt;br /&gt;
'''[[DCR_Video_iOS_SDK_xcframework|XCFramework]]''' is solution for the problems described above Apple recommends to use XCFrameworks. In XCFramework, we no longer build a single framework with multiple architectures. Instead, we build one small framework for each combination of architecture and target and store it in its own folder. The top-level XCFramework folder have folders like ios-arm64, ios-arm64-simulator, etc. Each of these folders is its own framework, complete with headers, modules, and binary.&lt;br /&gt;
&lt;br /&gt;
=== Configuring Xcode Development Environment ===&lt;br /&gt;
Starting with SDK version 6.0.0.0, the Nielsen App SDK is compatible with Apple iOS versions 8.0 and above.  In addition, when using the dynamic framework,  all the required frameworks are linked automatically as the are needed.  More details can be found here: https://stackoverflow.com/questions/24902787/dont-we-need-to-link-framework-to-xcode-project-anymore&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': All communications between the SDK and the Census (Collection Facility) use HTTPS.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Special Note for Static Framework ===&lt;br /&gt;
Starting from 8.2.0.0 release framework is build from the mixed (swift + objc) source code.&lt;br /&gt;
If [[iOS_Static_Framework_Setup|static (xc)framework is integrated additional settings]] should be applied to fix build or runtime issues.&lt;br /&gt;
&lt;br /&gt;
=== Download Framework ===&lt;br /&gt;
The first step is to download and copy the [[Special:Downloads|NielsenAppApi.framework]] bundle to the app project directory. (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
=== Add Framework ===&lt;br /&gt;
In the General tab for app configuration add NielsenAppApi.framework in the list of Embedded Binaries.  (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
=== Add Path ===&lt;br /&gt;
Add path to the NielsenAppApi.framework in the Framework Search Paths build setting.  (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
=== Import Framework ===&lt;br /&gt;
Add NielsenAppApi.framework module in the source file of your app:&lt;br /&gt;
&lt;br /&gt;
==== Using Swift ====&lt;br /&gt;
Add the following:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
import NielsenAppApi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using Objective-C ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang =&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
@import NielsenAppApi;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== xCode 12 building errors ====&lt;br /&gt;
Developers who uses &amp;quot;fat&amp;quot; framework in their apps started reporting the following error that they get building the app in xCode 12.3+:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Building for iOS Simulator, but the linked and embedded framework 'MyFramework.framework' was built for iOS + iOS Simulator.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
The binary framework contains different code for the same architecture in multiple places, and Xcode doesn’t know how to handle it. There is workaround that people recommend to use in such cases:&lt;br /&gt;
* https://stackoverflow.com/questions/63267897/building-for-ios-simulator-but-the-linked-framework-framework-was-built&lt;br /&gt;
* https://stackoverflow.com/questions/63932158/xcode12-issus-ld-building-for-ios-simulator-but-linking-in-object-file-built&lt;br /&gt;
&lt;br /&gt;
==== IPA processing failure ====&lt;br /&gt;
&amp;lt;code&amp;gt;Assertion failed: Expected 4 archs in otool output:&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The error above is due to the &amp;quot;fat&amp;quot; (simulator+device) framework which will not appear if you have not enabled Bitcode.  To build your app with full Bitcode support, it is recommended that you use a [[DCR_Video_iOS_SDK_xcframework|XCFramework]] to avoid the 4 archs in otool output message.&lt;br /&gt;
&lt;br /&gt;
== SDK Initialization ==&lt;br /&gt;
The latest version of the Nielsen App SDK allows instantiating multiple instances of the SDK object, which can be used simultaneously without any issue. The sharedInstance API that creates a singleton object was deprecated prior to version 5.1.1. [[Dual_Instances_of_SDK|(Click here for an example of multiple instances)]]&lt;br /&gt;
&lt;br /&gt;
The following table contains the list of arguments that can be passed via the AppInfo JSON schema.&lt;br /&gt;
*The appid is provided by the Nielsen Technical Account Manager (TAM). The appid is a GUID data type and is specific to the application.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter / Argument !! Description !! Source !! Required? !! Example&lt;br /&gt;
|-&lt;br /&gt;
| appid || Unique Nielsen ID for the application. The ID is a GUID data type. If you did not receive your App ID, let us know and we will provide you. || Nielsen-specified || Yes || PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&lt;br /&gt;
|-&lt;br /&gt;
| appname || Name of the application&lt;br /&gt;
|| Client-defined || Yes || &amp;quot;Nielsen Sample App&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| appversion || Current version of the app used&lt;br /&gt;
|| Client-defined || Yes || &amp;quot;1.0.2&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| sfcode || Nielsen collection facility to which the SDK should connect.&lt;br /&gt;
Italian Clients:&lt;br /&gt;
*&amp;quot;it&amp;quot;&lt;br /&gt;
|| Nielsen-specified || Yes || &amp;quot;it&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| nol_devDebug || Enables Nielsen console logging. Only required for testing&lt;br /&gt;
|| Nielsen-specified || Yes for Debugging / Testing App || &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Debug flag for development environment ==&lt;br /&gt;
Player application developers / integrators can use Debug flag to check whether an App SDK API call made is successful. To activate the Debug flag,&lt;br /&gt;
Pass the argument &amp;lt;code&amp;gt;@&amp;quot;nol_devDebug&amp;quot;:@&amp;quot;DEBUG&amp;quot;&amp;lt;/code&amp;gt;, in the JSON string . The permitted values are:&lt;br /&gt;
&lt;br /&gt;
* '''INFO''': Displays the API calls and the input data from the application (validate player name, app ID, etc.). It can be used as certification Aid.&lt;br /&gt;
* '''WARN''': Indicates potential integration / configuration errors or SDK issues.&lt;br /&gt;
* '''ERROR''': Indicates important integration errors or non-recoverable SDK issues.&lt;br /&gt;
* '''DEBUG''': Debug logs, used by the developers to debug more complex issues.&lt;br /&gt;
&lt;br /&gt;
Once the flag is active, it logs each API call made and the data passed. The log created by this flag is minimal.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': Activate the Debug flag in a Test environment.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sample SDK Initialization Code ===&lt;br /&gt;
&lt;br /&gt;
==== App tracking transparency framework ====&lt;br /&gt;
&lt;br /&gt;
To display the App Tracking Transparency authorization request for accessing the IDFA, update your &amp;lt;code&amp;gt;info.plist&amp;lt;/code&amp;gt; to add the &amp;lt;code&amp;gt;NSUserTrackingUsageDescription&amp;lt;/code&amp;gt; key with a custom message describing your usage. Below is an example description text:&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;key&amp;gt;NSUserTrackingUsageDescription&amp;lt;/key&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;string&amp;gt;This identifier will be used to deliver personalized ads to you.&amp;lt;/string&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The system automatically generates the prompt’s title, which includes the name of your app, then the usage description appears as part of the App Tracking&lt;br /&gt;
&lt;br /&gt;
To present the authorization request, call requestTrackingAuthorizationWithCompletionHandler.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Please NOTE: It is important to initialize the NielsenSDK after the ATTrackingManager has Authorized usage.  When the SDK initializes, it checks the status of the ATTrackingManager.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can find an example in the file [[Special:Downloads|Global iOS SDK Download]] from the '''SDK Downloads''' section, folder name NielsenSampleVideoPlayer.&lt;br /&gt;
&lt;br /&gt;
====Swift 4.0 Example:====&lt;br /&gt;
&amp;lt;code&amp;gt;NielsenInit.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
import Foundation&lt;br /&gt;
import NielsenAppApi&lt;br /&gt;
&lt;br /&gt;
class NielsenInit : NSObject {&lt;br /&gt;
    class func createNielsenApi(delegate: NielsenAppApiDelegate) -&amp;gt; NielsenAppApi?{&lt;br /&gt;
        &lt;br /&gt;
        let appInformation:[String: String] = [&lt;br /&gt;
            &amp;quot;appid&amp;quot;: &amp;quot;PDA7D5EE6-B1B8-4123-9277-2A788XXXXXXX&amp;quot;,&lt;br /&gt;
            &amp;quot;appversion&amp;quot;: &amp;quot;1.0.2&amp;quot;,&lt;br /&gt;
            &amp;quot;appname&amp;quot;: &amp;quot;Nielsen Sample App&amp;quot;,&lt;br /&gt;
            &amp;quot;sfcode&amp;quot;: &amp;quot;it&amp;quot;,&lt;br /&gt;
            &amp;quot;nol_devDebug&amp;quot;: &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
        ]       &lt;br /&gt;
        return NielsenAppApi(appInfo:appInformation, delegate:delegate)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Sample code using AVPlayer===&lt;br /&gt;
&amp;lt;code&amp;gt;ViewController.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class ViewController: UIViewController, NielsenAppApiDelegate, AVPictureInPictureControllerDelegate, CLLocationManagerDelegate  {&lt;br /&gt;
    &lt;br /&gt;
    let avPlayerViewController = AVPlayerViewController()&lt;br /&gt;
    var avPlayer:AVPlayer?&lt;br /&gt;
    var nielsenAppApi: NielsenAppApi!&lt;br /&gt;
&lt;br /&gt;
  override func viewDidLoad() {&lt;br /&gt;
        super.viewDidLoad()&lt;br /&gt;
&lt;br /&gt;
self.nielsenAppApi = NielsenInit.createNielsenAppApi(delegate: self)&lt;br /&gt;
NSLog(&amp;quot;Nielsen SDK initialized&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
            }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Objective C ==== &lt;br /&gt;
Initialize the Nielsen App object within the viewDidLoad view controller delegate method using initWithAppInfo:delegate:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;If App SDK is initialized using init or new methods, it will ignore the API calls resulting in no measurement. The SDK will not return any errors.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;    &lt;br /&gt;
#import &amp;quot;NlsAppApiFactory.h&amp;quot;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenAppApi.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@implementation NlsAppApiFactory&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppApi *)createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
{&lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
    NSDictionary *appInformation = @{ &lt;br /&gt;
                                     @&amp;quot;appid&amp;quot;: &amp;quot;PDA7D5EE6-B1B8-4123-9277-2A788XXXXXXX&amp;quot;,&lt;br /&gt;
                                     @&amp;quot;appversion&amp;quot;: &amp;quot;1.0.2&amp;quot;,&lt;br /&gt;
                                     @&amp;quot;appname&amp;quot;: &amp;quot;Nielsen Sample App&amp;quot;,&lt;br /&gt;
                                     @&amp;quot;sfcode&amp;quot;: &amp;quot;it&amp;quot;,&lt;br /&gt;
                                     @&amp;quot;nol_devDebug&amp;quot;: @&amp;quot;DEBUG&amp;quot;&lt;br /&gt;
                                    };&lt;br /&gt;
    &lt;br /&gt;
    return [[NielsenAppApi alloc] initWithAppInfo:appInformation delegate:delegate];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following would be the &amp;lt;code&amp;gt;NlsAppApiFactory.h&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;Foundation/Foundation.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@class NielsenAppApi;&lt;br /&gt;
@protocol NielsenAppApiDelegate;&lt;br /&gt;
&lt;br /&gt;
@interface NlsAppApiFactory : NSObject &lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppAPI *) createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sample Code: ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
@implementation ViewController&lt;br /&gt;
&lt;br /&gt;
- (void)viewDidLoad {&lt;br /&gt;
    [super viewDidLoad];&lt;br /&gt;
        &lt;br /&gt;
    //Getting the instance of Nielsen SDK&lt;br /&gt;
    nielsenApi = [NlsAppApiFactory createNielsenAppApiWithDelegate:nil];&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
== Initializing the Nielsen AppSDK to measure the Viewability ==&lt;br /&gt;
The integrator to support the viewability metrics in the application has to provide a tag value of the player view to let Nielsen AppSDK know that there is a player that needs to be tracked. It’s called the ‘containerId’ and it should be passed in application info dictionary as string while initializing the Nielsen AppSDK.&lt;br /&gt;
&lt;br /&gt;
=== Android ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! #	!! Parameter Name	!! Description !! Supported Values !! Example&lt;br /&gt;
|-&lt;br /&gt;
| 1	|| containerId ||View ID of the UI element used as player view in application. getId() method of View class can be used to get this value.	||A positive integer used to identify the view. || 2131558561&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== iOS ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! #	!! Parameter Name	!! Description !! Supported Values !! Example&lt;br /&gt;
|-&lt;br /&gt;
| 1	|| containerId ||The tag of the UIView that represents the Player View	||The string value representing the NSInteger value with maximum value of NSIntegerMax that is related on 32- or 64-bit applications. || &amp;quot;100&amp;quot; &amp;lt;br&amp;gt; &amp;quot;2131558561&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For iOS it is required to link additional frameworks that are needed for viewability engine:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;JavaScriptCore.framework&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;WebKit.framework&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Nielsen AppSDK uses a tracking WebView (TWV) approach.  For more information on Viewability, please refer to [https://engineeringportal.nielsen.com/docs/Implementing_Viewability_with_AppSDK Implementing Viewability with AppSDK.]&lt;br /&gt;
--&amp;gt;&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, please review the [[APP SDK Event Codes|App SDK Event Code]] Reference page.&lt;br /&gt;
&lt;br /&gt;
== Configure Metadata ==&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 Nielsen Key names (e.g. appid, program) 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;
{{ExampleCode|&lt;br /&gt;
|Swift = &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
let channelInfo = [&lt;br /&gt;
            &amp;quot;channelName&amp;quot;: &amp;quot;My Channel Name 1&amp;quot;,&lt;br /&gt;
];&lt;br /&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;88675545&amp;quot;,&lt;br /&gt;
            &amp;quot;title&amp;quot;: &amp;quot;Program S3, EP1&amp;quot;,&lt;br /&gt;
            &amp;quot;isfullepisode&amp;quot;:&amp;quot;y&amp;quot;,&lt;br /&gt;
            &amp;quot;adloadtype&amp;quot;:&amp;quot;2&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;
];&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  *channelInfo = @&lt;br /&gt;
{&lt;br /&gt;
  @&amp;quot;channelName&amp;quot;:@&amp;quot;My Channel Name 1&amp;quot;,&lt;br /&gt;
}&lt;br /&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;88675545&amp;quot;,&lt;br /&gt;
    @ &amp;quot;title&amp;quot;: @ &amp;quot;Program S3, EP1&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;20200321 10:05:00&amp;quot;,&lt;br /&gt;
    @ &amp;quot;adloadtype&amp;quot;: @ &amp;quot;2&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
=== Configure metadata === &lt;br /&gt;
channelName should remain constant throughout the completion of an episode or live stream.&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;
| channelName	|| ChannelInfo refers to the Channel name. This can be a free-form value&lt;br /&gt;
value such as a friendly name for the content being played. the SDK&amp;lt;br/&amp;gt;&lt;br /&gt;
will pass the application name automatically.&lt;br /&gt;
|| custom	|| No&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Configure metadata ===&lt;br /&gt;
Configure metadata should remain constant throughout the completion of an episode or live stream&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;
| channelName 	|| Any string representing the channel/stream || custom || Yes&lt;br /&gt;
|}&lt;br /&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;
{| 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 asset || &amp;lt;code&amp;gt;'content'&amp;lt;/code&amp;gt; || Yes&lt;br /&gt;
|-&lt;br /&gt;
| assetid || unique ID assigned to asset (32 Character limit) || custom (no [[Special Characters|Special Characters]]) || Yes&lt;br /&gt;
|-&lt;br /&gt;
| program || name of program (100 character limit) || custom || Yes&lt;br /&gt;
|-&lt;br /&gt;
| title || name of program (100 character limit) || custom || Yes&lt;br /&gt;
|-&lt;br /&gt;
| length || length of content in seconds || &amp;lt;code&amp;gt;seconds&amp;lt;/code&amp;gt; (0 for live stream) || Yes&lt;br /&gt;
|-&lt;br /&gt;
| airdate || the airdate in the linear TV || YYYYMMDD HH24:MI:SS || Yes&lt;br /&gt;
|-&lt;br /&gt;
| isfullepisode || full episode flag || &amp;lt;code&amp;gt;'y'&amp;lt;/code&amp;gt;- full episode, &amp;lt;code&amp;gt;'n'&amp;lt;/code&amp;gt;- non full episode || Yes&lt;br /&gt;
|-&lt;br /&gt;
| adloadtype || type of ad load:&lt;br /&gt;
*&amp;lt;code&amp;gt;'1'&amp;lt;/code&amp;gt; Linear – matches TV ad load&lt;br /&gt;
*&amp;lt;code&amp;gt;'2'&amp;lt;/code&amp;gt; Dynamic – Dynamic Ad Insertion (DAI)&lt;br /&gt;
|| &amp;lt;code&amp;gt;'2'&amp;lt;/code&amp;gt; - DCR measures content with dynamic ads &lt;br /&gt;
|| Yes&lt;br /&gt;
&lt;br /&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; || Yes&lt;br /&gt;
|-&lt;br /&gt;
| assetid ||	unique ID assigned to Ad	|| custom (no [[Special Characters|Special Characters]]) || Yes&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;
== Configure API Calls ==&lt;br /&gt;
&amp;lt;!--[[File:appsdkTimeline-DCR.png|icon|link=]]--&amp;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;syntaxhighlight lang=Swift&amp;gt;&lt;br /&gt;
NielsenInit.createMainBrandApi(delegate: self)&lt;br /&gt;
self.data = loadStaticMetadata()&lt;br /&gt;
self.nielsenMeter .loadMetadata(self.data)&amp;lt;/syntaxhighlight&amp;gt; || // Pass Static Metadata here if applicable&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(contentMetadata)&amp;lt;/code&amp;gt; || // MetadataObject contains the JSON metadata&amp;lt;br&amp;gt; for the content being played&lt;br /&gt;
|-&lt;br /&gt;
| Content || &amp;lt;code&amp;gt;nielsenMeter.playheadPosition(pos);&amp;lt;/code&amp;gt; || // playheadPosition is position of the playhead &amp;lt;br&amp;gt;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;
| 'playheadPosition'	|| 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: 'PlayheadPosition' 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 videoplayer is reloaded 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 '''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 content or Ad playback is interrupted and at the end of each Ad. &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. &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;'''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;88675545&amp;quot;,&lt;br /&gt;
  &amp;quot;title&amp;quot;: &amp;quot;Program S3, EP1&amp;quot;,&lt;br /&gt;
  &amp;quot;isfullepisode&amp;quot;:&amp;quot;y&amp;quot;,&lt;br /&gt;
  &amp;quot;adloadtype&amp;quot;:&amp;quot;2&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;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Call [[playheadPosition|playheadPosition()]] 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;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Note:&lt;br /&gt;
*For Audiweb there is no need to tag ads in video stream ... please see 1st example about how to use the SDK without ads.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Call [[play()]] at start of stream&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;ad123&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 [[playheadPosition|playheadPosition()]] 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;
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.playheadPosition(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.playheadPosition(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.playheadPosition(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.playheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // position 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;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.playheadPosition(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 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;
== Sequence of Calls ==&lt;br /&gt;
=== play ===&lt;br /&gt;
Call &amp;lt;code&amp;gt;play&amp;lt;/code&amp;gt; at the start of each new stream. If changing videos or watching a new video, call &amp;lt;code&amp;gt;play()&amp;lt;/code&amp;gt; each time. &lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Objective C = &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;   [nielsenAppApi play:()];&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Swift = &amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;nielsenAppApi?.play();&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== loadMetadata ===&lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Objective C = &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;[nielsenApi loadMetadata:(contentMetadata)];&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Swift = &amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;self.nielsenAppApi?.loadMetadata(contentMetadata)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== playheadPosition ===&lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Objective C = &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
-(void) setPlayHeadPosition {&lt;br /&gt;
    &lt;br /&gt;
    //Setting play head position&lt;br /&gt;
    CMTime timeInterval = CMTimeMakeWithSeconds(1, 1);&lt;br /&gt;
    [player addPeriodicTimeObserverForInterval:(timeInterval) queue:dispatch_get_main_queue() usingBlock:^(CMTime time){&lt;br /&gt;
        NSTimeInterval seconds = CMTimeGetSeconds(time);&lt;br /&gt;
        NSInteger intSec = seconds;&lt;br /&gt;
        &lt;br /&gt;
        //Sending data dictionary to SDK with updated playHead position.&lt;br /&gt;
        [nielsenApi playheadPosition:(intSec)];&lt;br /&gt;
    }];&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|Swift = &amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
        //Monitor the Playhead position of the AVPlayer&lt;br /&gt;
        let timeInterval: CMTime = CMTimeMakeWithSeconds(1.0,10)&lt;br /&gt;
        self.avPlayerViewController.player?.addPeriodicTimeObserver(forInterval: timeInterval, queue: DispatchQueue.main) {(elapsedTime: CMTime) -&amp;gt; Void in&lt;br /&gt;
            if self.avPlayerViewController.player!.currentItem?.status == .readyToPlay {&lt;br /&gt;
                let time : Float64 = self.avPlayerViewController.player!.currentTime().seconds;&lt;br /&gt;
                let pos = Int64(time);&lt;br /&gt;
                NSLog(&amp;quot;New Elapse Time = \(time)&amp;quot;);&lt;br /&gt;
                self.nielsenAppApi?.playheadPosition(pos);&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;
=== stop ===&lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Objective C = &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;[nielsenApi stop];&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Swift = &amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;nielsenApi.stop()&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&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;
{{ExampleCode|&lt;br /&gt;
|Objective C = &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;[nielsenApi end];&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Swift = &amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;nielsenApi.end()&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Handling Foreground and Background states ==&lt;br /&gt;
For iOS, background/foreground detection is handled by the app lifecylce APIs which are provided by [https://developer.apple.com/library/content/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/TheAppLifeCycle/TheAppLifeCycle.html Apple:]&lt;br /&gt;
&lt;br /&gt;
Foreground/Background state measurement is a requirement of Nielsen AppSDK implementation which is especially crucial for static measurement.&lt;br /&gt;
&lt;br /&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; for the new 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;
== Privacy and Opt-Out ==&lt;br /&gt;
There are two primary methods for implementing user Opt-out preferences:&lt;br /&gt;
&lt;br /&gt;
*[[DCR_Italy_Video_iOS_SDK#OS-level_Opt-out|OS-level Opt-out]] - managed by AppTracking or Limit Ad Tracking setting on device (preferred approach).&lt;br /&gt;
*[[DCR_Italy_Video_iOS_SDK#User_Choice|User Choice]] - Direct call to SDK. Can be used without the Ad Framework&lt;br /&gt;
&lt;br /&gt;
=== Special Note Regarding Apps in the Kids Category ===&lt;br /&gt;
If you are building an app that will be listed in the Kids Category:&lt;br /&gt;
&lt;br /&gt;
Ensure that you are using the [https://nielsendownloads-green.digitalengsdk.com/digital/Nielsen-iOS-App-SDK-GlobalNoId_latest.zip NoID version:] of the Nielsen SDK Framework. Also, you can use the [[Digital_Measurement_iOS_Artifactory_Guide|Artifactory method.]]&lt;br /&gt;
Immediately following the initialization of the Nielsen SDK ensure you call the userOptOut API with Opt out selection:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;NielsenAppApi?.userOptOut(&amp;quot;nielsenappsdk://1&amp;quot;); // User opt-outv&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== OS-level Opt-out ===&lt;br /&gt;
''OS-level Opt-out'' method available on Nielsen iOS&lt;br /&gt;
&lt;br /&gt;
The Nielsen SDK automatically leverages the iOS's '''Limit Ad Tracking''' or '''AppTracking''' setting.&lt;br /&gt;
&lt;br /&gt;
*If the User's device is running &amp;lt; iOS 13.x, the Nielsen SDK will check the status of '''Limit Ad Tracking'''.&lt;br /&gt;
*iOS14 modifies the way Apple manages the collection of a User's Opt-In status through '''AppTracking'''. Starting with Version 8.x+, the Nielsen App SDK will check the iOS version during initialization. If the device is running iOS12 or iOS13, the Limit Ad Tracking setting is requested. If iOS14.x +, then AppTracking is utilized.&lt;br /&gt;
&lt;br /&gt;
==== Get the latest Nielsen opt-out URL ====&lt;br /&gt;
&lt;br /&gt;
*Get the current Nielsen opt-out URL via [[optOutURL|optOutURL]]&lt;br /&gt;
*Display a WebView element whose loadUrl is set to the value obtained from [[optOutURL|optOutURL]]&lt;br /&gt;
&lt;br /&gt;
==== Webview Example ====&lt;br /&gt;
The below code is an example of displaying the Nielsen Privacy page to the user.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Note: Apple released a policy update stating that the App Store will no longer accept updates for apps using the deprecated UIWebView (no specific date has been confirmed). Since then, we’ve recommended that you adopt WKWebView instead of UIWebView and WebView.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
import UIKit&lt;br /&gt;
import WebKit&lt;br /&gt;
import NielsenAppApi&lt;br /&gt;
&lt;br /&gt;
class OptOutVC: UIViewController, NielsenAppApiDelegate, WKNavigationDelegate {&lt;br /&gt;
    var webView: WKWebView!&lt;br /&gt;
    var nielsenApi: NielsenAppApi!&lt;br /&gt;
    &lt;br /&gt;
    override func loadView() {&lt;br /&gt;
        webView = WKWebView()&lt;br /&gt;
        webView.navigationDelegate = self&lt;br /&gt;
        view = webView  }&lt;br /&gt;
    &lt;br /&gt;
    override func viewDidLoad() {&lt;br /&gt;
        super.viewDidLoad()&lt;br /&gt;
        self.view.backgroundColor = UIColor(patternImage: UIImage(named: &amp;quot;new_ios_bg.png&amp;quot;)!) &lt;br /&gt;
        self.nielsenApi = NielsenInit.createNielsenApi(delegate: self)  //create an instance &lt;br /&gt;
        &lt;br /&gt;
        if let appApi = self.nielsenApi {&lt;br /&gt;
            //Getting the optPut URL from SDK&lt;br /&gt;
            if let url = URL(string: appApi.optOutURL) { //query the nielsensdk for the current privacy page&lt;br /&gt;
                webView.load(URLRequest(url: url))&lt;br /&gt;
                webView.allowsBackForwardNavigationGestures = true&lt;br /&gt;
            }}}}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== User Choice ===&lt;br /&gt;
The User Choice method can be used without the Ad Framework, or in situations where the publisher does not wish to use the [https://developer.apple.com/documentation/apptrackingtransparency App Tracking Transparency Framework.]&lt;br /&gt;
&lt;br /&gt;
==== The User Choice opt-out method works as follows: ====&lt;br /&gt;
&lt;br /&gt;
*Get the Nielsen opt-out URL via [[optOutURL|optOutURL]]&lt;br /&gt;
*Display a WebView element whose loadUrl is set to the value obtained from [[optOutURL|optOutURL]]&lt;br /&gt;
*Detect if the WebView URL changes to a special URL that indicates Opt-in, or Opt-out and close the WebView&lt;br /&gt;
**Opt-out if the WebView URL = &amp;lt;code&amp;gt;nielsenappsdk://1&amp;lt;/code&amp;gt;&lt;br /&gt;
**Opt-in if the WebView URL = &amp;lt;code&amp;gt;nielsenappsdk://0&amp;lt;/code&amp;gt;&lt;br /&gt;
*Pass the detected URL to the [[userOptOut|userOptOut]] function&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;NielsenAppApi?.userOptOut(&amp;quot;nielsenappsdk://1&amp;quot;); // User opt-out &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Opt-out example code ====&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Note: Apple released a policy update stating that the App Store will no longer accept updates for apps using the deprecated UIWebView (no specific date has been confirmed). Since then, we’ve recommended that you adopt WKWebView instead of UIWebView and WebView.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Objective-C =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)&lt;br /&gt;
navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {&lt;br /&gt;
&lt;br /&gt;
    NSURLRequest *request = [navigationAction request];&lt;br /&gt;
    NSString *url = [[request URL]absoluteString];&lt;br /&gt;
    &lt;br /&gt;
    if([url isEqualToString:self.NIELSEN_URL_OPT_OUT] || [url isEqualToString:self.NIELSEN_URL_OPT_IN]){&lt;br /&gt;
        [self.nielsenApi userOptOut:url];&lt;br /&gt;
        decisionHandler(WKNavigationActionPolicyAllow);&lt;br /&gt;
    }else{&lt;br /&gt;
        decisionHandler(WKNavigationActionPolicyCancel);&lt;br /&gt;
    }        &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Swift =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
var webView: WKWebView!&lt;br /&gt;
var NIELSEN_URL_OPT_OUT : String = &amp;quot;nielsenappsdk://1&amp;quot;&lt;br /&gt;
var NIELSEN_URL_OPT_IN : String = &amp;quot;nielsenappsdk://0&amp;quot;&lt;br /&gt;
&lt;br /&gt;
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, &lt;br /&gt;
decisionHandler: @escaping (WKNavigationActionPolicy) -&amp;gt; Void) {&lt;br /&gt;
&lt;br /&gt;
       let urlStr = navigationAction.request.url?.absoluteString&lt;br /&gt;
&lt;br /&gt;
        if(urlStr == NIELSEN_URL_OPT_OUT || urlStr == NIELSEN_URL_OPT_IN){&lt;br /&gt;
            let appApi = self.nielsenApi&lt;br /&gt;
            appApi?.userOptOut(urlStr)&lt;br /&gt;
            decisionHandler(.allow)&lt;br /&gt;
&lt;br /&gt;
        }else{&lt;br /&gt;
           decisionHandler(.cancel)&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Retrieve current Opt-Out preference ===&lt;br /&gt;
Whether the user is opted out via OS-level Opt-out or via User Choice Opt-out, the current Opt-Out status as detected by the SDK is available via the [[optOutStatus|optOutStatus]] property in the Nielsen SDK API&lt;br /&gt;
&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;
In addition, the following text must be included in your app store description.&lt;br /&gt;
&lt;br /&gt;
Si prega di notare che questa app include il software di misurazione proprietario di Nielsen che contribuisce alla ricerca di mercato. Per ulteriori informazioni, si prega di consultare il seguente link [https://global.nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/?lang=it https://global.nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/?lang=it]&lt;br /&gt;
&lt;br /&gt;
== Going Live ==&lt;br /&gt;
Following Nielsen testing, you will need to:&lt;br /&gt;
&lt;br /&gt;
# '''Disable Debug Logging''': Disable logging by deleting &amp;lt;code&amp;gt;{nol_devDebug: 'DEBUG'}&amp;lt;/code&amp;gt; from initialization call.&lt;br /&gt;
# '''Notify Nielsen''': Once you are ready to go live, let us know so we can enable you for reporting. We will not be able to collect or report data prior to receiving notification from you.&lt;br /&gt;
&lt;br /&gt;
== Removing Simulators (Dynamic Framework Only)==&lt;br /&gt;
&lt;br /&gt;
Simulator slices are needed to let clients build and debug their app on the simulators, but they should be removed before sending the app to the AppStore.  Here is an example Shell script that could be added as a Run Script phase in the application.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang='bash'&amp;gt;&lt;br /&gt;
&lt;br /&gt;
APP_PATH=&amp;quot;${TARGET_BUILD_DIR}/${WRAPPER_NAME}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# This script loops through the frameworks embedded in the application and&lt;br /&gt;
# removes unused architectures.&lt;br /&gt;
find &amp;quot;$APP_PATH&amp;quot; -name '*.framework' -type d | while read -r FRAMEWORK&lt;br /&gt;
do&lt;br /&gt;
FRAMEWORK_EXECUTABLE_NAME=$(defaults read &amp;quot;$FRAMEWORK/Info.plist&amp;quot; CFBundleExecutable)&lt;br /&gt;
FRAMEWORK_EXECUTABLE_PATH=&amp;quot;$FRAMEWORK/$FRAMEWORK_EXECUTABLE_NAME&amp;quot;&lt;br /&gt;
echo &amp;quot;Executable is $FRAMEWORK_EXECUTABLE_PATH&amp;quot;&lt;br /&gt;
&lt;br /&gt;
EXTRACTED_ARCHS=()&lt;br /&gt;
&lt;br /&gt;
for ARCH in $ARCHS&lt;br /&gt;
do&lt;br /&gt;
echo &amp;quot;Extracting $ARCH from $FRAMEWORK_EXECUTABLE_NAME&amp;quot;&lt;br /&gt;
lipo -extract &amp;quot;$ARCH&amp;quot; &amp;quot;$FRAMEWORK_EXECUTABLE_PATH&amp;quot; -o &amp;quot;$FRAMEWORK_EXECUTABLE_PATH-$ARCH&amp;quot;&lt;br /&gt;
EXTRACTED_ARCHS+=(&amp;quot;$FRAMEWORK_EXECUTABLE_PATH-$ARCH&amp;quot;)&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Merging extracted architectures: ${ARCHS}&amp;quot;&lt;br /&gt;
lipo -o &amp;quot;$FRAMEWORK_EXECUTABLE_PATH-merged&amp;quot; -create &amp;quot;${EXTRACTED_ARCHS[@]}&amp;quot;&lt;br /&gt;
rm &amp;quot;${EXTRACTED_ARCHS[@]}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Replacing original executable with thinned version&amp;quot;&lt;br /&gt;
rm &amp;quot;$FRAMEWORK_EXECUTABLE_PATH&amp;quot;&lt;br /&gt;
mv &amp;quot;$FRAMEWORK_EXECUTABLE_PATH-merged&amp;quot; &amp;quot;$FRAMEWORK_EXECUTABLE_PATH&amp;quot;&lt;br /&gt;
&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sample Applications ==&lt;br /&gt;
You can find some examples in the file [[Special:Downloads|Global iOS SDK Download]] from the '''SDK Downloads''' section&lt;/div&gt;</summary>
		<author><name>NickParrucci</name></author>
	</entry>
	<entry>
		<id>https://nielsentest.mywikis.net/w/index.php?title=DCR_Poland_Video_iOS_SDK&amp;diff=6459</id>
		<title>DCR Poland Video iOS SDK</title>
		<link rel="alternate" type="text/html" href="https://nielsentest.mywikis.net/w/index.php?title=DCR_Poland_Video_iOS_SDK&amp;diff=6459"/>
		<updated>2023-07-20T12:15:50Z</updated>

		<summary type="html">&lt;p&gt;NickParrucci: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|International DCR}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
__TOC__&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;
&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;
&lt;br /&gt;
==  Implementation ==&lt;br /&gt;
This guide covers implementation steps for iOS using Xcode utilizing the Standard Nielsen SDK for DCR.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== How to obtain the NielsenAppApi.Framework ===&lt;br /&gt;
The Nielsen AppSDK can either be downloaded directly or can be integrated directly within an application through the use of CocoaPods. We recommend using the CocoaPods-based integration whenever possible to ensure you maintain the most recent changes and enhancements to the Nielsen libraries.&lt;br /&gt;
* [[Digital_Measurement_iOS_Artifactory_Guide|Select to obtain CocoaPods implementation guide]]&lt;br /&gt;
* [[Special:Downloads|Select to Download Directly]]&lt;br /&gt;
* [[DCR_Video_iOS_SDK_xcframework|Using the XCFramework bundle]]&lt;br /&gt;
&lt;br /&gt;
== Special Notes regarding iOS14 ==&lt;br /&gt;
=== Permission to Track === &lt;br /&gt;
&lt;br /&gt;
Apple recently released a new policy on consent requirements, that require the user's permission, to track them using their device's advertising identifier (IDFA).  To request the user's permission, use the AppTrackingTransparency framework. &lt;br /&gt;
&lt;br /&gt;
For more information, see:&lt;br /&gt;
* [https://developer.apple.com/documentation/apptrackingtransparency App Tracking Transparency]&lt;br /&gt;
* [https://developer.apple.com/design/human-interface-guidelines/ios/app-architecture/requesting-permission/ Human Interface Guidelines]&lt;br /&gt;
* [https://developer.apple.com/documentation/adsupport AdSupport Framework]&lt;br /&gt;
&lt;br /&gt;
More detailed information on how the Nielsen SDK versions work with the AppTrackingTransparency framework is located on our [[ DCR Video iOS14 Migration|DCR Video iOS14 Migration]] page.&lt;br /&gt;
&lt;br /&gt;
== Setting up your  Development Environment  ==&lt;br /&gt;
Prior to SDK Version 6.2.0.0 the  IOS framework has been distributed as a static library packaged into framework bundle format. Apple recommends to use dynamic framework, it has some benefits over static libraries like less executable file size of an app, faster startup time and native support in xCode IDE. Nielsen AppSDK has been transformed into dynamic framework in this release ([[iOS_Static_Framework_Setup|static framework]] is still available).&lt;br /&gt;
&lt;br /&gt;
If migrating from the static library to this new dynamic framework, once implemented, unless your specific application requires, you can remove the following Frameworks that were once required:&amp;lt;code&amp;gt; [AdSupport, JavascriptCore, SystemConfiguration, Security, AVFoundation, libc++] &amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The '''Dynamic framework''' is created as a fat framework. It means that it contains slices required for devices (armv7, arm64) as well as slices required for simulators (i386, x86_64). Simulator slices are needed to let clients build and debug their app on the simulators, but they should be removed before sending the app to the AppStore. The example of the shell script that should be added as a Run Script phase in the application can be [[DCR_Video_iOS_SDK#Removing_Simulators_.28Dynamic_Framework_Only.29|found below]].&lt;br /&gt;
&lt;br /&gt;
'''[[DCR_Video_iOS_SDK_xcframework|XCFramework]]''' is solution for the problems described above Apple recommends to use XCFrameworks. In XCFramework, we no longer build a single framework with multiple architectures. Instead, we build one small framework for each combination of architecture and target and store it in its own folder. The top-level XCFramework folder have folders like ios-arm64, ios-arm64-simulator, etc. Each of these folders is its own framework, complete with headers, modules, and binary.&lt;br /&gt;
&lt;br /&gt;
=== Configuring Xcode Development Environment ===&lt;br /&gt;
Starting with SDK version 6.0.0.0, the Nielsen App SDK is compatible with Apple iOS versions 8.0 and above.  In addition, when using the dynamic framework,  all the required frameworks are linked automatically as the are needed.  More details can be found here: https://stackoverflow.com/questions/24902787/dont-we-need-to-link-framework-to-xcode-project-anymore&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': All communications between the SDK and the Census (Collection Facility) use HTTPS.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Special Note for Static Framework ===&lt;br /&gt;
Starting from 8.2.0.0 release framework is build from the mixed (swift + objc) source code.&lt;br /&gt;
If [[iOS_Static_Framework_Setup|static (xc)framework is integrated additional settings]] should be applied to fix build or runtime issues.&lt;br /&gt;
&lt;br /&gt;
=== Download Framework ===&lt;br /&gt;
The first step is to download and copy the [[Special:Downloads|NielsenAppApi.framework]] bundle to the app project directory. (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
=== Add Framework ===&lt;br /&gt;
In the General tab for app configuration add NielsenAppApi.framework in the list of Embedded Binaries.  (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
=== Add Path ===&lt;br /&gt;
Add path to the NielsenAppApi.framework in the Framework Search Paths build setting.  (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
=== Import Framework ===&lt;br /&gt;
Add NielsenAppApi.framework module in the source file of your app:&lt;br /&gt;
&lt;br /&gt;
==== Using Swift ====&lt;br /&gt;
Add the following:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
import NielsenAppApi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using Objective-C ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang =&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
@import NielsenAppApi;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== xCode 12 building errors ====&lt;br /&gt;
Developers who uses &amp;quot;fat&amp;quot; framework in their apps started reporting the following error that they get building the app in xCode 12.3+:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Building for iOS Simulator, but the linked and embedded framework 'MyFramework.framework' was built for iOS + iOS Simulator.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
The binary framework contains different code for the same architecture in multiple places, and Xcode doesn’t know how to handle it. There is workaround that people recommend to use in such cases:&lt;br /&gt;
* https://stackoverflow.com/questions/63267897/building-for-ios-simulator-but-the-linked-framework-framework-was-built&lt;br /&gt;
* https://stackoverflow.com/questions/63932158/xcode12-issus-ld-building-for-ios-simulator-but-linking-in-object-file-built&lt;br /&gt;
&lt;br /&gt;
==== IPA processing failure ====&lt;br /&gt;
&amp;lt;code&amp;gt;Assertion failed: Expected 4 archs in otool output:&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The error above is due to the &amp;quot;fat&amp;quot; (simulator+device) framework which will not appear if you have not enabled Bitcode.  To build your app with full Bitcode support, it is recommended that you use a [[DCR_Video_iOS_SDK_xcframework|XCFramework]] to avoid the 4 archs in otool output message.&lt;br /&gt;
&lt;br /&gt;
== SDK Initialization ==&lt;br /&gt;
The latest version of the Nielsen App SDK allows instantiating multiple instances of the SDK object, which can be used simultaneously without any issue. The sharedInstance API that creates a singleton object was deprecated prior to version 5.1.1. [[Dual_Instances_of_SDK|(Click here for an example of multiple instances)]]&lt;br /&gt;
&lt;br /&gt;
The following table contains the list of arguments that can be passed via the AppInfo JSON schema.&lt;br /&gt;
&lt;br /&gt;
* The appid is provided by the Nielsen Technical Account Manager (TAM). The appid is a GUID data type and is specific to the application.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter / Argument !! Description !! Source !! Required? !! Example&lt;br /&gt;
|-&lt;br /&gt;
| appid || Unique id for the application assigned by Nielsen. It is GUID data type.|| Nielsen-specified || Yes || PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&lt;br /&gt;
|-&lt;br /&gt;
| appname || Name of the application || Client-defined || Optional; automatically detected in SDK 6.0.0.4 and above || Nielsen Sample App&lt;br /&gt;
|-&lt;br /&gt;
| sfcode || Nielsen collection facility to which the SDK should connect.&lt;br /&gt;
* &amp;quot;pl&amp;quot; &lt;br /&gt;
|| Nielsen-specified || Yes || pl&lt;br /&gt;
|-&lt;br /&gt;
| nol_devDebug || Enables Nielsen console logging. Only required for testing&lt;br /&gt;
|| Nielsen-specified || Optional || &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Debug flag for development environment ==&lt;br /&gt;
Player application developers / integrators can use Debug flag to check whether an App SDK API call made is successful. To activate the Debug flag,&lt;br /&gt;
Pass the argument &amp;lt;code&amp;gt;@&amp;quot;nol_devDebug&amp;quot;:@&amp;quot;INFO&amp;quot;&amp;lt;/code&amp;gt;, in the JSON string . The permitted values are:&lt;br /&gt;
&lt;br /&gt;
* '''INFO''': Displays the API calls and the input data from the application (validate player name, app ID, etc.). It can be used as certification Aid.&lt;br /&gt;
* '''WARN''': Indicates potential integration / configuration errors or SDK issues.&lt;br /&gt;
* '''ERROR''': Indicates important integration errors or non-recoverable SDK issues.&lt;br /&gt;
* '''DEBUG''': Debug logs, used by the developers to debug more complex issues.&lt;br /&gt;
&lt;br /&gt;
Once the flag is active, it logs each API call made and the data passed. The log created by this flag is minimal.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': DO NOT activate the Debug flag in a production environment.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sample SDK Initialization Code ===&lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Swift  = &lt;br /&gt;
Swift 4.0 Example:&lt;br /&gt;
&amp;lt;code&amp;gt;NielsenInit.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
import Foundation&lt;br /&gt;
import NielsenAppApi&lt;br /&gt;
&lt;br /&gt;
class NielsenInit : NSObject {&lt;br /&gt;
    class func createNielsenApi(delegate: NielsenAppApiDelegate) -&amp;gt; NielsenAppApi?{&lt;br /&gt;
        &lt;br /&gt;
        let appInformation:[String: String] = [&lt;br /&gt;
            &amp;quot;appid&amp;quot;: &amp;quot;PDA7D5EE6-B1B8-4123-9277-2A788XXXXXXX&amp;quot;,&lt;br /&gt;
            &amp;quot;sfcode&amp;quot;: &amp;quot;pl&amp;quot;,&lt;br /&gt;
            &amp;quot;nol_devDebug&amp;quot;: &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
        ]       &lt;br /&gt;
        return NielsenAppApi(appInfo:appInformation, delegate:delegate)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sample code using AVPlayer.&lt;br /&gt;
&amp;lt;code&amp;gt;ViewController.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class ViewController: UIViewController, NielsenAppApiDelegate, AVPlayerViewControllerDelegate  {&lt;br /&gt;
&lt;br /&gt;
// your code//    &lt;br /&gt;
&lt;br /&gt;
  override func viewDidLoad() {&lt;br /&gt;
        super.viewDidLoad()&lt;br /&gt;
&lt;br /&gt;
        //Getting the instance of NielsenApi&lt;br /&gt;
        self.nielsenApi = NielsenInit.createNielsenApi(delegate: self)&lt;br /&gt;
&lt;br /&gt;
            }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Objective C = &lt;br /&gt;
Initialize the Nielsen App object within the viewDidLoad view controller delegate method using initWithAppInfo:delegate:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;If App SDK is initialized using init or new methods, it will ignore the API calls resulting in no measurement. The SDK will not return any errors.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;    &lt;br /&gt;
#import &amp;quot;NielsenInit.h&amp;quot;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenAppApi.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@implementation NielsenInit&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppApi *)createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate&lt;br /&gt;
{    &lt;br /&gt;
    NSDictionary *appInformation = @{ @&amp;quot;appid&amp;quot;: @&amp;quot;PDA7D5EE6-B1B8-4123-9277-2A788XXXXXXX&amp;quot;,&lt;br /&gt;
                            @&amp;quot;appversion&amp;quot;: @&amp;quot;1.0&amp;quot;,&lt;br /&gt;
                            @&amp;quot;sfcode&amp;quot;: @&amp;quot;pl&amp;quot;,&lt;br /&gt;
                            @&amp;quot;nol_devDebug&amp;quot;: @&amp;quot;DEBUG&amp;quot;, };&lt;br /&gt;
    &lt;br /&gt;
    return [[NielsenAppApi alloc] initWithAppInfo:appInformation delegate:delegate];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following would be the &amp;lt;code&amp;gt;NielsenInit.h&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;Foundation/Foundation.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@class NielsenAppApi;&lt;br /&gt;
@protocol NielsenAppApiDelegate;&lt;br /&gt;
&lt;br /&gt;
@interface NielsenInit : NSObject&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppApi *)createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Sample Code:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
@implementation ViewController&lt;br /&gt;
&lt;br /&gt;
- (void)viewDidLoad {&lt;br /&gt;
    [super viewDidLoad];&lt;br /&gt;
        &lt;br /&gt;
    //Getting the instance of Nielsen SDK&lt;br /&gt;
    nielsenApi = [NielsenInit createNielsenAppApiWithDelegate:nil];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&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;
{{ExampleCode|&lt;br /&gt;
|Swift = &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
let channelInfo = [&lt;br /&gt;
    &amp;quot;channelName&amp;quot;: &amp;quot;My Channel Name 1&amp;quot;,&lt;br /&gt;
];&lt;br /&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 * channelInfo = @ {&lt;br /&gt;
    @ &amp;quot;channelName&amp;quot;: @ &amp;quot;My Channel Name 1&amp;quot;,&lt;br /&gt;
}&lt;br /&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;
=== ChannelName metadata ===&lt;br /&gt;
channelName should remain constant throughout the completion of an episode or live stream.&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;
| channelName	|| ChannelInfo refers to the Channel name. This can be a free-form value&lt;br /&gt;
value such as a friendly name for the content being played. the SDK&amp;lt;br/&amp;gt;&lt;br /&gt;
will pass the application name automatically.&lt;br /&gt;
|| custom	|| No&lt;br /&gt;
|-&lt;br /&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;
{| 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;
| assetid	|| unique ID assigned to asset (max 64 characters; only characters 0-9, a-z, A-Z underscore and minus are allowed - no special characters or vowel mutations) || custom (no [[Special Characters]])|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| program	|| (string) name of program (max 254 characters)	|| custom	|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| title	|| (string) episode title (max 254 characters)	|| custom - no backslash allowed in string (because of 3rd party data processing) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| length	|| (int) length of content in seconds	|| 86400 seconds for live stream. For Event-Livestreams planned length. For VoD video length||	✓&lt;br /&gt;
|-&lt;br /&gt;
| airdate || The airdate in the linear TV. Original (local) air date and time (hh:mm:ss as 24h time stamp); if not known set it to eg. &amp;quot;19700101 00:00:00&amp;quot;	||	YYYY-MM-DDTHH:MI:SS&amp;lt;br&amp;gt;&lt;br /&gt;
YYYY-MM-DDHH:MI:SS&amp;lt;br&amp;gt;&lt;br /&gt;
YYYY-MM-DDTHH:MI:SS+xx:xx&amp;lt;br&amp;gt;&lt;br /&gt;
YYYY-MM-DDTHH:MI:SS-xx:xx&amp;lt;br&amp;gt;&lt;br /&gt;
YYYYMMDDHH:MI:SS&amp;lt;br&amp;gt;&lt;br /&gt;
YYYYMMDD HH:MI:SS&amp;lt;br&amp;gt;&lt;br /&gt;
MM-DD-YYYY&amp;lt;br&amp;gt;&lt;br /&gt;
MM/DD/YYYY&amp;lt;br&amp;gt;&lt;br /&gt;
 (pass beginning of epoch if unknown)&lt;br /&gt;
	|| ✓&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;
| adloadtype || type of ad load:&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;quot;1&amp;quot;&amp;lt;/code&amp;gt; Linear – matches TV ad load&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;quot;2&amp;quot;&amp;lt;/code&amp;gt; Dynamic – Dynamic Ad Insertion (DAI)&lt;br /&gt;
|| &amp;lt;code&amp;gt;&amp;quot;2&amp;quot;&amp;lt;/code&amp;gt; - DCR measures content with dynamic ads ||  ✓&lt;br /&gt;
|-&lt;br /&gt;
| progen || program genre	||	custom	||&lt;br /&gt;
|-&lt;br /&gt;
| segB || custom segment	||	custom	||&lt;br /&gt;
|-&lt;br /&gt;
| segC || custom segment	||	custom	||&lt;br /&gt;
|-&lt;br /&gt;
| crossId1 || standard episode ID	||	custom	||&lt;br /&gt;
|-&lt;br /&gt;
| clientid	|| &lt;br /&gt;
parent ID – value is automatically populated through provided AppID.&amp;lt;br/&amp;gt;&lt;br /&gt;
In order to override the brand configured to the AppID, pass parent &amp;lt;br/&amp;gt;&lt;br /&gt;
value here and the sub-brand ID associated to that brand in the subbrand &amp;lt;br/&amp;gt;&lt;br /&gt;
key (e.g. multiple brands in App)	&lt;br /&gt;
||&lt;br /&gt;
provided by Nielsen	&lt;br /&gt;
||&lt;br /&gt;
|-&lt;br /&gt;
| subbrand	|| vcid/sub-brand ID – value is automatically populated through provided&amp;lt;br/&amp;gt;&lt;br /&gt;
AppID. In order to override the sub-brand configured to the AppID, value can &amp;lt;br/&amp;gt;&lt;br /&gt;
be passed here (e.g. multiple sub-brands in App)&lt;br /&gt;
||&lt;br /&gt;
provided by Nielsen&lt;br /&gt;
||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Ad Metadata ===&lt;br /&gt;
The ad metadata (if applicable) should be passed for each individual ad, if ads are available during or before the stream begins.&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;||	✓&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;
{{ExampleCode|&lt;br /&gt;
|Swift = &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
let adMetadata = [&lt;br /&gt;
    &amp;quot;type&amp;quot;: &amp;quot;preroll&amp;quot;,&lt;br /&gt;
    &amp;quot;assetid&amp;quot;: &amp;quot;123456&amp;quot;&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 * adMetadata = @ {&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;
&lt;br /&gt;
== Nielsen API Documentation ==&lt;br /&gt;
=== play ===&lt;br /&gt;
Use &amp;lt;code&amp;gt;play&amp;lt;/code&amp;gt; to pass the channel descriptor information through channelName parameter when the user taps the '''Play''' button on the player. Pass in channelName metadata as described above.&lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Objective C = &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;   [nielsenApi play:([NSDictionary *channel loadChannelInfo)];&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Swift = &amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;nielsenApi?.play(channelInfo);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== loadMetadata ===&lt;br /&gt;
Call to inform SDK about asset being played. Pass in metadata as described here [[#Configure Payload]], [[#Content Metadata]]&lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Objective C = &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;[nielsenApi loadMetadata:(contentMetadata)];&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Swift = &amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;nielsenApi?.loadMetadata(contentMetadata)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== playheadPosition ===&lt;br /&gt;
Call to inform Nielsen SDK about position in video asset (for VOD pass second within video, for livestreams UTC timestamp in seconds).&lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Objective C = &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;[nielsenApi playheadPosition:secondsAsInt];&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Swift = &amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;nielsenApi?.playheadPosition(secondsAsInt)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== stop ===&lt;br /&gt;
Call to indicate interruption during playback, e.g. pause. (more on interruption scenarios here: [[#Interruptions during playback]] )&lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Objective C = &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;[nielsenApi stop];&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Swift = &amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;nielsenApi?.stop()&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== end ===&lt;br /&gt;
Call when content finished playback and content cannot be resumed from the same position (it can only be restarted from the beginning of stream).&lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Objective C = &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;[nielsenApi end];&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Swift = &amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;nielsenApi?.end()&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Call Nielsen APIs ==&lt;br /&gt;
[[File:appsdkTimeline-DCR.png|icon|link=]]&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;syntaxhighlight lang=Swift&amp;gt;&lt;br /&gt;
nielsenApi = NielsenInit.createNielsenApi(delegate: self);&lt;br /&gt;
data = loadStaticMetadata();&lt;br /&gt;
nielsenApi.loadMetadata(self.data);&amp;lt;/syntaxhighlight&amp;gt; || // Pass Static Metadata here if applicable&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Start of stream || &amp;lt;code&amp;gt;nielsenApi.play(channelName)&amp;lt;/code&amp;gt; || // channelName now automatically generated by Nielsen SDK&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;nielsenApi.loadMetadata(contentMetadata)&amp;lt;/code&amp;gt; || // MetadataObject contains the JSON metadata&amp;lt;br&amp;gt; for the content being played&lt;br /&gt;
|-&lt;br /&gt;
| Content || &amp;lt;code&amp;gt;nielsenApi.playheadPosition(pos);&amp;lt;/code&amp;gt; || // playheadPosition is position of the playhead &amp;lt;br&amp;gt;while the content is being played&lt;br /&gt;
|-&lt;br /&gt;
| End of Stream || &amp;lt;code&amp;gt;nielsenApi.end()&amp;lt;/code&amp;gt; || // Content playback is completed.&lt;br /&gt;
|}&lt;br /&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 '''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;
== API Call Sequence ==&lt;br /&gt;
=== Use Case 1: Content has no Advertisements ===&lt;br /&gt;
Call [[play()]] with channelName JSON as below.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;{&lt;br /&gt;
   &amp;quot;channelName&amp;quot;: &amp;quot;TheMovieTitle&amp;quot;&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;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 [[playheadPosition|playheadPosition()]] 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;nielsenApi.play(channelName); &amp;lt;/code&amp;gt; || // channelName now automatically generated by Nielsen SDK&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;nielsenApi.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;nielsenApi.playheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // position 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;nielsenApi.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()]] with channelName JSON as below.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;{&lt;br /&gt;
   &amp;quot;channelName&amp;quot;: &amp;quot;TheMovieTitle&amp;quot;&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;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 [[playheadPosition|playheadPosition()]] 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;
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;nielsenApi.play(channelName); &amp;lt;/code&amp;gt; || // channelName now automatically generated by Nielsen SDK&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;nielsenApi.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;nielsenApi.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;nielsenApi.playheadPosition(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;nielsenApi.stop();&amp;lt;/code&amp;gt; || // Call stop after preroll occurs&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | Content || &amp;lt;code&amp;gt;nielsenApi.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;nielsenApi.playheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // position is position of the playhead while the content is being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;nielsenApi.stop();&amp;lt;/code&amp;gt; || // Call stop after the content is paused (ad starts)&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;6&amp;quot; | Midroll || &amp;lt;code&amp;gt;nielsenApi.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;nielsenApi.playheadPosition(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;nielsenApi.stop();&amp;lt;/code&amp;gt; || // App moves to background(midroll pauses) &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;nielsenApi.loadMetadata(midrollMetaDataObject);&amp;lt;/code&amp;gt; || // App moves to foreground (midroll resumes) &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;nielsenApi.playheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // playheadPosition is position of the playhead while the midroll ad is being played &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;nielsenApi.stop();&amp;lt;/code&amp;gt; || // Call stop after midroll occurs&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | Content (End of stream) || &amp;lt;code&amp;gt;nielsenApi.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;nielsenApi.playheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // position is position of the playhead while the content is being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;nielsenApi.stop();&amp;lt;/code&amp;gt; || // Always call stop irrespective of postroll is followed or not&lt;br /&gt;
|-&lt;br /&gt;
| End of Stream || &amp;lt;code&amp;gt;nielsenApi.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;nielsenApi.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;nielsenApi.playheadPosition(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;nielsenApi.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 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;
For iOS, background/foreground detection is handled by the app lifecylce APIs which are provided by [https://developer.apple.com/library/content/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/TheAppLifeCycle/TheAppLifeCycle.html Apple:]&lt;br /&gt;
&lt;br /&gt;
Foreground/Background state measurement is a requirement of Nielsen AppSDK implementation which is especially crucial for static measurement.&lt;br /&gt;
&lt;br /&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 (Video players only, not for Audio players)&lt;br /&gt;
* App going in the Background/Foreground (Video players only, not for Audio players)&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 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; for the new 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;
== Privacy and Opt-Out ==&lt;br /&gt;
There are three primary methods for implementing user Opt-out preferences:&lt;br /&gt;
# '''[[#OS-level_Opt-out|OS-level Opt-out]]''' - managed by ''Limit Ad Tracking'' setting on device ('''preferred approach''').&lt;br /&gt;
# '''[[#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;
# '''[[#App_Level_Opt_Out|App Level Opt-Out]]''' - Where [https://developer.apple.com/documentation/adsupport Ad Framework] cannot be leveraged&lt;br /&gt;
&lt;br /&gt;
=== OS-level Opt-out ===&lt;br /&gt;
''OS-level Opt-out'' method available on Nielsen iOS '''SDK Versions 5.1.1.18 and above'''.&lt;br /&gt;
&lt;br /&gt;
The Nielsen SDK automatically leverages the iOS's ''Limit Ad Tracking'' setting. The user is opted out of demographic measurement if the OS-level ''&amp;quot;Limit Ad Tracking&amp;quot;'' setting is ''enabled''. As a publisher, you cannot override this setting.&lt;br /&gt;
&lt;br /&gt;
=== Legacy Opt-out ===&lt;br /&gt;
The ''Legacy opt-out'' method is only necessary for Nielsen iOS '''SDK versions less than 5.1.1.18'''.&lt;br /&gt;
&lt;br /&gt;
Nielsen iOS SDK 5.1.1.17 and above will check for ''OS-level opt-out'' first, if available. The user will be opted out if indicated at the OS-level '''OR''' the App-level.&lt;br /&gt;
&lt;br /&gt;
==== The legacy opt-out method works as follows: ====&lt;br /&gt;
* Get the legacy Nielsen opt-out URL via [[optOutURL]]&lt;br /&gt;
* Display a WebView element whose loadUrl is set to the value obtained from [[optOutURL]]&lt;br /&gt;
* Detect if the WebView URL changes to a special URL that indicates Opt-in, or Opt-out and close the WebView&lt;br /&gt;
** Opt-out if the WebView URL = &amp;lt;code&amp;gt;nielsenappsdk://1&amp;lt;/code&amp;gt;&lt;br /&gt;
** Opt-in if the WebView URL = &amp;lt;code&amp;gt;nielsenappsdk://0&amp;lt;/code&amp;gt;&lt;br /&gt;
* Pass the detected URL to the [[userOptOut]] function&lt;br /&gt;
** Example: &amp;lt;syntaxhighlight lang=swift&amp;gt;NielsenAppApi?.userOptOut(&amp;quot;nielsenappsdk://1&amp;quot;); // User opt-out&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Legacy Opt-out example code ====&lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Objective C = &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {&lt;br /&gt;
&lt;br /&gt;
    NSURLRequest *request = [navigationAction request];&lt;br /&gt;
    NSString *url = [[request URL]absoluteString];&lt;br /&gt;
    &lt;br /&gt;
    if([url isEqualToString:self.NIELSEN_URL_OPT_OUT] || [url isEqualToString:self.NIELSEN_URL_OPT_IN]){&lt;br /&gt;
        [self.nielsenApi userOptOut:url];&lt;br /&gt;
        decisionHandler(WKNavigationActionPolicyAllow);&lt;br /&gt;
    }else{&lt;br /&gt;
        decisionHandler(WKNavigationActionPolicyCancel);&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;
&lt;br /&gt;
var webView: WKWebView!&lt;br /&gt;
var NIELSEN_URL_OPT_OUT : String = &amp;quot;nielsenappsdk://1&amp;quot;&lt;br /&gt;
var NIELSEN_URL_OPT_IN : String = &amp;quot;nielsenappsdk://0&amp;quot;&lt;br /&gt;
&lt;br /&gt;
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -&amp;gt; Void) {&lt;br /&gt;
&lt;br /&gt;
       let urlStr = navigationAction.request.url?.absoluteString&lt;br /&gt;
&lt;br /&gt;
        if(urlStr == NIELSEN_URL_OPT_OUT || urlStr == NIELSEN_URL_OPT_IN){&lt;br /&gt;
            let appApi = self.nielsenApi&lt;br /&gt;
            appApi?.userOptOut(urlStr)&lt;br /&gt;
            decisionHandler(.allow)&lt;br /&gt;
&lt;br /&gt;
        }else{&lt;br /&gt;
           decisionHandler(.cancel)&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Retrieve current Opt-Out preference ===&lt;br /&gt;
Whether the user is opted out via OS-level Opt-out or via App-level Opt-out, the current Opt-Out status as detected by the SDK is available via the [[optOutStatus]] property in the Nielsen SDK API&lt;br /&gt;
&lt;br /&gt;
=== First Party ID (FPID)===&lt;br /&gt;
- The broadcaster must enableFPID in the initialization settings which is set to &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt; depending on user consent. This is to be set by the broadcaster when initializing our SDK.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
- The &amp;lt;code&amp;gt;enableFpid&amp;lt;/code&amp;gt; flag is needed to enable/disable FPID usage for the AppID. The default value for this flag is true. If this flag is changed from true to false, then the AppSDK should wipe out the stored FPID and use a blank value for the FPID parameter in all the pings.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
- Generated FPID value is stored in the persistent memory until the application is uninstalled from a device or until FPID is wiped out or until it is expired.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
- The default value for this parameter is 180 days. Once this timeout is reached, the FPID should be regenerated.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
- Example: disable FPID during init call&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class NielsenInit : NSObject {&lt;br /&gt;
    class func createNielsenApi(delegate: NielsenAppApiDelegate) -&amp;gt; NielsenAppApi?{&lt;br /&gt;
        &lt;br /&gt;
        let appInformation:[String: String] = [&lt;br /&gt;
            &amp;quot;appid&amp;quot;: &amp;quot;PDA7D5EE6-B1B8-4123-9277-2A788XXXXXXX&amp;quot;,&lt;br /&gt;
            &amp;quot;sfcode&amp;quot;: &amp;quot;pl&amp;quot;, // sfcode for Poland&lt;br /&gt;
            &amp;quot;enableFpid&amp;quot;: &amp;quot;false&amp;quot; //false = FPID is disabled, true= FPID is enabled&lt;br /&gt;
            &amp;quot;nol_devDebug&amp;quot;: &amp;quot;DEBUG&amp;quot; // only for debug builds and see the Nielsen logs&lt;br /&gt;
        ]       &lt;br /&gt;
        return NielsenAppApi(appInfo:appInformation, delegate:delegate)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&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;
In addition, the following text must be included in your app store description.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
'''&amp;quot;Please note: This app features Nielsen’s proprietary measurement software which contributes to market research, like Nielsen’s TV Ratings. Please see https://priv-policy.imrworldwide.com/priv/mobile/pl/pl/optout.html for more information&amp;quot;'''&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Webview Example  ====&lt;br /&gt;
The below code is an example of displaying the Nielsen Privacy page to the user.&lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Objective C = &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
- (void)viewDidLoad {&lt;br /&gt;
&lt;br /&gt;
    [super viewDidLoad];&lt;br /&gt;
    &lt;br /&gt;
    //Setting background image&lt;br /&gt;
    UIImage *backgroundImage = [UIImage imageNamed:@&amp;quot;new_ios_bg.png&amp;quot;];&lt;br /&gt;
    UIImageView *backgroundImageView=[[UIImageView alloc]initWithFrame:self.view.frame];&lt;br /&gt;
    backgroundImageView.image=backgroundImage;&lt;br /&gt;
    [self.view insertSubview:backgroundImageView atIndex:0];&lt;br /&gt;
&lt;br /&gt;
    self.nielsenApi = [NielsenInit createNielsenAppApiWithDelegate:nil];&lt;br /&gt;
&lt;br /&gt;
    //Initialising the webview&lt;br /&gt;
    WKWebViewConfiguration *theConfiguration = [[WKWebViewConfiguration alloc] init];&lt;br /&gt;
    _wkwebView = [[WKWebView alloc] initWithFrame:self.view.frame configuration:theConfiguration];&lt;br /&gt;
    _wkwebView.navigationDelegate = self;&lt;br /&gt;
&lt;br /&gt;
     //Getting the optPut URL from SDK&lt;br /&gt;
    NSURL *nsurl=[NSURL URLWithString:[self.nielsenApi optOutURL]];&lt;br /&gt;
&lt;br /&gt;
    //Setting url request in webview&lt;br /&gt;
    NSURLRequest *nsrequest=[NSURLRequest requestWithURL:nsurl];&lt;br /&gt;
&lt;br /&gt;
     //Setting url request in webview&lt;br /&gt;
    [_wkwebView loadRequest:nsrequest];&lt;br /&gt;
&lt;br /&gt;
      //Adding webview to the controller view &lt;br /&gt;
    [self.view addSubview:_wkwebView];   &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;
import UIKit&lt;br /&gt;
import WebKit&lt;br /&gt;
import NielsenAppApi&lt;br /&gt;
&lt;br /&gt;
class OptOutVC: UIViewController, NielsenAppApiDelegate, WKNavigationDelegate {&lt;br /&gt;
    &lt;br /&gt;
    var webView: WKWebView!&lt;br /&gt;
    var nielsenApi: NielsenAppApi!&lt;br /&gt;
    &lt;br /&gt;
    override func loadView() {&lt;br /&gt;
        webView = WKWebView()&lt;br /&gt;
        webView.navigationDelegate = self&lt;br /&gt;
        view = webView&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    override func viewDidLoad() {&lt;br /&gt;
        super.viewDidLoad()&lt;br /&gt;
        self.view.backgroundColor = UIColor(patternImage: UIImage(named: &amp;quot;new_ios_bg.png&amp;quot;)!) &lt;br /&gt;
        self.nielsenApi = NielsenInit.createNielsenApi(delegate: self)&lt;br /&gt;
        &lt;br /&gt;
        if let appApi = self.nielsenApi {&lt;br /&gt;
            //Getting the optPut URL from SDK&lt;br /&gt;
            if let url = URL(string: appApi.optOutURL) {&lt;br /&gt;
                webView.load(URLRequest(url: url))&lt;br /&gt;
                webView.allowsBackForwardNavigationGestures = true&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;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== App Level Opt Out ===&lt;br /&gt;
This is only used if the Ad Framework is not available.  The Opt-Out occurs by opening a Nielsen-defined web page and passing the user choice from the 'WebView'. In order to do this, the application needs to:&lt;br /&gt;
* Implement the UIWebView delegate method to open the Nielsen Privacy web page&lt;br /&gt;
* Capture user's selection&lt;br /&gt;
* Pass the selection back to the SDK via the &amp;lt;code&amp;gt;userOptOut&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Capture and forward user selection ====&lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Objective C = &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType&lt;br /&gt;
{&lt;br /&gt;
    NSString *command = [NSString stringWithFormat:@&amp;quot;%@&amp;quot;,request.URL];&lt;br /&gt;
    if ([command isEqualToString:kNielsenWebClose]) {&lt;br /&gt;
        // Close the WebView&lt;br /&gt;
        [self performSelector:@selector(closeOptOutView) withObject:nil afterDelay:0];&lt;br /&gt;
        return NO;&lt;br /&gt;
    }&lt;br /&gt;
    // Retrieve next URL if it’s not opt-in/out selection&lt;br /&gt;
    return (![nAppApiObject userOptOut:command]);&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*The app gets the user selection string via webviews shouldStartLoadWithRequest and invokes &amp;lt;code&amp;gt;userOptOut&amp;lt;/code&amp;gt; with user selection. The delegate method handles the 'WebView' URL requests, interprets the commands, and calls the SDK accordingly.&lt;br /&gt;
**&amp;lt;code&amp;gt;[nAppApiObject userOptOut:command]&amp;lt;/code&amp;gt; passes the user's selection on Nielsen Privacy page to the SDK to allow the SDK to perform the required functions.&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. The 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;
|Swift = &amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
 func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -&amp;gt; Bool {&lt;br /&gt;
&lt;br /&gt;
        let command = request.url?.absoluteString&lt;br /&gt;
        if  command ==  &amp;quot;kNielsenWebClose&amp;quot;{&lt;br /&gt;
&lt;br /&gt;
            self.perform(#selector(closeOptOutView), with: nil, afterDelay: 0)&lt;br /&gt;
&lt;br /&gt;
            return false&lt;br /&gt;
        }    &lt;br /&gt;
        return NielsenAppApi.optOutURL&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*The app gets the user selection string via webviews shouldStartLoadWithRequest and invokes &amp;lt;code&amp;gt;userOptOut&amp;lt;/code&amp;gt; with user selection. The delegate method handles the 'WebView' URL requests, interprets the commands, and calls the SDK accordingly.&lt;br /&gt;
**&amp;lt;code&amp;gt;[nAppApiObject userOptOut:command]&amp;lt;/code&amp;gt; passes the user's selection on Nielsen Privacy page to the SDK to allow the SDK to perform the required functions.&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. The 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;
&lt;br /&gt;
== AirPlay ==&lt;br /&gt;
To implement OTT measurement, report OTT changes to the SDK using public API interface: [[updateOTT]]&lt;br /&gt;
&lt;br /&gt;
In order to detect AirPlay and mirroring changes we use AVAudioSessionPortDescription properties that are different on different iOS versions. We found that on iOS versions 8 - 10 &amp;lt;code&amp;gt;AVAudioSessionPortDescription&amp;lt;/code&amp;gt; has the following values:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
AirPlay: type = AirPlay; name = Apple TV 4K; UID = DC:56:E7:53:72:85-airplay &amp;lt;br&amp;gt;&lt;br /&gt;
Mirroring: type = AirPlay; name = Apple TV 4K; UID = DC:56:E7:53:72:85-screen&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For iOS 11+ some parameters like name and UID have different values:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
AirPlay: type = AirPlay; name = AirPlay; UID = 0eb63aae-5915-45f1-b0f7-0102a0e50d53 &amp;lt;br&amp;gt;&lt;br /&gt;
Mirroring: type = AirPlay; name = Apple TV 4K; UID = 4335E8A9-1C0A-4251-9000-28CA5FA2F3CF-192731714653291-screen&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following code snipped is suggested for AirPlay / mirroring detection on iOS devices.&lt;br /&gt;
&lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Objective C = &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
– (void)updateOTT:(id)ottInfo;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Subscribe to AVAudioSessionRouteChangeNotification ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleRouteChanged:) name:AVAudioSessionRouteChangeNotification object:nil];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Handle AVAudioSessionRouteChangeNotification and prepare OTT dictionary:===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
- (void)handleRouteChanged:(NSNotification *)notification&lt;br /&gt;
{&lt;br /&gt;
NSMutableDictionary *ottDict = [NSMutableDictionary dictionaryWithDictionary: @{@&amp;quot;ottStatus&amp;quot;: @&amp;quot;0&amp;quot;}];&lt;br /&gt;
&lt;br /&gt;
AVAudioSession *audioSession = [AVAudioSession sharedInstance];&lt;br /&gt;
AVAudioSessionRouteDescription *currentRoute = audioSession.currentRoute;&lt;br /&gt;
for (AVAudioSessionPortDescription *outputPort in currentRoute.outputs) {&lt;br /&gt;
if ([outputPort.portType isEqualToString:AVAudioSessionPortAirPlay]) {&lt;br /&gt;
ottDict[@&amp;quot;ottStatus&amp;quot;] = @&amp;quot;1&amp;quot;;&lt;br /&gt;
ottDict[@&amp;quot;ottDeviceModel&amp;quot;] = outputPort.portName;&lt;br /&gt;
ottDict[@&amp;quot;ottDeviceID&amp;quot;] = outputPort.UID;&lt;br /&gt;
&lt;br /&gt;
if ([outputPort.portName isEqualToString:@&amp;quot;AirPlay&amp;quot;]) {&lt;br /&gt;
ottDict[@&amp;quot;ottDevice&amp;quot;] = @&amp;quot;airplay&amp;quot;;&lt;br /&gt;
ottDict[@&amp;quot;ottType&amp;quot;] = @&amp;quot;airplay&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
else {&lt;br /&gt;
if ([outputPort.portName containsString:@&amp;quot;Apple TV&amp;quot;]) {&lt;br /&gt;
ottDict[@&amp;quot;ottDevice&amp;quot;] = @&amp;quot;appleTV&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
else {&lt;br /&gt;
ottDict[@&amp;quot;ottDevice&amp;quot;] = @&amp;quot;other&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
if ([outputPort.UID hasSuffix:@&amp;quot;airplay&amp;quot;]) {&lt;br /&gt;
ottDict[@&amp;quot;ottType&amp;quot;] = @&amp;quot;airplay&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
else if ([outputPort.UID hasSuffix:@&amp;quot;screen&amp;quot;]) {&lt;br /&gt;
ottDict[@&amp;quot;ottType&amp;quot;] = @&amp;quot;mirroring&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
else {&lt;br /&gt;
ottDict[@&amp;quot;ottType&amp;quot;] = @&amp;quot;other&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// report OTT status update to Nielsen SDK&lt;br /&gt;
[self reportOTTWithDict:ottDict];&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Report OTT update to the Nielsen SDK ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
- (void)reportOTTWithDict:(NSDictionary *)ottDict&lt;br /&gt;
{&lt;br /&gt;
[self.nielsenSDK updateOTT:ottDict];&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|Swift = &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
nielsenSdk.updateOTT(currentStatus)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Subscribe to AVAudioSessionRouteChangeNotification === &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
NotificationCenter.default.addObserver(self, selector: #selector(handleRouteChanged(_:)), name: NSNotification.Name.AVAudioSessionRouteChange, object: nil)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Handle AVAudioSessionRouteChangeNotification and prepare OTT dictionary:===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang =&amp;quot;Swift&amp;quot;&amp;gt;&lt;br /&gt;
func handleRouteChanged(_ notification: Notification) {&lt;br /&gt;
var currentStatus: [String: String] = [&amp;quot;ottStatus&amp;quot;: &amp;quot;0&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
let session = AVAudioSession.sharedInstance()&lt;br /&gt;
let currentRoute = session.currentRoute&lt;br /&gt;
for outputPort in currentRoute.outputs {&lt;br /&gt;
if outputPort.portType == AVAudioSessionPortAirPlay {&lt;br /&gt;
currentStatus[&amp;quot;ottStatus&amp;quot;] = &amp;quot;1&amp;quot;&lt;br /&gt;
currentStatus[&amp;quot;ottDeviceModel&amp;quot;] = outputPort.portName&lt;br /&gt;
currentStatus[&amp;quot;ottDeviceID&amp;quot;] = outputPort.uid&lt;br /&gt;
&lt;br /&gt;
if outputPort.portName == &amp;quot;AirPlay&amp;quot; {&lt;br /&gt;
currentStatus[&amp;quot;ottDevice&amp;quot;] = &amp;quot;airplay&amp;quot;&lt;br /&gt;
currentStatus[&amp;quot;ottType&amp;quot;] = &amp;quot;airplay&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
else {&lt;br /&gt;
if outputPort.portName.contains(&amp;quot;Apple TV&amp;quot;) {&lt;br /&gt;
currentStatus[&amp;quot;ottDevice&amp;quot;] = &amp;quot;appleTV&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
else {&lt;br /&gt;
currentStatus[&amp;quot;ottDevice&amp;quot;] = &amp;quot;other&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
if outputPort.uid.hasSuffix(&amp;quot;airplay&amp;quot;) {&lt;br /&gt;
currentStatus[&amp;quot;ottType&amp;quot;] = &amp;quot;airplay&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
else if outputPort.uid.hasSuffix(&amp;quot;screen&amp;quot;) {&lt;br /&gt;
currentStatus[&amp;quot;ottType&amp;quot;] = &amp;quot;mirroring&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
else {&lt;br /&gt;
currentStatus[&amp;quot;ottType&amp;quot;] = &amp;quot;other&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// report OTT status update to Nielsen SDK&lt;br /&gt;
self.reportOTTUpdate(currentStatus)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Report OTT update to the Nielsen SDK===&lt;br /&gt;
&amp;lt;syntaxhighlight lang =&amp;quot;Swift&amp;quot;&amp;gt;&lt;br /&gt;
func reportOTTUpdate(_ ottDict: [String: String]) {&lt;br /&gt;
if let nielsenSdk = self.nielsenAppApi {&lt;br /&gt;
nielsenSdk.updateOTT(currentStatus)&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Going Live ==&lt;br /&gt;
Following Nielsen testing, users need to make one update to the initialization call to ensure that the site is being measured properly.&lt;br /&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;
&amp;lt;br/&amp;gt;&lt;br /&gt;
'''Note''': before going live you have to inform Nielsen team - this is necessary, because Nielsen team has to adjust internal configuration parameter to enable data collection. Without that notification no data will be collected and no data will be reported.&lt;br /&gt;
&lt;br /&gt;
== Removing Simulators (Dynamic Framework Only)==&lt;br /&gt;
&lt;br /&gt;
Simulator slices are needed to let clients build and debug their app on the simulators, but they should be removed before sending the app to the AppStore.  Here is an example Shell script that could be added as a Run Script phase in the application.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang='bash'&amp;gt;&lt;br /&gt;
&lt;br /&gt;
APP_PATH=&amp;quot;${TARGET_BUILD_DIR}/${WRAPPER_NAME}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# This script loops through the frameworks embedded in the application and&lt;br /&gt;
# removes unused architectures.&lt;br /&gt;
find &amp;quot;$APP_PATH&amp;quot; -name '*.framework' -type d | while read -r FRAMEWORK&lt;br /&gt;
do&lt;br /&gt;
FRAMEWORK_EXECUTABLE_NAME=$(defaults read &amp;quot;$FRAMEWORK/Info.plist&amp;quot; CFBundleExecutable)&lt;br /&gt;
FRAMEWORK_EXECUTABLE_PATH=&amp;quot;$FRAMEWORK/$FRAMEWORK_EXECUTABLE_NAME&amp;quot;&lt;br /&gt;
echo &amp;quot;Executable is $FRAMEWORK_EXECUTABLE_PATH&amp;quot;&lt;br /&gt;
&lt;br /&gt;
EXTRACTED_ARCHS=()&lt;br /&gt;
&lt;br /&gt;
for ARCH in $ARCHS&lt;br /&gt;
do&lt;br /&gt;
echo &amp;quot;Extracting $ARCH from $FRAMEWORK_EXECUTABLE_NAME&amp;quot;&lt;br /&gt;
lipo -extract &amp;quot;$ARCH&amp;quot; &amp;quot;$FRAMEWORK_EXECUTABLE_PATH&amp;quot; -o &amp;quot;$FRAMEWORK_EXECUTABLE_PATH-$ARCH&amp;quot;&lt;br /&gt;
EXTRACTED_ARCHS+=(&amp;quot;$FRAMEWORK_EXECUTABLE_PATH-$ARCH&amp;quot;)&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Merging extracted architectures: ${ARCHS}&amp;quot;&lt;br /&gt;
lipo -o &amp;quot;$FRAMEWORK_EXECUTABLE_PATH-merged&amp;quot; -create &amp;quot;${EXTRACTED_ARCHS[@]}&amp;quot;&lt;br /&gt;
rm &amp;quot;${EXTRACTED_ARCHS[@]}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Replacing original executable with thinned version&amp;quot;&lt;br /&gt;
rm &amp;quot;$FRAMEWORK_EXECUTABLE_PATH&amp;quot;&lt;br /&gt;
mv &amp;quot;$FRAMEWORK_EXECUTABLE_PATH-merged&amp;quot; &amp;quot;$FRAMEWORK_EXECUTABLE_PATH&amp;quot;&lt;br /&gt;
&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sample Applications ==&lt;br /&gt;
The below sample applications have been designed to show the Simplified API's functionality and are broken into two distinct categories:&lt;br /&gt;
* '''Basic''' - To show the functionality of the Nielsen Simplified API using a standard no-frills player.&lt;br /&gt;
** [[Swift Basic Sample|Swift 4.0 Sample]]&lt;br /&gt;
** [[Objective-c Basic example|Objective-C Sample]]&lt;br /&gt;
** [[Android Basic example|Android Studio Example]]&lt;br /&gt;
&lt;br /&gt;
* '''Advanced''' - Nielsen Simplified API integrated into a custom video player.&lt;br /&gt;
** [https://engineeringportal.nielsen.com/docs/Special:Downloads Swift 4.0 Sample]&lt;br /&gt;
** [https://engineeringportal.nielsen.com/docs/Special:Downloads Objective-C Sample]&lt;br /&gt;
** [https://engineeringportal.nielsen.com/docs/Special:Downloads Java/Android Studio Sample]&lt;/div&gt;</summary>
		<author><name>NickParrucci</name></author>
	</entry>
	<entry>
		<id>https://nielsentest.mywikis.net/w/index.php?title=iOS_Static_Framework_Setup&amp;diff=6458</id>
		<title>iOS Static Framework Setup</title>
		<link rel="alternate" type="text/html" href="https://nielsentest.mywikis.net/w/index.php?title=iOS_Static_Framework_Setup&amp;diff=6458"/>
		<updated>2023-07-20T12:15:20Z</updated>

		<summary type="html">&lt;p&gt;NickParrucci: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|DCR &amp;amp; DTVR}} {{Breadcrumb|DCR Video iOS SDK}} {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
__NOTOC__&lt;br /&gt;
= Configuring Xcode Development Environment for Static Framework =&lt;br /&gt;
== Importing Frameworks ==&lt;br /&gt;
The first step is to ensure that the following frameworks and libraries are imported into the Frameworks folder of the Xcode project before creating an instance of the Nielsen App SDK object.&lt;br /&gt;
* UIKit.framework&lt;br /&gt;
* Foundation.framework&lt;br /&gt;
* AdSupport.framework&lt;br /&gt;
* JavascriptCore.framework&lt;br /&gt;
* WebKit.framework&lt;br /&gt;
* SystemConfiguration.framework&lt;br /&gt;
* Security.framework&lt;br /&gt;
** Nielsen Analytics framework makes use of a number of functions in this library.&lt;br /&gt;
* AVFoundation.framework&lt;br /&gt;
* NielsenAppApi.framework&lt;br /&gt;
* libc++.tbd (as SDK contains Objective C++ source file)&lt;br /&gt;
** Alternatively, include -lstdc++ in Build Settings → Other Linker Flag of the Xcode project&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Example'''&lt;br /&gt;
* Extract “NielsenAppApi.Framework” from the Nielsen App SDK sample app and copy it to Frameworks folder of the Xcode project.&lt;br /&gt;
* Add the code &amp;lt;code&amp;gt;-#import NielsenAppApi/NielsenAppApi.h&amp;lt;/code&amp;gt; to the View Controller’s header file.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Ensure that the following are included in the Linked Frameworks and Libraries list (located in the project’s Summary settings).&lt;br /&gt;
* Nielsen App SDK&lt;br /&gt;
* iOS security framework&lt;br /&gt;
=== Mixed Nielsen SDK static (xc)frameworks integration errors ===&lt;br /&gt;
Starting from 8.2.0.0 release framework is build from the mixed (swift + objc) source code.&amp;lt;br&amp;gt;&lt;br /&gt;
If static (xc)framework is integrated additional settings should be applied to fix build or runtime issues:&lt;br /&gt;
&lt;br /&gt;
==== Empty Swift file ====&lt;br /&gt;
If static mixed (xc)framework is integrated into pure ObjC application, link issue occurs during building:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p style=&amp;quot;color:red;&amp;quot;&amp;gt;&lt;br /&gt;
Undefined symbol: _OBJC_CLASS_$__TtCs12_SwiftObject&amp;lt;br&amp;gt;&lt;br /&gt;
Undefined symbol: nominal type descriptor for Dispatch.DispatchSpecificKey&amp;lt;br&amp;gt;&lt;br /&gt;
Undefined symbol: Dispatch.DispatchSpecificKey.init() -&amp;gt; Dispatch.DispatchSpecificKey&amp;lt;A&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Undefined symbol: static (extension in Dispatch):__C.OS_dispatch_queue.getSpecific&amp;lt;A&amp;gt;(key: Dispatch.DispatchSpecificKey&amp;lt;A&amp;gt;) -&amp;gt; A?&amp;lt;br&amp;gt;&lt;br /&gt;
Undefined symbol: (extension in Dispatch):__C.OS_dispatch_queue.label.getter : Swift.String&amp;lt;br&amp;gt;&lt;br /&gt;
Undefined symbol: _swift_weakDestroy&amp;lt;br&amp;gt;&lt;br /&gt;
Undefined symbol: _swift_deallocObject&amp;lt;br&amp;gt;&lt;br /&gt;
Undefined symbol: type metadata accessor for Network.NWPathMonitor&amp;lt;br&amp;gt;&lt;br /&gt;
Undefined symbol: Network.NWPathMonitor.init() -&amp;gt; Network.NWPathMonitor&amp;lt;br&amp;gt;&lt;br /&gt;
Undefined symbol: _swift_weakInit&amp;lt;br&amp;gt;&lt;br /&gt;
...&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To fix it an empty file with .swift extension should be added into the Application project target(s).&lt;br /&gt;
&lt;br /&gt;
[[File:Screen Shot 2022-02-22 at 12.34.12.png|frame|center]]&lt;br /&gt;
&lt;br /&gt;
==== -ObjC linker flag ====&lt;br /&gt;
Static library doesn't automatically load every source code entity. This leads to the runtime exception kind of:&lt;br /&gt;
&amp;lt;p style=&amp;quot;color:red;&amp;quot;&amp;gt;&lt;br /&gt;
unrecognized selector sent to class 0x1087b7a50, AppApiExceptionName=NSInvalidArgumentException&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is a known swift issue:&lt;br /&gt;
https://bugs.swift.org/browse/SR-6004&lt;br /&gt;
&lt;br /&gt;
To fix:&amp;lt;br&amp;gt;&lt;br /&gt;
Build Settings → Other Linker flags -&amp;gt; -ObjC&lt;br /&gt;
&lt;br /&gt;
[[File:Screen Shot 2022-02-22 at 12.45.15.png|frame|center]]&lt;br /&gt;
&lt;br /&gt;
=== Using Objective-C ===&lt;br /&gt;
Add the code &lt;br /&gt;
&amp;lt;syntaxhighlight lang =&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenAppApi.h&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 to the View Controller’s header file.&lt;/div&gt;</summary>
		<author><name>NickParrucci</name></author>
	</entry>
	<entry>
		<id>https://nielsentest.mywikis.net/w/index.php?title=DCR_Italy_AUDIO_iOS_SDK&amp;diff=6457</id>
		<title>DCR Italy AUDIO iOS SDK</title>
		<link rel="alternate" type="text/html" href="https://nielsentest.mywikis.net/w/index.php?title=DCR_Italy_AUDIO_iOS_SDK&amp;diff=6457"/>
		<updated>2023-07-20T12:15:08Z</updated>

		<summary type="html">&lt;p&gt;NickParrucci: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|International DCR}}  {{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 page / sub section in the application.&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: 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. || Provided by 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;
 || '''sfcode''' || Unique identifier for the environment that the SDK should point to || Provided by Nielsen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
If need App ID(s) or our SDKs, feel free to reach out to us and we will be happy to help you get started.&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;
=== Notes for WebView Contents ===&lt;br /&gt;
&amp;lt;code&amp;gt;Please note that if within your APP user can surf '''static contents''' recalled from your website the [[DCR_Italy_Static_Browser_SDK|browser static SDK]] have to inhibit from this pages.&amp;lt;/code&amp;gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==  Implementation ==&lt;br /&gt;
This guide covers implementation steps for iOS using Xcode utilizing the Standard Nielsen SDK for DCR.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;If you are building an app for the 'kids category' please review the [[DCR_Italy_Video_iOS_SDK#Special_Note_Regarding_Apps_in_the_Kids_Category|Opt Out Requirement.]]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== How to obtain the NielsenAppApi.Framework ===&lt;br /&gt;
The Nielsen AppSDK can either be downloaded directly or can be integrated directly within an application through the use of CocoaPods. We recommend using the CocoaPods-based integration whenever possible to ensure you maintain the most recent changes and enhancements to the Nielsen libraries.&lt;br /&gt;
* [[Digital_Measurement_iOS_Artifactory_Guide|Select to obtain CocoaPods implementation guide]]&lt;br /&gt;
* [[Special:Downloads|Select to Download Directly]]&lt;br /&gt;
* [[DCR_Video_iOS_SDK_xcframework|Using the XCFramework bundle]]&lt;br /&gt;
&lt;br /&gt;
== Special Notes regarding iOS14 ==&lt;br /&gt;
=== Permission to Track === &lt;br /&gt;
&lt;br /&gt;
Apple recently released a new policy on consent requirements, that require the user's permission, to track them using their device's advertising identifier (IDFA).  To request the user's permission, use the AppTrackingTransparency framework. &lt;br /&gt;
&lt;br /&gt;
For more information, see:&lt;br /&gt;
* [https://developer.apple.com/documentation/apptrackingtransparency App Tracking Transparency]&lt;br /&gt;
* [https://developer.apple.com/design/human-interface-guidelines/ios/app-architecture/requesting-permission/ Human Interface Guidelines]&lt;br /&gt;
* [https://developer.apple.com/documentation/adsupport AdSupport Framework]&lt;br /&gt;
&lt;br /&gt;
More detailed information on how the Nielsen SDK versions work with the AppTrackingTransparency framework is located on our [[ DCR Video iOS14 Migration|DCR Audio/Video iOS14 Migration]] page.&lt;br /&gt;
&lt;br /&gt;
== Setting up your  Development Environment  ==&lt;br /&gt;
Prior to SDK Version 6.2.0.0 the  IOS framework has been distributed as a static library packaged into framework bundle format. Apple recommends to use dynamic framework, it has some benefits over static libraries like less executable file size of an app, faster startup time and native support in xCode IDE. Nielsen AppSDK has been transformed into dynamic framework in this release ([[iOS_Static_Framework_Setup|static framework]] is still available).&lt;br /&gt;
&lt;br /&gt;
If migrating from the static library to this new dynamic framework, once implemented, unless your specific application requires, you can remove the following Frameworks that were once required:&amp;lt;code&amp;gt; [AdSupport, JavascriptCore, SystemConfiguration, Security, AVFoundation, libc++] &amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The '''Dynamic framework''' is created as a fat framework. It means that it contains slices required for devices (armv7, arm64) as well as slices required for simulators (i386, x86_64). Simulator slices are needed to let clients build and debug their app on the simulators, but they should be removed before sending the app to the AppStore. The example of the shell script that should be added as a Run Script phase in the application can be [[DCR_Video_iOS_SDK#Removing_Simulators_.28Dynamic_Framework_Only.29|found below]].&lt;br /&gt;
&lt;br /&gt;
'''[[DCR_Video_iOS_SDK_xcframework|XCFramework]]''' is solution for the problems described above Apple recommends to use XCFrameworks. In XCFramework, we no longer build a single framework with multiple architectures. Instead, we build one small framework for each combination of architecture and target and store it in its own folder. The top-level XCFramework folder have folders like ios-arm64, ios-arm64-simulator, etc. Each of these folders is its own framework, complete with headers, modules, and binary.&lt;br /&gt;
&lt;br /&gt;
=== Configuring Xcode Development Environment ===&lt;br /&gt;
Starting with SDK version 6.0.0.0, the Nielsen App SDK is compatible with Apple iOS versions 8.0 and above.  In addition, when using the dynamic framework,  all the required frameworks are linked automatically as the are needed.  More details can be found here: https://stackoverflow.com/questions/24902787/dont-we-need-to-link-framework-to-xcode-project-anymore&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': All communications between the SDK and the Census (Collection Facility) use HTTPS.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Special Note for Static Framework ===&lt;br /&gt;
Starting from 8.2.0.0 release framework is build from the mixed (swift + objc) source code.&lt;br /&gt;
If [[iOS_Static_Framework_Setup|static (xc)framework is integrated additional settings]] should be applied to fix build or runtime issues.&lt;br /&gt;
&lt;br /&gt;
=== Download Framework ===&lt;br /&gt;
The first step is to download and copy the [[Special:Downloads|NielsenAppApi.framework]] bundle to the app project directory. (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
=== Add Framework ===&lt;br /&gt;
In the General tab for app configuration add NielsenAppApi.framework in the list of Embedded Binaries.  (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
=== Add Path ===&lt;br /&gt;
Add path to the NielsenAppApi.framework in the Framework Search Paths build setting.  (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
=== Import Framework ===&lt;br /&gt;
Add NielsenAppApi.framework module in the source file of your app:&lt;br /&gt;
&lt;br /&gt;
==== Using Swift ====&lt;br /&gt;
Add the following:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
import NielsenAppApi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using Objective-C ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang =&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
@import NielsenAppApi;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== xCode 12 building errors ====&lt;br /&gt;
Developers who uses &amp;quot;fat&amp;quot; framework in their apps started reporting the following error that they get building the app in xCode 12.3+:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Building for iOS Simulator, but the linked and embedded framework 'MyFramework.framework' was built for iOS + iOS Simulator.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
The binary framework contains different code for the same architecture in multiple places, and Xcode doesn’t know how to handle it. There is workaround that people recommend to use in such cases:&lt;br /&gt;
* https://stackoverflow.com/questions/63267897/building-for-ios-simulator-but-the-linked-framework-framework-was-built&lt;br /&gt;
* https://stackoverflow.com/questions/63932158/xcode12-issus-ld-building-for-ios-simulator-but-linking-in-object-file-built&lt;br /&gt;
&lt;br /&gt;
==== IPA processing failure ====&lt;br /&gt;
&amp;lt;code&amp;gt;Assertion failed: Expected 4 archs in otool output:&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The error above is due to the &amp;quot;fat&amp;quot; (simulator+device) framework which will not appear if you have not enabled Bitcode.  To build your app with full Bitcode support, it is recommended that you use a [[DCR_Video_iOS_SDK_xcframework|XCFramework]] to avoid the 4 archs in otool output message.&lt;br /&gt;
&lt;br /&gt;
== SDK Initialization ==&lt;br /&gt;
The latest version of the Nielsen App SDK allows instantiating multiple instances of the SDK object, which can be used simultaneously without any issue. The sharedInstance API that creates a singleton object was deprecated prior to version 5.1.1. [[Dual_Instances_of_SDK|(Click here for an example of multiple instances)]]&lt;br /&gt;
&lt;br /&gt;
The following table contains the list of arguments that can be passed via the AppInfo JSON schema.&lt;br /&gt;
*The appid is provided by the Nielsen Technical Account Manager (TAM). The appid is a GUID data type and is specific to the application.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter / Argument !! Description !! Source !! Required? !! Example&lt;br /&gt;
|-&lt;br /&gt;
| appid || Unique Nielsen ID for the application. The ID is a GUID data type. If you did not receive your App ID, let us know and we will provide you. || Nielsen-specified || Yes || PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&lt;br /&gt;
|-&lt;br /&gt;
| appname || Name of the application&lt;br /&gt;
|| Client-defined || Yes || &amp;quot;Nielsen Sample App&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| appversion || Current version of the app used&lt;br /&gt;
|| Client-defined || Yes || &amp;quot;1.0.2&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| sfcode || Nielsen collection facility to which the SDK should connect.&lt;br /&gt;
&lt;br /&gt;
|| Nielsen-specified || Yes || &lt;br /&gt;
|-&lt;br /&gt;
| nol_devDebug || Enables Nielsen console logging. Only required for testing&lt;br /&gt;
|| Nielsen-specified || Yes for Debugging / Testing App || &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Debug flag for development environment ==&lt;br /&gt;
Player application developers / integrators can use Debug flag to check whether an App SDK API call made is successful. To activate the Debug flag,&lt;br /&gt;
Pass the argument &amp;lt;code&amp;gt;@&amp;quot;nol_devDebug&amp;quot;:@&amp;quot;DEBUG&amp;quot;&amp;lt;/code&amp;gt;, in the JSON string . The permitted values are:&lt;br /&gt;
&lt;br /&gt;
* '''INFO''': Displays the API calls and the input data from the application (validate player name, app ID, etc.). It can be used as certification Aid.&lt;br /&gt;
* '''WARN''': Indicates potential integration / configuration errors or SDK issues.&lt;br /&gt;
* '''ERROR''': Indicates important integration errors or non-recoverable SDK issues.&lt;br /&gt;
* '''DEBUG''': Debug logs, used by the developers to debug more complex issues.&lt;br /&gt;
&lt;br /&gt;
Once the flag is active, it logs each API call made and the data passed. The log created by this flag is minimal.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': Activate the Debug flag in a Test environment.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sample SDK Initialization Code ===&lt;br /&gt;
&lt;br /&gt;
==== App tracking transparency framework ====&lt;br /&gt;
&lt;br /&gt;
To display the App Tracking Transparency authorization request for accessing the IDFA, update your &amp;lt;code&amp;gt;info.plist&amp;lt;/code&amp;gt; to add the &amp;lt;code&amp;gt;NSUserTrackingUsageDescription&amp;lt;/code&amp;gt; key with a custom message describing your usage. Below is an example description text:&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;key&amp;gt;NSUserTrackingUsageDescription&amp;lt;/key&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;string&amp;gt;This identifier will be used to deliver personalized ads to you.&amp;lt;/string&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The system automatically generates the prompt’s title, which includes the name of your app, then the usage description appears as part of the App Tracking&lt;br /&gt;
&lt;br /&gt;
To present the authorization request, call requestTrackingAuthorizationWithCompletionHandler.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Please NOTE: It is important to initialize the NielsenSDK after the ATTrackingManager has Authorized usage.  When the SDK initializes, it checks the status of the ATTrackingManager.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can find an example in the file [[Special:Downloads|Global iOS SDK Download]] from the '''SDK Downloads''' section, folder name NielsenSampleVideoPlayer.&lt;br /&gt;
&lt;br /&gt;
====Swift 4.0 Example:====&lt;br /&gt;
&amp;lt;code&amp;gt;NielsenInit.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
import Foundation&lt;br /&gt;
import NielsenAppApi&lt;br /&gt;
&lt;br /&gt;
class NielsenInit : NSObject {&lt;br /&gt;
    class func createNielsenApi(delegate: NielsenAppApiDelegate) -&amp;gt; NielsenAppApi?{&lt;br /&gt;
        &lt;br /&gt;
        let appInformation:[String: String] = [&lt;br /&gt;
            &amp;quot;appid&amp;quot;: &amp;quot;PDA7D5EE6-B1B8-4123-9277-2A788XXXXXXX&amp;quot;,&lt;br /&gt;
            &amp;quot;appversion&amp;quot;: &amp;quot;1.0.2&amp;quot;,&lt;br /&gt;
            &amp;quot;appname&amp;quot;: &amp;quot;Nielsen Sample App&amp;quot;,&lt;br /&gt;
            &amp;quot;nol_devDebug&amp;quot;: &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
        ]       &lt;br /&gt;
        return NielsenAppApi(appInfo:appInformation, delegate:delegate)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Sample code using AVPlayer===&lt;br /&gt;
&amp;lt;code&amp;gt;ViewController.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class ViewController: UIViewController, NielsenAppApiDelegate, AVPictureInPictureControllerDelegate, CLLocationManagerDelegate  {&lt;br /&gt;
    &lt;br /&gt;
    let avPlayerViewController = AVPlayerViewController()&lt;br /&gt;
    var avPlayer:AVPlayer?&lt;br /&gt;
    var nielsenAppApi: NielsenAppApi!&lt;br /&gt;
&lt;br /&gt;
  override func viewDidLoad() {&lt;br /&gt;
        super.viewDidLoad()&lt;br /&gt;
&lt;br /&gt;
self.nielsenAppApi = NielsenInit.createNielsenAppApi(delegate: self)&lt;br /&gt;
NSLog(&amp;quot;Nielsen SDK initialized&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
            }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Objective C ==== &lt;br /&gt;
Initialize the Nielsen App object within the viewDidLoad view controller delegate method using initWithAppInfo:delegate:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;If App SDK is initialized using init or new methods, it will ignore the API calls resulting in no measurement. The SDK will not return any errors.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;    &lt;br /&gt;
#import &amp;quot;NlsAppApiFactory.h&amp;quot;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenAppApi.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@implementation NlsAppApiFactory&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppApi *)createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
{&lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
    NSDictionary *appInformation = @{ &lt;br /&gt;
                                     @&amp;quot;appid&amp;quot;: &amp;quot;PDA7D5EE6-B1B8-4123-9277-2A788XXXXXXX&amp;quot;,&lt;br /&gt;
                                     @&amp;quot;appversion&amp;quot;: &amp;quot;1.0.2&amp;quot;,&lt;br /&gt;
                                     @&amp;quot;appname&amp;quot;: &amp;quot;Nielsen Sample App&amp;quot;,&lt;br /&gt;
                                     @&amp;quot;nol_devDebug&amp;quot;: @&amp;quot;DEBUG&amp;quot;&lt;br /&gt;
                                    };&lt;br /&gt;
    &lt;br /&gt;
    return [[NielsenAppApi alloc] initWithAppInfo:appInformation delegate:delegate];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following would be the &amp;lt;code&amp;gt;NlsAppApiFactory.h&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;Foundation/Foundation.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@class NielsenAppApi;&lt;br /&gt;
@protocol NielsenAppApiDelegate;&lt;br /&gt;
&lt;br /&gt;
@interface NlsAppApiFactory : NSObject &lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppAPI *) createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sample Code: ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
@implementation ViewController&lt;br /&gt;
&lt;br /&gt;
- (void)viewDidLoad {&lt;br /&gt;
    [super viewDidLoad];&lt;br /&gt;
        &lt;br /&gt;
    //Getting the instance of Nielsen SDK&lt;br /&gt;
    nielsenApi = [NlsAppApiFactory createNielsenAppApiWithDelegate:nil];&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
== Initializing the Nielsen AppSDK to measure the Viewability ==&lt;br /&gt;
The integrator to support the viewability metrics in the application has to provide a tag value of the player view to let Nielsen AppSDK know that there is a player that needs to be tracked. It’s called the ‘containerId’ and it should be passed in application info dictionary as string while initializing the Nielsen AppSDK.&lt;br /&gt;
&lt;br /&gt;
=== Android ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! #	!! Parameter Name	!! Description !! Supported Values !! Example&lt;br /&gt;
|-&lt;br /&gt;
| 1	|| containerId ||View ID of the UI element used as player view in application. getId() method of View class can be used to get this value.	||A positive integer used to identify the view. || 2131558561&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== iOS ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! #	!! Parameter Name	!! Description !! Supported Values !! Example&lt;br /&gt;
|-&lt;br /&gt;
| 1	|| containerId ||The tag of the UIView that represents the Player View	||The string value representing the NSInteger value with maximum value of NSIntegerMax that is related on 32- or 64-bit applications. || &amp;quot;100&amp;quot; &amp;lt;br&amp;gt; &amp;quot;2131558561&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For iOS it is required to link additional frameworks that are needed for viewability engine:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;JavaScriptCore.framework&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;WebKit.framework&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Nielsen AppSDK uses a tracking WebView (TWV) approach.  For more information on Viewability, please refer to [https://engineeringportal.nielsen.com/docs/Implementing_Viewability_with_AppSDK Implementing Viewability with AppSDK.]&lt;br /&gt;
--&amp;gt;&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, please review the [[APP SDK Event Codes|App SDK Event Code]] Reference page.&lt;br /&gt;
&lt;br /&gt;
== Configure Metadata ==&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 Nielsen Key names (e.g. appid, program) 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;
&lt;br /&gt;
Example for Audio measurement:&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;
&lt;br /&gt;
let channelInfo = [&lt;br /&gt;
            &amp;quot;channelName&amp;quot;: &amp;quot;My Channel Name 1&amp;quot;,&lt;br /&gt;
];&lt;br /&gt;
        &lt;br /&gt;
let contentMetadata = [&lt;br /&gt;
            &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;,&lt;br /&gt;
            &amp;quot;isAudio&amp;quot;: &amp;quot;true&amp;quot;,&lt;br /&gt;
            &amp;quot;assetid&amp;quot;: &amp;quot;88675545&amp;quot;,&lt;br /&gt;
            &amp;quot;title&amp;quot;: &amp;quot;Program S3, EP1&amp;quot;,&lt;br /&gt;
            &amp;quot;isfullepisode&amp;quot;:&amp;quot;y&amp;quot;,&lt;br /&gt;
            &amp;quot;adloadtype&amp;quot;:&amp;quot;2&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;
];&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  *channelInfo = @&lt;br /&gt;
{&lt;br /&gt;
  @&amp;quot;channelName&amp;quot;:@&amp;quot;My Channel Name 1&amp;quot;,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
NSDictionary * contentMetadata = @ {&lt;br /&gt;
    @ &amp;quot;type&amp;quot;: @ &amp;quot;content&amp;quot;,&lt;br /&gt;
    @ &amp;quot;isAudio&amp;quot;: @&amp;quot;true&amp;quot;,&lt;br /&gt;
    @ &amp;quot;assetid&amp;quot;: @ &amp;quot;88675545&amp;quot;,&lt;br /&gt;
    @ &amp;quot;title&amp;quot;: @ &amp;quot;Program S3, EP1&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;20200321 10:05:00&amp;quot;,&lt;br /&gt;
    @ &amp;quot;adloadtype&amp;quot;: @ &amp;quot;2&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
=== Configure metadata === &lt;br /&gt;
channelName should remain constant throughout the completion of an episode or live stream.&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;
| channelName	|| ChannelInfo refers to the Channel name. This can be a free-form value&lt;br /&gt;
value such as a friendly name for the content being played. the SDK&amp;lt;br/&amp;gt;&lt;br /&gt;
will pass the application name automatically.&lt;br /&gt;
|| custom	|| No&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Configure metadata ===&lt;br /&gt;
Configure metadata should remain constant throughout the completion of an episode or live stream&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;
| channelName 	|| Any string representing the channel/stream || custom || Yes&lt;br /&gt;
|}&lt;br /&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 audio /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;
==== Audio Content Metadata ====&lt;br /&gt;
Content metadata should remain constant throughout the entirety of an episode/clip including when ads play.&lt;br /&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 asset || &amp;lt;code&amp;gt;'content'&amp;lt;/code&amp;gt; || Yes&lt;br /&gt;
|-&lt;br /&gt;
| isAudio || indicate measurement of audio ads or audio content || &amp;lt;code&amp;gt;'true'&amp;lt;/code&amp;gt; || Yes&lt;br /&gt;
|-&lt;br /&gt;
| assetid || unique ID assigned to asset (32 Character limit) || custom (no [[Special Characters|Special Characters]]) || Yes&lt;br /&gt;
|-&lt;br /&gt;
| program || name of program (100 character limit) || custom || Yes&lt;br /&gt;
|-&lt;br /&gt;
| title || name of program (100 character limit) || custom || Yes&lt;br /&gt;
|-&lt;br /&gt;
| length || length of content in seconds || Length of content in seconds (86400 seconds for live stream (24/7). For Event-Live streams planned length. For AOD video length)|| Yes&lt;br /&gt;
|-&lt;br /&gt;
| airdate || The airdate in the linear over-the-air broadcast. Original (local) air date and time (hh:mm:ss as 24h time stamp); if not known set it to eg. &amp;quot;19700101 00:00:00&amp;quot; || YYYYMMDD HH24:MI:SS &lt;br /&gt;
(if not known set it to eg. &amp;quot;19700101 00:00:00&amp;quot;) &lt;br /&gt;
|| Yes&lt;br /&gt;
|-&lt;br /&gt;
| isfullepisode || full episode flag || &amp;lt;code&amp;gt;'y'&amp;lt;/code&amp;gt;- full episode, &amp;lt;code&amp;gt;'n'&amp;lt;/code&amp;gt;- non full episode || Yes&lt;br /&gt;
|-&lt;br /&gt;
| adloadtype || type of ad load:&lt;br /&gt;
*&amp;lt;code&amp;gt;'1'&amp;lt;/code&amp;gt; Linear – matches TV ad load&lt;br /&gt;
*&amp;lt;code&amp;gt;'2'&amp;lt;/code&amp;gt; Dynamic – Dynamic Ad Insertion (DAI)&lt;br /&gt;
|| &amp;lt;code&amp;gt;'2'&amp;lt;/code&amp;gt; - DCR measures content with dynamic ads &lt;br /&gt;
|| Yes&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== Example Audio Content Object =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
let contentMetadata = [&lt;br /&gt;
            &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;,&lt;br /&gt;
            &amp;quot;isAudio&amp;quot;: &amp;quot;true&amp;quot;,&lt;br /&gt;
            &amp;quot;assetid&amp;quot;: &amp;quot;88675545&amp;quot;,&lt;br /&gt;
            &amp;quot;title&amp;quot;: &amp;quot;Program S3, EP1&amp;quot;,&lt;br /&gt;
            &amp;quot;isfullepisode&amp;quot;:&amp;quot;y&amp;quot;,&lt;br /&gt;
            &amp;quot;adloadtype&amp;quot;:&amp;quot;2&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;
];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Video Content Metadata ====&lt;br /&gt;
Content metadata should remain constant throughout the entirety of an episode/clip including when ads play.&lt;br /&gt;
&lt;br /&gt;
'''Don't pass audio key &amp;quot;isAudio&amp;quot; into the loadmetadata call for video measurement'''.&lt;br /&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 asset || &amp;lt;code&amp;gt;'content'&amp;lt;/code&amp;gt; || Yes&lt;br /&gt;
|-&lt;br /&gt;
| assetid || unique ID assigned to asset (32 Character limit) || custom (no [[Special Characters|Special Characters]]) || Yes&lt;br /&gt;
|-&lt;br /&gt;
| program || name of program (100 character limit) || custom || Yes&lt;br /&gt;
|-&lt;br /&gt;
| title || name of program (100 character limit) || custom || Yes&lt;br /&gt;
|-&lt;br /&gt;
| length || length of content in seconds || Length of content in seconds (86400 seconds for live stream (24/7). For Event-Live streams planned length. For AOD video length)|| Yes&lt;br /&gt;
|-&lt;br /&gt;
| airdate || The airdate in the linear over-the-air broadcast. Original (local) air date and time (hh:mm:ss as 24h time stamp); if not known set it to eg. &amp;quot;19700101 00:00:00&amp;quot; || YYYYMMDD HH24:MI:SS &lt;br /&gt;
(if not known set it to eg. &amp;quot;19700101 00:00:00&amp;quot;) &lt;br /&gt;
|| Yes&lt;br /&gt;
|-&lt;br /&gt;
| isfullepisode || full episode flag || &amp;lt;code&amp;gt;'y'&amp;lt;/code&amp;gt;- full episode, &amp;lt;code&amp;gt;'n'&amp;lt;/code&amp;gt;- non full episode || Yes&lt;br /&gt;
|-&lt;br /&gt;
| adloadtype || type of ad load:&lt;br /&gt;
*&amp;lt;code&amp;gt;'1'&amp;lt;/code&amp;gt; Linear – matches TV ad load&lt;br /&gt;
*&amp;lt;code&amp;gt;'2'&amp;lt;/code&amp;gt; Dynamic – Dynamic Ad Insertion (DAI)&lt;br /&gt;
|| &amp;lt;code&amp;gt;'2'&amp;lt;/code&amp;gt; - DCR measures content with dynamic ads &lt;br /&gt;
|| Yes&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== Example Video Content Object =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&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;88675545&amp;quot;,&lt;br /&gt;
            &amp;quot;title&amp;quot;: &amp;quot;Program S3, EP1&amp;quot;,&lt;br /&gt;
            &amp;quot;isfullepisode&amp;quot;:&amp;quot;y&amp;quot;,&lt;br /&gt;
            &amp;quot;adloadtype&amp;quot;:&amp;quot;2&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;
];&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; || Yes&lt;br /&gt;
|-&lt;br /&gt;
| assetid ||	unique ID assigned to Ad	|| custom (no [[Special Characters|Special Characters]]) || Yes&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Example Ad Object ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  let adMetadata = [&lt;br /&gt;
        &amp;quot;assetid&amp;quot; : &amp;quot;unique_postroll_ad_id&amp;quot;,&lt;br /&gt;
        &amp;quot;type&amp;quot; : &amp;quot;preroll&amp;quot;&lt;br /&gt;
    ]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Configure API Calls ==&lt;br /&gt;
&amp;lt;!--[[File:appsdkTimeline-DCR.png|icon|link=]]--&amp;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;syntaxhighlight lang=Swift&amp;gt;&lt;br /&gt;
NielsenInit.createMainBrandApi(delegate: self)&lt;br /&gt;
self.data = loadStaticMetadata()&lt;br /&gt;
self.nielsenMeter .loadMetadata(self.data)&amp;lt;/syntaxhighlight&amp;gt; || // Pass Static Metadata here if applicable&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(contentMetadata)&amp;lt;/code&amp;gt; || // MetadataObject contains the JSON metadata&amp;lt;br&amp;gt; for the content being played&lt;br /&gt;
|-&lt;br /&gt;
| Content || &amp;lt;code&amp;gt;nielsenMeter.playheadPosition(pos);&amp;lt;/code&amp;gt; || // playheadPosition is position of the playhead &amp;lt;br&amp;gt;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;
| 'playheadPosition'	|| playhead position as integer&amp;lt;br/&amp;gt;&lt;br /&gt;
AOD: 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: 'PlayheadPosition' 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 audio 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 media player is reloaded or closed.&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Note: For livestream, send the UNIX timestamp, for AOD 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 '''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 content or Ad playback is interrupted and at the end of each Ad. &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. &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;'''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;isAudio&amp;quot;: &amp;quot;true&amp;quot;,&lt;br /&gt;
  &amp;quot;assetid&amp;quot;: &amp;quot;88675545&amp;quot;,&lt;br /&gt;
  &amp;quot;title&amp;quot;: &amp;quot;Program S3, EP1&amp;quot;,&lt;br /&gt;
  &amp;quot;isfullepisode&amp;quot;:&amp;quot;y&amp;quot;,&lt;br /&gt;
  &amp;quot;adloadtype&amp;quot;:&amp;quot;2&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;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Call [[playheadPosition|playheadPosition()]] 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;
&lt;br /&gt;
&lt;br /&gt;
Call [[play()]] at start of stream&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;ad123&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 [[playheadPosition|playheadPosition()]] 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;
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.playheadPosition(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.playheadPosition(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.playheadPosition(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.playheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // position 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;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.playheadPosition(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 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;
== Sequence of Calls ==&lt;br /&gt;
=== play ===&lt;br /&gt;
Call &amp;lt;code&amp;gt;play&amp;lt;/code&amp;gt; at the start of each new stream. If changing audio or listening to a new audio, call &amp;lt;code&amp;gt;play()&amp;lt;/code&amp;gt; each time. &lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Objective C = &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;   [nielsenAppApi play:()];&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Swift = &amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;nielsenAppApi?.play();&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== loadMetadata ===&lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Objective C = &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;[nielsenApi loadMetadata:(contentMetadata)];&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Swift = &amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;self.nielsenAppApi?.loadMetadata(contentMetadata)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== playheadPosition ===&lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Objective C = &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
-(void) setPlayHeadPosition {&lt;br /&gt;
    &lt;br /&gt;
    //Setting play head position&lt;br /&gt;
    CMTime timeInterval = CMTimeMakeWithSeconds(1, 1);&lt;br /&gt;
    [player addPeriodicTimeObserverForInterval:(timeInterval) queue:dispatch_get_main_queue() usingBlock:^(CMTime time){&lt;br /&gt;
        NSTimeInterval seconds = CMTimeGetSeconds(time);&lt;br /&gt;
        NSInteger intSec = seconds;&lt;br /&gt;
        &lt;br /&gt;
        //Sending data dictionary to SDK with updated playHead position.&lt;br /&gt;
        [nielsenApi playheadPosition:(intSec)];&lt;br /&gt;
    }];&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|Swift = &amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
        //Monitor the Playhead position of the AVPlayer&lt;br /&gt;
        let timeInterval: CMTime = CMTimeMakeWithSeconds(1.0,10)&lt;br /&gt;
        self.avPlayerViewController.player?.addPeriodicTimeObserver(forInterval: timeInterval, queue: DispatchQueue.main) {(elapsedTime: CMTime) -&amp;gt; Void in&lt;br /&gt;
            if self.avPlayerViewController.player!.currentItem?.status == .readyToPlay {&lt;br /&gt;
                let time : Float64 = self.avPlayerViewController.player!.currentTime().seconds;&lt;br /&gt;
                let pos = Int64(time);&lt;br /&gt;
                NSLog(&amp;quot;New Elapse Time = \(time)&amp;quot;);&lt;br /&gt;
                self.nielsenAppApi?.playheadPosition(pos);&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;
=== stop ===&lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Objective C = &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;[nielsenApi stop];&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Swift = &amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;nielsenApi.stop()&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&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;
{{ExampleCode|&lt;br /&gt;
|Objective C = &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;[nielsenApi end];&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Swift = &amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;nielsenApi.end()&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Handling Foreground and Background states ==&lt;br /&gt;
For iOS, background/foreground detection is handled by the app lifecylce APIs which are provided by [https://developer.apple.com/library/content/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/TheAppLifeCycle/TheAppLifeCycle.html Apple:]&lt;br /&gt;
&lt;br /&gt;
Foreground/Background state measurement is a requirement of Nielsen AppSDK implementation which is especially crucial for static measurement.&lt;br /&gt;
&lt;br /&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; for the new 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;
== Privacy and Opt-Out ==&lt;br /&gt;
There are two primary methods for implementing user Opt-out preferences:&lt;br /&gt;
&lt;br /&gt;
*[[DCR_Italy_Video_iOS_SDK#OS-level_Opt-out|OS-level Opt-out]] - managed by AppTracking or Limit Ad Tracking setting on device (preferred approach).&lt;br /&gt;
*[[DCR_Italy_Video_iOS_SDK#User_Choice|User Choice]] - Direct call to SDK. Can be used without the Ad Framework&lt;br /&gt;
&lt;br /&gt;
=== Special Note Regarding Apps in the Kids Category ===&lt;br /&gt;
If you are building an app that will be listed in the Kids Category:&lt;br /&gt;
&lt;br /&gt;
Ensure that you are using the [https://nielsendownloads-green.digitalengsdk.com/digital/Nielsen-iOS-App-SDK-GlobalNoId_latest.zip NoID version:] of the Nielsen SDK Framework. Also, you can use the [[Digital_Measurement_iOS_Artifactory_Guide|Artifactory method.]]&lt;br /&gt;
Immediately following the initialization of the Nielsen SDK ensure you call the userOptOut API with Opt out selection:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;NielsenAppApi?.userOptOut(&amp;quot;nielsenappsdk://1&amp;quot;); // User opt-outv&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== OS-level Opt-out ===&lt;br /&gt;
''OS-level Opt-out'' method available on Nielsen iOS&lt;br /&gt;
&lt;br /&gt;
The Nielsen SDK automatically leverages the iOS's '''Limit Ad Tracking''' or '''AppTracking''' setting.&lt;br /&gt;
&lt;br /&gt;
*If the User's device is running &amp;lt; iOS 13.x, the Nielsen SDK will check the status of '''Limit Ad Tracking'''.&lt;br /&gt;
*iOS14 modifies the way Apple manages the collection of a User's Opt-In status through '''AppTracking'''. Starting with Version 8.x+, the Nielsen App SDK will check the iOS version during initialization. If the device is running iOS12 or iOS13, the Limit Ad Tracking setting is requested. If iOS14.x +, then AppTracking is utilized.&lt;br /&gt;
&lt;br /&gt;
==== Get the latest Nielsen opt-out URL ====&lt;br /&gt;
&lt;br /&gt;
*Get the current Nielsen opt-out URL via [[optOutURL|optOutURL]]&lt;br /&gt;
*Display a WebView element whose loadUrl is set to the value obtained from [[optOutURL|optOutURL]]&lt;br /&gt;
&lt;br /&gt;
==== Webview Example ====&lt;br /&gt;
The below code is an example of displaying the Nielsen Privacy page to the user.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Note: Apple released a policy update stating that the App Store will no longer accept updates for apps using the deprecated UIWebView (no specific date has been confirmed). Since then, we’ve recommended that you adopt WKWebView instead of UIWebView and WebView.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
import UIKit&lt;br /&gt;
import WebKit&lt;br /&gt;
import NielsenAppApi&lt;br /&gt;
&lt;br /&gt;
class OptOutVC: UIViewController, NielsenAppApiDelegate, WKNavigationDelegate {&lt;br /&gt;
    var webView: WKWebView!&lt;br /&gt;
    var nielsenApi: NielsenAppApi!&lt;br /&gt;
    &lt;br /&gt;
    override func loadView() {&lt;br /&gt;
        webView = WKWebView()&lt;br /&gt;
        webView.navigationDelegate = self&lt;br /&gt;
        view = webView  }&lt;br /&gt;
    &lt;br /&gt;
    override func viewDidLoad() {&lt;br /&gt;
        super.viewDidLoad()&lt;br /&gt;
        self.view.backgroundColor = UIColor(patternImage: UIImage(named: &amp;quot;new_ios_bg.png&amp;quot;)!) &lt;br /&gt;
        self.nielsenApi = NielsenInit.createNielsenApi(delegate: self)  //create an instance &lt;br /&gt;
        &lt;br /&gt;
        if let appApi = self.nielsenApi {&lt;br /&gt;
            //Getting the optPut URL from SDK&lt;br /&gt;
            if let url = URL(string: appApi.optOutURL) { //query the nielsensdk for the current privacy page&lt;br /&gt;
                webView.load(URLRequest(url: url))&lt;br /&gt;
                webView.allowsBackForwardNavigationGestures = true&lt;br /&gt;
            }}}}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== User Choice ===&lt;br /&gt;
The User Choice method can be used without the Ad Framework, or in situations where the publisher does not wish to use the [https://developer.apple.com/documentation/apptrackingtransparency App Tracking Transparency Framework.]&lt;br /&gt;
&lt;br /&gt;
==== The User Choice opt-out method works as follows: ====&lt;br /&gt;
&lt;br /&gt;
*Get the Nielsen opt-out URL via [[optOutURL|optOutURL]]&lt;br /&gt;
*Display a WebView element whose loadUrl is set to the value obtained from [[optOutURL|optOutURL]]&lt;br /&gt;
*Detect if the WebView URL changes to a special URL that indicates Opt-in, or Opt-out and close the WebView&lt;br /&gt;
**Opt-out if the WebView URL = &amp;lt;code&amp;gt;nielsenappsdk://1&amp;lt;/code&amp;gt;&lt;br /&gt;
**Opt-in if the WebView URL = &amp;lt;code&amp;gt;nielsenappsdk://0&amp;lt;/code&amp;gt;&lt;br /&gt;
*Pass the detected URL to the [[userOptOut|userOptOut]] function&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;NielsenAppApi?.userOptOut(&amp;quot;nielsenappsdk://1&amp;quot;); // User opt-out &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Opt-out example code ====&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Note: Apple released a policy update stating that the App Store will no longer accept updates for apps using the deprecated UIWebView (no specific date has been confirmed). Since then, we’ve recommended that you adopt WKWebView instead of UIWebView and WebView.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Objective-C =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)&lt;br /&gt;
navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {&lt;br /&gt;
&lt;br /&gt;
    NSURLRequest *request = [navigationAction request];&lt;br /&gt;
    NSString *url = [[request URL]absoluteString];&lt;br /&gt;
    &lt;br /&gt;
    if([url isEqualToString:self.NIELSEN_URL_OPT_OUT] || [url isEqualToString:self.NIELSEN_URL_OPT_IN]){&lt;br /&gt;
        [self.nielsenApi userOptOut:url];&lt;br /&gt;
        decisionHandler(WKNavigationActionPolicyAllow);&lt;br /&gt;
    }else{&lt;br /&gt;
        decisionHandler(WKNavigationActionPolicyCancel);&lt;br /&gt;
    }        &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Swift =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
var webView: WKWebView!&lt;br /&gt;
var NIELSEN_URL_OPT_OUT : String = &amp;quot;nielsenappsdk://1&amp;quot;&lt;br /&gt;
var NIELSEN_URL_OPT_IN : String = &amp;quot;nielsenappsdk://0&amp;quot;&lt;br /&gt;
&lt;br /&gt;
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, &lt;br /&gt;
decisionHandler: @escaping (WKNavigationActionPolicy) -&amp;gt; Void) {&lt;br /&gt;
&lt;br /&gt;
       let urlStr = navigationAction.request.url?.absoluteString&lt;br /&gt;
&lt;br /&gt;
        if(urlStr == NIELSEN_URL_OPT_OUT || urlStr == NIELSEN_URL_OPT_IN){&lt;br /&gt;
            let appApi = self.nielsenApi&lt;br /&gt;
            appApi?.userOptOut(urlStr)&lt;br /&gt;
            decisionHandler(.allow)&lt;br /&gt;
&lt;br /&gt;
        }else{&lt;br /&gt;
           decisionHandler(.cancel)&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Retrieve current Opt-Out preference ===&lt;br /&gt;
Whether the user is opted out via OS-level Opt-out or via User Choice Opt-out, the current Opt-Out status as detected by the SDK is available via the [[optOutStatus|optOutStatus]] property in the Nielsen SDK API&lt;br /&gt;
&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;
In addition, the following text must be included in your app store description.&lt;br /&gt;
&lt;br /&gt;
Si prega di notare che questa app include il software di misurazione proprietario di Nielsen che contribuisce alla ricerca di mercato. Per ulteriori informazioni, si prega di consultare il seguente link [https://global.nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/?lang=it https://global.nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/?lang=it]&lt;br /&gt;
&lt;br /&gt;
== Going Live ==&lt;br /&gt;
Following Nielsen testing, you will need to:&lt;br /&gt;
&lt;br /&gt;
# '''Disable Debug Logging''': Disable logging by deleting &amp;lt;code&amp;gt;{nol_devDebug: 'DEBUG'}&amp;lt;/code&amp;gt; from initialization call.&lt;br /&gt;
# '''Notify Nielsen''': Once you are ready to go live, let us know so we can enable you for reporting. We will not be able to collect or report data prior to receiving notification from you.&lt;br /&gt;
&lt;br /&gt;
== Removing Simulators (Dynamic Framework Only)==&lt;br /&gt;
&lt;br /&gt;
Simulator slices are needed to let clients build and debug their app on the simulators, but they should be removed before sending the app to the AppStore.  Here is an example Shell script that could be added as a Run Script phase in the application.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang='bash'&amp;gt;&lt;br /&gt;
&lt;br /&gt;
APP_PATH=&amp;quot;${TARGET_BUILD_DIR}/${WRAPPER_NAME}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# This script loops through the frameworks embedded in the application and&lt;br /&gt;
# removes unused architectures.&lt;br /&gt;
find &amp;quot;$APP_PATH&amp;quot; -name '*.framework' -type d | while read -r FRAMEWORK&lt;br /&gt;
do&lt;br /&gt;
FRAMEWORK_EXECUTABLE_NAME=$(defaults read &amp;quot;$FRAMEWORK/Info.plist&amp;quot; CFBundleExecutable)&lt;br /&gt;
FRAMEWORK_EXECUTABLE_PATH=&amp;quot;$FRAMEWORK/$FRAMEWORK_EXECUTABLE_NAME&amp;quot;&lt;br /&gt;
echo &amp;quot;Executable is $FRAMEWORK_EXECUTABLE_PATH&amp;quot;&lt;br /&gt;
&lt;br /&gt;
EXTRACTED_ARCHS=()&lt;br /&gt;
&lt;br /&gt;
for ARCH in $ARCHS&lt;br /&gt;
do&lt;br /&gt;
echo &amp;quot;Extracting $ARCH from $FRAMEWORK_EXECUTABLE_NAME&amp;quot;&lt;br /&gt;
lipo -extract &amp;quot;$ARCH&amp;quot; &amp;quot;$FRAMEWORK_EXECUTABLE_PATH&amp;quot; -o &amp;quot;$FRAMEWORK_EXECUTABLE_PATH-$ARCH&amp;quot;&lt;br /&gt;
EXTRACTED_ARCHS+=(&amp;quot;$FRAMEWORK_EXECUTABLE_PATH-$ARCH&amp;quot;)&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Merging extracted architectures: ${ARCHS}&amp;quot;&lt;br /&gt;
lipo -o &amp;quot;$FRAMEWORK_EXECUTABLE_PATH-merged&amp;quot; -create &amp;quot;${EXTRACTED_ARCHS[@]}&amp;quot;&lt;br /&gt;
rm &amp;quot;${EXTRACTED_ARCHS[@]}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Replacing original executable with thinned version&amp;quot;&lt;br /&gt;
rm &amp;quot;$FRAMEWORK_EXECUTABLE_PATH&amp;quot;&lt;br /&gt;
mv &amp;quot;$FRAMEWORK_EXECUTABLE_PATH-merged&amp;quot; &amp;quot;$FRAMEWORK_EXECUTABLE_PATH&amp;quot;&lt;br /&gt;
&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sample Applications ==&lt;br /&gt;
You can find some examples in the file [[Special:Downloads|Global iOS SDK Download]] from the '''SDK Downloads''' section&lt;/div&gt;</summary>
		<author><name>NickParrucci</name></author>
	</entry>
	<entry>
		<id>https://nielsentest.mywikis.net/w/index.php?title=DCR_KSA_Video_iOS_SDK&amp;diff=6456</id>
		<title>DCR KSA Video iOS SDK</title>
		<link rel="alternate" type="text/html" href="https://nielsentest.mywikis.net/w/index.php?title=DCR_KSA_Video_iOS_SDK&amp;diff=6456"/>
		<updated>2023-07-20T12:14:38Z</updated>

		<summary type="html">&lt;p&gt;NickParrucci: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|International DCR}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The Nielsen SDK is one of the 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 Content Ratings (DCR), 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;
{{iOS_SpecialNotes_for_iOS14}}&lt;br /&gt;
&lt;br /&gt;
{{iOS_Prerequisites_and_Implementation_Overview}}&lt;br /&gt;
&lt;br /&gt;
== Setting up your  Development Environment  ==&lt;br /&gt;
Prior to SDK Version 6.2.0.0 the  IOS framework has been distributed as a static library packaged into framework bundle format. Apple recommends to use dynamic framework, it has some benefits over static libraries like less executable file size of an app, faster startup time and native support in xCode IDE. Nielsen AppSDK has been transformed into dynamic framework in this release ([[iOS_Static_Framework_Setup|static framework]] is still available).&lt;br /&gt;
&lt;br /&gt;
If migrating from the static library to this new dynamic framework, once implemented, unless your specific application requires, you can remove the following Frameworks that were once required:&amp;lt;code&amp;gt; [AdSupport, JavascriptCore, SystemConfiguration, Security, AVFoundation, libc++] &amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The '''Dynamic framework''' is created as a fat framework. It means that it contains slices required for devices (armv7, arm64) as well as slices required for simulators (i386, x86_64). Simulator slices are needed to let clients build and debug their app on the simulators, but they should be removed before sending the app to the AppStore. The example of the shell script that should be added as a Run Script phase in the application can be [[DCR_Video_iOS_SDK#Removing_Simulators_.28Dynamic_Framework_Only.29|found below]].&lt;br /&gt;
&lt;br /&gt;
'''[[DCR_Video_iOS_SDK_xcframework|XCFramework]]''' is solution for the problems described above Apple recommends to use XCFrameworks. In XCFramework, we no longer build a single framework with multiple architectures. Instead, we build one small framework for each combination of architecture and target and store it in its own folder. The top-level XCFramework folder have folders like ios-arm64, ios-arm64-simulator, etc. Each of these folders is its own framework, complete with headers, modules, and binary.&lt;br /&gt;
&lt;br /&gt;
=== Configuring Xcode Development Environment ===&lt;br /&gt;
Starting with SDK version 6.0.0.0, the Nielsen App SDK is compatible with Apple iOS versions 8.0 and above.  In addition, when using the dynamic framework,  all the required frameworks are linked automatically as the are needed.  More details can be found here: https://stackoverflow.com/questions/24902787/dont-we-need-to-link-framework-to-xcode-project-anymore&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': All communications between the SDK and the Census (Collection Facility) use HTTPS.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Special Note for Static Framework ===&lt;br /&gt;
Starting from 8.2.0.0 release framework is build from the mixed (swift + objc) source code.&lt;br /&gt;
If [[iOS_Static_Framework_Setup|static (xc)framework is integrated additional settings]] should be applied to fix build or runtime issues.&lt;br /&gt;
&lt;br /&gt;
=== Download Framework ===&lt;br /&gt;
The first step is to download and copy the [[Special:Downloads|NielsenAppApi.framework]] bundle to the app project directory. (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
=== Add Framework ===&lt;br /&gt;
In the General tab for app configuration add NielsenAppApi.framework in the list of Embedded Binaries.  (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
=== Add Path ===&lt;br /&gt;
Add path to the NielsenAppApi.framework in the Framework Search Paths build setting.  (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
=== Import Framework ===&lt;br /&gt;
Add NielsenAppApi.framework module in the source file of your app:&lt;br /&gt;
&lt;br /&gt;
==== Using Swift ====&lt;br /&gt;
Add the following:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
import NielsenAppApi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using Objective-C ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang =&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
@import NielsenAppApi;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== xCode 12 building errors ====&lt;br /&gt;
Developers who uses &amp;quot;fat&amp;quot; framework in their apps started reporting the following error that they get building the app in xCode 12.3+:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Building for iOS Simulator, but the linked and embedded framework 'MyFramework.framework' was built for iOS + iOS Simulator.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
The binary framework contains different code for the same architecture in multiple places, and Xcode doesn’t know how to handle it. There is workaround that people recommend to use in such cases:&lt;br /&gt;
* https://stackoverflow.com/questions/63267897/building-for-ios-simulator-but-the-linked-framework-framework-was-built&lt;br /&gt;
* https://stackoverflow.com/questions/63932158/xcode12-issus-ld-building-for-ios-simulator-but-linking-in-object-file-built&lt;br /&gt;
&lt;br /&gt;
==== IPA processing failure ====&lt;br /&gt;
&amp;lt;code&amp;gt;Assertion failed: Expected 4 archs in otool output:&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The error above is due to the &amp;quot;fat&amp;quot; (simulator+device) framework which will not appear if you have not enabled Bitcode.  To build your app with full Bitcode support, it is recommended that you use a [[DCR_Video_iOS_SDK_xcframework|XCFramework]] to avoid the 4 archs in otool output message.&lt;br /&gt;
&lt;br /&gt;
== Create SDK Instance ==&lt;br /&gt;
The latest version of the Nielsen App SDK allows instantiating multiple instances of the SDK object when needed, which can then be used simultaneously. '''For the general use case where only one video is played at the same time in the App, a single instance of SDK object can then be used to play back and measure all watched streams one after another.'''&lt;br /&gt;
&lt;br /&gt;
The following table contains the list of arguments that can be passed via the AppInfo JSON schema.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter / Argument !! Description !! Source !! Required/Obligatory? !! Example&lt;br /&gt;
|-&lt;br /&gt;
| appid || Unique id for the application assigned by Nielsen. It is GUID data type.|| Nielsen-specified || Yes || &amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| appname || Name of the application || Client-defined || Yes || &amp;quot;Nielsen Sample App&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| appversion || Current version of the app used || Client-defined || Yes || &amp;quot;1.0.4&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| sfcode || Nielsen collection facility to which the SDK should connect.&lt;br /&gt;
|| Nielsen-specified || Yes || &amp;quot;ksa&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| nol_devDebug || Enables Nielsen console logging. Only required for testing&lt;br /&gt;
|| Nielsen-specified || Optional || &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Debug flag for development environment ==&lt;br /&gt;
Player application developers / integrators can use Debug flag to check whether an App SDK API call made is successful. To activate the Debug flag,&lt;br /&gt;
Pass the argument &amp;lt;code&amp;gt;@&amp;quot;nol_devDebug&amp;quot;:@&amp;quot;DEBUG&amp;quot;&amp;lt;/code&amp;gt;, in the JSON string.&lt;br /&gt;
&lt;br /&gt;
* '''DEBUG''': Debug logs, used by the developers to debug more complex issues.&lt;br /&gt;
&lt;br /&gt;
Once the flag is active, it logs each API call made and the data passed. The log created by this flag is minimal.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': DO NOT activate the Debug flag in a production environment.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Sample SDK Initialization Code ====&lt;br /&gt;
&lt;br /&gt;
Initialize the Nielsen App object within the viewDidLoad view controller delegate method using initWithAppInfo:delegate:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;If App SDK is initialized using init or new methods, it will ignore the API calls resulting in no measurement. The SDK will not return any errors.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Using Objective-C=====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;quot;NlsAppApiFactory.h&amp;quot;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenAppApi.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@implementation NlsAppApiFactory&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppApi *)createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
{&lt;br /&gt;
    NSDictionary *appInformation = @{&lt;br /&gt;
                                     @&amp;quot;appid&amp;quot;: &amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;,&lt;br /&gt;
                                     @&amp;quot;appversion&amp;quot;: &amp;quot;1.0&amp;quot;,&lt;br /&gt;
                                     @&amp;quot;appname&amp;quot;: &amp;quot;app name here&amp;quot;,&lt;br /&gt;
                                     @&amp;quot;sfcode&amp;quot;: &amp;quot;ksa&amp;quot;,&lt;br /&gt;
                                     @&amp;quot;nol_devDebug&amp;quot;: @&amp;quot;DEBUG&amp;quot;&lt;br /&gt;
                                    };&lt;br /&gt;
    return [[NielsenAppApi alloc] initWithAppInfo:appInformation delegate:delegate];&lt;br /&gt;
}&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following would be the &amp;lt;code&amp;gt;NlsAppApiFactory.h&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;Foundation/Foundation.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@class NielsenAppApi;&lt;br /&gt;
@protocol NielsenAppApiDeligate;&lt;br /&gt;
&lt;br /&gt;
@interface NlsAppApiFactory : NSObject&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppAPI *) createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Using Swift =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;NielsenInit.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class NielsenInit: NSObject {&lt;br /&gt;
    class func createNielsenAppApi(delegate: NielsenAppApiDelegate) -&amp;gt; NielsenAppApi?{&lt;br /&gt;
    let appInformation:[String: String] = [&lt;br /&gt;
            &amp;quot;appid&amp;quot;: &amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;,&lt;br /&gt;
            &amp;quot;appversion&amp;quot;: &amp;quot;1.0&amp;quot;,&lt;br /&gt;
            &amp;quot;appname&amp;quot;: &amp;quot;app name here&amp;quot;,&lt;br /&gt;
            &amp;quot;sfcode&amp;quot;: &amp;quot;ksa&amp;quot;,&lt;br /&gt;
            &amp;quot;nol_devDebug&amp;quot;: &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
        ]&lt;br /&gt;
        return NielsenAppApi(appInfo:appInformation, delegate:delegate)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Sample code using AVPlayer.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;ViewController.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class ViewController: UIViewController, NielsenAppApiDelegate, AVPictureInPictureControllerDelegate, CLLocationManagerDelegate  {&lt;br /&gt;
&lt;br /&gt;
    let avPlayerViewController = AVPlayerViewController()&lt;br /&gt;
    var avPlayer:AVPlayer?&lt;br /&gt;
    var nielsenAppApi: NielsenAppApi!&lt;br /&gt;
&lt;br /&gt;
  override func viewDidLoad() {&lt;br /&gt;
        super.viewDidLoad()&lt;br /&gt;
&lt;br /&gt;
        self.nielsenAppApi = NielsenInit.createNielsenAppApi(delegate: self)&lt;br /&gt;
        NSLog(&amp;quot;Nielsen SDK initialized&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
            }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&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;
==== Life cycle of SDK instance ====&lt;br /&gt;
The 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. API calls &amp;quot;play&amp;quot; and &amp;quot;loadMetadata&amp;quot; move the SDK instance into this state. In this state, the SDK instance will be able to process the API calls (see below)&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 called&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
@property (assign) BOOL appDisableApi;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Create Metadata Objects ==&lt;br /&gt;
The parameters passed must be either a JSON formatted NSString 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, 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.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Create channelName Metadata ===&lt;br /&gt;
channelName 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;
| channelName	|| Any string representing the channel/stream	|| custom	|| Yes&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Create Content Metadata ===&lt;br /&gt;
Content metadata should remain constant throughout the entirety of an episode/clip including when ads play.&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 asset || &amp;lt;code&amp;gt;'content'&amp;lt;/code&amp;gt; || Yes&lt;br /&gt;
|-&lt;br /&gt;
| assetid || unique ID assigned to asset (32 Character limit) || custom (no [[Special Characters|Special Characters]]) || Yes&lt;br /&gt;
|-&lt;br /&gt;
| program || name of program (100 character limit) || custom || Yes&lt;br /&gt;
|-&lt;br /&gt;
| title || name of program (100 character limit) || custom || Yes&lt;br /&gt;
|-&lt;br /&gt;
| length || length of content in seconds || Length of content in seconds (86400 seconds for live stream (24/7). For Event-Live streams planned length. For VoD video length) || Yes&lt;br /&gt;
|-&lt;br /&gt;
| airdate || the airdate in the linear TV || YYYYMMDD HH24:MI:SS || Yes&lt;br /&gt;
|-&lt;br /&gt;
| isfullepisode || full episode flag || &amp;lt;code&amp;gt;'y'&amp;lt;/code&amp;gt;- full episode, &amp;lt;code&amp;gt;'n'&amp;lt;/code&amp;gt;- non full episode || Yes&lt;br /&gt;
|-&lt;br /&gt;
| adloadtype || type of ad load:&lt;br /&gt;
*&amp;lt;code&amp;gt;'1'&amp;lt;/code&amp;gt; Linear – matches TV ad load&lt;br /&gt;
*&amp;lt;code&amp;gt;'2'&amp;lt;/code&amp;gt; Dynamic – Dynamic Ad Insertion (DAI)&lt;br /&gt;
|| &amp;lt;code&amp;gt;'2'&amp;lt;/code&amp;gt; - DCR measures content with dynamic ads &lt;br /&gt;
|| Yes&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Create 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; || Yes&lt;br /&gt;
|-&lt;br /&gt;
| assetid ||	unique ID assigned to Ad	|| custom (no [[Special Characters|Special Characters]]) || Yes&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
'''Note:''' All metadata values should be passed as UTF-8 strings.&lt;br /&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;
=== MetaData Example ===&lt;br /&gt;
&lt;br /&gt;
==== Using Objective-C ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
NSDictionary  *channelInfo = @&lt;br /&gt;
{&lt;br /&gt;
    @&amp;quot;channelName&amp;quot;:@&amp;quot;My Channel Name 1&amp;quot;,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
NSDictionary *contentMetadata = @&lt;br /&gt;
  {&lt;br /&gt;
    @ &amp;quot;type&amp;quot;: @ &amp;quot;content&amp;quot;,&lt;br /&gt;
    @ &amp;quot;assetid&amp;quot;: @ &amp;quot;88675545&amp;quot;,&lt;br /&gt;
    @ &amp;quot;title&amp;quot;: @ &amp;quot;Program S3, EP1&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;20200321 10:05:00&amp;quot;,&lt;br /&gt;
    @ &amp;quot;adloadtype&amp;quot;: @ &amp;quot;2&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
NSDictionary *adMetadata = @&lt;br /&gt;
  {&lt;br /&gt;
    @&amp;quot;type&amp;quot; : &amp;quot;postroll&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;
==== Using Swift ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
     let channelInfo = [&lt;br /&gt;
        &amp;quot;channelName&amp;quot;: &amp;quot;My Channel Name 1&amp;quot;,&lt;br /&gt;
     ]&lt;br /&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;88675545&amp;quot;,&lt;br /&gt;
         &amp;quot;title&amp;quot;: &amp;quot;Program S3, EP1&amp;quot;,&lt;br /&gt;
         &amp;quot;isfullepisode&amp;quot;:&amp;quot;y&amp;quot;,&lt;br /&gt;
         &amp;quot;adloadtype&amp;quot;:&amp;quot;2&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;
     ]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    let adMetadata = [&lt;br /&gt;
        &amp;quot;type&amp;quot;: &amp;quot;preroll&amp;quot;,&lt;br /&gt;
        &amp;quot;assetid&amp;quot; : &amp;quot;ad123&amp;quot;&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Start the Measurement ==&lt;br /&gt;
&lt;br /&gt;
=== Overview of SDK API Calls ===&lt;br /&gt;
&lt;br /&gt;
==== play ====&lt;br /&gt;
The play method prepares the SDK for reporting once an asset has loaded and playback has begun. Use play to pass the channel descriptor information through channelName parameter when the user taps the '''Play''' button on the player. Call play only when initially starting the video.&lt;br /&gt;
===== Using Objective-C =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;[self.nielsenAppApi play:channelInfo];&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===== Using Swift =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;self.nielsenAppApi?.play(channelInfo);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== loadMetadata ====&lt;br /&gt;
Needs to be called at the beginning of each asset, pass JSON object for relevant content or ad. Make sure to pass as 1st loadMetadata for content at the begining of playlist - see below API call sequence examples.&lt;br /&gt;
===== Using Objective-C =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;[self.nielsenAppApi loadMetadata:metadataDict];&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===== Using Swift =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;self.nielsenAppApi?.loadMetadata(metadataDict)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== playheadPosition ====&lt;br /&gt;
Pass playhead position every second during playback. for VOD: pass current position in seconds. for Live: current Unix timestamp (seconds since Jan-1-1970 UTC) - if it is possible to seek back in Live content, then pass related Unix time (not current). Pass whole number that increments only by 1 like 1,2,3..&lt;br /&gt;
===== Using Objective-C =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
[self.nielsenAppApi playheadPosition:pos];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===== Using Swift =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
self.nielsenAppApi?.playheadPosition(pos);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== stop ====&lt;br /&gt;
Call when&lt;br /&gt;
* ads complete playing&lt;br /&gt;
* when a user pauses playback&lt;br /&gt;
* upon any user interruption scenario - see bellow chapter Interruption scenario&lt;br /&gt;
===== Using Objective-C =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;[self.nielsenAppApi stop];&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===== Using Swift =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;self.nielsenAppApi?.stop;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== end ====&lt;br /&gt;
Call when the content asset completes playback.  Stops measurement progress.&lt;br /&gt;
===== Using Objective-C =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;[self.nielsenAppApi end];&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===== Using Swift =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;self.nielsenAppApi?.end&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== API Call Sequence ===&lt;br /&gt;
==== Use Case 1: Content has no Ads ====&lt;br /&gt;
Call [[play()]] with channelName JSON as below.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;{&lt;br /&gt;
   &amp;quot;channelName&amp;quot;: &amp;quot;ChannelName&amp;quot;&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;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 [[playheadPosition|playheadPosition()]] every one second until a pause.&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(channelName); &amp;lt;/code&amp;gt; || // channelName contains JSON metadata of channel/video name being played&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.playheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // position 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;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 Ads ====&lt;br /&gt;
Call [[play()]] with channelName JSON as below.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;{&lt;br /&gt;
   &amp;quot;channelName&amp;quot;: &amp;quot;ChannelName&amp;quot;&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;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;
   ...&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 [[playheadPosition|playheadPosition()]] every one second until a pause / 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;
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(channelName); &amp;lt;/code&amp;gt; || // channelName contains JSON metadata of channel/video name being played&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.playheadPosition(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;6&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.playheadPosition(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; || // App moves to background(midroll pauses) &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.loadMetadata(midrollMetaDataObject);&amp;lt;/code&amp;gt; || // App moves to foreground (midroll resumes) &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.playheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // playheadPosition 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 (End of stream) || &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.playheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // position 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;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.playheadPosition(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;
== Stop/Resume the Measurement for video Playback Interruptions ==&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 (Video players only, not for Audio players)&lt;br /&gt;
* App going in the Background/Foreground (Video players only, not for Audio players)&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 &amp;lt;code&amp;gt;stop&amp;lt;/code&amp;gt; immediately (except when content is buffering) and withhold sending playhead position.&lt;br /&gt;
* Once the playback resumes, start sending pings &amp;lt;code&amp;gt;playheadPosition&amp;lt;/code&amp;gt; for the new viewing session.&lt;br /&gt;
Please see the [[Digital Measurement FAQ]] for more details&lt;br /&gt;
&lt;br /&gt;
== Review SDK Integration Architecture Diagram ==&lt;br /&gt;
&lt;br /&gt;
=== For Content Playback ===&lt;br /&gt;
&lt;br /&gt;
[[File:nlsn-sdk-achitecture-diagram-content-v1.png||SDK Integration Architecture Diagram - Content]]&lt;br /&gt;
&lt;br /&gt;
=== For Ad Playback ===&lt;br /&gt;
[[File:nlsn-sdk-achitecture-diagram-ad-v1.png||SDK Integration Architecture Diagram - Ad]]&lt;br /&gt;
&lt;br /&gt;
{{iOS_NoID_Privacy_and_Opt-Out}}&lt;br /&gt;
&lt;br /&gt;
{{iOS_Airplay}}&lt;br /&gt;
== Test your player by yourself ==&lt;br /&gt;
=== Guide ===&lt;br /&gt;
1. Connect your PC and test device (tablet or phone) via same router.&amp;lt;br /&amp;gt;&lt;br /&gt;
2. PC side: run Proxy sw (like Charles) and get local IP&amp;lt;br /&amp;gt;&lt;br /&gt;
3. Test device: modify Wifi setting to pass through Proxy IP from step 2.&amp;lt;br /&amp;gt;&lt;br /&gt;
4. Test device: run your player, launch video&amp;lt;br /&amp;gt;&lt;br /&gt;
5. PC side: filter traffic by &amp;quot;nmrodam&amp;quot; and confirm presence of SDK pings&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example of SDK ping (https call) ===&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;https://secure-ksa.nmrodam.com/cgi-bin/gn?prd=dcr&amp;amp;ci=se-910685&amp;amp;ch=se-910685_c01_P&amp;amp;asn=defChnAsset&amp;amp;fp_id=a2nfmy17lyvkhlxqstvmgypqly90m1629966210&amp;amp;fp_cr_tm=1629966210&amp;amp;fp_acc_tm=1629966210&amp;amp;fp_emm_tm=1629966210&amp;amp;ve_id=20A7CFD5-9860-4256-A6CE-45C251F4C243&amp;amp;sessionId=yvx0rtsxydmaxueji8zgfzj0f2f1w1629966209&amp;amp;tl=&amp;amp;prv=1&amp;amp;c6=vc,c01&amp;amp;ca=se-910685_c01_51HERB1501&amp;amp;cg=Play%20%3E%20Webbtv%20%3E%20Nyheter&amp;amp;c13=asid,P3D8D326A-2DBC-486A-8FD8-9AF4452B2A41&amp;amp;c32=segA,NA&amp;amp;c33=segB,NA&amp;amp;c34=segC,NA&amp;amp;c15=apn,Aftonbladet&amp;amp;plugv=&amp;amp;playerv=&amp;amp;sup=1&amp;amp;segment2=&amp;amp;segment1=&amp;amp;forward=0&amp;amp;ad=1&amp;amp;cr=4_00_99_D1_00000&amp;amp;c9=devid,12b9377cbe7e5c94e8a70d9d23929523d14afa954793130f8a3959c7b849aca8&amp;amp;enc=true&amp;amp;c1=nuid,12b9377cbe7e5c94e8a70d9d23929523d14afa954793130f8a3959c7b849aca8&amp;amp;at=timer&amp;amp;rt=video&amp;amp;c16=sdkv,ai.8.1.0&amp;amp;c27=cln,15&amp;amp;crs=&amp;amp;lat=&amp;amp;lon=&amp;amp;c29=plid,16299662096458868&amp;amp;c30=bldv,ai.8.1.0.0_gsxaoni&amp;amp;st=dcr&amp;amp;c7=osgrp,&amp;amp;c8=devgrp,&amp;amp;c10=plt,&amp;amp;c40=adbid,&amp;amp;c14=osver,iOS14.6&amp;amp;c26=dmap,1&amp;amp;dd=&amp;amp;hrd=&amp;amp;wkd=&amp;amp;c35=adrsid,&amp;amp;c36=cref1,&amp;amp;c37=cref2,&amp;amp;c11=agg,1&amp;amp;c12=apv,5.47.83.0.25245&amp;amp;c51=adl,15&amp;amp;c52=noad,1&amp;amp;sd=15&amp;amp;pc=NA&amp;amp;c53=fef,n&amp;amp;c54=oad,&amp;amp;c55=cref3,&amp;amp;c57=adldf,2&amp;amp;ai=51HERB1501&amp;amp;c3=st,a&amp;amp;c64=starttm,1629966240&amp;amp;adid=51HERB1501&amp;amp;c58=isLive,false&amp;amp;c59=sesid,iqal6k21r0de8gm901kif5xznar7q1629966240&amp;amp;c61=createtm,1629966255&amp;amp;c63=pipMode,&amp;amp;ci_userid=&amp;amp;is_auto_play=&amp;amp;pl_title=&amp;amp;is_prem=&amp;amp;is_prog=&amp;amp;ad_origin=&amp;amp;adidx=1%2F1&amp;amp;is_tpad=&amp;amp;ci_passthr=&amp;amp;c62=sendTime,1629966255&amp;amp;c68=bndlid,se.aftonbladet.Aftonbladet&amp;amp;c69=cvw,&amp;amp;nodeTM=&amp;amp;logTM=&amp;amp;c73=phtype,&amp;amp;c74=dvcnm,&amp;amp;c76=adbsnid,&amp;amp;uoo=&amp;amp;c44=progen,&amp;amp;davty=1&amp;amp;si=&amp;amp;c66=mediaurl,&amp;amp;sdd=retry,0~~retryreason,~~devmodel,iPhone9%2C4~~devtypid,iPhone9%2C4~~sysname,iOS~~sysversion,14.6~~manuf,Apple&amp;amp;cat_id=a6f7fb13-8801-484c-9692-6db6dfb470aa&amp;amp;vtoff=0&amp;amp;rnd=1629966255319&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Provide your app for certification ==&lt;br /&gt;
Once ready please send your application to Nielsen local staff for certification.&lt;br /&gt;
&lt;br /&gt;
== Going Live ==&lt;br /&gt;
Following Nielsen testing, you will need to:&lt;br /&gt;
&lt;br /&gt;
# '''Disable Debug Logging''': Disable logging by deleting &amp;lt;code&amp;gt;{nol_devDebug: 'DEBUG'}&amp;lt;/code&amp;gt; from initialization call.&lt;br /&gt;
# '''Notify Nielsen''': Once you are ready to go live, let us know so we can enable you for reporting. We will not be able to collect or report data prior to receiving notification from you.&lt;/div&gt;</summary>
		<author><name>NickParrucci</name></author>
	</entry>
	<entry>
		<id>https://nielsentest.mywikis.net/w/index.php?title=DCR_Ireland_Video_iOS_SDK&amp;diff=6455</id>
		<title>DCR Ireland Video iOS SDK</title>
		<link rel="alternate" type="text/html" href="https://nielsentest.mywikis.net/w/index.php?title=DCR_Ireland_Video_iOS_SDK&amp;diff=6455"/>
		<updated>2023-07-20T12:14:01Z</updated>

		<summary type="html">&lt;p&gt;NickParrucci: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|International DCR}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The Nielsen SDK is one of the 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 Content Ratings (DCR), 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;
{{iOS_SpecialNotes_for_iOS14}}&lt;br /&gt;
&lt;br /&gt;
{{iOS_Prerequisites_and_Implementation_Overview}}&lt;br /&gt;
&lt;br /&gt;
== Setting up your  Development Environment  ==&lt;br /&gt;
Prior to SDK Version 6.2.0.0 the  IOS framework has been distributed as a static library packaged into framework bundle format. Apple recommends to use dynamic framework, it has some benefits over static libraries like less executable file size of an app, faster startup time and native support in xCode IDE. Nielsen AppSDK has been transformed into dynamic framework in this release ([[iOS_Static_Framework_Setup|static framework]] is still available).&lt;br /&gt;
&lt;br /&gt;
If migrating from the static library to this new dynamic framework, once implemented, unless your specific application requires, you can remove the following Frameworks that were once required:&amp;lt;code&amp;gt; [AdSupport, JavascriptCore, SystemConfiguration, Security, AVFoundation, libc++] &amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The '''Dynamic framework''' is created as a fat framework. It means that it contains slices required for devices (armv7, arm64) as well as slices required for simulators (i386, x86_64). Simulator slices are needed to let clients build and debug their app on the simulators, but they should be removed before sending the app to the AppStore. The example of the shell script that should be added as a Run Script phase in the application can be [[DCR_Video_iOS_SDK#Removing_Simulators_.28Dynamic_Framework_Only.29|found below]].&lt;br /&gt;
&lt;br /&gt;
'''[[DCR_Video_iOS_SDK_xcframework|XCFramework]]''' is solution for the problems described above Apple recommends to use XCFrameworks. In XCFramework, we no longer build a single framework with multiple architectures. Instead, we build one small framework for each combination of architecture and target and store it in its own folder. The top-level XCFramework folder have folders like ios-arm64, ios-arm64-simulator, etc. Each of these folders is its own framework, complete with headers, modules, and binary.&lt;br /&gt;
&lt;br /&gt;
=== Configuring Xcode Development Environment ===&lt;br /&gt;
Starting with SDK version 6.0.0.0, the Nielsen App SDK is compatible with Apple iOS versions 8.0 and above.  In addition, when using the dynamic framework,  all the required frameworks are linked automatically as the are needed.  More details can be found here: https://stackoverflow.com/questions/24902787/dont-we-need-to-link-framework-to-xcode-project-anymore&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': All communications between the SDK and the Census (Collection Facility) use HTTPS.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Special Note for Static Framework ===&lt;br /&gt;
Starting from 8.2.0.0 release framework is build from the mixed (swift + objc) source code.&lt;br /&gt;
If [[iOS_Static_Framework_Setup|static (xc)framework is integrated additional settings]] should be applied to fix build or runtime issues.&lt;br /&gt;
&lt;br /&gt;
=== Download Framework ===&lt;br /&gt;
The first step is to download and copy the [[Special:Downloads|NielsenAppApi.framework]] bundle to the app project directory. (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
=== Add Framework ===&lt;br /&gt;
In the General tab for app configuration add NielsenAppApi.framework in the list of Embedded Binaries.  (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
=== Add Path ===&lt;br /&gt;
Add path to the NielsenAppApi.framework in the Framework Search Paths build setting.  (''Not required if using CocaPods'')&lt;br /&gt;
&lt;br /&gt;
=== Import Framework ===&lt;br /&gt;
Add NielsenAppApi.framework module in the source file of your app:&lt;br /&gt;
&lt;br /&gt;
==== Using Swift ====&lt;br /&gt;
Add the following:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
import NielsenAppApi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using Objective-C ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang =&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
@import NielsenAppApi;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== xCode 12 building errors ====&lt;br /&gt;
Developers who uses &amp;quot;fat&amp;quot; framework in their apps started reporting the following error that they get building the app in xCode 12.3+:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Building for iOS Simulator, but the linked and embedded framework 'MyFramework.framework' was built for iOS + iOS Simulator.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
The binary framework contains different code for the same architecture in multiple places, and Xcode doesn’t know how to handle it. There is workaround that people recommend to use in such cases:&lt;br /&gt;
* https://stackoverflow.com/questions/63267897/building-for-ios-simulator-but-the-linked-framework-framework-was-built&lt;br /&gt;
* https://stackoverflow.com/questions/63932158/xcode12-issus-ld-building-for-ios-simulator-but-linking-in-object-file-built&lt;br /&gt;
&lt;br /&gt;
==== IPA processing failure ====&lt;br /&gt;
&amp;lt;code&amp;gt;Assertion failed: Expected 4 archs in otool output:&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The error above is due to the &amp;quot;fat&amp;quot; (simulator+device) framework which will not appear if you have not enabled Bitcode.  To build your app with full Bitcode support, it is recommended that you use a [[DCR_Video_iOS_SDK_xcframework|XCFramework]] to avoid the 4 archs in otool output message.&lt;br /&gt;
&lt;br /&gt;
== Create SDK Instance ==&lt;br /&gt;
The latest version of the Nielsen App SDK allows instantiating multiple instances of the SDK object when needed, which can then be used simultaneously. '''For the general use case where only one video is played at the same time in the App, a single instance of SDK object can then be used to play back and measure all watched streams one after another.'''&lt;br /&gt;
&lt;br /&gt;
The following table contains the list of arguments that can be passed via the AppInfo JSON schema.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter / Argument !! Description !! Source !! Required/Obligatory? !! Example&lt;br /&gt;
|-&lt;br /&gt;
| appid || Unique id for the application assigned by Nielsen. It is GUID data type.|| Nielsen-specified || Yes || &amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| appname || Name of the application || Client-defined || Yes || &amp;quot;Nielsen Sample App&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| appversion || Current version of the app used || Client-defined || Yes || &amp;quot;1.0.2&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| sfcode || Nielsen collection facility to which the SDK should connect.&lt;br /&gt;
|| Nielsen-specified || Yes || &amp;quot;ire&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| nol_devDebug || Enables Nielsen console logging. Only required for testing&lt;br /&gt;
|| Nielsen-specified || Optional || &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Debug flag for development environment ==&lt;br /&gt;
Player application developers / integrators can use Debug flag to check whether an App SDK API call made is successful. To activate the Debug flag,&lt;br /&gt;
Pass the argument &amp;lt;code&amp;gt;@&amp;quot;nol_devDebug&amp;quot;:@&amp;quot;DEBUG&amp;quot;&amp;lt;/code&amp;gt;, in the JSON string.&lt;br /&gt;
&lt;br /&gt;
* '''DEBUG''': Debug logs, used by the developers to debug more complex issues.&lt;br /&gt;
&lt;br /&gt;
Once the flag is active, it logs each API call made and the data passed. The log created by this flag is minimal.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': DO NOT activate the Debug flag in a production environment.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Sample SDK Initialization Code ====&lt;br /&gt;
&lt;br /&gt;
Initialize the Nielsen App object within the viewDidLoad view controller delegate method using initWithAppInfo:delegate:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;If App SDK is initialized using init or new methods, it will ignore the API calls resulting in no measurement. The SDK will not return any errors.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Using Objective-C=====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;quot;NlsAppApiFactory.h&amp;quot;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenAppApi.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@implementation NlsAppApiFactory&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppApi *)createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
{&lt;br /&gt;
    NSDictionary *appInformation = @{&lt;br /&gt;
                                     @&amp;quot;appid&amp;quot;: &amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;,&lt;br /&gt;
                                     @&amp;quot;appversion&amp;quot;: &amp;quot;1.0&amp;quot;,&lt;br /&gt;
                                     @&amp;quot;appname&amp;quot;: &amp;quot;app name here&amp;quot;,&lt;br /&gt;
                                     @&amp;quot;sfcode&amp;quot;: &amp;quot;ire&amp;quot;,&lt;br /&gt;
                                     @&amp;quot;nol_devDebug&amp;quot;: @&amp;quot;DEBUG&amp;quot;&lt;br /&gt;
                                    };&lt;br /&gt;
    return [[NielsenAppApi alloc] initWithAppInfo:appInformation delegate:delegate];&lt;br /&gt;
}&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following would be the &amp;lt;code&amp;gt;NlsAppApiFactory.h&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;Foundation/Foundation.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@class NielsenAppApi;&lt;br /&gt;
@protocol NielsenAppApiDeligate;&lt;br /&gt;
&lt;br /&gt;
@interface NlsAppApiFactory : NSObject&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppAPI *) createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Using Swift =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;NielsenInit.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class NielsenInit: NSObject {&lt;br /&gt;
    class func createNielsenAppApi(delegate: NielsenAppApiDelegate) -&amp;gt; NielsenAppApi?{&lt;br /&gt;
    let appInformation:[String: String] = [&lt;br /&gt;
            &amp;quot;appid&amp;quot;: &amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;,&lt;br /&gt;
            &amp;quot;appversion&amp;quot;: &amp;quot;1.0&amp;quot;,&lt;br /&gt;
            &amp;quot;appname&amp;quot;: &amp;quot;app name here&amp;quot;,&lt;br /&gt;
            &amp;quot;sfcode&amp;quot;: &amp;quot;ire&amp;quot;,&lt;br /&gt;
            &amp;quot;nol_devDebug&amp;quot;: &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
        ]&lt;br /&gt;
        return NielsenAppApi(appInfo:appInformation, delegate:delegate)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Sample code using AVPlayer.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;ViewController.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class ViewController: UIViewController, NielsenAppApiDelegate, AVPictureInPictureControllerDelegate, CLLocationManagerDelegate  {&lt;br /&gt;
&lt;br /&gt;
    let avPlayerViewController = AVPlayerViewController()&lt;br /&gt;
    var avPlayer:AVPlayer?&lt;br /&gt;
    var nielsenAppApi: NielsenAppApi!&lt;br /&gt;
&lt;br /&gt;
  override func viewDidLoad() {&lt;br /&gt;
        super.viewDidLoad()&lt;br /&gt;
&lt;br /&gt;
        self.nielsenAppApi = NielsenInit.createNielsenAppApi(delegate: self)&lt;br /&gt;
        NSLog(&amp;quot;Nielsen SDK initialized&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
            }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&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;
==== Life cycle of SDK instance ====&lt;br /&gt;
The 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. API calls &amp;quot;play&amp;quot; and &amp;quot;loadMetadata&amp;quot; move the SDK instance into this state. In this state, the SDK instance will be able to process the API calls (see below)&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 called&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
@property (assign) BOOL appDisableApi;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Create Metadata Objects ==&lt;br /&gt;
The parameters passed must be either a JSON formatted NSString 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, 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.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Create channelName Metadata ===&lt;br /&gt;
channelName 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;
| channelName	|| Any string representing the channel/stream	|| custom	|| Yes&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Create Content Metadata ===&lt;br /&gt;
Content metadata should remain constant throughout the entirety of an episode/clip including when ads play.&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 asset || &amp;lt;code&amp;gt;'content'&amp;lt;/code&amp;gt; || Yes&lt;br /&gt;
|-&lt;br /&gt;
| assetid || unique ID assigned to asset (32 Character limit) || custom (no [[Special Characters|Special Characters]]) || Yes&lt;br /&gt;
|-&lt;br /&gt;
| program || name of program (100 character limit) || custom || Yes&lt;br /&gt;
|-&lt;br /&gt;
| title || name of program (100 character limit) || custom || Yes&lt;br /&gt;
|-&lt;br /&gt;
| length || length of content in seconds || Length of content in seconds (86400 seconds for live stream (24/7). For Event-Live streams planned length. For VoD video length) || Yes&lt;br /&gt;
|-&lt;br /&gt;
| airdate || the airdate in the linear TV || YYYYMMDD HH24:MI:SS || Yes&lt;br /&gt;
|-&lt;br /&gt;
| isfullepisode || full episode flag || &amp;lt;code&amp;gt;'y'&amp;lt;/code&amp;gt;- full episode, &amp;lt;code&amp;gt;'n'&amp;lt;/code&amp;gt;- non full episode || Yes&lt;br /&gt;
|-&lt;br /&gt;
| adloadtype || type of ad load:&lt;br /&gt;
*&amp;lt;code&amp;gt;'1'&amp;lt;/code&amp;gt; Linear – matches TV ad load&lt;br /&gt;
*&amp;lt;code&amp;gt;'2'&amp;lt;/code&amp;gt; Dynamic – Dynamic Ad Insertion (DAI)&lt;br /&gt;
|| &amp;lt;code&amp;gt;'2'&amp;lt;/code&amp;gt; - DCR measures content with dynamic ads &lt;br /&gt;
|| Yes&lt;br /&gt;
|-&lt;br /&gt;
| segB || custom segment for the clients granular reporting within a brand&lt;br /&gt;
|| Example: ChannelName&lt;br /&gt;
|| Optional&lt;br /&gt;
|-&lt;br /&gt;
| segC || custom segment for the clients granular reporting within a brand&lt;br /&gt;
|| Example: PlayerName&lt;br /&gt;
|| Optional&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Create 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; || Yes&lt;br /&gt;
|-&lt;br /&gt;
| assetid ||	unique ID assigned to Ad	|| custom (no [[Special Characters|Special Characters]]) || Yes&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
'''Note:''' All metadata values should be passed as UTF-8 strings.&lt;br /&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;
=== MetaData Example ===&lt;br /&gt;
&lt;br /&gt;
==== Using Objective-C ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
NSDictionary  *channelInfo = @&lt;br /&gt;
{&lt;br /&gt;
    @&amp;quot;channelName&amp;quot;:@&amp;quot;My Channel Name 1&amp;quot;,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
NSDictionary *contentMetadata = @&lt;br /&gt;
  {&lt;br /&gt;
    @ &amp;quot;type&amp;quot;: @ &amp;quot;content&amp;quot;,&lt;br /&gt;
    @ &amp;quot;assetid&amp;quot;: @ &amp;quot;88675545&amp;quot;,&lt;br /&gt;
    @ &amp;quot;title&amp;quot;: @ &amp;quot;Program S3, EP1&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;20200321 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;ChannelName&amp;quot;, //optional&lt;br /&gt;
    @ &amp;quot;segC&amp;quot;: @ &amp;quot;PlayerName&amp;quot; //optional&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
NSDictionary *adMetadata = @&lt;br /&gt;
  {&lt;br /&gt;
    @&amp;quot;type&amp;quot; : &amp;quot;postroll&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;
==== Using Swift ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
     let channelInfo = [&lt;br /&gt;
        &amp;quot;channelName&amp;quot;: &amp;quot;My Channel Name 1&amp;quot;,&lt;br /&gt;
     ]&lt;br /&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;88675545&amp;quot;,&lt;br /&gt;
         &amp;quot;title&amp;quot;: &amp;quot;Program S3, EP1&amp;quot;,&lt;br /&gt;
         &amp;quot;isfullepisode&amp;quot;:&amp;quot;y&amp;quot;,&lt;br /&gt;
         &amp;quot;adloadtype&amp;quot;:&amp;quot;2&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;segB&amp;quot;: &amp;quot;ChannelName&amp;quot;, //optional&lt;br /&gt;
         &amp;quot;segC&amp;quot;: &amp;quot;PlayerName&amp;quot; //optional&lt;br /&gt;
     ]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    let adMetadata = [&lt;br /&gt;
        &amp;quot;type&amp;quot;: &amp;quot;preroll&amp;quot;,&lt;br /&gt;
        &amp;quot;assetid&amp;quot; : &amp;quot;ad123&amp;quot;&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Start the Measurement ==&lt;br /&gt;
&lt;br /&gt;
=== Overview of SDK API Calls ===&lt;br /&gt;
&lt;br /&gt;
==== play ====&lt;br /&gt;
The play method prepares the SDK for reporting once an asset has loaded and playback has begun. Use play to pass the channel descriptor information through channelName parameter when the user taps the '''Play''' button on the player. Call play only when initially starting the video.&lt;br /&gt;
===== Using Objective-C =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;[self.nielsenAppApi play:channelInfo];&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===== Using Swift =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;self.nielsenAppApi?.play(channelInfo);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== loadMetadata ====&lt;br /&gt;
Needs to be called at the beginning of each asset, pass JSON object for relevant content or ad. Make sure to pass as 1st loadMetadata for content at the begining of playlist - see below API call sequence examples.&lt;br /&gt;
===== Using Objective-C =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;[self.nielsenAppApi loadMetadata:metadataDict];&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===== Using Swift =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;self.nielsenAppApi?.loadMetadata(metadataDict)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== playheadPosition ====&lt;br /&gt;
Pass playhead position every second during playback. for VOD: pass current position in seconds. for Live: current Unix timestamp (seconds since Jan-1-1970 UTC) - if it is possible to seek back in Live content, then pass related Unix time (not current). Pass whole number that increments only by 1 like 1,2,3..&lt;br /&gt;
===== Using Objective-C =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
[self.nielsenAppApi playheadPosition:pos];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===== Using Swift =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
self.nielsenAppApi?.playheadPosition(pos);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== stop ====&lt;br /&gt;
Call when&lt;br /&gt;
* ads complete playing&lt;br /&gt;
* when a user pauses playback&lt;br /&gt;
* upon any user interruption scenario - see bellow chapter Interruption scenario&lt;br /&gt;
===== Using Objective-C =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;[self.nielsenAppApi stop];&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===== Using Swift =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;self.nielsenAppApi?.stop;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== end ====&lt;br /&gt;
Call when the content asset completes playback.  Stops measurement progress.&lt;br /&gt;
===== Using Objective-C =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;[self.nielsenAppApi end];&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===== Using Swift =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;self.nielsenAppApi?.end&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== API Call Sequence ===&lt;br /&gt;
==== Use Case 1: Content has no Ads ====&lt;br /&gt;
Call [[play()]] with channelName JSON as below.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;{&lt;br /&gt;
   &amp;quot;channelName&amp;quot;: &amp;quot;ChannelName&amp;quot;&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;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 [[playheadPosition|playheadPosition()]] every one second until a pause.&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(channelName); &amp;lt;/code&amp;gt; || // channelName contains JSON metadata of channel/video name being played&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.playheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // position 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;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 Ads ====&lt;br /&gt;
Call [[play()]] with channelName JSON as below.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;{&lt;br /&gt;
   &amp;quot;channelName&amp;quot;: &amp;quot;ChannelName&amp;quot;&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;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;
   ...&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 [[playheadPosition|playheadPosition()]] every one second until a pause / 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;
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(channelName); &amp;lt;/code&amp;gt; || // channelName contains JSON metadata of channel/video name being played&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.playheadPosition(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;6&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.playheadPosition(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; || // App moves to background(midroll pauses) &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.loadMetadata(midrollMetaDataObject);&amp;lt;/code&amp;gt; || // App moves to foreground (midroll resumes) &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.playheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // playheadPosition 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 (End of stream) || &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.playheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // position 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;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.playheadPosition(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;
== Stop/Resume the Measurement for video Playback Interruptions ==&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 (Video players only, not for Audio players)&lt;br /&gt;
* App going in the Background/Foreground (Video players only, not for Audio players)&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 &amp;lt;code&amp;gt;stop&amp;lt;/code&amp;gt; immediately (except when content is buffering) and withhold sending playhead position.&lt;br /&gt;
* Once the playback resumes, start sending pings &amp;lt;code&amp;gt;playheadPosition&amp;lt;/code&amp;gt; for the new viewing session.&lt;br /&gt;
Please see the [[Digital Measurement FAQ]] for more details&lt;br /&gt;
&lt;br /&gt;
== Review SDK Integration Architecture Diagram ==&lt;br /&gt;
&lt;br /&gt;
=== For Content Playback ===&lt;br /&gt;
&lt;br /&gt;
[[File:nlsn-sdk-achitecture-diagram-content-v1.png||SDK Integration Architecture Diagram - Content]]&lt;br /&gt;
&lt;br /&gt;
=== For Ad Playback ===&lt;br /&gt;
[[File:nlsn-sdk-achitecture-diagram-ad-v1.png||SDK Integration Architecture Diagram - Ad]]&lt;br /&gt;
&lt;br /&gt;
{{iOS_NoID_Privacy_and_Opt-Out}}&lt;br /&gt;
&lt;br /&gt;
{{iOS_Airplay}}&lt;br /&gt;
== Test your player by yourself ==&lt;br /&gt;
=== Guide ===&lt;br /&gt;
1. Connect your PC and test device (tablet or phone) via same router.&amp;lt;br /&amp;gt;&lt;br /&gt;
2. PC side: run Proxy sw (like Charles) and get local IP&amp;lt;br /&amp;gt;&lt;br /&gt;
3. Test device: modify Wifi setting to pass through Proxy IP from step 2.&amp;lt;br /&amp;gt;&lt;br /&gt;
4. Test device: run your player, launch video&amp;lt;br /&amp;gt;&lt;br /&gt;
5. PC side: filter traffic by &amp;quot;nmrodam&amp;quot; and confirm presence of SDK pings&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example of SDK ping (https call) ===&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;https://secure-ire.nmrodam.com/cgi-bin/gn?prd=dcr&amp;amp;ci=se-910685&amp;amp;ch=se-910685_c01_P&amp;amp;asn=defChnAsset&amp;amp;fp_id=a2nfmy17lyvkhlxqstvmgypqly90m1629966210&amp;amp;fp_cr_tm=1629966210&amp;amp;fp_acc_tm=1629966210&amp;amp;fp_emm_tm=1629966210&amp;amp;ve_id=20A7CFD5-9860-4256-A6CE-45C251F4C243&amp;amp;sessionId=yvx0rtsxydmaxueji8zgfzj0f2f1w1629966209&amp;amp;tl=&amp;amp;prv=1&amp;amp;c6=vc,c01&amp;amp;ca=se-910685_c01_51HERB1501&amp;amp;cg=Play%20%3E%20Webbtv%20%3E%20Nyheter&amp;amp;c13=asid,P3D8D326A-2DBC-486A-8FD8-9AF4452B2A41&amp;amp;c32=segA,NA&amp;amp;c33=segB,NA&amp;amp;c34=segC,NA&amp;amp;c15=apn,Aftonbladet&amp;amp;plugv=&amp;amp;playerv=&amp;amp;sup=1&amp;amp;segment2=&amp;amp;segment1=&amp;amp;forward=0&amp;amp;ad=1&amp;amp;cr=4_00_99_D1_00000&amp;amp;c9=devid,12b9377cbe7e5c94e8a70d9d23929523d14afa954793130f8a3959c7b849aca8&amp;amp;enc=true&amp;amp;c1=nuid,12b9377cbe7e5c94e8a70d9d23929523d14afa954793130f8a3959c7b849aca8&amp;amp;at=timer&amp;amp;rt=video&amp;amp;c16=sdkv,ai.8.1.0&amp;amp;c27=cln,15&amp;amp;crs=&amp;amp;lat=&amp;amp;lon=&amp;amp;c29=plid,16299662096458868&amp;amp;c30=bldv,ai.8.1.0.0_gsxaoni&amp;amp;st=dcr&amp;amp;c7=osgrp,&amp;amp;c8=devgrp,&amp;amp;c10=plt,&amp;amp;c40=adbid,&amp;amp;c14=osver,iOS14.6&amp;amp;c26=dmap,1&amp;amp;dd=&amp;amp;hrd=&amp;amp;wkd=&amp;amp;c35=adrsid,&amp;amp;c36=cref1,&amp;amp;c37=cref2,&amp;amp;c11=agg,1&amp;amp;c12=apv,5.47.83.0.25245&amp;amp;c51=adl,15&amp;amp;c52=noad,1&amp;amp;sd=15&amp;amp;pc=NA&amp;amp;c53=fef,n&amp;amp;c54=oad,&amp;amp;c55=cref3,&amp;amp;c57=adldf,2&amp;amp;ai=51HERB1501&amp;amp;c3=st,a&amp;amp;c64=starttm,1629966240&amp;amp;adid=51HERB1501&amp;amp;c58=isLive,false&amp;amp;c59=sesid,iqal6k21r0de8gm901kif5xznar7q1629966240&amp;amp;c61=createtm,1629966255&amp;amp;c63=pipMode,&amp;amp;ci_userid=&amp;amp;is_auto_play=&amp;amp;pl_title=&amp;amp;is_prem=&amp;amp;is_prog=&amp;amp;ad_origin=&amp;amp;adidx=1%2F1&amp;amp;is_tpad=&amp;amp;ci_passthr=&amp;amp;c62=sendTime,1629966255&amp;amp;c68=bndlid,se.aftonbladet.Aftonbladet&amp;amp;c69=cvw,&amp;amp;nodeTM=&amp;amp;logTM=&amp;amp;c73=phtype,&amp;amp;c74=dvcnm,&amp;amp;c76=adbsnid,&amp;amp;uoo=&amp;amp;c44=progen,&amp;amp;davty=1&amp;amp;si=&amp;amp;c66=mediaurl,&amp;amp;sdd=retry,0~~retryreason,~~devmodel,iPhone9%2C4~~devtypid,iPhone9%2C4~~sysname,iOS~~sysversion,14.6~~manuf,Apple&amp;amp;cat_id=a6f7fb13-8801-484c-9692-6db6dfb470aa&amp;amp;vtoff=0&amp;amp;rnd=1629966255319&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Provide your app for certification ==&lt;br /&gt;
Once ready please send your application to Nielsen local staff for certification.&lt;br /&gt;
&lt;br /&gt;
== Going Live ==&lt;br /&gt;
Following Nielsen testing, you will need to:&lt;br /&gt;
&lt;br /&gt;
# '''Disable Debug Logging''': Disable logging by deleting &amp;lt;code&amp;gt;{nol_devDebug: 'DEBUG'}&amp;lt;/code&amp;gt; from initialization call.&lt;br /&gt;
# '''Notify Nielsen''': Once you are ready to go live, let us know so we can enable you for reporting. We will not be able to collect or report data prior to receiving notification from you.&lt;/div&gt;</summary>
		<author><name>NickParrucci</name></author>
	</entry>
	<entry>
		<id>https://nielsentest.mywikis.net/w/index.php?title=DCR_Video_iOS_SDK&amp;diff=6391</id>
		<title>DCR Video iOS SDK</title>
		<link rel="alternate" type="text/html" href="https://nielsentest.mywikis.net/w/index.php?title=DCR_Video_iOS_SDK&amp;diff=6391"/>
		<updated>2023-06-21T18:53:39Z</updated>

		<summary type="html">&lt;p&gt;NickParrucci: &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;
If the content being played contains ID3 tags, when played on a mobile device or within a browser, these tags can be sent to Nielsen for collection/processing via the Nielsen SDK.  &lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
VOD in TV Ratings (formally knows as Recently Telecast VOD) support is now available; however, you must notify us to ensure accurate reporting.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
This guide covers implementation steps for iOS using Xcode utilizing the Standard Nielsen SDK for DCR.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
{{iOS_SpecialNotes_for_iOS14}}&lt;br /&gt;
&lt;br /&gt;
{{iOS_Prerequisites_and_Implementation_Overview}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{iOS_Setting_Up_Development_Environment}}&lt;br /&gt;
&lt;br /&gt;
{{iOS_SDK_Initialization}}&lt;br /&gt;
&lt;br /&gt;
{{iOS_Configure_Metadata}}&lt;br /&gt;
&lt;br /&gt;
{{iOS_LifeCycle_of_SDK}}&lt;br /&gt;
&lt;br /&gt;
{{iOS_Configure_API_Calls}}&lt;br /&gt;
&lt;br /&gt;
{{iOS_Sequence_of_Calls}}&lt;br /&gt;
&lt;br /&gt;
{{iOS_Foreground_and_Background}}&lt;br /&gt;
&lt;br /&gt;
{{iOS_Interuptions_during_Playback}}&lt;br /&gt;
&lt;br /&gt;
{{iOS_NielsenAppSDKJSHandler}}&lt;br /&gt;
&lt;br /&gt;
{{iOS_PreCertification_Checklists}}&lt;br /&gt;
&lt;br /&gt;
{{Template:iOS_Privacy_and_Opt-Out}}&lt;br /&gt;
&lt;br /&gt;
{{iOS_Airplay}}&lt;br /&gt;
&lt;br /&gt;
{{iOS_Going_Live}}&lt;br /&gt;
&lt;br /&gt;
{{iOS_Removing_Simulator_Slices}}&lt;br /&gt;
&lt;br /&gt;
{{iOS_Keychain_Sharing}}&lt;br /&gt;
&lt;br /&gt;
{{iOS_Sample_Apps}}&lt;/div&gt;</summary>
		<author><name>NickParrucci</name></author>
	</entry>
	<entry>
		<id>https://nielsentest.mywikis.net/w/index.php?title=Template:Android_SDK_Initialization&amp;diff=6383</id>
		<title>Template:Android SDK Initialization</title>
		<link rel="alternate" type="text/html" href="https://nielsentest.mywikis.net/w/index.php?title=Template:Android_SDK_Initialization&amp;diff=6383"/>
		<updated>2023-06-09T19:40:02Z</updated>

		<summary type="html">&lt;p&gt;NickParrucci: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== SDK Initialization ==&lt;br /&gt;
The latest version of the Nielsen App SDK allows instantiating multiple instances of the SDK object, which can be used simultaneously without any issue. The sharedInstance API that creates a singleton object was deprecated prior to version 5.1.1. (Version 4.0 for Android)&lt;br /&gt;
&lt;br /&gt;
The following table contains the list of arguments that can be passed via the AppInfo JSON schema.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter / Argument !! Description !! Source !! Required? !! Example&lt;br /&gt;
|-&lt;br /&gt;
| appid || Unique Nielsen ID for the application. The ID is a GUID data type. If you did not receive your App ID, let us know and we will provide you. || Nielsen-specified || Yes || PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&lt;br /&gt;
|-&lt;br /&gt;
| nol_devDebug || Enables Nielsen console logging. Only required for testing&lt;br /&gt;
|| Nielsen-specified || Optional || &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
== Debug flag for development environment ==&lt;br /&gt;
Player application developers / integrators can use Debug flag to check whether an App SDK API call made is successful. To activate the Debug flag,&lt;br /&gt;
Pass the argument &amp;lt;code&amp;gt;@&amp;quot;nol_devDebug&amp;quot;:@&amp;quot;INFO&amp;quot;&amp;lt;/code&amp;gt;, in the JSON string . The permitted values are:&lt;br /&gt;
&lt;br /&gt;
* '''INFO''': Displays the API calls and the input data from the application (validate player name, app ID, etc.). It can be used as certification Aid.&lt;br /&gt;
* '''WARN''': Indicates potential integration / configuration errors or SDK issues.&lt;br /&gt;
* '''ERROR''': Indicates important integration errors or non-recoverable SDK issues.&lt;br /&gt;
* '''DEBUG''': Debug logs, used by the developers to debug more complex issues.&lt;br /&gt;
&lt;br /&gt;
Once the flag is active, it logs each API call made and the data passed. The log created by this flag is minimal.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': DO NOT activate the Debug flag in a production environment.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Sample SDK Initialization Code ====&lt;br /&gt;
[[AppSDK()]] is no longer a singleton object and should be initialized as below.&lt;br /&gt;
&lt;br /&gt;
'''Initialization of App SDK object through a JSON object'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;try&lt;br /&gt;
{&lt;br /&gt;
  // Prepare AppSdk configuration object (JSONObject)&lt;br /&gt;
  JSONObject appSdkConfig = new JSONObject()&lt;br /&gt;
          .put(&amp;quot;appid&amp;quot;, &amp;quot;PDA7D5EE6-B1B8-XXXX-XXXX-2A788BCXXXCA&amp;quot;)&lt;br /&gt;
          .put(&amp;quot;nol_devDebug&amp;quot;, &amp;quot;DEBUG&amp;quot;); // only for debug builds&lt;br /&gt;
&lt;br /&gt;
// Pass appSdkConfig to the AppSdk constructor&lt;br /&gt;
mAppSdk = new AppSdk(appContext, appSdkConfig, appSdkListener);&lt;br /&gt;
}&lt;br /&gt;
catch (JSONException e)&lt;br /&gt;
{&lt;br /&gt;
  Log.e(TAG, &amp;quot;Couldn’t prepare JSONObject for appSdkConfig&amp;quot;, e);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Here, &amp;lt;code&amp;gt;appContext&amp;lt;/code&amp;gt; is the App context object and &amp;lt;code&amp;gt;appSdkConfig&amp;lt;/code&amp;gt; is JSON object for holding the parameters (&amp;lt;code&amp;gt;appid&amp;lt;/code&amp;gt;) the App passes to the Nielsen App SDK via a JSON string. The appid is obtained from Nielsen operational support and is unique to the app.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The integration of Nielsen App SDK will depend on type of client app.&amp;lt;br /&amp;gt;&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;
== Initializing Viewability and Audibility Measurement ==&lt;br /&gt;
If your Nielsen integration will be enabled for viewability/audibility measurement, your app should call trackViewability after initializing the SDK (previous paragraphs). &lt;br /&gt;
&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. Audibility metrics report on the device volume level.&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;
== Calling trackViewability for player view ==&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;
| data || JSONObject object with the following objects and keys:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| viewTag (mandatory) || value of String type, tag identifier for the target player view object. This tag can be assigned for the player view either programmatically or in the layout xml, as explained in above section. &lt;br /&gt;
|-&lt;br /&gt;
| viewContainer (mandatory) || Reference to the activity object. It is needed to identify and search the target player view in current visible screen. This parameter can not be nil. This should be the current activity object where target view is loaded. If the player view is rendered in a fragment, please provide the parent activity reference of the fragment.&lt;br /&gt;
|-&lt;br /&gt;
| friendlyObstructions (optional) || an array of tags of the views which should be ignored during the intersection ratio calculation. Those are views like loading activity indicator, player controls, view with a watermark, etc. which are displayed in front of the target view, but should not reduce the viewability intersection ratio. The tags of such should be wrapped into the String objects before adding into the array. This parameter is nullable, empty array is also accepted.&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Syntax ==&lt;br /&gt;
&amp;lt;br/&amp;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;
== Usage Example ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
String targetViewTag = targetView.getTag().toString();&lt;br /&gt;
String activityObj = MainActivity.this;&lt;br /&gt;
JSONArray friendlyTags = new JSONArray();&lt;br /&gt;
friendlyTags.put(&amp;quot;friendlyViewTag1&amp;quot;);&lt;br /&gt;
friendlyTags.put(&amp;quot;friendlyViewTag2&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
JSONObject json = new JSONObject();&lt;br /&gt;
json.put(&amp;quot;viewContainer&amp;quot;, activityObj);&lt;br /&gt;
json.put(&amp;quot;viewTag&amp;quot;, targetViewTag);&lt;br /&gt;
json.put(&amp;quot;friendlyObstructions&amp;quot;, friendlyTags);&lt;br /&gt;
sdkInstance.trackViewability(json);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:PlayerScreen_ViewContainer-ViewTag-FriendlyViews.png|300px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Setting tag for a player view in layout xml ==&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;SurfaceView&lt;br /&gt;
   android:id=&amp;quot;@+id/playerView&amp;quot;&lt;br /&gt;
   android:tag=&amp;quot;playerViewTag&amp;quot;           &lt;br /&gt;
   android:layout_width=&amp;quot;match_parent&amp;quot;&lt;br /&gt;
   android:layout_height=&amp;quot;match_parent&amp;quot;&lt;br /&gt;
/&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Setting tag for a player view in Activity/Fragment ==&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
mPlayerView = (SurfaceView) findViewById(R.id.playerView);&lt;br /&gt;
mPlayerView.setTag(&amp;quot;playerViewTag&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&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;/div&gt;</summary>
		<author><name>NickParrucci</name></author>
	</entry>
	<entry>
		<id>https://nielsentest.mywikis.net/w/index.php?title=DTVR_Android_SDK&amp;diff=6382</id>
		<title>DTVR Android SDK</title>
		<link rel="alternate" type="text/html" href="https://nielsentest.mywikis.net/w/index.php?title=DTVR_Android_SDK&amp;diff=6382"/>
		<updated>2023-06-09T19:19:11Z</updated>

		<summary type="html">&lt;p&gt;NickParrucci: &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;
If the content being played contains ID3 tags, when played on a mobile device or within a browser, these tags can be sent to Nielsen for collection/processing via the Nielsen SDK.  &lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
VOD in TV Ratings (formally knows as Recently Telecast VOD) support is now available; however, you must notify us to ensure accurate reporting.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&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: 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. || Provided by Nielsen&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
 || '''Nielsen SDK''' || Includes SDK frameworks and '''sample implementation'''; ''See [[Android SDK Release Notes]]'' || [[Special:Downloads|Download]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
If need App ID(s) or our SDKs, feel free to reach out to us and we will be happy to help you get started.&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;
&lt;br /&gt;
{{Android_Implementation}}&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
{{Android_Setting_Up_Development_Envrionment}}&lt;br /&gt;
&lt;br /&gt;
{{Android_SDK_Initialization}}&lt;br /&gt;
&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;
== Content Metadata and SDK Events ==&lt;br /&gt;
=== Content Metadata ===&lt;br /&gt;
Content metadata should remain constant throughout the completion of an episode or live stream.&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      || ✓&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;    &lt;br /&gt;
    //Loading Channel Info.&lt;br /&gt;
    public JSONObject loadChannelInfo(){&lt;br /&gt;
        JSONObject channel = null;&lt;br /&gt;
        try {&lt;br /&gt;
        channel = new JSONObject()&lt;br /&gt;
                .put(&amp;quot;channelName&amp;quot;, &amp;quot;ChannelTitle&amp;quot;);&lt;br /&gt;
        } catch (JSONException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
        return  channel;&lt;br /&gt;
    }&lt;br /&gt;
    &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
------------------------&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;   &lt;br /&gt;
    public JSONObject loadDtvr() {&lt;br /&gt;
     try {&lt;br /&gt;
            dtvr = new JSONObject()&lt;br /&gt;
                    .put( &amp;quot;type&amp;quot;,&amp;quot;content&amp;quot;)&lt;br /&gt;
                    .put(&amp;quot;adModel&amp;quot;, &amp;quot;1&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        return dtvr;&lt;br /&gt;
    }&lt;br /&gt;
    &amp;lt;/syntaxhighlight&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 to pass type and adModel.&lt;br /&gt;
|-&lt;br /&gt;
|'play'||||Call when starting or resuming a streaming session. '''Note:''' Not required starting at SDK version 7.2.0 or higher.&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;
|-&lt;br /&gt;
| 'stop' ||	playhead position	|| Call when content or ads complete playing and pass playhead position&lt;br /&gt;
'''Note:'''no longer required for SDK version 7.2 or higher.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Configure API calls - play ===&lt;br /&gt;
Call play at start of new stream:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;  appSdk.play();&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Note:''' no longer required for SDK version 7.2 or higher.&lt;br /&gt;
&lt;br /&gt;
=== Configure API calls - loadMetadata ===&lt;br /&gt;
Use &amp;lt;code&amp;gt;loadMetadata&amp;lt;/code&amp;gt; to pass ‘content’ and ‘ad’ &amp;lt;code&amp;gt;Digital Measurement Metadata&amp;lt;/code&amp;gt;. The CMS data must be passed as a JSON object.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt; appSdk.loadMetadata(data);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Configure API calls - sendID3 ===&lt;br /&gt;
[[sendID3]] API is a receiver for timed metadata events (ID3 tags. This API filters out Nielsen-specific ID3 tags from the system and buffers the data for transfer to Nielsen’s collection facility.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt; //Sending ID3 tag to SDK.&lt;br /&gt;
appSdk.sendID3(id3String);&amp;lt;/syntaxhighlight&amp;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;
Refer to [[Android SDK API Reference#Retrieving ID3 Tags|Retrieving ID3 Tags]] section to know more details.&lt;br /&gt;
&lt;br /&gt;
===Configure API calls - stop ===&lt;br /&gt;
Call &amp;lt;code&amp;gt;stop&amp;lt;/code&amp;gt; in case of interruptions during playback like flight mode, Wi-Fi toggle, etc. &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;[nielsenApi stop];&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Note:''' no longer required for SDK version 7.2 or higher.&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;
===  Examples of extracting ID3 tags fromAndroid 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 mediaPlayer, TimedMetaData timedMetaData) {&lt;br /&gt;
&lt;br /&gt;
        if(timedMetaData != null &amp;amp;&amp;amp; timedMetaData.getMetaData() != null &amp;amp;&amp;amp; mMediaPlayer.isPlaying()){&lt;br /&gt;
&lt;br /&gt;
            //getting metadata.&lt;br /&gt;
            String iD3Payload = new String(timedMetaData.getMetaData(), StandardCharsets.UTF_8);&lt;br /&gt;
&lt;br /&gt;
            //If tag metadata contains &amp;quot;www.nielsen.com&amp;quot;, then only sending to SDK&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;
                //getting index&lt;br /&gt;
                int index = iD3Payload.indexOf(&amp;quot;www.nielsen.com&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
                //getting substring as ID3 tag will be of 249 characters&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;
&lt;br /&gt;
                //Sending ID3 tag to SDK.&lt;br /&gt;
                appSdk.sendID3(id3String);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/syntaxhighlight&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; call moves 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;'''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. 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;   ''(This is testing purposes only. Not for User Opt-Out.)''&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 &amp;lt;/code&amp;gt;stop&amp;lt;/code&amp;gt; to stop the measurement.&lt;br /&gt;
&lt;br /&gt;
== Handling Foreground and Background states ==&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.&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;
&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 (Video players only, not for Audio players)&lt;br /&gt;
* App going in the Background/Foreground (Video players only, not for Audio players)&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;
&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;
&lt;br /&gt;
== Going Live ==&lt;br /&gt;
Following Nielsen testing, you will need to:&lt;br /&gt;
&lt;br /&gt;
# '''Disable Debug Logging''': Disable logging by deleting &amp;lt;code&amp;gt;{nol_devDebug: 'DEBUG'}&amp;lt;/code&amp;gt; from initialization call.&lt;br /&gt;
# '''Notify Nielsen''': Once you are ready to go live, let us know so we can enable you for reporting. We will not be able to collect or report data prior to receiving notification from you.&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 contained in the ZIP package.&lt;/div&gt;</summary>
		<author><name>NickParrucci</name></author>
	</entry>
</feed>