DCR & DTVR Xamarin Simplified API Integration

From Engineering Client Portal

Revision as of 03:36, 19 November 2020 by ColinBrown (talk | contribs) (ColinBrown moved page Xamarin TrackEvent Integration to DCR & DTVR Xamarin Simplified API Integration without leaving a redirect)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Engineering Portal breadcrumbArrow.png Digital breadcrumbArrow.png US DCR & DTVR breadcrumbArrow.png DCR & DTVR Xamarin Simplified API Integration

Related Topics :
Integrate Nielsen SDK in Xamarin App

Integrate Nielsen SDK Simplified Api in Xamarin App

Overview

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. 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 & 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:

  • Application launch events and how long app was running
  • Time of viewing a sub section / page in the application.

This guide will show how to use the Nielsen SDK in Xamarin applications on Android and iOS devices. We will not go into detail about what Xamarin is or how to create Apps with this Framework. If you are looking for information on this, please read the Xamarin documentation.

Note : Support for Xamarin in Nielsen SDK is available from version 8.0.0.0

Prerequisites

To start using the App SDK, the following details are required:

  • App ID (appid): Unique ID assigned to the player/site and configured by product.
  • sfcode: Unique identifier for the environment that the SDK should point to.
  • Nielsen SDK: The Nielsen SDK package contains a variety of sample players for your reference.

If you do not have any of these prerequisites or if you have any questions, please contact our SDK sales support team. Refer to Digital Measurement Onboarding guide for information on how to get a Nielsen App SDK and appid.

For more detail on the native SDKs please refer to the App integration guides available on this portal.

Implementation

This guide covers implementation covers

  • the details of integration of Nielsen SDK library into Xamarin app for iOS and Android platforms
  • the usage of the Nielsen SDK Simplified API

What we will not cover is the general setup of Xamarin applications. If you are new to Xamarin please refer to Xamarin for documentation.

For simplicity we have focused on implementing a single instance of the Nielsen SDK. Should there be the need for multiple instances developers have to add some logic for that.

Setting up your Environment

   iOS

Nielsen SDK is distributed is the form of .dll library for Xamarin. The first step is to copy NielsenIOSSDK.dll into some folder inside of the Xamarin app folder on a filesystem a make a reference to this .dll in the iOS target:

Link

Nielsens App SDK is compatible with Apple iOS versions 9.0 and above.


   Android


Link

Nielsen's App SDK is compatible with Android SDK version 4.0 and above.


Nielsen Xamarin library APIs

Nielsen SDK is initially a native framework for iOS and Android platforms. For Xamarin it is distributed as the .dll library that exports all the APIs from the native framework. Please refer to the integration guides for Nielsens native SDKs to get a deeper understanding of the technical detail.

   iOS

Nielsen iOS Xamarin library has bindings to the native Objective C Nielsen iOS dynamic framework. All the details about the Nielsen iOS SDK could be found on engineering portal page for iOS app developers.

Simplified API for the native Objective C library contains one main class NielsenEventTracker and a protocol public class NielsenEventTrackerDelegate that is used to get updates about events and errors occurred in the Nielsen SDK library.

The table below describes the binding from the native library Objective C calls to C#.

   NielsenEventTracker
Objective C API C# API Description
- (instancetype)initWithAppInfo:(id)appInfo
delegate:(id<NielsenEventTrackerDelegate>)delegate;
[Export ("initWithAppInfo:delegate:")]
public NielsenEventTracker (NSObject appInfo,
NielsenEventTrackerDelegate @delegate)
  : base (NSObjectFlag.Empty);
Used to create a new instance of the SDK object
- (void)trackEvent:(NSDictionary *)data;
[Export ("trackEvent:")]
public virtual void TrackEvent (NSDictionary data);
Use to send different data combined into one single dictionary.
@property (readonly) NSString *optOutURL;
public virtual string OptOutURL
{
    [Export ("optOutURL")]
    get;
}
Used to fetch the Nielsen opt-out web page URL.
@property (readonly) BOOL optOutStatus;
public virtual bool OptOutStatus
{
    [Export ("optOutStatus")]
    get;}
Used to retrieve the Opt-Out or Opt-In state.
@property (assign) BOOL appDisableApi;
public virtual bool AppDisableApi
{    [Export ("appDisableApi")]get;    [Export ("setAppDisableApi:")]set;}
Used to disable the SDK.
@property (readonly) NSDictionary *lastErrorDict;
public virtual NSDictionary LastErrorDict
{    [Export ("lastErrorDict")]get;}
Returns SDK error in the form of dictionary if any error has occurred.
@property (readonly) NSDictionary *lastEventDict;
public virtual NSDictionary LastEventDict
{    [Export ("lastEventDict")]get;}
Returns SDK event in the form of dictionary if any event has occurred.
@property (readonly) NSString *meterVersion;
public virtual string MeterVersion
{    [Export ("meterVersion")]get;}
Returns the current SDK version.
@property (readonly) NSString *nielsenId;
public virtual string NielsenId
{    [Export ("nielsenId")]get;}
Used to get a string defining the Nielsen ID (NUID) number for the device.
@property (readonly) NSString *demographicId;
public virtual string DemographicId
{    [Export ("demographicId")]get;}
Used to retrieve Demographic ID (Device ID) of the current device.
@property (readonly) NSString *vendorId;
public virtual string VendorId
{    [Export ("vendorId")]get;}
Used to retrieve Vendor ID.
@property (readonly) NSString *firstPartyId;
public virtual string FirstPartyId
{    [Export ("firstPartyId")]get;}
Used to retrieve First Party ID (Device ID) of the current device.
@property (assign) BOOL debug;
public virtual bool Debug
{    [Export ("debug")]get;    [Export ("setDebug:")]set;}
Used to enable/disable debug flags
   NielsenEventTrackerDelegate
Objective C API C# API Description
- (void)nielsenEventTracker:(NielsenEventTracker *)api
errorOccurred:(NSDictionary *)error;
[Export ("nielsenEventTracker:errorOccurred:")]
public virtual void ErrorOccurred
(NielsenEventTracker api, NSDictionary error);
Notifies about the last error that occurred
- (void)nielsenEventTracker:(NielsenEventTracker *)api
eventOccurred:(NSDictionary *)event;
[Export ("nielsenEventTracker:eventOccurred:")]
public virtual void EventOccurred
(NielsenEventTracker api, NSDictionary @event);
Notifies about the last event that occurred


   Android

Nielsen Android Xamarin library has bindings to the native Java Nielsen Android Jar. All the details about the Nielsen Android SDK API could be found on engineering portal page for Android app developers. It is fully applicable for Xamarin applications.

Simplified API for the native Java library contains one main class NielsenEventTracker and an interface IAppNotifier that is used to get updates about events and errors occurred in the Nielsen SDK library.

The table below describes the binding from the native library Java calls to C#.

   NielsenEventTracker
Java API C# API Description
public NielsenEventTracker(Context context, JSONObject appInfo, 
IAppNotifier notifier);
public unsafe NielsenEventTracker (Context context, JSONObject appInfo, 
IAppNotifier notifier) : base (IntPtr.Zero, 
JniHandleOwnership.DoNotTransfer);
Used to create a new instance of the SDK object
public void trackEvent(JSONObject data);
public unsafe virtual void TrackEvent (JSONObject data);
Use to send different data combined into one single json object. 
public String userOptOutURLString();
public virtual string UserOptOutURLString ();
Used to fetch the Nielsen opt-out web page URL.
public boolean getOptOutStatus();
public virtual bool OptOutStatus
{
    [Register ("getOptOutStatus", "()Z", 
    "GetGetOptOutStatusHandler")]
    get;}
Used to retrieve the Opt-Out or Opt-In state. Note: This method must not be called from main/ui thread as it will turn up to be a blocking call.
public void appDisableApi(boolean disabled);
public unsafe virtual void AppDisableApi (bool disabled);
Used to disable the SDK.
public String getLastError();
public virtual string LastError
{    [Register ("getLastError", "()Ljava/lang/String;", 
    "GetGetLastErrorHandler")]
    get;}
Returns SDK error in the form of string if any error has occurred.
public String getLastEvent();
public virtual string LastEvent
{    [Register ("getLastEvent", "()Ljava/lang/String;", 
    "GetGetLastEventHandler")]
    get;}
Returns SDK event in the form of string if any event has occurred.
public static String getMeterVersion();
public static string MeterVersion
{    [Register ("getMeterVersion", "()Ljava/lang/String;", "")]
    get;}
Returns the current SDK version.
public String getNielsenId();
public virtual string NielsenId
{    [Register ("getNielsenId", "()Ljava/lang/String;", 
    "GetGetNielsenIdHandler")]
    get;}
Used to get a string defining the Nielsen ID (NUID) number for the device. Note: Please make sure that you call this method on worker thread but not on main/ui thread.
public String getDemographicId();
public virtual string DemographicId
{    [Register ("getDemographicId", "()Ljava/lang/String;", 
    "GetGetDemographicIdHandler")]
    get;}
Used to retrieve Demographic ID (Device ID) of the current device. Note: Please make sure that you call this method on worker thread but not on main/ui thread.
public String getFirstPartyId();
public virtual string FirstPartyId
{    [Register ("getFirstPartyId", "()Ljava/lang/String;", 
    "GetGetFirstPartyIdHandler")]
    get;}
Returns First Party Id for this instance if available otherwise blank
public String getVendorId();
public virtual string VendorId
{    [Register ("getVendorId", "()Ljava/lang/String;", 
    "GetGetVendorIdHandler")]
    get;}
Returns Vendor Id if available otherwise blank
public static void setDebug(char debugState);
public unsafe static void SetDebug (char debugState);
Used to enable/disable debug flags
   IAppNotifier
Java API C# API Description
public void onAppSdkEvent(long timestamp, int code, String description);
void OnAppSdkEvent (long p0, int p1, string p2);
Method called whenever an event is to be reported from the App SDK


Library common interface

Nielsen SDK APIs are similar for both platforms iOS and Android. For cross platforms Xamarin applications it could be convenient to create a single interface than will be used in the common code of the Xamarin app. Please use our Xamarin sample application code as a reference.

public interface INielsenAnalytics
{
    // construct SDK
    void CreateNativeSDK();

    // static reporting
    void StaticForSection(string sectionName);

    // video reporting
    void PlayWithChannelName(string channelName, string mediaURL);
    void PlayheadPosition(long pos);
    void SendID3(string id3Data);
    void Stop();
    void End();

    // optout
    bool Optout(string command);

    // additional properties
    string Version { get; }
    string DemoId { get; }
    string VendorId { get; }
    string FirstPartyId { get; }
    string OptoutURL { get; }
    bool OptoutStatus { get; }
    bool MeterOn { get; set; }
}


While creating a Xamarin app instance the proper platform based implementation is provided as part of App constructor parameter:

App.xaml.cs
public partial class App : Application
{
    public static INielsenAnalytics NielsenAnalytics { get; private set; }

    public App(INielsenAnalytics nielsenAnalyticsImpl)
    {
        InitializeComponent();

        App.NielsenAnalytics = nielsenAnalyticsImpl;
        MainPage = new NavigationPage(new HomePage());
    }
}


Instance of platform specific interface implementation to be created before creating an App

   iOS
AppDelegate.cs
public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
{
    // This method is invoked when the application has loaded and is ready to run. In this 
    // method you should instantiate the window, load the UI into it and then make the window
    // visible.

    public override bool FinishedLaunching(UIApplication app, NSDictionary options)
    {
        global::Xamarin.Forms.Forms.Init();
        LoadApplication(new App(new iOSNielsenAnalytics()));

        return base.FinishedLaunching(app, options);
    }
}


   Android
MainActivity.cs
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);

        TabLayoutResource = Resource.Layout.Tabbar;
        ToolbarResource = Resource.Layout.Toolbar;

        global::Xamarin.Forms.Forms.Init(this, bundle);

        LoadApplication(new App(new AndroidNielsenAnalytics(base.ApplicationContext)));
    }
}




Platform-based implementation of this interface can be done in the platform specific code.

   iOS
public class iOSNielsenAnalytics : INielsenAnalytics
{
    public iOSNielsenAnalytics()
    {
    }

    public void CreateNativeSDK()
    {
        
    }

    
}


   Android
public class AndroidNielsenAnalytics : INielsenAnalytics
{
    
    public AndroidNielsenAnalytics(Context context)
    {
        ...
    }

    public void CreateNativeSDK()
    {
        ...
    }

    ...
}




Please note that this common interface is created just as a reference. Please extend the methods to provide more parameters into the API calls (like parameter “length” in metadata) or use a different approach if such interface does follow your application design and architecture.

SDK Initialization

Xamarin sample application creates and uses one single instance of Nielsen App SDK. This instance is created immediately on application launch and accessed using a reference to the main App object. This approach is used in order to simplify the referenced code. The latest version of the Nielsen App SDK allows instantiating multiple instances of the SDK object, which can be used simultaneously without any issue. In the real applications please create as many instances as needed according to the application architecture. It could be required to use different instances for different products like DCR Static and DCR Video. For more information on this please read the relevant App SDK Guide.

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? Example
appid Unique id for the application assigned by Nielsen. It is GUID data type. Nielsen-specified Yes 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"
sfcode Nielsen collection facility to which the SDK should connect.

Italian Clients

  • "it"
Nielsen-specified Yes "it"
nol_devDebug Enables Nielsen console logging. Only required for testing Nielsen-specified While not live "DEBUG"

SDK Initialization

Xamarin sample application creates and uses one single instance of Nielsen App SDK. This instance is created immediately on application launch and accessed using a reference to the main App object. This approach is used in order to simplify the referenced code. The latest version of the Nielsen App SDK allows instantiating multiple instances of the SDK object, which can be used simultaneously without any issue. In the real applications please create as many instances as needed according to the application architecture. It could be required to use different instances for different products like DCR Static and DCR Video. For more information on this please read the relevant App SDK Guide.

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? Example
appid Unique id for the application assigned by Nielsen. It is GUID data type. Nielsen-specified Yes 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"
sfcode Nielsen collection facility to which the SDK should connect.

Italian Clients

  • "it"
Nielsen-specified Yes "it"
nol_devDebug Enables Nielsen console logging. Only required for testing Nielsen-specified While not live "DEBUG"

Sample SDK Initialization Code

NielsenAppApi library supports multiple SDK instance creation and operations.

   iOS

This method implements CreateNativeSDK defined in INielsenAnalytics above.

Xamarin sample application uses Newtonsoft.Json.Linq module to create NSString objects with JSON.

public class iOSNielsenAnalytics : INielsenAnalytics
{
    private NielsenEventTracker appApiTE;
    private TrackEventDelegate appApiTEDelegate;

    public void CreateNativeSDK()
    {
        JObject appInfo = new JObject {
            { "appid", "PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"},
            { "nol_devDebug", "DEBUG" }
        };

        NSObject appInfoObj = NSObject.FromObject(appInfo.ToString());
        appApiTEDelegate = new TrackEventDelegate();
        appApiTE = new NielsenEventTracker(appInfoObj, appApiTEDelegate);    
    }
}


Nielsen App SDK initialiser needs an instance of a delegate class to be provided as a second parameter. This additional class needs to be inherited from NielsenEventTrackerDelegate and implement ErrorOccurred and EventOccurred API methods.

private class TrackEventDelegate : NielsenEventTrackerDelegate
{
    public TrackEventDelegate()
    {
    }

    public override void ErrorOccurred(NielsenEventTracker appApi, NSDictionary error)
    {
        Console.WriteLine(error.ToString());
    }

    public override void EventOccurred(NielsenEventTracker appApi, NSDictionary @event)
    {
        Console.WriteLine(@event.ToString());
    }
}


   Android

This class implements CreateNativeSDK defined in INielsenAnalytics above.

public class AndroidNielsenAnalytics : INielsenAnalytics
{   
    private NielsenEventTracker nielsenEventTracker;

    private IAppNotifier iAppNotifierImpl;

    public void CreateNativeSDK()
    {
        JSONObject appInfo = new JSONObject()
                .Put("appid", "PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX")
                .Put("nol_devDebug", "DEBUG");

        iAppNotifierImpl = new AppNotifierImpl();        

        nielsenEventTracker = new NielsenEventTracker(context, appInfo, iAppNotifierImpl);
    }
}


Nielsen App SDK initialiser needs an instance of a delegate class to be provided as a second parameter. This additional class needs to be implemented from IAppNotifier interface thereby implementing OnAppSdkEvent API method.

private class AppNotifierImpl : IAppNotifier
{
        public void OnAppSdkEvent(long timestamp, int code, string description)
        {
            Console.WriteLine("OnAppSdkEvent => " + description);
        }
}


SDK Instance Removal

It is allowed to create and use multiple instances of the Nielsen App SDK. But sometimes it's also important to remove the SDK instance once we are done with it.

   iOS

Xamarin.iOS has a garbage collector that will take care of releasing resources for you when they are no longer in use. In addition to the garbage collector, all objects that derive from NSObject implement the System.IDisposable interface. You can call Dispose() to immediately release NielsenEventTracker object, instead of waiting for Mono to perform a garbage collection cycle. When a managed object is disposed, it is no longer useful. You might still have a reference to the objects, but the object is for all intents and purposes invalid at this point.

If you do not keep a reference in your static or instance variables to your objects, Mono will happily call the Dispose() method on them, and they will release the reference to the object. Since this might be the only outstanding reference, the Objective-C runtime will destroy the object for you.

   Android
In Android AppSDK, we have a method -
 public virtual void Close ();
which disposes and frees all resources taken by the corresponding AppSdk object.

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.

App Sdk Api Calls

The NielsenEventTracker provides single api "trackEvent" to process all the playback metadata. Below code snippet demonstrates this

   iOS

iOS SDK uses NSDictionary objects as parameters for TrackEvent calls

...
var keys = new[] {
    new NSString("type"),
    new NSString("section")
};
var values = new[] {
    new NSString("static"),
    new NSString("homeSection")
};
var staticMetadataDict = new NSDictionary<NSString, NSObject>(keys, values);
var metadataKeys = new[] {
    new NSString("static")
};
var metadataValues = new[] {
    staticMetadataDict
};
var metadataDict = new NSDictionary<NSString, NSObject>(metadataKeys, metadataValues);

List<NSString> keysList = new List<NSString>();
keysList.Add(new NSString("event"));
keysList.Add(new NSString("type"));
keysList.Add(new NSString("metadata"));

List<NSObject> valuesList = new List<NSObject>();
valuesList.Add(new NSString("playhead"));
valuesList.Add(new NSString("static"));
valuesList.Add(metadataDict);

var keys = keysList.ToArray();
var values = valuesList.ToArray();

var teDict = new NSDictionary<NSString, NSObject>(keys, values);
nielsenEventTracker.TrackEvent(teDict);
...


   Android
...
JSONObject staticMetadata = new JSONObject()
    .Put("type", "static")
    .Put("section", "homeSection");

JSONObject metadataJSON = new JSONObject();
metadataJSON.Put("static", staticMetadata);

JSONObject trackEventJSON = new JSONObject();
trackEventJSON
    .Put("metadata", metadataJSON)
    .Put("event", "playhead")
    .Put("type", "static");
nielsenEventTracker.TrackEvent(trackEventJSON);
...

Privacy and Opt-Out

Opt-Out Implementation

To opt out, users must have access to "About Nielsen Measurement" page. User can click this page from app settings screen.

Include About Nielsen Measurement and Your Choices link in the Privacy Policy / EULA or as a button near the link to the app's Privacy Policy.

  • URL for the Nielsen Privacy web page should be retrieved from via the OptOutURL() method of the SDK and opened in 'WebView' / External browser.
  • If the returned value is null or empty, handle the exception gracefully and retry later.

The app must provide access to "About Nielsen Measurement" page for the users. Include "About Nielsen Measurement" and Your Choices link in the Privacy Policy / EULA or as a button near the link to the app's Privacy Policy.

Privacy policy iOS.jpg

  • App should provide a UI control like 'close' or 'back' button to close the 'WebView' / External browser.


Users can opt out or opt back into Nielsen Measurement. Opt-Out feature relies on iOS' system setting – "Limit Ad Tracking". The setting can be accessed in the Settings application on any iOS device: Settings → Privacy → Advertising → Limit Ad Tracking.

User is opted out of Nielsen online measurement research when the "Limit Ad Tracking" setting is enabled.

Opt-Out iOS.jpg


In Android too users can opt out or opt back into Nielsen Measurement. SDK Opt-Out has to be done via Google Settings → Ads → Opt out of Ads Personalization.

User is opted out of Nielsen online measurement research when the "Opt out of Ads Personalization" setting is enabled.

andr-ads.jpg

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.

Nuget Packages


To start using the Android App SDK in Xamarin application, the following nuget packages are required:

  • Xamarin.AndroidX.Lifecycle.Common
  • Xamarin.AndroidX.Lifecycle.Process
  • Xamarin.AndroidX.Lifecycle.LiveData
  • Xamarin.AndroidX.Browser
  • Xamarin.AndroidX.Legacy.Support.V4
  • Xamarin.Google.Android.Material
  • Xamarin.GooglePlayServices.Identity
  • Xamarin.GooglePlayServices.Ads


In AndroidManifest.xml under <application> node add the following metadata (needed for Xamarin.GooglePlayServices.Ads) -


<meta-data android:name="com.google.android.gms.ads.AD_MANAGER_APP" android:value="true" />

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_devDebug: 'DEBUG'} from initialization call.
    • Example Production Initialization Call - Refer to the production initialization call below:

Example:

   iOS
JObject appInfo = new JObject {
    { "appid", "PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"},
    { "sfcode", "dcr" },
    { "nol_devDebug", "DEBUG" }
};

NSObject appInfoObj = NSObject.FromObject(appInfo.ToString());
appApiDelegate = new TrackEventDelegate();
appApi = new NielsenEventTracker(appInfoObj, appApiDelegate);


   Android
JSONObject appInfo = new JSONObject()
                .Put("appid", "PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX")
                .Put("sfcode", "dcr"),
                .Put("nol_devDebug", "DEBUG");

AppNotifierImpl iAppNotifierImpl = new AppNotifierImpl();        

NielsenEventTracker nielsenEventTracker = new NielsenEventTracker(context, appInfo, iAppNotifierImpl);