DCR Germany Static App SDK: Difference between revisions

From Engineering Client Portal

No edit summary
 
(3 intermediate revisions by the same user not shown)
Line 16: Line 16:


* <blockquote>'''No ID AppSDK''': <pre style="color: red">ONLY the No ID AppSDK should be downloaded for the AGF market!</pre>
* <blockquote>'''No ID AppSDK''': <pre style="color: red">ONLY the No ID AppSDK should be downloaded for the AGF market!</pre>
</blockquote>
* <blockquote>'''AppSDK version >= 9.1.0.0 is required''': <pre style="color: red"> The newly introduced AppSDK API staticEnd() is available only for AppSDK version 9.1.0.0 or higher </pre>
</blockquote>
</blockquote>


Line 46: Line 49:
|-
|-
| appversion || Current version of the app used || Client-defined || No || "1.0.2"
| appversion || Current version of the app used || Client-defined || No || "1.0.2"
|-
| sfcode || Nielsen collection facility to which the SDK should connect.
'''AGF Clients'''
* "eu" (For Testing/Certification and in Pproduction)
|| Nielsen-specified || ✓ || "eu"
|-
|-
| nol_devDebug || Enables Nielsen console logging. Has to be set to "DEBUG" until certified
| nol_devDebug || Enables Nielsen console logging. Has to be set to "DEBUG" until certified
Line 67: Line 65:
     let appInformation:[String: String] = [
     let appInformation:[String: String] = [
           "appid": "PDA7D5EE6-B1B8-XXXX-XXXX-2A788BCXXXCA",
           "appid": "PDA7D5EE6-B1B8-XXXX-XXXX-2A788BCXXXCA",
            "sfcode": "eu",
             "nol_devDebug": "DEBUG"
             "nol_devDebug": "DEBUG"
         ]
         ]
Line 110: Line 107:
     NSDictionary *appInformation = @{
     NSDictionary *appInformation = @{
                                     @"appid": "PDA7D5EE6-B1B8-XXXX-XXXX-2A788BCXXXCA",
                                     @"appid": "PDA7D5EE6-B1B8-XXXX-XXXX-2A788BCXXXCA",
                                    @"sfcode": "eu",
                                     @"nol_devDebug": @"DEBUG"
                                     @"nol_devDebug": @"DEBUG"
                                     };
                                     };
Line 146: Line 142:
   JSONObject appSdkConfig = new JSONObject()
   JSONObject appSdkConfig = new JSONObject()
           .put("appid", "PDA7D5EE6-B1B8-XXXX-XXXX-2A788BCXXXCA")
           .put("appid", "PDA7D5EE6-B1B8-XXXX-XXXX-2A788BCXXXCA")
          .put("sfcode", "eu")
           .put("nol_devDebug", "DEBUG");
           .put("nol_devDebug", "DEBUG");


Line 170: Line 165:
== Step 4: Create Metadata Object for your page section ==
== Step 4: Create Metadata Object for your page section ==


{| class="wikitable"
The full description of the other key/value pairs for Metadata can be found here:
|-
'''[[AGF Metadata Convention#Static Measurement|AGF Metadata Convention for Static Measurement]]'''
! Key !! Description !! Values !! Required (Obligatory)
|-
| assetid || unique ID assigned to each article/page; only characters 0-9, a-z, A-Z underscore and minus are allowed - no special characters or vowel mutations) || custom (no [[Special Characters]])|| ✓
|-
| section || section of each site (e.g. section value should be first level in page URL: website.com/section) || custom || ✓
|-
| segA ||  custom segment for reporting: unique values across custom segments (segA + segB + segC) || custom || ✓
|-
| segB ||  custom segment for reporting: unique values across custom segments (segA + segB + segC) || custom ||
|-
| segC ||  custom segment for reporting: unique values across custom segments (segA + segB + segC) || custom ||
|-
| subbrand ||  vcid/sub-brand ID – value is automatically populated through provided App ID. In order to override the sub-brand configured to the App ID, value can be passed here (e.g. multiple sub-brands in App) || provided by Nielsen ||
|}


=== Example Web Page Metadata Object ===
=== Example Web Page Metadata Object ===
Line 202: Line 183:
         "section": "Unique_section_ID",
         "section": "Unique_section_ID",
         "segA": "Unique_section_segA",
         "segA": "Unique_section_segA",
         "segB": "Optional_section_segB",
         "segB": "Mandatory_section_segB",
         "segC": "Optional_section_segC",
         "segC": "Optional_section_segC",
         "subbrand": "subbrand_received_from_Nielsen"
         "subbrand": "subbrand_received_from_Nielsen"
Line 218: Line 199:
         @ "section": @ "Unique_section_ID",
         @ "section": @ "Unique_section_ID",
         @ "segA": @ "Unique_section_segA",
         @ "segA": @ "Unique_section_segA",
         @ "segB": @ "Optional_section_segB",
         @ "segB": @ "Mandatory_section_segB",
         @ "segC": @ "Optional_section_segC",
         @ "segC": @ "Optional_section_segC",
         @ "subbrand": @ "subbrand_received_from_Nielsen"
         @ "subbrand": @ "subbrand_received_from_Nielsen"
Line 230: Line 211:
         .put("assetid", "Unique_asset_ID")
         .put("assetid", "Unique_asset_ID")
         .put("segA", "Unique_section_segA")
         .put("segA", "Unique_section_segA")
         .put("segB", "Optional_section_segB")
         .put("segB", "Mandatory_section_segB")
         .put("segC","Optional_section_segC")
         .put("segC","Optional_section_segC")
         .put("subbrand","subbrand_received_from_Nielsen");
         .put("subbrand","subbrand_received_from_Nielsen");
     </syntaxhighlight>
     </syntaxhighlight>
 


== Step 5: Start the Measurement by calling the loadMetadata AppSDK API ==
== Step 5: Start the Measurement by calling the loadMetadata AppSDK API ==
Line 241: Line 221:


{{ExampleCode|
{{ExampleCode|
|Objective C = <syntaxhighlight lang="objective-c">– (void)loadMetadata:(id)contentMetadata;</syntaxhighlight>
|Android = <syntaxhighlight lang="java">public void loadMetadata(JSONObject contentMetadata);</syntaxhighlight>
|Android = <syntaxhighlight lang="java">public void loadMetadata(JSONObject contentMetadata);</syntaxhighlight>
|Swift = <syntaxhighlight lang="swift">self.nielsenAppApi?.loadMetadata(contentMetadata)</syntaxhighlight>
|Objective C = <syntaxhighlight lang="objective-c">- (void)loadMetadata:(id)contentMetadata;</syntaxhighlight>
}}
<br>
<blockquote>
[[Image:AlertIcon.png|left|60px|link=|class=smallIcon]] Call <code>staticEnd()</code> to stop the static measurement of the current page before starting a new measurement with <code>loadMetadata()</code> for the next page.'''
</blockquote>
 
== Step 6: Include the measurement of Advertising Medium (Werbeträger) if applicable  ==
 
=== Description ===
 
A page impression is a user action on the page that leads or could lead to an advertisement being called up. Each user action may only be counted once.
 
However, a page impression occurs when the content of the viewport of the respective device is completely reloaded/rendered by scrolling/swiping and replaced by new
content.
 
When counting views, a distinction is made between content
views (CPI) and advertising medium views after a user action (WPI). There can be
only one content view per page. Each additional user action on the same page (click,
scroll or swipe, e.g. click through an image gallery) will lead to an advertising medium view (WPI) accordingly. The implementation should follow the IVW guidelines for
defining user actions.
 
'''Note''':
The differentiation between the measurement of Content vs. advertising medium is achieved by setting accordingly the "segB" value in the metadata object  , see '''[[AGF Metadata Convention#Static Measurement|AGF Metadata Convention for Static Measurement]]'''
 
=== Implementation Details ===
How to trigger a page impression for advertising medium?
In order to trigger a new view for an advertising medium, you have to stop the measurement of the page and start the measurement of the advertising medium, see example code below:
 
==== Stop static measurement for the page(current metadata): ====
{{ExampleCode|
|Android = <syntaxhighlight lang="java"> public void staticEnd(); </syntaxhighlight>
|Objective C = <syntaxhighlight lang="objective-c">- (void)staticEnd; </syntaxhighlight>
}}
 
==== Start static measurement for the advertising medium after user interaction(new metadata): ====
{{ExampleCode|
|Android = <syntaxhighlight lang="java">public void loadMetadata(JSONObject contentMetadata);</syntaxhighlight>
|Objective C = <syntaxhighlight lang="objective-c">- (void)loadMetadata:(id)contentMetadata;</syntaxhighlight>
}}
}}


== Step 6: Privacy and Opt-Out ==
== Step 7: Privacy and Opt-Out ==


The AppSDK measurement is working without cookies and other personal information. No user can be identified personally, therefore an opt-out functionality is not required. The Nielsen AppSDK measurement is utilizing a cookieless domain.
The AppSDK measurement is working without cookies and other personal information. No user can be identified personally, therefore an opt-out functionality is not required. The Nielsen AppSDK measurement is utilizing a cookieless domain.
In order to disclose Nielsen measurement privacy statement, please include the following items in your privacy policy:
In order to disclose Nielsen measurement privacy statement, please include the following items in your privacy policy:
* A notice that the player includes third party measurement software that allows users to contribute to market research with anonymous data.
* A notice that the player includes third party measurement software that allows users to contribute to market research with anonymous data.
* A link to the Nielsen Digital Measurement Privacy Policy located at https://www.nielsen.com/de/de/legal/privacy-statement/digital-measurement/ .
* A link to the Nielsen Digital Measurement Privacy Policy located at https://nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/?lang=de .
   
   
Please contact your Nielsen SDK support team directly for any related questions.
Please contact your Nielsen SDK support team directly for any related questions.


== Step 7: Going Live ==
== Step 8: Going Live ==
Following Nielsen testing, users need to make one update to the initialization call to ensure that the site is being measured properly.
Following Nielsen testing, users need to make one update to the initialization call to ensure that the site is being measured properly.


Line 268: Line 285:
     let appInformation:[String: String] = [
     let appInformation:[String: String] = [
             "appid": "PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
             "appid": "PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
            "sfcode": "eu"
             // Remove Flag:  "nol_devDebug": "DEBUG"
             // Remove Flag:  "nol_devDebug": "DEBUG"
         ]
         ]
Line 283: Line 299:
   JSONObject appSdkConfig = new JSONObject()
   JSONObject appSdkConfig = new JSONObject()
           .put("appid", "PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX")
           .put("appid", "PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX")
          .put("sfcode", "eu")
             // Remove Flag:  "nol_devDebug": "DEBUG"
             // Remove Flag:  "nol_devDebug": "DEBUG"



Latest revision as of 09:39, 31 March 2023

Engineering Portal / Digital / AGF Implementation Documentation / DCR Germany Static App SDK

Overview

The Nielsen App 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. The App SDK is the framework for iOS and Android Apps developers to integrate Nielsen Measurement into their App for the Static Content Measurement.

This guide will show you how to enable Static measurement in your App. The Nielsen App Static Measurement of each different page/section requires different metadata.

Prerequisites

  • To get started, an AppID is needed. The AppID is a unique ID assigned to the App. This will be provided upon starting the integration from Nielsen.
  apid: "XXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" // eg. PDA7D5EE6-B1B8-XXXX-XXXX-2A788BCXXXCA
  • No ID AppSDK:

    ONLY the No ID AppSDK should be downloaded for the AGF market!
  • AppSDK version >= 9.1.0.0 is required:

     The newly introduced AppSDK API staticEnd() is available only for AppSDK version 9.1.0.0 or higher 

Step 1: Set up your Development Environment

iOS

For setting up your iOS Development Environment, refer to DCR Germany Video App SDK#iOS

Android

For setting up your Android Development Environment, refer to DCR Germany Video App SDK#Android


Step 2: Create and Initialize SDK Instance

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)

  • A maximum of four SDK instances per appid are supported. When a fifth SDK instance is launched, the SDK will return “nil” from initWithAppInfo:delegate:
  • When four SDK instances exist, you must destroy an old instance before creating a new one.

The following table contains the list of arguments that can be passed via the AppInfo JSON schema.

  • The appid is provided by the Nielsen Technical Account Manager (TAM). The appid is a GUID data type and is specific to the application.
Parameter / Argument Description Source Required/Obligatory? Example
appid Unique id for the application assigned by Nielsen. It is GUID data type. Nielsen-specified "PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
appname Name of the application Client-defined No "Nielsen Sample App"
appversion Current version of the app used Client-defined No "1.0.2"
nol_devDebug Enables Nielsen console logging. Has to be set to "DEBUG" until certified Nielsen-specified Optional "DEBUG"


Sample SDK Initialization Code

iOS
Swift
class NielsenInit: NSObject {
    class func createNielsenAppApi(delegate: NielsenAppApiDelegate) -> NielsenAppApi?{
    let appInformation:[String: String] = [
           "appid": "PDA7D5EE6-B1B8-XXXX-XXXX-2A788BCXXXCA",
            "nol_devDebug": "DEBUG"
        ]
        return NielsenAppApi(appInfo:appInformation, delegate:delegate)
    }
}


Sample code using AVPlayer.
ViewController.swift

class ViewController: UIViewController, NielsenAppApiDelegate, AVPictureInPictureControllerDelegate, CLLocationManagerDelegate  {
    
    let avPlayerViewController = AVPlayerViewController()
    var avPlayer:AVPlayer?
    var nielsenAppApi: NielsenAppApi!

  override func viewDidLoad() {
        super.viewDidLoad()

self.nielsenAppApi = NielsenInit.createNielsenAppApi(delegate: self)
NSLog("Nielsen SDK initialized")

            }
  }
Objective-C

Initialize the Nielsen App object within the viewDidLoad view controller delegate method using initWithAppInfo:delegate:

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.

    
#import "NlsAppApiFactory.h"
#import <NielsenAppApi/NielsenAppApi.h>

@implementation NlsAppApiFactory

+ (NielsenAppApi *)createNielsenAppApiWithDelegate:(id<NielsenAppApiDelegate>)delegate;
{
    NSDictionary *appInformation = @{
                                     @"appid": "PDA7D5EE6-B1B8-XXXX-XXXX-2A788BCXXXCA",
                                     @"nol_devDebug": @"DEBUG"
                                     };
    return [[NielsenAppApi alloc] initWithAppInfo:appInformation delegate:delegate];
}
@end


The following would be the NlsAppApiFactory.h file:

#import <Foundation/Foundation.h>

@class NielsenAppApi;
@protocol NielsenAppApiDeligate;

@interface NlsAppApiFactory : NSObject 

+ (NielsenAppAPI *) createNielsenAppApiWithDelegate:(id<NielsenAppApiDelegate>)delegate;

@end
Android
Java

AppSDK is no longer a singleton object and should be initialized as below.

Initialization of App SDK object through a JSON object

  

try
{
  // Prepare AppSdk configuration object (JSONObject)
  JSONObject appSdkConfig = new JSONObject()
          .put("appid", "PDA7D5EE6-B1B8-XXXX-XXXX-2A788BCXXXCA")
          .put("nol_devDebug", "DEBUG");

// Pass appSdkConfig to the AppSdk constructor
mAppSdk = new AppSdk(appContext, appSdkConfig, appSdkListener);
}
catch (JSONException e)
{
  Log.e(TAG, "Couldn’t prepare JSONObject for appSdkConfig", e);
}

Here, appContext is the App context object and appSdkConfig is JSON object for holding the parameters (appid, appname, sfcode) 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.


The integration of Nielsen App SDK will depend on type of client app.

  • Ensure that SDK file AppSdk.jar is 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).


Step 3: Review the APP SDK Error & Event Codes

To view the Error and Event codes for iOS and Android, please review the App SDK Event Code Reference page.


Step 4: Create Metadata Object for your page section

The full description of the other key/value pairs for Metadata can be found here: AGF Metadata Convention for Static Measurement

Example Web Page Metadata Object

iOS

Swift
 class SDKMethods : NSObject{ 
    func loadStaticMaster() -> [String : Any] {      
        //Loading Static Main data      
        let staticData =
            [
        "type": "static",
        "assetid": "Unique_asset_ID",
        "section": "Unique_section_ID",
        "segA": "Unique_section_segA",
        "segB": "Mandatory_section_segB",
        "segC": "Optional_section_segC",
        "subbrand": "subbrand_received_from_Nielsen"
        ]       
        return staticData    
    }
Objective-C
 
NSDictionary * staticMetadata = @ {
    @ "type": @ "static",
        @ "assetid": @ "Unique_asset_ID",
        @ "section": @ "Unique_section_ID",
        @ "segA": @ "Unique_section_segA",
        @ "segB": @ "Mandatory_section_segB",
        @ "segC": @ "Optional_section_segC",
        @ "subbrand": @ "subbrand_received_from_Nielsen"
}

Android

   staticMetadata = new JSONObject()
        .put("type", "static")
        .put("section", "Unique_section_ID")
        .put("assetid", "Unique_asset_ID")
        .put("segA", "Unique_section_segA")
        .put("segB", "Mandatory_section_segB")
        .put("segC","Optional_section_segC")
        .put("subbrand","subbrand_received_from_Nielsen");

Step 5: Start the Measurement by calling the loadMetadata AppSDK API

Use the metadata object created in the previous step in the loadMetadata AppSDK API Call.


Objective C

- (void)loadMetadata:(id)contentMetadata;

Java

public void loadMetadata(JSONObject contentMetadata);


AlertIcon.png

Call staticEnd() to stop the static measurement of the current page before starting a new measurement with loadMetadata() for the next page.

Step 6: Include the measurement of Advertising Medium (Werbeträger) if applicable

Description

A page impression is a user action on the page that leads or could lead to an advertisement being called up. Each user action may only be counted once.

However, a page impression occurs when the content of the viewport of the respective device is completely reloaded/rendered by scrolling/swiping and replaced by new content.

When counting views, a distinction is made between content views (CPI) and advertising medium views after a user action (WPI). There can be only one content view per page. Each additional user action on the same page (click, scroll or swipe, e.g. click through an image gallery) will lead to an advertising medium view (WPI) accordingly. The implementation should follow the IVW guidelines for defining user actions.

Note: The differentiation between the measurement of Content vs. advertising medium is achieved by setting accordingly the "segB" value in the metadata object , see AGF Metadata Convention for Static Measurement

Implementation Details

How to trigger a page impression for advertising medium? In order to trigger a new view for an advertising medium, you have to stop the measurement of the page and start the measurement of the advertising medium, see example code below:

Stop static measurement for the page(current metadata):


Objective C

- (void)staticEnd;

Java

 public void staticEnd();

Start static measurement for the advertising medium after user interaction(new metadata):


Objective C

- (void)loadMetadata:(id)contentMetadata;

Java

public void loadMetadata(JSONObject contentMetadata);

Step 7: Privacy and Opt-Out

The AppSDK measurement is working without cookies and other personal information. No user can be identified personally, therefore an opt-out functionality is not required. The Nielsen AppSDK measurement is utilizing a cookieless domain. In order to disclose Nielsen measurement privacy statement, please include the following items in your privacy policy:

Please contact your Nielsen SDK support team directly for any related questions.

Step 8: Going Live

Following Nielsen testing, users need to make one update to the initialization call to ensure that the site is being measured properly.

  1. Debug Logging: Disable logging by deleting {nol_sdkDebug: 'DEBUG'} from initialization call.
    • Example Production Initialization Call - Refer to the production initialization call below:

iOS Example:

class NielsenInit: NSObject {
    class func createNielsenAppApi(delegate: NielsenAppApiDelegate) -> NielsenAppApi?{
    let appInformation:[String: String] = [
            "appid": "PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
            // Remove Flag:   "nol_devDebug": "DEBUG"
        ]
        return NielsenAppApi(appInfo:appInformation, delegate:delegate)
    }
}

Android Example:

  
try
{
  // Prepare AppSdk configuration object (JSONObject)
  JSONObject appSdkConfig = new JSONObject()
          .put("appid", "PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX")
            // Remove Flag:   "nol_devDebug": "DEBUG"

// Pass appSdkConfig to the AppSdk constructor
mAppSdk = new AppSdk(appContext, appSdkConfig, appSdkListener);
}
catch (JSONException e)
{
  Log.e(TAG, "Couldn’t prepare JSONObject for appSdkConfig", e);
}


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.