Manual for iOS SDK

Introduction

Dialogue Ads allow users to engage with ads using voice commands. While listening to music or a stream, an ad user can speak various voice commands which will be introduced to users within the ad creative. When a user says ‘skip it’, ‘next’, ‘cancel’, ‘not interested’, etc, we stop serving the current ad and play the next one if there is one scheduled.

When a user engages with the ad, we perform the requested action, e.g. open browser, playing a successive audio with ‘more details’, etc.

Actions can be ‘positive’ when users want to ‘know more’ or make a purchase or ‘negative’ when users say ‘no’ or ‘I’m not interested’.

First, you need to add "Privacy - Microphone Usage Description" flag to info.plist in order to prevent future app crashes. Then, use the code below in order to set up the microphone access request.

//
// ViewController.m
// AdmanUi
//
// Created by test name on 12/13/16.
// Copyright В© 2016 Unisound. All rights reserved.
//
#import <AVFoundation/AVFoundation.h>
#import <UIKit/UIKit.h>
@interface DialogSampleController : UIViewController
@end
@interface DialogSampleController ()
@end
@implementation DialogSampleController
- (void)viewDidLoad {
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (void) showRequestInfoDialog
{
if ([[AVAudioSession sharedInstance] recordPermission] == AVAudioSessionRecordPermissionGranted)
return;
if ([[AVAudioSession sharedInstance] recordPermission] == AVAudioSessionRecordPermissionDenied ||
[[NSUserDefaults standardUserDefaults] objectForKey:@"admanLastMicroPermissionNotifyDate"] != nil) {
NSDate *lastNotifyDate = [[NSUserDefaults standardUserDefaults] objectForKey:@"admanLastMicroPermissionNotifyDate"];
NSDateComponents *diff = [[NSCalendar currentCalendar] components:NSCalendarUnitDay fromDate:lastNotifyDate toDate:[NSDate new] options:NSCalendarWrapComponents];
if ([diff day] <= 6)
return;
UIAlertController * alert = [UIAlertController
alertControllerWithTitle:@"Microphone for voice ads control disabled."
message:@"If you want to enable advertising voice control allow microphone permission in Settings for this app."
preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction
actionWithTitle:@"Ok"
style:UIAlertActionStyleDefault
handler:nil]];
[self presentViewController:alert animated:NO completion:nil];
return;
}
UIAlertController * infoDialog = [UIAlertController
alertControllerWithTitle:@"Now you can control advertising with your voice."
message:@"That includes skipping ads, learning more and other useful commands. Do you want to enable advertising voice control?"
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* noButton = [UIAlertAction
actionWithTitle:@"No"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSDate *today = [NSDate new];
[defaults setObject:today forKey:@"admanLastMicroPermissionNotifyDate"];
[defaults synchronize];
}];
UIAlertAction* yesButton = [UIAlertAction
actionWithTitle:@"Yes"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
[[AVAudioSession sharedInstance] requestRecordPermission:^(BOOL permission) {}];
}];
[infoDialog addAction:noButton];
[infoDialog addAction:yesButton];
[self presentViewController:infoDialog animated:NO completion:nil];
}
@end

Please see video below for the implementation example:

Implementation

Cocoapods
Manual Implementation
Open Source Version

If you are using CocoaPods you should add the following to a podfile:

pod 'Adman'

Then, 'pod update' command should be used to update all the libraries from the podfile, including our SDK and 'pod update Adman' should be used to update our SDK only.

To install the SDK manually, please download it using this link (AFNetworking 3.0 and SocketRocket and google/promises shared libraries required.)

The recent version of SDK is 2.16.12

The open-source version of SDK can be found HERE . Please note, that any change in the code will affect the performance and revenue.

The recent version of SDK is 2.16.12

Integration Example

For the sample of integration, please find the code example below. (In this example our SDK is used to run an ad every 90 seconds):

Please note, that Demo project you can find in open source version shouldn't be used for integration. The aim of the project is to demonstrate the technology. It shouldn't be inserted to the application in any way.

#import <AVFoundation/AVPlayer.h>
#import <UIKit/UIKit.h>
#import <Adman_framework/Adman.h>
#import <Adman_framework/AdmanUIBase.h>
@interface ViewController : UIViewController<AdmanDelegate>
@end
@interface ViewController ()
@property Adman *adman;
@property AVPlayer *player;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// init media player
_player = [AVPlayer playerWithURL:[NSURL URLWithString:@"https://playlist.pls"]];;
// init libAdman
_adman = [Adman sharedManagerWithSiteId:1063 region:AdmanRegionGlobal testMode:false];
_adman.delegate = self;
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[_player setVolume:1.0];
// init ads preloading
[_adman prepareWithType:AdmanTypeAny];
// start audio playback
[_player play];
// play ads each 90 seconds
[NSTimer timerWithTimeInterval:90 repeats:YES block:^(NSTimer *timer) {
// report can_show stat event
[self.adman reportAdEvent:@"can_show"];
// start ad playback
if (self.adman.state == AdmanStateReadyForPlayback) {
AdmanUIBase *admanUI = [[AdmanUIBase alloc] init];
[admanUI show:self];
[self.adman play];
}
}];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (void)admanStateDidChange:(Adman *)sender {
switch (sender.state) {
case AdmanStateAdChangedForPlayback:
break;
case AdmanStatePlaying:
break;
case AdmanStatePlaybackCompleted:
[_player play];
[_adman prepareWithType:AdmanTypeAny];
break;
case AdmanStateFetchingInfo:
break;
case AdmanStateVoiceInteractionStarted:
break;
case AdmanStateStopped:
case AdmanStateVoiceInteractionEnded:
break;
case AdmanStateVoiceResponsePlaying:
break;
case AdmanStateReadyForPlayback:
break;
case AdmanStateError:
case AdmanStateAdNone:
[_player play];
[_adman prepareWithType:AdmanTypeAny];
break;
default:
break;
}
}
@end

How it work?

Here is a detailed explanation of how our Dialogue Ads SDK for iOS works:

Ad Request

After importing the library, you need to create a class instance to control the advertisement:

_adman = [Adman sharedManagerWithSiteId:1063 region:AdmanRegionGlobal testMode:false];

In this case, 1063 is a publisher ID. We use 1063 for testing purposes only. The value for region will be different for different publishers. Please ask our representatives for your value. In this manual we are using 'Global' , but for EU server you should use 'AdmanRegionEU' . Please, do not change the server during the initial integration.

To fetch Dialogue ads from ad server you should use:

[_adman prepareWithType:AdmanTypeVoice];

If you need to work with Dialogue ads and Audio ads simultaneously you should use:

[_adman prepareWithType:AdmanTypeAny];

If an ad request is completed correctly, the state of Adman object will be changed. This occurs every time the state of Adman object is changed:

- (void)stateDidChange:(Adman *)sender

The above method will be called and you can check it using:

sender.state == AdmanStateReadyForPlayback

Here is the list of possible values:

Value

Description

AdmanStateInitial

Initial state for the library

AdmanStateFetchingInfo

Library is fetching the ad info

AdmanStateReadyForPlayback

Ad is ready for playback

AdmanStatePlaying

Ad is playing

AdmanStatePaused

Ad is paused

AdmanStatePlaybackCompleted

Creative playback completed

AdmanStateStopped

Ad finished playing

AdmanStatePreloading

Ad is preloading

AdmanStateAdNone

No ad for the certain listener

AdmanStateError

Error (network error, ad server error, etc)

AdmanStateVoiceInteractionStarted

Microphone is turned on and waiting for a response

AdmanStateVoiceResponsePlaying

The AI response is playing

AdmanStateVoiceInteractionEnded

Response received and microphone is turned off

Please note, that in case of "AdNone" or "Error" you need to return the user to the content and stop ad playback.

If there is an ad available for playback, then playback should be started. Before starting the playback, the following method should be called:

[adman reportAdEvent:@"can_show"];

You need to call [adman reportAdEvent:@"can_show"]; in any case when you're supposed to play an ad, even if you haven't received any. The method should be called at any possible ad placement in the app. This is very important and will dramatically affect the revenue. Please, see the example below for reference.

Ad Playback

First of all, advertising audio files and banner (in case of presence of a banner) will be cached. Then our SDK will call statistic pixels in order to report that ad request was made and ad was received successfully. Then, the following method must be used:

AdmanUIBase *admanUI = [[AdmanUIBase alloc] init];
[admanUI show:self];
[self.adman play];

Please note, that DefaultView will automatically start ad playback when autoPlay:true is used. So, no need to use (void)play method to start playback. This view is recommended for the best user experience.

On ad start Adman state will be changed to AdmanStatePlaying and start event will be reported by calling the corresponding statistic pixel and the Teaser audio will be delivered. At the end of Teaser audio, our SDK will activate the device microphone in order to receive a voice response from the listener. The microphone will remain active for 4 seconds. After 3 seconds, the microphone will be disabled and all the recorded material will be sent to Instreamatic recognition server. If the response was shorter than 3 seconds, our voice activity detection technology will handle it, and microphone will be turned off before 3 sec mark.

Depending on the recognition result, our SDK will perform the following actions:

  • Will deliver a second audio component;

  • Will open a link in the browser;

  • Will initiate a phone call;

  • Will deliver an AI response if user wasn’t interested in the ad subject.

In cases when a response wasn’t interpreted in the context of an actual ad, a listener will be asked to repeat the response. A listener will be able to reply once again, and then ad playback will be stopped.

In cases, when voice recognition server sensed silence or unknown noises, AI response will be played and app user will be returned to content.

In case of successful interpretation of a listener response or silence, Adman states will be changed in the following order:

In case of an unsuccessful interpretation of a listener response, Adman states will be changed in the following order:

After the ad, listener should be returned to content.

Instance Methods Reference

Please contact us before using any additional methods!

- (void)prepare;
- (void)prepareWithType:(AdmanType)type;

These methods used to send a request to the ad server to get an ad. If succeed it starts to buffer an audio and caching of companion banner (if exists). Please see below for possible values of 'type'

Value

Description

AdmanTypeAudioOnly

Requests audio-only ads

AdmanTypeAudioPlus

Requests audio ads with companion banner

AdmanTypeVoice

Requests only Dialogue Ads

AdmanTypeAny

Requests ads on any type

_______________________________________________________________________________

To enable DTMF ads detection, the below method can be used:

- (void)enableDtmfAdsDetectionForStation:(nonnull NSString *)name preload:(BOOL)preload vc:(nullable UIViewController *)vc;

Please note, that the above method shouldn't be used if your app is not working with DTMF ad insertion.

Parameter

Description

name

Radio station name, should be provided by publisher before the integration (along with the other DTMF parameters)

preload

To enable automatic ad preloading

vc

ViewController for the default SDK banner view

To disable DTMF detection, please use the below method:

- (void) disableDtmfAdsDetection;

_______________________________________________________________________________

To report Ad Events for tracking use the following:

- (void)reportAdEvent:(nonnull NSString *)eventName;

Please note that you shouldn't use this method if you are using showDefaultView

eventName is a VAST-specific event name (See https://www.iab.com/guidelines/digital-video-ad-serving-template-vast-3-0 for more information about ad event names). First eventName letter should be always in lowerCase (e.g creativeView, clickTracking)

_______________________________________________________________________________

Please, contact us before using the below methods instead of showDefaultView

Ad playback:

- (void)play;

Ad pause:

- (void)pause;

Ad resume (after the pause):

- (void)resume;

Ad stop:

- (void)stop;

_______________________________________________________________________________

To send data for targeting, the below method can be used

- (void)setAdvertisingInfo:(AdmanAdvertisingOptions *)params;

This method must be used before prepare.

Usage example:

[adman setAdvertisingInfo:[[AdmanAdvertisingOptions alloc] initWithParams:@"71f4e05e10d2757e" gender:AdmanGenderMale age:47]];
[adman setAdvertisingInfo:[[AdmanAdvertisingOptions alloc] initWithParams:@"e757d01e603a6f" gender:AdmanGenderFemale age:66]];

_______________________________________________________________________________

To get the SDK version, the below method can be used

- (nonnull NSString *) getVersion;

AdmanDelegate Reference

- (void)admanStateDidChange:(nonnull Adman *) sender;

Called when adman state changed.

_______________________________________________________________________________

- (void)phraseRecognized:(nonnull NSString *)phrase;

Handles all the responses from speech recognition server. Result displays two keys: phrase transcript and target action.

_______________________________________________________________________________

- (void)userPhraseValid:(nonnull NSString *)phrase;

Used when a phrase was recognised successfully and the target action can be performed by SDK.

_______________________________________________________________________________

- (void)userPhraseInvalid:(nonnull NSString *)phrase;

Used when a phrase wasn't interpreted or in cases when SDK got silence instead of human voice.

_______________________________________________________________________________

- (void)customVoiceIntentHandler;

Handled when there is a specific section for Dialogue Ads in received VAST-Document.

_______________________________________________________________________________

- (void)bannerTouched:(nullable NSString *) urlToNavigate;

Handled when listener tapped on banner image.

_______________________________________________________________________________

- (void)viewClosed;

Handled when Default View is closed.

_______________________________________________________________________________

- (void)errorReceived:(nullable NSError *) error;

Handled when SDK got an error from the network or audio player.

_______________________________________________________________________________

- (void)dtmfIn;

DTMF label 'In' received.

_______________________________________________________________________________

- (void)dtmfOut;

DTMF label 'Out' received.

_______________________________________________________________________________

- (void)log:(nonnull NSString*)message;

Use this to enable more detailed logging.

How to test the integration?

Please go to Test and Activation page in order to find out how to test the integration.

How to send bug reports?

Please send all the reports by mail to support@instreamatic.com .

In case of unusual behavior (wrong responses, ad skips, etc), please send your idfa along with the incident description. So we will be able to analyze what happened. The good practice is to collect some incidents and send them all in one mail instead of sending them one my one.

In case of a crash, please send the crash log/report to inspect.

Please see our FAQ Page below for frequently asked questions

Why SDK?

Your decision to make Instreamatic Dialogue Ads available on your native mobile apps will provide a highly valuable and unique audio communication capability that makes audio ads “smart”. These ads are driven by Voice AI and allow the listener to respond to various scenarios with voice commands that drive target actions.

The Instreamatic SDK is the most simple and hassle-free way to integrate Dialogue ads to your app. There will be no need for complex coding or fine-tuning, just integrate our SDK by following this short manual and you are ready to go. The whole installation should only take an hour or so for a qualified tech professional and we will support your installation all through the process.

Is it safe?

Yes, our SDK is completely safe for your app and your users. Upon your request, we will share our tech specifications, so you can easily check for yourself that our SDK is completely safe for using it in your apps. You will have the full support from us during the integration process and even afterwards. Our SDK was tested on all Apple devices available in the market, so the possibility of a crash has been eliminated. You can implement in a test environment first to review with your QA team to become absolutely comfortable and again, we will support you through the entire process.

And our SDK is now listed on the SafeDK marketplace which means it has passed security and compatibility checks. This test and review by SafeDK provides users assurance that our SDK is both stable and secure so your data is safe.

You can find our SDK here on the marketplace - https://www.safedk.com/marketplace/sdks/instreamatic-adman

What kind of support can I expect?

Our support team is available by email during business hours on weekdays in most time zones. We also provide detailed installation manuals that provide clear instructions and answer most all questions. We will also answer the questions during the initial integration. Please note, that you should provide all the information regarding the issues during the integration if you need support from our side.

Please see our FAQ Page below for frequently asked questions

What to do if I do not want to use SDK?

You can contact your account manager or support team in order to get tech specifications of the protocol we are using. With our documentation, you will be able to build your own integration, but please keep in mind that you will need to perform some complex coding in order to build the integration. We will still provide support if you decide to take this option.

Feel free to contact our support at support@instreamatic.com