Checklist: Submitting an App with Ads to the Windows Store

Preface

When you use the Microsoft Advertising Services, adding AdControls to your app is the easy part of the job (see my posts with a sample showing all the available ad types and how to configure AdControls to make it easy to switch between test mode and production ad).

The harder part from my point of view is to comply with the terms and conditions to submit an app using Microsoft Advertising Services to the Windows Store.

To have a list ready for the next time, I have collected all the things required especially for apps with ads here. Please remind that the list might not reflect the latest changes. So use the links below to verify the requirements.

The List

Check Privacy Statement in your app: Your app must have a privacy statement included. Use the Settings charm to add one. Depending on what kind of data your app is collecting and/or giving to third parties, the content of the privacy statement might defer. For a sample on how to add items to the Settings charm, have a look at my post Implement Settings Popup Pages for Windows Store Apps.

Check Link to Advertisment Choice in your app: You must ensure that this link, https://choice.microsoft.com/AdvertisementChoice/, is accessible from your App after installation, such as by including this link in the Settings charm or in your own privacy policy.

Check Microsoft Advertising User Opt Out through Settings charm: will be included automatically when using the latest Microsoft Advertising SDK for Windows 8. It was introduced by the June 2013 release. Great thing, really no need to do anything by yourself.

Check Age Notification in the App Store description: Your Windows 8 apps must have an Age rating of at least 12+ in the Windows Store to receive Ads.

Check Additional license terms in the App Store description: This text is required: This app is supported by ads from Microsoft Advertising. Learn more about Microsoft’s privacy practices and your choices. Learn more link: https://choice.microsoft.com/AdvertisementChoice/.

Check Privacy Policy in the App Store description: You need to add a link to your company’s privacy policy here.

Check Description’s First Paragraph in the App Store description should contain a summary. It is this part that is displayed as the description in the app overview of the Windows Store. All the rest is only shown when the user clicks “Read more”. So make sure the first paragraph contains the main features of the app. And don’t use too many words. The text might get truncated in the overview.

Check Have relevant content on the first page. Otherwise, the Windows Store testers might refuse the certification because the app did not appear to provide value or did not seem useful.

Check Support the Windows Store testers by giving relevant information in the notes to the testers. Sometimes, it is also helpful to shortly describe from your perspective what the value of the app is.

Links

Microsoft Advertising Services / Developer Information / Submitting an App with Ads to the Windows Store

Microsoft Advertising Services Terms and Condidions

Microsoft Advertising Services AdControl Error Handling in XAML/C#

Preface

The Do’s + Don’ts of the Advertising SDK say “DO plan for times when no ads are available.” The links of that item leads to the ErrorCode enumeration and a rudimentarily error handling sample, writing text to debug output.

In this post, I will show an error handling where the AdControl is replaced by a TextBlock when an error occurs. Of course, this is still not a high sophisticated error handling. But it might give an idea what to do when no ad is available.

Ian Ferreira suggests in his blog post Keep Users First By Using These Resources For Ad Control Error Handling to hard code a house ad into the real-estate where an ad will appear.

Error Handling by Convention

The error handling is based on naming conventions. What it does is looking for a TextBlock having a name matching the naming pattern.

Following the convention, the name of the TextBlock has to be the name of the AdControl to be replaced, extended by ErrorTextBlock.

Sample: The name of the AdControl receiving an error is AdControlBottom. According to the naming convention, the name of the TextBlock to handle the error is AdControlBottomErrorTextBlock.

This makes it easy to implement a search for the correct replacement control. No additional properties need to be defined for the AdControl. And it follows MVC’s “Convention instead of Configuration” approach.

When an error occurs, the AdControl is made invisible, while the TextBlock at the same position will become visible. To make sure the design of the page does not change, the control that replaces the AdControl must have the same size as the AdControl.

In the sample app, just the name of the error-causing control, the reason, and the error text is displayed, no matter what the error code is. In real world scenarios, one should handle different errors differently. For example, just because an ad cannot be refreshed, I would not replace the existing one.

Here is how the handler is implemented:

protected virtual void OnAdControlErrorOccurred
  (
  object sender,
  AdErrorEventArgs args
  )
{
  AdControl adControl = sender as AdControl;

  // If event is not thrown by an Ad Control, do nothing
  if (adControl == null)
  {
    return;
  }

  // Just write out an error message.
  Debug.WriteLine("AdControl error (" + adControl.Name + "): " 
    + args.Error + " ErrorCode: " + args.ErrorCode.ToString());

  // Replace adControl by TextBlock showing error message.
  // Find the TextBlock by naming conventions. 
  // The name of the TextBlock is the name of the AdControl plus "ErrorTextBlock".
  TextBlock textBlock = FindName(
    String.Format("{0}ErrorTextBlock", adControl.Name)) 
  as TextBlock;

  if (textBlock == null)
  {
    return;
  }

  // Hide the AdControl
  adControl.Visibility = Visibility.Collapsed;

  // Show the TextBlock and copy properties.
  textBlock.Visibility = Visibility.Visible;

  textBlock.Height = adControl.Height;

  textBlock.Width = adControl.Width;

  // Set some text.
  textBlock.Text = String.Format("Sorry!{0}"
    + "Can't show AdControl '{1}'.{0}{0}ErrorCode: {2}{0}{0}ErrorMessage: {3}", 
    Environment.NewLine, adControl.Name, args.ErrorCode, args.Error.Message);
}

Please have a look at the sample code to see the XAML implementation. You can look at SubPages/SamplePage300x250.xaml, SubPages/SamplePage300x600.xaml, or SubPages/ SamplePageMultiple.xaml.

Sample Code

The sample code is part of the post Configure Microsoft Advertising Services’ AdControl using XAML/C#.

Links

Ads in Apps for Windows 8

AdControl Error Handling

AdControl ErrorCode Enumeration

Microsoft Advertising Services AdControl Transition in XAML/C#

Preface

According to the documentation, AdControls are hosted in a WebView control. For some reasons I was not able to figure out, WebView controls do not slide in when a page loads (or pop in, whatever the correct wording is). This means that your AdControl will not slide in neither.

Now imagine the following: You have created a great page including an AdControl. When the page is opened, all content slides in, except the AdControl. Would you like that? I do not.

Make AdControls Sliding

For all who are familiar with transitions and storyboards in XAML, this won’t bring much or any news. For those who are not, like I was when using AdControls the first time, this might help save some time.

The key is to add a Storyboard to the page containing the AdControl. And luckily, there is a predefined ThemeAnimation to do the pop in: the PopInThemeAnimation. Here is a sample:

<Page.Resources>
  <Storyboard x:Name="PopInStoryboard">
    <PopInThemeAnimation 
        Storyboard.TargetName="AdControlPanel728x90" 
        FromHorizontalOffset="120" 
        SpeedRatio=".3"/>
  </Storyboard>
</Page.Resources>

The Storyboard.TargetName is the name of the control to animate. In case you use the AdControl configuration presented in the post Configure Microsoft Advertising Services’ AdControl using XAML/C#, make sure that you assign the name to the dynamically created AdControl. The class AdControlContainingPage of the sample takes care of it.

The FromHorizontalOffset “… sets the distance by which the target is translated in the horizontal direction when the animation is active” (description copied from MSDN online docs). Unfortunately, the docs don’t say what the reference point is. So you have to play around a little bit to make sure the AdControl slides in the same distances as the other controls do. In my sample, it was almost the left margin of topmost panel – but only almost, not always.

The SpeedRatio is “… a finite value greater than 0 that specifies the rate at which time progresses for this timeline, relative to the speed of the timeline’s parent. If this timeline is a root timeline, specifies the default timeline speed. The value is expressed as a factor where 1 represents normal speed, 2 is double speed, 0.5 is half speed, and so on.” (description copied from MSDN online docs). In my experience, the value of 0.3 makes the AdControl slide in as fast as the other controls.

Adding the storyboard is only on half of the work. The other part is to make the storyboard run.

// Run storyboard if one exists.
Storyboard storyboard = FindName("PopInStoryboard") as Storyboard;

if (storyboard != null)
{
  storyboard.Begin();
}

I put this code sniped into the LoadState method of my AdControlContainingPage base class, which is derived from LayoutAwarePage. LoadState is called when the page is about to be displayed. I think this is a good place to start transitions.

The AdControlContainingPage is the base class of all pages containing AdControls. So I just have to define the StoryBoard in the XAML, and I am done 🙂

Links

The AdControl animation is part of the sample code of the post Configure Microsoft Advertising Services’ AdControl using XAML/C#, where you can download the code.

Configure Microsoft Advertising Services’ AdControl using XAML/C#

Preface

The Microsoft Advertising SDK for Windows 8 allows developers to show ads in their apps. When you look at the walkthrough for putting ads in an app using XAML/C#, you can see that you have to set the ApplicationId and AdUnitId property of each AdControl control in your app.

For testing purposes, Microsoft has defined the ApplicationId d25517cb-12d4-4699-8bdc-52040c712cab and several AdUnitIds (can be found on the Test Mode Values page). These values are required in case you have no ids created in the pubCenter for yourself or in case you want to test your app in the emulator. (Well, on my machine the emulator showed productive ads even though the docs says it does not.)

Since I do not want to change my app every time I switch between the emulator and my dev machine, I was looking for a way to make these setting configurable.

Where to Store the Configuration Data?

In common .NET applications, the answer to this question is very simple: put it in the app.config. Unfortunately, for Windows Store apps the app.config approach is not available, or at least not offered by .NET for Windows Store apps.

So I built my own app.config mimic. Please have a look at the post Mimic app.config in Windows Store Apps for further details.

How to Change the Values During Runtime?

My first try was to define the AdControls in the XAML file and change both ApplicationId and AdUnitId in the constructor of the page’s class right after the call to PageClass.InitializeComponent. After receiving “NoAdAvailable” errors (which shows how important it is to implement an error event handler for AdControls), I had a look at the documentation.

In the remarks to the AdUnitId property the docs says that “This property can be set only when the AdControl is instantiated using the default constructor. Once set, this property cannot be modified.” The ApplicationId can be changed whenever you want. But that won’t help, because ApplicationId and AdUnitId are strongly tied together. Means, an AdUnitId is only valid in conjunction with its corresponding ApplicationId.

This means I cannot change the AdUnitId of all the AdControls that are defined in the XAML. Bad news? Not that bad – because we can also create UI controls during runtime, not only in XAML!

The AdControl Replacement Approach

After playing around a little bit I was choosing a replacement approach. This means that I define AdControls in XAML, and replace them during page initialization with those AdControls having the correct values for Application- and AdUnitId.

I prefer this approach because it offers the ability to check the look of the page also during design time, not only at runtime. So it is much easier to see if the page looks good. This requires me to set the (matching) height and width of the AdControls properly both in the XAML and configuration.

There is one prerequisite to use the replacement approach the way I implemented it: the AdControl to be replaced has to be a child control of a Panel (or derived class). Otherwise it is not possible to put the new AdControl at the place where the old one was.

The definition of the required config values is encapsulated by the class AdControlConfigData. The class looks like this:

public class AdControlConfigData
{
  [XmlAttribute]
  public string AdControlName { get; set; }

  [XmlAttribute]
  public string AdUnitId { get; set; }

  [XmlAttribute]
  public double Height { get; set; }

  [XmlAttribute]
  public double Width { get; set; }
}

The corresponding serialized data in the app.config looks like this:

<AdControlConfigData AdControlName="AdControl300x600" 
  AdUnitId="10043030" Width="300" Height="600"/>

The value of the ApplicationId is not part of this container. It is defined as a simple and single value in the app.config, since it is the same for all AdControls.

Replace the AdControls

In the sample code, I created a class called AdControlContainingPage, which is derived from LayoutAwarePage. This class is the base class of all pages containing AdControls. It holds all the functionality required to replace them, plus a basic handler for AdControl errors.

The XML config data is read by the ConfigurationManager class introduced in the Mimic app.config in Windows Store Apps post, also the XmlDeserialize used later.

For the sample app, the content of the app.config looks like this:

<?xml version="1.0" encoding="utf-8" ?>
<!-- Configuration settings for Debug Build -->
<configuration>
  <appSettings>
    <!-- Use Microsoft Advertising Services Test ApplicationId -->
    <add key="AdApplicationId" 
            value="d25517cb-12d4-4699-8bdc-52040c712cab"/>
  </appSettings>

  <AdControlConfigList300x600>
    <AdControlConfigData AdControlName="AdControl300x600" 
          AdUnitId="10043030" Width="300" Height="600"/>
  </AdControlConfigList300x600>

  <AdControlConfigList300x250>
    <AdControlConfigData AdControlName="AdControl300x250" 
          AdUnitId="10043056" Width="300" Height="250"/>
  </AdControlConfigList300x250>

  <AdControlConfigListMultiple>
    <AdControlConfigData AdControlName="AdControl160x600" 
          AdUnitId="10043136" Width="160" Height="600"/>
    <AdControlConfigData AdControlName="AdControl728x90" 
          AdUnitId="10042998" Width="728" Height="90"/>
  </AdControlConfigListMultiple>
</configuration>

The different AdControlConfigData entities are extracted by the method AdControlContainingPage.GetAdControlConfiguration, which is shown here:

private static List<AdControlConfigData> GetAdControlConfiguration
  (
  XmlDocument xmlConfig,
  string sectionName
  )
{
  List<AdControlConfigData> configDataList 
    = new List<AdControlConfigData>();

  XmlNodeList xmlConfigDataList 
    = xmlConfig.DocumentElement
      .SelectNodes(
        String.Format("./{0}/AdControlConfigData", sectionName));

  foreach (IXmlNode node in xmlConfigDataList)
  {
    AdControlConfigData configData 
     = XmlDeserializer.Deserialize<AdControlConfigData>(node);

    configDataList.Add(configData);
  }

  return (configDataList);
}

Now that we have the configuration settings as a list of objects, which is really easy to handle, we can go on to replace the controls. This is done by AdControlContainingPage.ReplaceAdControls.

private void ReplaceAdControls
  (
  List<AdControlConfigData> adControlConfigDataList,
  string adApplicationId
  )
{
  // iterate over the list of configured AdControls.
  foreach (AdControlConfigData configData in adControlConfigDataList)
  {
    // Find the AdControl to be replaced.
    AdControl oldAdControl 
      = FindName(configData.AdControlName) as AdControl;

    // If the oldAdControl is not found, we can't replace it. So try the next one.
    if (oldAdControl == null)
    {
      Debug.WriteLine(String.Format("AdControl name >{0}< not found", configData.AdControlName));
      continue;
    }

    // Get the parent of the adcontrol. Needs to be a kind of panel.
    Panel parent = oldAdControl.Parent as Panel;

    // If the parent is not a panel, try the next one.
    if (parent == null)
    {
      Debug.WriteLine(String.Format("AdControl name >{0}< is not placed inside a panel or derived class. AdControl cannot be replaced.",
        configData.AdControlName));
      continue;
    }

    // Keep the position of the old AdControl.
    int postion = parent.Children.IndexOf(oldAdControl);

    // and remove it
    parent.Children.RemoveAt(postion);

    // Create the new AdControl with the correct ApplicationId and AdUnitId.
    AdControl adControl = new AdControl()
    {
      ApplicationId = adApplicationId,
      AdUnitId = configData.AdUnitId, // From msdn: This property can be set only when the AdControl is instantiated. Once set, this property cannot be modified.
      HorizontalAlignment = HorizontalAlignment.Left,
      Height = configData.Height,
      IsAutoRefreshEnabled = true,
      VerticalAlignment = VerticalAlignment.Top,
      Width = configData.Width
    };

    // Add the error hander
    adControl.ErrorOccurred += OnAdControlErrorOccurred;

    // Add the new control to the parent at the correct position.
    parent.Children.Insert(postion, adControl);
  }
}

The orchestration of these activities is done by AdControlContainingPage.SetupAdControls, which looks as follows:

protected async void SetupAdControls
  (
  string configSectionName
  )
{
  try
  {
    // Load the app.config.
    XmlDocument xmlConfig = await ConfigurationManager.GetConfig();

    // Get the AdApplicationId
    string adApplicationId 
      = ConfigurationManager
        .GetAppSettingsValue(xmlConfig, "AdApplicationId");

    // Extract the AdControl config data from the XML into a object list.
    List<AdControlConfigData> adControlConfigDataList 
      = AdControlContainingPage
        .GetAdControlConfiguration(xmlConfig, configSectionName);

    // Replace the AdControls
    ReplaceAdControls(adControlConfigDataList, adApplicationId);
  }
  catch (Exception e)
  {
    Debug.WriteLine(String.Format("Exception occurred:{0}{1}", 
      Environment.NewLine, e));
  }
}

One should call AdControlContainingPage.SetupAdControls right after the call of InitializeComponent of the derived class. In the sample, the derived classes are SamplePage300x250, SamplePage300x600, and SamplePageMultiple, which can be found in the SubPages folder of the solution.

The Sample Code

can be found here. To build and run the sample, you need to have the Microsoft Advertising SDK for Windows 8 installed. Have fun 🙂

Load It From The Windows Store

A slightly extented version of the sample can also be found in the Windows Store.

And finally, some screenshots of the sample app.

Main Page

Sample Page

Sample Page

Sample Page

Microsoft Advertising Services Test Mode Sample for Windows 8

Microsoft offers a very simple way to show advertising in Windows Store apps. A starting point is adsinapps.microsoft.com. The Microsoft Advertising SDK for Windows 8 can be found here: msdn.microsoft.com/en-us/library/hh506371%28v=msads.10%29.aspx.

The SDK docs lead you to a document, listing all the possible advertising test modes with their appropriate test values: msdn.microsoft.com/en-us/library/advertising-windows-test-mode-values%28v=msads.10%29.aspx.

Unfortunately, this page does not contain a sample to see all these ad services in action. So I created a quick & dirty one just to give me an idea of how the ads might look like. Here is a screenshot:

Ads in action

In my sample the following test mode values did not work as expected:
10043135: Video Ad with click to Full Screen Video (160×600)
10043056: Video Ad with click to Full Screen Video (300×250)
10042999: Video Ad with click to Full Screen Video (728×90).
The test mode value table states, that these services are videos, where a click opens another video. In my samples, these services only show images, opening a video when clicked. Maybe they will show images in production, which I hadn’t checked yet.

You can find the source code (VS 2012) here. To compile and run the sample, the Microsoft Advertising SDK for Windows 8 (can be found here: go.microsoft.com/?linkid=9815330) has to be installed. I was using the January 2013 version.

2013-07-23: Source code update V3.2
Minor design changes (logo & splash screen).

2013-07-10: Source code update V3.1
Minor design changes (headline & font).

2013-07-04: Source code update V3.0
Added new test mode id 10043030 (Image Ad 300×600); marked deprecated test mode ids as deprecated (10043124, 10043074, and 10043008 500×130)

2013-06-28: Source code update V2.0
Added scrolling to support screen resolutions less than 1920×1200