Engineering Portal / Digital / DCR & DTVR   /  Digital Pre-Certification Checklist App SDK 
Pre-certification Checklist
Before starting the certification process, please verify the following steps have been completed.
- Your Client Service representative should have already discussed a reporting hierarchy with you -- along with a Parent, Brand, and Sub-brand/Channel
- Your Technical Account Manager should have:
- provided you with an AppID
- informed you of our Opt-Out requirement for your App/Play Store description
- informed you of our Opt-Out requirement for a WebView inside your apps
 
- Retrieving AppSDK logs
- 'nol_devDebug' : 'DEBUG' should be present in initialization call (see below)
- Android: use adb logcat (note: requires Android Studio)
- iOS: idevicesyslog (note: requires XCode)
 
Initialization
The first step in the Certification process is to ensure that the Nielsen SDK is initializing at app startup, and that the global metadata values are present.
| Keys | Value | 
| appid | XXXXX-XXXXXX-XXXXX-XXXXX | 
| appname | example app name | 
| appversion | 2.0 | 
| nol_devDebug | debug | 
iOS Example
NSDictionary* appInformation = @
{ // AppID is Nielsen-supplied
	 @"appid": @"XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
 	 @"appname": @"Sample App Name",
 	 @"appversion": @"2.0",
 	 @"nol_devDebug": @"DEBUG" // required for testing only
}
Android Example
JSONObject appSdkConfig = new JSONObject()
          .put("appid", "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX")
          .put("appname", "Sample App Name")
          .put("appversion","2.0")
          .put("nol_devDebug”, "DEBUG"); // required for testing only
// Pass appSdkConfig to the AppSdk constructor
mAppSdk = new AppSdk(appContext, appSdkConfig, appSdkListener);
Test Cases
The following lists the test cases along with the Expected results:
| Test Case | Param | Expected Result | Pass/Fail | 
| SDK Initialized | appid | Correct app id |  | 
|  | appname | Player name |  | 
|  | appversion | Correct build |  | 
|  | nol_devDebug | "DEBUG" |  | 
play()
- The play()call is required only once per viewing session (until app is killed)
- Called just before playback commences for first piece of content
| Test Case | Param | Expected Result | Pass/Fail | 
| Play | channelname | Name of Channel |  | 
loadMetadata() - Content
- Called at beginning of content, or when resuming content from interruption
| Test | Param | Example Value | Accepted Values | Pass/Fail | 
| loadMetadata | type | "content" | "content" |  | 
|  | assetid | "unique_id_500291" | (unique per asset, no Special Characters) |  | 
|  | length | "600" | length in seconds (int or float) |  | 
|  | title | "Episode Title" | (any non-empty value) |  | 
|  | program | "Show Name" | (any non-empty value) |  | 
|  | segB | "Primetime" | (any value), used for optional breakdown |  | 
|  | segC | "Comedy" | (any value), used for optional breakdown |  | 
|  | crossId1 | "EP018S9S290015" | Gracenote ID |  | 
|  | crossId2 | "ABC" | Network Name |  | 
|  | isfullepisode | "y" | ( "y"or"n") ("Y"or"N") |  | 
|  | airdate | "20160206 23:00:00" | "YYYYMMDD[space]HH:MM:SS"-- note: HH=24 hour time |  | 
|  | adloadtype | "1" | "1"for linear ads,"2"for DAI |  | 
|  | hasAds | "1" | "0"for no ads,"1"for has ads |  | 
loadMetadata() - ad
- Called at beginning of ad, or when resuming ad from interruption
| Test | Param | Example Value | Accepted Values | Pass/Fail | 
| loadMetadata | assetid | "ad_2201343201" | (any non-empty value) |  | 
|  | type | "midroll" | "preroll","midroll","postroll" | Example | 
setPlayheadPosition() - Preroll ad
- Track current position of playhead
- Starts at 0 at the beginning of ad
- Updated at least once per second
- Separate playhead position for ads and content, should accurately reflect current position in either ads or content
- Final playhead position for content must equal the length specified in loadMetadata(), followed by end() call
| Test Case | Test Condition | Pass/Fail | 
| setPlayehadPosition | Called every second |  | 
| stop() | Called at the end of Ad |  | 
loadMetadata() - Content
- Test is to validate Content metadata is the same as original metadata passed during initial loadMetadata call.
| Test | Param | Example Value | Accepted Values | Pass/Fail | 
| loadMetadata | type | "content" | "content" |  | 
|  | assetid | "unique_id_500291" | (unique per asset) |  | 
|  | length | "600" | length in seconds (int or float) |  | 
|  | title | "Episode Title" | (any non-empty value) |  | 
|  | program | "Show Name" | (any non-empty value) |  | 
|  | segB | "Primetime" | (any value), used for optional breakdown |  | 
|  | segC | "Comedy" | (any value), used for optional breakdown |  | 
|  | crossId1 | "EP018S9S290015" | Gracenote ID |  | 
|  | crossId2 | "ABC" | Network Name |  | 
|  | isfullepisode | "y" | ( "y"or"n") ("Y"or"N") |  | 
|  | airdate | "20160206 23:00:00" | "YYYYMMDD[space]HH:MM:SS"-- note: HH=24 hour time |  | 
|  | adloadtype | "1" | "1"for linear ads,"2"for DAI |  | 
|  | hasAds | "1" | "0"for no ads,"1"for has ads |  | 
setPlayheadPosition() - Content
- Track current position of playhead
- Starts at 0 at the beginning of content
- Updated at least once per second
- Separate playhead position for ads and content, should accurately reflect current position in either ads or content
- Final playhead position for content must equal the length specified in loadMetadata(), followed by end() call
| Test Case | Test Condition | Pass/Fail | 
| setPlayehadPosition | Called every second |  | 
| stop() | Called at the end of Content |  | 
stop()
- Indicates one of the following:
- Playback of content or ad was interrupted
- Reached end of ad (no parameters or metadata)
end()
- Reached the end of content (no parameters or metadata)
Interruptions
- All interruptions to playback of content or ads should trigger a call to stop(). Once the interruption is over, loadMetadata() with the same metadata should be called, followed by playheadPosition resuming from where it left off.
- Interruptions include:
- user-induced pause
- screen turned off
- app sent to background
- headphones removed (note, if app simply switches audio output from headphones to speaker without pausing, there is no need to call stop())
- alarm/call interruption
- internet connection lost (n.b. cached playback plays as normal until it expires)
 
| Test Case | Test Condition | Pass/Fail | 
| user-induced pause | stop(),loadMetadata()&playheadPosition |  | 
| screen turned off | stop(),loadMetadata()&playheadPosition |  | 
| app sent to background | stop(),loadMetadata()&playheadPosition |  | 
| headphones removed | stop(),loadMetadata()&playheadPosition |  | 
| alarm/call interruption | stop(),loadMetadata()&playheadPosition |  | 
| internet connection lost | stop(),loadMetadata()&playheadPosition |  | 
| content paused | playheadPositionis not passed |  | 
| resume content | loadMetadata()is called for content |  | 
|  | loadMetadataMis the same as original |  | 
|  | playheadPositioncontinues from resumed position |  | 
Expected SDK behavior for all interruptions:
- interruption triggers stop() call
- when content resumes, loadMetadata() is called with the same metadata that was playing previously (ad or content)
- playheadPosition() resumes from the same position before the interruption
Example session:
- 5 minutes of content played, call interruption, content resumes until end of 15 min video
Scrubbing
| Test Case | Test Condition | Pass/Fail | 
| Scrub Backward | new playhead position is accurate |  | 
|  | new playhead continues from new position |  | 
| Scrub Forward | new playhead position is accurate |  | 
|  | new playhead continues from new position |  | 
| Scrub to end | final playhead position is passed |  | 
|  | end event called at completion of content playback |  | 
| Scrub past midroll | Playhead for content stops |  | 
Midroll & Postroll Ads
| Test Case | Test Condition | Pass/Fail | 
| loadMetadata() | Called for each Ad |  | 
|  | Required Metadata is accurate |  | 
| playheadPosition | Passed every second |  | 
| stop() | called for each ad |  | 
| loadMetadata(),playheadPosition,stop() | correct sequence for each ad |  | 
Opt-Out
Users must have access to "About Nielsen Measurement" page. User can click this page from app settings screen.
- URL to this web page should be called from SDK by invoking optOutURL and opened in 'WebView' / External browser.
- If the App SDK returns NULL as Opt-Out URL, handle the exception gracefully and retry later.
- To retrieve the current Opt-Out status of a device, use the optOutStatus method.
| Test Case | Test Condition | Pass/Fail | 
| optOutView | User can Opt-Out |  |