Searching a database solution for Windows Phone 7-8 and for Windows 8

I’m preparing for one of my new app-ideas. This app-idea requires a local storage of data, initially I want to create this app for Windows Phone, but I would like to have as much code-reuse as possible. So it would be very nice to have the same database solution for all platforms.

I’ve been using Sterling in the past for Windows Phone. This was before SQL CE was available for Windows Phone. Looking at releases, the last release of Sterling is from June 2011, more than a year and half ago. When I’m looking at the Source Code I’m seeing an resume in commits in last December. So the project is not dead, at least it doesn’t look dead to me. There’s also a discussion on the Future of Sterling which might interest you. There seems to be an issue with Windows Phone 8 which you can easily patch yourself. Okay, interesting, but there is no solution for Windows 8 apps yet.

Let’s explore the other options. SQL CE was added to Windows Phone 7 during one of the updates. However it’s not added to Windows 8 and will probably not be added to Windows 8 because there has been a lot of talking about SQLite in the area of Windows 8. But for Windows Phone 8 SQL CE seems to be lacking and there’s an option to use SQLite for Windows Phone 8 as well. So definitely no SQL CE for me, I want to have a solution that works at least for the whole Phone platform and not just the Windows Phone 7 platform.

So there’s a lot of talking about SQLite? It does support Windows 8 and Windows Phone 8 apps. After some searching there isn’t any official support for Windows Phone 7. I found an article written in 2011 that might help get SQLite on Windows Phone 7. This is an almost solution, maybe I just need to give SQLite a try.

While browsing the Sterling discussions I came around a comment about Lex.DB. This might be an interesting alternative, but it doesn’t support Windows Phone 7 yet. I’ll keep an eye on this project, but it’s very new in this space.

Update 26-01-2013:

In the comments Marcio already says that SQL CE works fine on Windows Phone 8. So even while there isn’t much to be found on that subject it should work. I had to try this myself, so I did. And the end-result? Windows Phone 8 supports SQL CE very well, nothing special that I’ve found in there so far.

NuGet packages are powerful, but the Transformations are not. Time for a solution!

First of all I don’t want to complain about NuGet. I love it every day and I have created two packages myself that I want be easy to use for everyone. It should be a matter of just Install-Package PackageName and not much more.

I currently have the following packages.

It was last week when I wanted to update the Google Analytics package that I found a problem. When the package was used in a previous version, and I run the update it did a strange thing in the transformation I made before. The transformation I created was transforming the App.xaml file by adding an element to the xaml.

<GoogleAnalyticsService WebPropertyId="UA-12345-6" xmlns="clr-namespace:$rootnamespace$.Analytics" />

The transformation in NuGet aren’t really intelligent. It just adds the above element. And when you have an update for the package it will ad the element again. That’s something I would like to be able to prevent. So are the solutions at the table? Yes there are, you can use PowerShell.

So I took a little bit of time to learn more about PowerShell. I knew it was something like batch, but with support for .NET Libraries. The support for .NET Libraries implies easy use of XML editing, which will be handy Xaml is just Xml.

The first step I had to take is be able to read the content of the App.xaml file from the PowerShell script that can be used as part of the NuGet Package. I’m able to iterate through the project items to find the App.xaml project item which in turn helps me find the local path.

param($installPath, $toolsPath, $package, $project)

# find the App.xaml file 
$config = $project.ProjectItems | where {$_.Name -eq "App.xaml"}

# find its path on the file system 
$localPath = $config.Properties | where {$_.Name -eq "LocalPath"}

That wasn’t that hard, was it? Let’s read the App.xaml file into an Xml object. And look for an element with GoogleAnalyticsService as the name.

# load Web.config as XML 
$xml = New-Object xml 
$xml.Load($localPath.Value)

$gasnode = $xml.SelectNodes("//*") | where { $_.Name -eq "GoogleAnalyticsService"} 
if($gasnode -eq $null) 
{ 
} 

If we didn’t find that kind of element we want to create the element with the example WebPropertyId, just like I previously had in the App.xaml NuGet transformation. First I select the proposed parent element, being the “Application.ApplicationLifetimeObjects” element which I can use to add the to be created XmlNode to. Next I create the XmlNode in the appropriate namespace and add the element the parent element. What’s left is to save the App.xaml file.

$lto = $xml.SelectNodes("//*") | where { $_.Name -eq "Application.ApplicationLifetimeObjects"} 
$gas = $xml.CreateNode("element","analytics:GoogleAnalyticsService","clr-namespace:"+$project.Properties.Item("RootNamespace").Value+".Analytics") 
$gas.SetAttribute("WebPropertyId", "UA-12345-6") 
$lto.AppendChild($gas) 
# save the App.xaml file 
$xml.Save($localPath.Value)

And to be complete, this was the complete Install.ps1 file. Hope this helps all the people who have been struggling to solve the limited Transformations issue.

param($installPath, $toolsPath, $package, $project)

# find the App.xaml file 
$config = $project.ProjectItems | where {$_.Name -eq "App.xaml"}

# find its path on the file system 
$localPath = $config.Properties | where {$_.Name -eq "LocalPath"}

# load Web.config as XML 
$xml = New-Object xml 
$xml.Load($localPath.Value)

$gasnode = $xml.SelectNodes("//*") | where { $_.Name -eq "GoogleAnalyticsService"} 
if($gasnode -eq $null) 
{ 
  $lto = $xml.SelectNodes("//*") | where { $_.Name -eq "Application.ApplicationLifetimeObjects"} 
  $gas = $xml.CreateNode("element","analytics:GoogleAnalyticsService","clr-namespace:"+$project.Properties.Item("RootNamespace").Value+".Analytics") 
  $gas.SetAttribute("WebPropertyId", "UA-12345-6") 
  $lto.AppendChild($gas) 
  # save the App.xaml file 
  $xml.Save($localPath.Value) 
} 

Unified Ad for Windows Phone - Part 4 - GenericAdProviderForXaml

Alright, we have signed up to a lot of Ad Providers in Part 1, setup the Unified Ad control in Part 2 and even implemented the Remote Ad Provider configuration in Part 3. What’s next?

The Generic Ad Provider for Xaml

Think of the Generic Ad Provider as a very simple AdProvider. It can show Xaml and that’s basically it. You could use this Ad Provider for example to market your own applications within your own applications. So a piece of Xaml with a little bit of text and an HyperlinkButton that links to a Uri. And after a minute the Ad Provider will rotate to the next Ad Provider. The Xaml can be much more complex, we will come up to that in a moment. But first see a small example Ad in Xaml.

<Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      Width="480"
      Height="80"
      Background="{StaticResource PhoneBackgroundBrush}">
    <Border BorderBrush="{StaticResource PhoneAccentBrush}"
            BorderThickness="1">
        <Grid>
            <TextBlock Text="WP Unified Ad"
                       Foreground="{StaticResource PhoneAccentBrush}" Margin="0"
                       VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="35"/>
            <HyperlinkButton NavigateUri="http://wpunifiedad.codeplex.com"
                             HorizontalAlignment="Stretch"
                             VerticalAlignment="Stretch">
            </HyperlinkButton>
        </Grid>
    </Border>
</Grid>

Where do we put the Xaml?

Ideal it would be on a remote server. But if you don’t have the remote server or you want to have a fallback ad in case the remote server isn’t available you can use the OfflineContent property of the GenericAdProvider.

If you do have the remote server you can set the XamlUri property to the remote Url. In case you want to some more intelligent stuff, like a special ad for each country, or making sure you do something special for the current application, you can make use of the format parameters. The first {0} argument will be replaced by the ApplicationID and the second {1} argument will be replace by the CountryCode. So let’s say I have a server app that returns ads for me, my XamlUri could be configured like this:

http://someurlontheinternet.com/ProvideAd?Country={1}&AppId={0}

If you don’t need one or both arguments you could omit them off course.

Using Phone Styles

If you want to make sure that the advertisements have the same color palette as the Phone settings you can even make use of the usual Phone Resources. Like this example where the Background is set to the PhoneBackgroundBrush and the Border and Text to the PhoneAccentBrush.

<Grid Width="480"
        Height="80"
        Background="{StaticResource PhoneBackgroundBrush}">
    <Border BorderBrush="{StaticResource PhoneAccentBrush}"
            BorderThickness="1">
        <Grid>
            <TextBlock Text="WP Unified Ad"
                        Foreground="{StaticResource PhoneAccentBrush}"
                        Margin="0"
                        VerticalAlignment="Center"
                        HorizontalAlignment="Center"
                        FontSize="35" />
        </Grid>
    </Border>
</Grid>

How to add links

The easiest way to add a link is to put a HyperlinkButton on top of the full Xaml. You don’t have to give it a visual appearance as long as you make it stretch to the full Ad space. Put the Uri you want to link to in the NavigateUri. What? Yes put the Uri in the NavigateUri. But won’t that only work for navigation inside the application, from page to page? Yes but this is improved navigation.

  • http://anythingontheweb.com” and “https://anythingontheweb.com” will start the WebBrowserTask
  • “marketplace://search/some content” will start the MarketplaceSearchTask with “some content” as query.
  • “marketplace://review” will start the MarketplaceReviewTask for the current application.
  • “marketplace://detail” will start the MarketplaceDetailTask for the current application.
  • “marketplace://detail/5f171b43-6ea8-e011-a53c-78e7d1fa76f8” will start the MarketplaceDetailTask for the application with the mentioned ID.

This will enable you to create simple ads that show a webpage. But if you want more, like for example market your other apps you can do this as well.

Complex Ads

I’m not the best designer, but I know a little about Xaml. So I was interested to see if I could get a more complex Ad working. The below Ad for example has a Storyboard attached that changes the opacity of two elements. Sounds easy, it is easy. Just think about what more nice things you can do instead.

<Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      Width="480"
      Height="80"
      Background="{StaticResource PhoneBackgroundBrush}">
	<Grid.Resources>
		<Storyboard x:Name="Storyboard" AutoReverse="True" RepeatBehavior="Forever">
			<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="One">
				<EasingDoubleKeyFrame KeyTime="0" Value="1"/>
				<EasingDoubleKeyFrame KeyTime="0:0:2" Value="1"/>
				<EasingDoubleKeyFrame KeyTime="0:0:3" Value="0"/>
				<EasingDoubleKeyFrame KeyTime="0:0:5" Value="0"/>
			</DoubleAnimationUsingKeyFrames>
			<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="Two">
				<EasingDoubleKeyFrame KeyTime="0" Value="0"/>
				<EasingDoubleKeyFrame KeyTime="0:0:2" Value="0"/>
				<EasingDoubleKeyFrame KeyTime="0:0:3" Value="1"/>
				<EasingDoubleKeyFrame KeyTime="0:0:5" Value="1"/>
			</DoubleAnimationUsingKeyFrames>
		</Storyboard>
	</Grid.Resources>
    <Border BorderBrush="{StaticResource PhoneAccentBrush}"
            BorderThickness="1">
        <Grid>
            <Grid x:Name="One">
        		<TextBlock Text="WP Unified Ad"
        			Foreground="{StaticResource PhoneAccentBrush}" Margin="0"
        			VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="35"/>
        	</Grid>
            <Grid x:Name="Two" Opacity="0">
            	<TextBlock Text="by Mark Monster"
            		Foreground="{StaticResource PhoneAccentBrush}" Margin="0"
            		VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="35"/>
            </Grid>
            <HyperlinkButton NavigateUri="http://wpunifiedad.codeplex.com"
                             HorizontalAlignment="Stretch"
                             VerticalAlignment="Stretch"/>
        </Grid>
    </Border>
</Grid>

Unified Ad for Windows Phone - Part 3 - Remote Ad Provider configuration

Did you read the previous parts?

Part 1 – Introduction

Part 2 – Basic Usage

Done? Let’s continue with Part 3, configure the Ad Providers from a remote location.

Step 1, Add the RemoteAdProviderStrategy

Okay, let’s forget about the default AdProviderStrategy. The default just rotates between the different AdProviders, we want more. First we set the AdProviderStrategy property of the AdControl. Just like this.

<Ads:AdControl.AdProviderStrategy>
    <Strategy:RemoteAdProviderStrategy xmlns:Strategy="clr-namespace:MC.Phone.Ads.Strategy;assembly=MC.Phone.Ads" />
</Ads:AdControl.AdProviderStrategy>

Step 2, Create a configuration file

It could very well be that you already have a functional configuration file. When you for example made use of Windows Phone 7 Ad Rotator you already have a configuration file that’s fully compatible with the Unfied Ad. But if you want the full power of the Unified Ad you have to use a different configuration file structure. Xml files explain best by showing an example file.

<?xml version="1.0" encoding="utf-8" ?>
<AdSettings>
  <CountryDescriptors>
    <AdCountryDescriptor Country="US, GB">
      <Probability Value="70" AdProvider="None" />
      <Probability Value="10" AdProvider="AdMob" />
      <Probability Value="10" AdProvider="MobFox" />
      <Probability Value="10" AdProvider="AdDuplex" />
    </AdCountryDescriptor>
    <AdCountryDescriptor Country="DE">
      <Probability Value="15" AdProvider="PubCenter" />
      <Probability Value="15" AdProvider="AdMob" />
      <Probability Value="20" AdProvider="AdDuplex" />
      <Probability Value="50" AdProvider="None" />
    </AdCountryDescriptor>
    <AdCountryDescriptor>
      <Probability Value="20" AdProvider="PubCenter" />
      <Probability Value="20" AdProvider="AdMob" />
      <Probability Value="20" AdProvider="AdDuplex" />
      <Probability Value="20" AdProvider="Smaato" />
      <Probability Value="20" AdProvider="MobFox" />
    </AdCountryDescriptor>
  </CountryDescriptors>
</AdSettings>

Let examine the last AdCountryDescriptor element lines 16-22. Because this AdCountryDescriptor element doesn’t have a Country property this will be the default configuration to fall back to when there isn’t any other that matches the country of the user.

Inside the AdCountryDescriptor elements there are Probabilty elements, they consist of two values: a probability and an AdProvider name. You can best compare the Probabilty with the chance in percentage that the specific Ad Provider is chosen during AdRotation. If you don’t want an AdProvider to be shown during rotation you either put the probability to 0, but better just remove the element. The AdProvider property is the name of the AdProvider that has to be filled in. Currently that would be one of these AdProviders: AdMob, MobFox, AdDuplex, PubCenter, Smaato, InnerActive, None and GenericAdProviderForXaml.

If you want no ads to be displayed for a certain percentage of the time you should use the None AdProvider. In a future post we will discuss the GenericAdProviderForXaml, for now just see it as a remote location where you put some Xaml that will be displayed as an Ad.

So we now have a default configuration, what about specific country configurations? Yes important of course, by specifying the Country attribute of the AdCountryDescriptor element you can specify to which countries a specific configuration belongs. Which could be one country, or multiple countries. Each country is only allowed once in the configuration but you can specify multiple countries for one configuration by separating the country-codes by a “,”. For the country-codes make sure you use the two-letter codes from the ISO_3166-1, so for the UK this is GB.

Step 3, Where to put this configuration file?

Put it somewhere on a webserver where it’s accessible through http or https. Though if you don’t want to configure it remotely but ship this Xml file as part of your application that’s fine as well. But be aware that the only way to change your shipped configuration file is by shipping a new version of your application. But to have local configuration file makes sense even if you have a remote configuration file. When for example your remote config file cannot be accessed (could be any reason) the RemoteAdProviderStrategy will fallback to the local configuration file. So let’s configure the strategy accordingly.

<Ads:AdControl.AdProviderStrategy>
    <Strategy:RemoteAdProviderStrategy xmlns:Strategy="clr-namespace:MC.Phone.Ads.Strategy;assembly=MC.Phone.Ads"
                                        LocalProviderSettingsUri="Ads/AdSettings.xml"
                                        RemoteProviderSettingsUri="http://someurlinthewild.com/ads.xml" />
</Ads:AdControl.AdProviderStrategy>

The RemoteProviderSettingsUri needs to be filled with the remote location url. So put the file somewhere on an internet website, your own is probably the best so that you can easily change it when you want to. The local provider settings can be used as alternative to the remote location in case you don’t want to remotely configure your ads but it could also be used as fallback when the remote url is not available for some reason. For the LocalProviderSettingsUri you need to be aware that it’s an ResourceUri, not an internet Uri. This means that if your xml file has a BuildAction “Content” you can put a simple relative Uri in there, like in the above example. If you would add the Xml file with BuildAction “Resource” you would have to use an Uri like this “/MC.Phone.Ads.Example;component/Ads/AdSettings.xml”.

Hope this explains the Remote Ad Provider configuration a little bit. Please post any questions.

Unified Ad for Windows Phone - Part 2 - Basic Usage

Time for Part 2 of the Unified Ad for Windows Phone series. Also read part 1 for the introduction of the Unified Ad for Windows Phone. We covered the reason why we want the Unified ad for Windows Phone control and also registered for a couple of Ad Providers. Let’s start with implementing the Unified ad control in our application.

Install the NuGet Package for Unified Ad for Windows Phone

Start managing your NuGet Packages for your Windows Phone project. Search for “wpunifiedad” and click install.

Manage NuGet Packages, search for wpunifiedad

Go to one of your pages, for example “MainPage.xaml” and add the following Xaml in for example the ContentPanel Grid.

<Ads:AdControl x:Name="AdBasic"
                FallbackAdProviderName="AdDuplex"
                IsTest="True"
                xmlns:Ads="clr-namespace:MC.Phone.Ads;assembly=MC.Phone.Ads"
                xmlns:PubCenter="clr-namespace:MC.Phone.Ads.PubCenter;assembly=MC.Phone.Ads.PubCenter"
                xmlns:Smaato="clr-namespace:MC.Phone.Ads.Smaato;assembly=MC.Phone.Ads.Smaato"
                xmlns:MobFox="clr-namespace:MC.Phone.Ads.MobFox;assembly=MC.Phone.Ads.MobFox"
                xmlns:AdMob="clr-namespace:MC.Phone.Ads.AdMob;assembly=MC.Phone.Ads.AdMob"
                xmlns:Provider="clr-namespace:MC.Phone.Ads.Provider;assembly=MC.Phone.Ads"
                xmlns:AdDuplex="clr-namespace:MC.Phone.Ads.AdDuplex;assembly=MC.Phone.Ads.AdDuplex">
    <Ads:AdControl.AdProviders>
        <Provider:GenericAdProviderForXaml XamlUri="http://remoteurlontheinternet.com/Ad.xaml?appid={0}" />
        <Provider:NoneAdProvider />
        <AdDuplex:AdDuplexAdProvider App="" />
        <AdMob:AdMobAdProvider AdUnit="" />
        <MobFox:MobFoxAdProvider Publisher="test" />
        <Smaato:SmaatoAdProvider AdSpace="0"
                                    Publisher="0" />
        <PubCenter:PubCenterAdProvider Application=""
                                        AdUnit="" />
        <!--InnerActive is not really suitable for the Ad Rotation because it doesn't have any events to react on.-->
        <!--<InnerActive:InnerActiveAdProvider App="" />-->
    </Ads:AdControl.AdProviders>
</Ads:AdControl>

Lines 12 to 22 are the AdProviders that are available for the Unified ad control. Just remove the elements for the AdProviders that you’re not using or planning to use. For now also remove the GenericAdProviderForXaml element. This ad provider will be discussed separately in a next part. Also take a look at line 3, it is now configured to be run in Test mode. Now let’s start configuring the different ad providers.

AdDuplex configuration

After you added a new application to AdDuplex you will see the App ID. Copy this value to the App property of the AdDuplexAdProvider.

image

AdMob configuration

When you completed the configuration of a new site/app in AdMob you will see a so called Publisher ID. Copy this value to the AdUnit property of the AdMobAdProvider.

image

MobFox configuration

For MobFox you should copy the Publisher ID from the app to the Publisher property of the MobFoxAdProvider.

image

Smaato configuration

For Smaato you should fill in both the AdSpace and the Publisher number in the SmaatoAdProvider. Copy the AdSpaceId from the application list for your application to the AdSpace property for the SmaatoAdProvider. Copy the PubisherId below at that screen to the Publisher property for the SmaatoAdProvider.

image

PubCenter configuration

The PubCenter configuration consist of two parts. An Application, where you need to copy the Application ID to the Application property of the PubCenterAdProvider. And an Ad Unit where you need to copy the ID of the Ad Unit to the AdUnit property of the PubCenterAdProvider.

image

InnerActive configuration

InnerActive can be configured, but I cannot recommend using it in combination of the Unified Ad control. Inner Active doesn’t have any events that can be listened to like: NoAd, NewAd or AdEngaged. And because of this it’s impposible to let it rotate with the other Ad Providers. When you want to configure it though, you can. Copy the App Name and put it in the App property of the InnerActiveAdProvider.

image

Test or not?

You can put your AdControl in production mode by setting the IsTest property to False or completely removing the property from the Xaml.

The next part will be about the Remote Ad Provider configuration.