Implementing Viewability with AppSDK

From Engineering Client Portal

Revision as of 22:06, 11 December 2017 by Admin3 (talk | contribs) (Created page with "{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|DCR & DTVR}} {{CurrentBreadcrumb}} Category:Digital == The Viewability Metric integration == === Initializing the Nie...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Engineering Portal / Digital / DCR & DTVR / Implementing Viewability with AppSDK

The Viewability Metric integration

Initializing the Nielsen AppSDK to measure the Viewability

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.

Android

# Parameter Name Description Supported Values Example
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


iOS

# Parameter Name Description Supported Values Example
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. "100"
"2131558561"

For iOS it is required to link additional frameworks that are needed for viewability engine:
JavaScriptCore.framework
WebKit.framework

The Nielsen AppSDK uses a tracking WebView (TWV) approach. The main idea is that the TWV getting injected under the player view that is found by the Nielsen AppSDK and the TWV is in a JS execution environment, where all the calculation related to views is happening. The Nielsen AppSDK injects the TWV once the playing is started. After injecting, the Nielsen AppSDK keeps tracking main properties of the player view that could be used for measuring the viewability value: the frame, alpha value, the view is hidden or not, does it have superview or not. The use of TWV is required due to the IAB Open Measurement SDK’s approach to expose the JS execution environment.

Sample SDK Initialization Code

Swift

Swift 4.0 Example: NielsenInit.swift

class NielsenInit: NSObject {
    class func createNielsenAppApi(delegate: NielsenAppApiDelegate) -> NielsenAppApi?{
    let appInformation:[String: String] = [
           "appid": "PDA7D5EE6-B1B8-XXXX-XXXX-2A788BCXXXCA",
            "appversion": "1.0",
            "appname": "app name here",
            "sfcode": "dcr",
            "containerId":"647863",
            "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",
                                     @"appversion": "1.0",
                                     @"appname": "app name here",
                                     @"sfcode": "dcr",
                                     @"containerId": "647863",
                                     @"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

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("appversion", "1.0")
          .put("appname", "Sample App Name")
          .put("sfcode", "dcr"),
          .put("containerId", "647863"),
          .put("nol_devDebug", "DEBUG"); // only for debug builds

// 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 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).

Getting the Viewability Metric data

All the Viewability Metric data is presented in D-pings of DCR and DTVR processors. The D-ping has follow parameters:

  • invs - video series
  • inau - audability series
  • inss - device screen size
  • ines - player size series
  • invp – application size series
# Parameter Name Description Supported Values Example
1 invs Video series in percentage in view values Array of arrays object {
[100, 0, 1512300013, 10],
[50, 10, 1512300023, 5]
]
2 inau Audability series in percentage values Array of arrays object {
[0, 0, 1512300013, 10],
[100, 10, 1512300023, 5]
]
3 inss Device Screen Size The string in format <width>x<height> 320x568 ]
4 ines Player size series Array of arrays object {
[“320x205”, 0, 1512300013, 10],
[“150x100”, 10, 1512300023, 5]
]
5 invp Viewport series (application size) Array of arrays object {
[“768x1024”, 0, 1512300013, 10],
[“418x768”, 10, 1512300023, 5]
]

An example of the D-ping with viewability metric data is presented below:

http://secure-cert.imrworldwide.com/cgi-bin/gn?prd=dcr&ci=APRP3&ch=APRP3_NA_P&asn=defChnAsset&sessionId=
&tl=MyEpisode&prv=1&c6=vc,NA&ca=APRP3_NA_BIG_BUNNY&cg=MyProgram
&c13=asid,TF2D48D99-9B58-B05C-E040-070AAB3176DB&c32=segA,NA&c33=segB,NA&c34=segC,NA&
c15=apn,MTVR-EXO-QA&sup=1&segment2=539&segment1=usa&forward=0&ad=1&
cr=4_00_99_D1_11111&c9=devid,2fd530f10598cd9f4b4ad8fc35f8c1cec1b78a4dae19d648bf74830a768c0902&enc=true
&c1=nuid,14f000ed61b00da1a2d443faeaf1a51870657677520fd1c1490a70f63781ddf5&at=timer&rt=video
&c16=sdkv,aa.5.1.1&c27=cln,300&crs=0&lat=&lon=&c29=plid,TF2D48D99-9B58-B05C-E040-070AAB3176DB
&c30=bldv,aa.5.1.1.28&st=dcragf&c7=osgrp,DROID&c8=devgrp,TAB&c10=plt,MBL&c40=adbid,
&c14=osver,Android7.1.1&c26=dmap,1&dd=&hrd=&wkd=&c35=adrsid,&c36=cref1,&c37=cref2,
&c11=agg,1&c12=apv,exo.5.1.1.28&c51=adl,0&c52=noad,0&sd=6000&devtypid=htc-Nexus-9
&pc=NA&c53=fef,n&c54=oad,&c55=cref3,&c57=adldf,2&ai=BIG_BUNNY&c3=st,c
&c64=starttm,1506681882&adid=BIG_BUNNY&c58=isLive,false
&c59=sesid,fOeLAlHmGtKBD2OWAtrvM2W1UzrnM1506681885&c61=createtm,1506682185&c63=pipMode,
&c62=sendTime,1506682242&c68=bndlid,com.nielsen.sampleexomtvrqa&nodeTM=&logTM=&c73=phtype,Tablet
&c74=dvcnm,Google+Nexus+9&c76=adbsnid,&df=-1&c77=adsuprt,1&evdata=PL%3A1506681882762%3A0
&c71=ottflg,0&c72=otttyp,&c44=progen,&davty=1&si=&c66=mediaurl,http%3A%2F%2Fwww.nielseninterNielsen AppSDK.com%2FBBB%2Fprog_index.m3u8&uoo=&vtoff=57&
invs=[0,1,1507579800,14],[50,15,1507579815,75],[25,90,1507579890,15],[50,105,1507579905,25],
[100,130,1507579930,150],[0,280,1507579980,25]]&inau=[[100,1,1507579800,60],[0,61,1507579860,15]
,[100,76,1507579875,200]]&invp=[["800x600",1,1507579800,200]]&inss=1920x1360&ines=
[["480x360",1,1507579800,200]]&rnd=1506682245191

Understanding the Viewability Metrics

The viewability metric introduced in Nielsen AppSDK is representing the visibility of a video in the player along a playback. The viewability metric as a whole will be broken into 5 measurements. Four of them are related to visibility values – screen size, application size (viewport), element size (player) and percentage of visibility on the screen. The last one is related to volume of the video – the mutability/volume value, so called Audability.

Almost all viewability data is presented in series type fashion except of one – the screen size. These values are tracked second by second, and each change of the concrete value is presented by the new segment inside of the array:

[<element>, , <element>], where <element>
is
[<value>, <play head of the video in seconds>, <time interval since 1970>, <duration>]


For better understanding of the approach let’s see an example: if the user in the application drags the player from 100% of the visibility beyond the bounds of the screen after 10 seconds of watching it to 50% for 5 seconds and the user changes the volume from 0 to 100 while dragging the player, the next viewability data will be created:

  • video series: [[100, 0, <timestamp>, 10], [50, 10, <timestamp + 10>, 5]]
  • audio series: [[0, 0, <timestamp>, 10], [100, 10, <timestamp + 10>, 5]]
  • viewport series: [[“320x568”, 0, <timestamp>, 15]]
  • player size series: [[“320x205”, 0, <timestamp>, 15]]
  • screen size: 320x568

For most of the cases the viewport value will match the screen size value, but there could be cases when viewport value and screen size will not be same, as example, the split screens functionality for iPad, when the application could be presented on a half of a screen when it supported. In that case the viewport value will be 2 times lesser than screen size value.


The Viewability Approach Limitations

Android

The dynamic injection logic works fine in most of the cases. However, there may be some scenarios, where this logic could break the client UI. Few of these scenarios are listed below:

1. If the client app uses a LinearLayout with android:layout_weight / android:weightSum properties used for the player view. (Possible side effect : The complete UI layout balance is disturbed and the views don't get repositioned as desired)

2. If the client app uses a RelativeLayout with and it's child views (including the player view) use the relative positioning properties like android:layout_below, android:layout_above, android:layout_toLeftOf etc. to position themselves in the view tree. (Possible side effect : The complete UI layout balance is disturbed and the views don't get repositioned as desired)

3. If the client app uses the property xmlns:android="http://schemas.android.com/apk/res/android" for any of it's intermediate ViewGroup. (Possible side effect : The target player view's parent is fetched as a wrong ViewGroup)

4. There is also a common problem, where the total child view count of the View Tree is increased as we inject the Transparent WebView and FrameLayout (wherever needed) and also the index of the views changes. If any client app has a tightly coupled logic w.r.t. these counts/indexes, it could break UI logic. Though it's less likely that the client apps would rely on these initial static counts/indexes, but still we can't say with surety that they would not rely on these values.


iOS

1. As “Player in player” functionality uses different from UIView approach (CALayer is used), the OMID library doesn't handle picture moving with layers and it doesn't recognize frame change, so it means that even if the player is on the top of the screen, it (PiP) doesn't use the view that was tagged by the user. The view stays on his previous position, so if some view will cover tagged view, and PiP view will move from it, the OMID will take obstruction into account and the viewability value will be calculated with new intersection for tagged view, not for PiP controller.

2. The next limitation is related to showing the keyboard. When the keyboard has appeared, viewability value becomes 0 because of the way of implementing the keyboard. In iOS, a keyboard getting shown using a new UIWindow object. It appears on top of the screen with the size of the screen and "hides" all views under it. Even the UIWindow object's background is transparent, OMID doesn't take it into account because of alpha value set to bigger than 0.

3. When the UIAlertController is shown, even if it has transparent background, the viewability becomes 0 because of the implementation of the controller - it covers the full screen.

4. The Reachability mode is not supported for tracking the geometry change in Application. That means that if the user double taps on Home button and the player will go beyond the screen bounds, the percentage in view value will get changed.

5. The Slide Over (the new iOS 11 functionality) is not supported.

6. The Apple TV is not supported.