DCR & DTVR iOS Adobe Launch Extension
From Engineering Client Portal
Adobe Launch Extensions
Adobe Launch Extensions are building blocks for mobile application development. The necessary functionality can be implemented independently and put to separate Extensions, but make them able to communicate using Events. These extensions live on Artifactory servers and can be used by clients who develop their mobile applications.
Nielsen AppSDK Extension
Nielsen provides the Adobe Launch Extension based on AppSDK for measuring the video/audio content. It has the name Nielsen AppSDK Extension
and is available for android and iOS mobile platforms.
Extension Installation and Configuration
Adobe has developed an Extension to simplify adding Nielsen measurement into your video stream. The first step is to create and publish a property which is outlined in the Getting Started Guide.
Configure the Extension
If the user doesn’t want to set the configuration in the code and wants to make the configuration more flexible and changeable on the fly, it can be configured through the interface. In order to do that, go to the collection of installed extensions of the property. The configuration allows to set different configuration for iOS and Android platforms:
Build the Extension
After the Extension is configured, it can be “built” under the “library” on the Publishing page with other “libraries”. It is the main step for adding the configuration to the main configuration file and to register the package under specific App Id after building it.
Add a New library
Select to add a new library
Set the name, chose Environment (Production, Staging, Development):
Save and Build
Add all changed resources. When you get the Extension configured, it will appear in the list of changed resources. Select the Latest revision and press “Select & Create a New Revision” button:
Confirm
Once built, it will appear in the list of Development libraries:
View in Library
Once it is set up, the user will be prompted to the Environments page where it can be Installed.
Obtain Mobile Installation Instructions
You will then be provided the Mobile Installation Instructions.
How to add the Nielsen AppSDK extension to a Project in iOS
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.
Initial Configuration
The Nielsen SDK integration requires Cocoapods 1.4.0. or higher. The full installation guide for this framework is provided on the Getting Started page. How to set up the Podfile is mentioned in Using Cocoapods page.
Repository Credentials
The first step is to add the credentials received from Nielsen into your .netrc file. Navigate to your home folder and create a file called .netrc
cd ~/
vi .netrc
Within this file you need to add your credentials in the following format:
machine raw.githubusercontent.com
login <Nielsen App SDK client>
password <Auth token>
Your Credentials are:
machine raw.githubusercontent.com
login NielsenSdkRepo
password edec0d01b953171c704188c1d8fc0aa4217ec506
Verify version of Cocoapods
First verify that Cocoapods is installed.
pod --version
If it is not, then install.
Install via gem
sudo gem install cocoapods
Install using homebrew
brew install cocoapods
Add Cocoapod repository
From the command line, type the following:
pod repo add NielsenAppSDKExtension https://github.com/nielsendigitalsdk/nielsenappsdkextension-ios-specs.git
Please note, you must also add the repo source into your podfile. (See examples below) Make sure you run the pod init command in your project's directory.
pod init
You now need to slightly modify the PodFile that was created in this directory. The following must be in the PodFile:
Podfile
platform :ios, '11.0'
source 'https://github.com/NielsenDigitalSDK/nielsenappsdkextension-ios-specs.git'
source 'https://github.com/CocoaPods/Specs.git'
target 'YourTargetsNameHere' do
#Pods for ApplicationTarget
pod 'NielsenAppSDKExtension'
end
Once that has been edited, you can now execute the install:
pod install
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 NielsenAppSDKExtension framework.
Open the file with the extension of .xcworkspace
file using Xcode.
Integration
As per integration requirements provided by Adobe, the Extension object can be registered and created only once, and its instance is not accessible from the outside - the ACPCore keeps and doesn’t expose it.
Swift
ACPCore.setLogLevel(.debug)
ACPCore.setPrivacyStatus(.optIn)
do {
NielsenAppSDKExtension.registerListener(forSDKNotifier: NielsenAppSDKEventListener.self)
try ACPCore.registerExtension(NielsenAppSDKExtension.self)
} catch (let exception) {
print("Exception: \(exception)")
}
ACPCore.configure(withAppId: "Your Adobe Launch Property Key")
ACPCore.start {}
Objective-C
[ACPCore setLogLevel:ACPMobileLogLevelDebug];
[ACPCore setPrivacyStatus:ACPMobilePrivacyStatusOptIn];
NSError *error = nil;
:
[NielsenAppSDKExtension registerListenerForSDKNotifier:NielsenAppSDKEventListener.class];
[ACPCore registerExtension:NielsenAppSDKExtension.class error:&error];
if (error)
{
NSLog(@"%@", error);
}
[ACPCore configureWithAppId:@"Your Adobe Launch Property Key"];
[ACPCore start:^{}];
Communication
The communication with the Extension happens by two separate flows: API and Events. The first one just redirects Extension’s class-access methods to direct instances of the NielsenAppSDK. The second one works with ACPCore’s EventHub - the core of the extension. Through the Hub the Core receives all the events and notifies the listeners if they are subscribed for them.
NOTE: be aware of mixing the approaches. Because of different architectures for API approach and Event approach (and the asynchronous nature of Events), it is not guaranteed that events and API will be handled in order of their call.
The list of APIs (the meaning of each event and API is described later in this document)
Public APIs exposed by extension
+ (NSDictionary *)instantiateSDKWithConfiguration:(NSDictionary *)configuration;
+ (NSDictionary *)instantiateSDKWithRemoteConfiguration;
+ (NSDictionary *)removeSDKWithIdentifier:(NSString *)identifier;
+ (NSDictionary *)trackEvent:(NSDictionary *)event forSDKWithIdentifier:(NSString *)identifier;
+ (NSDictionary *)optOutStatusForSDKWithIdentifier:(NSString *)identifier;
+ (NSDictionary *)appDisableForSDKWithIdentifier:(NSString *)identifier;
+ (NSDictionary *)setAppDisable:(BOOL)appDisable forSDKWithIdentifier:(NSString *)identifier;
+ (NSDictionary *)debugForSDKWithIdentifier:(NSString *)identifier;
+ (NSDictionary *)setDebug:(BOOL)debug forSDKWithIdentifier:(NSString *)identifier;
+ (NSDictionary *)demographicIdForSDKWithIdentifier:(NSString *)identifier;
+ (NSDictionary *)optOutURLForSDKWithIdentifier:(NSString *)identifier;
+ (NSDictionary *)meterVersionForSDKWithIdentifier:(NSString *)identifier;
+ (void)registerListenerForSDKNotifier:(Class)aClass;
Events
- InstantiateSDKWithLocalConfigEvent
- InstantiateSDKWithRemoteConfigEvent
- RemoveSDKInstanceEvent
- TrackSDKEvent
- GetOptoutStatusEvent
- GetAppDisableEvent
- SetAppDisableEvent
- GetDebugEvent
- SetDebugEvent
- GetDemographicIdEvent
- GetOptoutURLEvent
- GetMeterVersionEvent
In order to fire the event, the next API of the ACPCore should be used:
NSError *error = nil;
NSString *name = @"...";
NSString *type = @"com.nielsen.eventType.instanceControl";
NSString *source = @"com.nielsen.eventSource.instanceControl";
NSDictionary *payload = @{
"identifier": "the identifier under which the instance is kept"
or
"data": {"appid":"...", ...}
};
ACPExtensionEvent *newEvent = [ACPExtensionEvent extensionEventWithName:name
type:type
source:source
data:payload
error:&error];
if (error)
{
NSLog(@"Error constructing new event %@:%ld", [error domain], (long)[error code]);
return;
}
[ACPCore dispatchEventWithResponseCallback:newEvent
responseCallback:^(ACPExtensionEvent * _Nonnull responseEvent) {
//Use responseEvent.eventData to collect the result data
} error:&error];
if (error)
{
NSLog(@"Error dispatching event %@:%ld", [error domain], (long)[error code]);
}
The Extension listens for specific events’ type and source and handles specific event names differently. The API and Event flows are mirroring each other. And they are mirroring NielsenAppSDK’s api.
Result
The result format that is returning with API flow and with Event flow is the same for both flows - this is a JSON object.
It consists of the result code, description and the identifier. { ‘identifier’ : ‘...’, //might not be there if the “remove” API or Event is made ‘code’ : 5001, ‘description’ : ‘...’ }
Possible error codes are:
typedef NS_ENUM(NSUInteger) {
NielsenAppSDKExtensionResultCodeSuccess = 5001,
NielsenAppSDKExtensionResultCodeUnexpected = 5002,
NielsenAppSDKExtensionResultCodeNoRemoteConfiguration = 5003,
NielsenAppSDKExtensionResultCodeNoLocalConfiguration = 5004,
NielsenAppSDKExtensionResultCodeMissingParameter = 5005,
NielsenAppSDKExtensionResultCodeSDKInstantiationFailure = 5006,
NielsenAppSDKExtensionResultCodeNoSDKInstance = 5010,
NielsenAppSDKExtensionResultCodeExceptionOccured = 5011,
NielsenAppSDKExtensionResultCodeInvalidEventReceived = 5012
} NielsenAppSDKExtensionResultCode;
API and Events description
Instantiating the SDK
NielsenAppSDK can support multiple instances, and not to lose this feature, the Extension keeps SDK instances by the identifiers. When the user requests to create the instance, the Extension instantiates it and returning back the identifier which the user will use for further SDK control.
There are two ways of initializing the SDK with configuration: the configuration provided in the code and configuration that is set up on the Adobe Launch panel of your property.
To support four flows (API, Events, Local Configuration and the Remote Configuration) the next APIs and events are introduced:
NSDictionary *result = [NielsenAppSDKExtension instantiateSDKWithConfiguration:@{"appid":"...", "sfcode":"..."}]
NSDictionary *result = [NielsenAppSDKExtension instantiateSDKWithRemoteConfiguration]
"InstantiateSDKWithLocalConfigurationEvent"
"InstantiateSDKWithRemoteConfigurationEvent"
To provide the configuration for “InstantiateSDKWithLocalConfigurationEvent” event, put the configuration under the “data” key in the JSON object:
{
"data" : {"appid":"...", "sfcode":"..."}
}
JSON Initialization Data
The following table contains the list of arguments that should be passed during initialization.
- The appid is provided by the Nielsen Technical Account Manager (TAM).
Parameter / Argument | Description | Source | Required? | Example |
---|---|---|---|---|
appid | Unique id for the application assigned by Nielsen.
It is GUID data type, provided by the Nielsen Technical Account Manager (TAM). |
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.
DTVR
Digital Audio
DCR
|
Nielsen-specified | Yes | "dcr" |
containerId | View ID of the UI element used as player view in application for Viewability (Future Feature) | Client-defined | No | "1234567" |
nol_devDebug | Enables Nielsen console logging. Only required for testing | Nielsen-specified | Optional | "DEBUG" |
Sample SDK Initialization Code
Initialization of App SDK object through a JSON object
appInformation = new JSONObject()
.put("appid", "PDA7D5EE6-B1B8-4123-9277-XXXXXXXXXXXX")
.put("appversion", "1.0")
.put("sfcode", "dcr")
.put("uoo", "0")
.put("nol_devDebug", "DEBUG");
The result of those APIs and events is a JSON object. It returns the identifier string under which a newly created instance is kept. Use the identifier to make further calls to control the NielsenAppSDK.
Removing the SDK instance
In order to remove the instance that the Extension is keeping, call the remove API or fire an event with providing the identifier.
NSDictionary *result = [NielsenAppSDKExtension removeSDKWithIdentifier:@"the identifier under which instance is kept"]
"RemoveSDKInstanceEvent"
To provide the identifier for “RemoveSDKInstanceEvent” event, put the configuration under the “identifier” key in the JSON object:
{
"identifier" : "the identifier under which instance is kept"
}
All result returned are in JSON object
Tracking the SDK Event
To track NielsenAppSDK’s event call the track SDK Event API or fire an event with providing the identifier.
NSDictionary *result = [NielsenAppSDKExtension trackSDKEvent:@{"event":"playhead", "playheadPosition":"0", ...}
forSDKWithIdentifier:@"the identifier under which instance is kept"]
Event Types
The following event types are supported:
Key | Description |
---|---|
playhead |
It is used to pass content, ad or static metadata, the current playhead value, Unix timestamp or id3 payload, OTT information to the SDK. |
pause |
This event should be used to in the following cases: application enters background, any application interruptions, content playback is paused. (Pause is detected by SDK automatically only if the time gap between commands exceeds 30 minutes.) |
complete |
It is called when session is completed or ends. |
adStop |
This event should be called at the end of each ad and is required when advertisements have the same assetId. |
To provide the identifier for “TrackSDKEvent” event, put the identifier under the “identifier” key in the JSON object and the event metadata:
{
"identifier" : "the identifier under which instance is kept",
"data" : {"event":"playhead", "playheadPosition":"0", ...}
}
Handling JSON Metadata
Parameter “data” is a JSON object with many key-value pairs that holds all information required by SDK.
Format of input object is the following:
{
"event": <event identifier>,
"type": <type of metadata>,
"metadata":{
"content": <content metadata object>,
"ad": <ad metadata object>,
"static": <static metadata object>
},
"playheadPosition":<playhead value | Unix Timestamp>,
"id3Data": <id3 payload>,
}
DCR
Digital Content Ratings
Parameter | Description | Supported values | Example |
---|---|---|---|
event | Event identifier |
|
"event":"playhead"
|
type | Determines the metadata object
that should be used for crediting. |
|
"type":"content"
|
metadata | Object that holds metadata values of specific types Detailed in tables below |
Object
|
"metadata":{
"content": <content metadata object>,
"ad": <ad metadata object>,
"static": <static metadata object>
},
|
playheadPosition | Playhead value as reported by video player. Unix timestamp (seconds since Jan-01-1970 UTC) for live video. |
String
|
Position value is Unix timestamp (live):
Position value is playhead:
|
Content Metadata
Content metadata sent for every playheadposition update.
Keys | Description | Example | Required |
---|---|---|---|
assetName | name of program (100 character limit) | "MyTest789" |
Yes |
assetid | unique ID assigned to asset | custom | Yes |
length | length of content in seconds | seconds (0 for live stream or unknown) |
Yes |
program | name of program (100 character limit) | custom | Yes |
segB | custom segment B ¹ | custom | |
segC | custom segment C ¹ | custom | |
title | name of program (100 character limit) | custom | Yes |
type | 'content', 'ad', 'static' |
'content' |
Yes |
section | Unique Value assigned to page/site section | HomePage | Yes |
airdate | the airdate in the linear TV ² | YYYYMMDD HH24:MI:SS | Yes |
isfullepisode | full episode flag | "y" - full episode, "n" - non full episode |
Yes |
crossId1 | standard episode ID | custom | ✓ |
crossId2 | content originator (only required for distributors) | Nielsen provided | |
adloadtype | linear vs dynamic ad model | 1=Linear
2=Dynamic Ads |
custom |
¹ 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.
² Acceptable Air Date Formats:
YYYYMMDD HH24:MI:SS
YYYYMMDDHH24MISS
YYYY-MM-DDTHH:MI:SS
YYYY-MM-DDHH:MI:SS
YYYYMMDDHH:MI:SS
MM-DD-YYYY
YYYYMMDD HH:MI:SS
For USA all times should be EST, for all other countries Local Time.
Below is a sample event for DCR. If no ad or static values, these can be left as blank/null.
{
"event": "playhead",
"type": "content",
"metadata": {
"content":{
"assetName":"Big Buck Bunny",
"assetid":"B66473",
"length":"3600",
"program":"MyProgram",
"segB":"CustomSegmentValueB",
"segC":"segmentC",
"title":"S2,E3",
"type":"content",
"section":"cloudApi_app",
"airdate":"20180120 10:00:00",
"isfullepisode":"y",
"crossId1":"Standard Episode ID",
"crossId2" :"Content Originator",
"adloadtype":"2"},
"ad": {},
"static": {}
},
"playheadPosition": "",
}
DTVR
Digital TV Ratings info
Parameter | Description | Supported values | Example |
---|---|---|---|
event | Event identifier |
|
"event":"playhead"
|
type | Determines the metadata object that should be used for crediting. |
|
"type":"content"
|
adModel | linear vs dynamic ad model | 1=Linear
2=Dynamic Ads |
custom |
channelName | Any string representing the.channel/stream | Object
|
custom |
playheadPosition | Playhead value or Unix timestamp (seconds since Jan-01-1970 UTC) | String
|
Position value is Unix timestamp:
Position value is playhead:
|
id3Data | Nielsen ID3 payload | String
|
|
Below is a sample event for DTVR. If no ad or static values, these can be left as blank/null.
{
"event": "playhead",
"type": "content",
"metadata": {
"content":{
"adModel":"1",
"channelname":"channel1"
},
"ad": {},
"static": {}
},
"playheadPosition": "",
"id3Data": "www.nielsen.com/065H2g6E7ZyQ5UdmMAbbpg==/_
EMc37zfVgq_8KB7baUYfg==/ADQCAmgV1Xyvnynyg60kZO_Ejkcn
2KLSrTzyJpZZ-QeRn8GpMGTWI7-HrEKzghxyzCyBEoIDv2kA2g1Q
JmeYOl5GnwfrLDVK2bNLTbQxr1z9VBfxahBcQP5tqbjhyMzdVqrMK
uvvJO1jhtSXa9AroChb11ZUnG1WVJx2O4M=/33648/22847/00"
}
DCR & DTVR
Applies to DCR and DTVR
Parameter | Description | Supported values | Example |
---|---|---|---|
event | Event identifier |
|
"event":"playhead"
|
type | Determines the metadata object that should be used for crediting. |
|
"type":"content"
|
metadata | Object that holds metadata values of specific types Detailed in tables below |
Object
|
"metadata":{
"content": <content metadata object>,
"ad": <ad metadata object>,
"static": <static metadata object>
},
|
playheadPosition | Playhead value or Unix timestamp (seconds since Jan-01-1970 UTC) | String
|
Position value is Unix timestamp:
Position value is playhead:
|
id3Data | Nielsen ID3 payload | Object
|
|
ottData | Object that holds OTT information | Object
|
"ottData": {
"ottStatus": 1,
"ottType": casting,
"ottDevice": chromecast,
"ottDeviceID": 1234
}
|
Content Metadata
Content metadata sent for every playheadposition update.
Keys | Description | Example | Required |
---|---|---|---|
length | length of content in seconds | seconds (0 for live stream) |
Yes |
type | "content", "ad", "static" |
"content" |
Yes |
adModel | linear vs dynamic ad model | 1=Linear
2=Dynamic Ads |
custom |
adloadtype | DCR Ad Model | 1=Linear
2=Dynamic Ads |
custom |
+ 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.
++ Acceptable Air Date Formats:
YYYYMMDD HH24:MI:SS
YYYYMMDDHH24MISS
YYYY-MM-DDTHH:MI:SS
YYYY-MM-DDHH:MI:SS
YYYYMMDDHH:MI:SS
MM-DD-YYYY
YYYYMMDD HH:MI:SS
Below is a sample event for DCR/DTVR joint integration. If no ad or static values, these can be left as blank/null.
{
"event": "playhead",
"type": "content",
"metadata": {
"content":{
"type":"content",
"length":"0",
"adModel":"1",
"adloadtype":"1"},
"ad": {},
"static": {}
},
"playheadPosition": "",
"id3Data": "www.nielsen.com/065H2g6E7ZyQ5UdmMAbbpg==/_
EMc37zfVgq_8KB7baUYfg==/ADQCAmgV1Xyvnynyg60kZO_Ejkcn
2KLSrTzyJpZZ-QeRn8GpMGTWI7-HrEKzghxyzCyBEoIDv2kA2g1Q
JmeYOl5GnwfrLDVK2bNLTbQxr1z9VBfxahBcQP5tqbjhyMzdVqrMK
uvvJO1jhtSXa9AroChb11ZUnG1WVJx2O4M=/33648/22847/00"
}
Retrieving the Opt Out Status
To get the opt out/opt in status, call according API or fire an event with providing the identifier.
NSDictionary *result = [NielsenAppSDKExtension optOutStatusForSDKWithIdentifier:@"the identifier under which instance is kept"]
"GetOptoutStatusEvent"
To provide the identifier for "GetOptoutStatusEvent" event, put the identifier under the “identifier” key in the JSON object:
{
"identifier" : "the identifier under which instance is kept"
}
The result of those APIs and events is a JSON object. The status is provided in the json object under the “optout_status” key:
{
"optout_status" : 0 or 1,
...}
Enabling and disabling the SDK
The user is able to get the SDK disabled if he doesn’t want to use its functionality. To use it, the disable API or Event should be made. To get the status, call API or fire an Event for getting the status.
NSDictionary *result = [NielsenAppSDKExtension setAppDisable:YES/NO forSDKWithIdentifier:@"the identifier under which instance is kept"]
NSDictionary *result = [NielsenAppSDKExtension appDisableForSDKWithIdentifier:@"the identifier under which instance is kept"]
"SetAppDisableEvent"
"GetAppDisableEvent"
To provide the identifier for "SetAppDisableEvent” event, put the identifier under the “identifier” key in the JSON object and if it is needed to disable the SDK, provide the value of 1 for “app_disable” key:
{
"identifier" : "the identifier under which instance is kept"
}
To retrieve the status just provide the identifier in the object for the "GetAppDisableEvent" event:
{
"identifier" : "the identifier under which instance is kept"
}
The status for "GetAppDisableEvent" event is provided in the json object under the “app_disable” key:
{
"app_disable" : 0 or 1,
}
Setting Debug mode for the SDK
The user is able to set the debug mode of the SDK to write debug logs into file. To use it, the debug API or Event should be made. To get the status, call API or fire an Event for getting the status.
NSDictionary *result = [NielsenAppSDKExtension setDebug:YES/NO forSDKWithIdentifier:@"the identifier under which instance is kept"
NSDictionary *result = [NielsenAppSDKExtension debugForSDKWithIdentifier:@"the identifier under which instance is kept"]
"SetDebugEvent"
"GetDebugEvent"
To provide the identifier for “SetDebugEvent” event, put the identifier under the “identifier” key in the JSON object and if it is needed to change the mode of the SDK to debug, provide the value of 1 for “debug” key:
{
"identifier" : "the identifier under which instance is kept",
"debug" : 0 or 1
}
To retrieve the status just provide the identifier in the object for the “GetDebugEvent” event:
{
"identifier" : "the identifier under which instance is kept"
}
Retrieving the Demographic Identifier
To get the demographic identifier, call according API or fire an event with providing the identifier.
NSDictionary *result = [NielsenAppSDKExtension demographicIdForSDKWithIdentifier:@"the identifier under which instance is kept"]
"GetDemographicIdEvent"
To provide the identifier for “GetDemographicIdEvent” event, put the identifier under the “identifier” key in the JSON object:
{
"identifier" : "the identifier under which instance is kept"
}
The result of those APIs and events is a JSON object. The demographic identifier is provided in the json object under the “demographic_id” key:
{
"demographic_id" : "the demographic identifier",
...
}
Retrieving the OptOut URL
To get the opt out URL, call according API or fire an event with providing the identifier.
NSDictionary *result = [NielsenAppSDKExtension optOutURLForSDKWithIdentifier:@"the identifier under which instance is kept"]
"GetOptoutURLEvent"
To provide the identifier for “GetOptoutURLEvent” event, put the identifier under the “identifier” key in the JSON object:
{
"identifier" : "the identifier under which instance is kept"
}
The result of those APIs and events is a JSON object. The opt out URL is provided in the json object under the "optout_url" key:
{
"optout_url" : "https://optout.url",
...
}
Retrieving the SDK Version
To get the SDK version, call according API or fire an event with providing the identifier.
NSDictionary *result = [NielsenAppSDKExtension meterVersionForSDKWithIdentifier:@"the identifier under which instance is kept"]
"GetMeterVersionEvent"
To provide the identifier for "GetMeterVersionEvent" event, put the identifier under the “identifier” key in the JSON object:
{
"identifier" : "the identifier under which instance is kept"
}
The result of those APIs and events is a JSON object. The version of the SDK is provided in the json object under the "meter_version" key:
{
"meter_version" : "version of the meter",
...}
Listening for NielsenAppSDK error events
If something happening in the internal kitchen of the SDK, it is always useful to get this information and use it. In order to achieve this, the Extension fires specific event to the EventHub, so user from the outside is able to listen to it and get the info. The listener can be built as standard ACPExtensionListener child of the ACPCore framework.
Once the class is created and the “hear” method is implemented, the listener can be registered by the NielsenAppSDKExtension using next API:
[NielsenAppSDKExtension registerListenerForSDKNotifier:NielsenAppSDKEventListener.class]
As per the architecture of the ACPCore, user doesn’t have access to the instance of the EventListener. But in order to be able to show a result somewhere, write to specific file, and so forth, he might fire Notification so the observers will be notified about the error happened (for example, a File Manager that will write the error to the file.
PLEASE NOTE: Ensure that you’re making the handling of the event asynchronously from the current thread. The reason is, the EventHub’s thread looks for the time of handling the event, and if it exceeds 100ms, it marks the handling as unsuccessful
@implementation NielsenAppSDKEventListener
- (void)hear:(ACPExtensionEvent *)event
{
dispatch_async(dispatch_get_main_queue(), ^{
NSNotification *notification = [NSNotification notificationWithName:@"NielsenAppSDKEventNotification" object:nil userInfo:event.eventData];
[NSNotificationCenter.defaultCenter postNotification:notification];
});
}
@end