Behind the scenes of “Universal Apps”

by Morten 3. April 2014 09:25

At Build 2014, Microsoft announced the new ‘Universal Apps’ project type that allows you to share code between Windows Phone and Windows Store apps, using a new ‘shared’ project. Below is an example of the default hub project that shares a lot of the code has individual views for the parts where you want to tweak the UI specifically for phone or tablets.

image

Before we had shared projects, we could do something similar, by linking the same code files into multiple projects. It worked fairly well, but which ever project you open the file from, is the ‘context’ you look at it, so intellisense etc might not match the platform you’re looking at. The universal apps really aren’t any different. This is really just a nice tooling on top of linked files that makes it easier to work with. Also it is much easier to change the ‘context’ the code is viewed in using a simple dropdown above your code:

image

As shown above, you can still use compiler conditionals to write individual differences for each platform and still share the rest of the code file. So again this is the same as when working with linked files, but the shared project makes this much easier.

So how does this really work? If we look in the project file for Windows Phone or Windows Store project you’ll find the highlighted tag:

image

So the specific project simply references another project – kind of like how a linked file works, but in this case an entire group of files. Looking in the shared project that’s references, you find a fairly simple file, but this in turn references a file called [ProjectName].Shared.projitems, and the contents of this is really just a standard project with the files etc that needs to be referenced in the referencing project.

image

image

The last piece to the puzzle is in the .sln solution file that makes sure the projects are nicely grouped together. There’s two parts to the solution that makes this work:

image

image

The Guids are the project guids referencing the projects that needs to be grouped as a universal project.

Microsoft only gives you the tooling to do Windows Store and Windows Phone Universal projects. However knowing how this now works, it makes you wonder if you can manually go add the Shared Project reference to for example your WPF application, and add it to the solution under the nested project parts. And in fact you can! Below is an example of the ArcGIS Runtime Toolkit (which today uses linked files to compile for Store, Phone and WPF): Note how ‘Generic.xaml’ is the only file not shared, because the UI has been optimized for each platform, and also WPF XAML isn’t compatible with Store and Phone. Again the Universal Apps makes this really easy to manage files you don’t want shared.

image

And the context switcher now also shows a third option:

image

In fact I can make a shared project that’s used in a Windows Store, Windows Phone, WPF, Silverlight, Console, Windows Forms etc etc! Of course at some point the platforms are so different the amount of code that is shared will be reduced, but I find this as a great alternative to PCL without the limitations of PCLs.

Talking to the people behind this feature, this functionality does come with a warning: First of all this hasn’t been extensively tested, so you might hit issues with it. Another thing to be careful with is build actions. For example if you want to share image Assets, you want to set the build action to ‘Content’ for Windows Phone and Windows Store, but in WPF you want to set it to ‘Resource’, and this naturally isn’t supported (but you can still used linked files in the individual projects to work around this).

Tags:

The layout of an ExtensionSDK

by Morten 28. January 2014 22:37

Extension SDKs are a very powerful way distribute your control libraries for use in Windows Store and Windows Phone apps.
This article will go through the layout of the extension sdk, and later take that knowledge to build an extension sdk from an already released app.

An ExtensionSDK essentially consists of 3 parts:

  • Files to use during design time
  • Files to deploy as content
  • Assemblies to use for reference

In addition there's a metadata file 'SDKManifest.xml' that describes the content.

The root layout then looks like the following:
    \EXTENSIONNAME\VERSION\DesignTime\
    \EXTENSIONNAME\VERSION\Redist\
    \EXTENSIONNAME\VERSION\References\
    \EXTENSIONNAME\VERSION\SDKManifest.xml
…where 'EXTENSIONAME' is the name of your extension, and VERSION is version number in the format "1.2.3.4".
   
For each of these groups you can control what gets deployed in debug and release or both. If you don't want to control whether you use debug or release, you will below these folders use the folder 'CommonConfiguration'. For debug specific configuration use 'Debug', and for release configuration use 'Retail'. In most case you will be using 'CommonConfiguration' though.
This means our folder structure now looks like this:
    \EXTENSIONNAME\VERSION\DesignTime\CommonConfiguration\
    \EXTENSIONNAME\VERSION\Redist\CommonConfiguration\
    \EXTENSIONNAME\VERSION\References\CommonConfiguration\

Next level down in the folders describe if files are related to AnyCPU, x86, x64 or ARM builds (the latter is very useful for C++ projects). For AnyCPU use 'neutral', meaning it doesn't matter. So use this for .NET Assemblies compiled for AnyCPU, image resources, winmd files etc. You will want to use the architecture specific folder if you deploy binaries that are architecture specific.

So what goes in what folders:

  • DesignTime: This is where you will put .Design assemblies if you have specific design time binaries for your assemblies, as well as Generic.xaml. You only need to deploy 'neutral' and/or 'x86' architectures, since VS runs in a 32bit process.
  • Redist: Images, shaders, Generic.xbf, videos etc, AND C++ binaries.
  • References: .NET DLLs, C++ WinMDs, xml doc.

Here's an example layout of an extension sdk that consists of two libraries: One C++ WinRT component (NativeLib) and a Managed library:
    \MyControlLib\1.0.0.0\SDKManifest.xml
    \MyControlLib\1.0.0.0\DesignTime\CommonConfiguration\neutral\ManagedLib\Themes\Generic.xaml
    \MyControlLib\1.0.0.0\DesignTime\CommonConfiguration\x86\ManagedLib.Design.dll
    \MyControlLib\1.0.0.0\Redist\CommonConfiguration\neutral\ManagedLib.pri
    \MyControlLib\1.0.0.0\Redist\CommonConfiguration\neutral\NativeLib.pri
    \MyControlLib\1.0.0.0\Redist\CommonConfiguration\neutral\ManagedLib\Icon.png
    \MyControlLib\1.0.0.0\Redist\CommonConfiguration\neutral\ManagedLib\Themes\Generic.xbf
    \MyControlLib\1.0.0.0\Redist\CommonConfiguration\neutral\NativeLib\shaders\PixelShader.cso
    \MyControlLib\1.0.0.0\Redist\CommonConfiguration\neutral\NativeLib\shaders\VertexShader.cso
    \MyControlLib\1.0.0.0\Redist\CommonConfiguration\ARM\NativeLib.dll
    \MyControlLib\1.0.0.0\Redist\CommonConfiguration\x86\NativeLib.dll
    \MyControlLib\1.0.0.0\Redist\CommonConfiguration\x64\NativeLib.dll
    \MyControlLib\1.0.0.0\References\CommonConfiguration\neutral\NativeLib.winmd
    \MyControlLib\1.0.0.0\References\CommonConfiguration\ARM\ManagedLib.dll
    \MyControlLib\1.0.0.0\References\CommonConfiguration\ARM\ManagedLib.xml
    \MyControlLib\1.0.0.0\References\CommonConfiguration\x64\ManagedLib.dll
    \MyControlLib\1.0.0.0\References\CommonConfiguration\x64\ManagedLib.xml
    \MyControlLib\1.0.0.0\References\CommonConfiguration\x86\ManagedLib.dll
    \MyControlLib\1.0.0.0\References\CommonConfiguration\x86\ManagedLib.xml

The SDKManifest could look like the following:

    <?xml version="1.0" encoding="utf-8" ?>
    <FileList
      xmlns:xsi="
http://www.w3.org/2001/XMLSchema-instance"
      xsi:noNamespaceSchemaLocation="SDKManifest.xsd"
      DisplayName="My Super Duper Control Library"
      ProductFamilyName="MyControlLib"
      Description="My Control Library"
      MinVSVersion="12.0"
      Identity="MyControlLib, Version=1.0.0.0"
      MinToolsVersion="12.0"
      AppliesTo="WindowsAppContainer + ( Managed )"
      SupportedArchitectures="x86;x64;ARM"
      DependsOn="Microsoft.VCLibs, version=12.0"
      SupportsMultipleVersions="Error">
        <File Reference="NativeLib.winmd" Implementation="NativeLib.dll" />
        <File Reference="ManagedLib.dll"/>
    </FileList>

   
Note that if you don't have native dependencies, this would change quite a lot. The full set of properties are pretty poorly documented today, so generally I download and install a wealth of extension sdks and look at them and see if they do similar things to me and then copy from that.

Building an Extension SDK from an installed app

So now that we know the layout of an extension sdk, let us apply that to 'reverse-engineering' an already deployed app into an extension sdk and use that to build our own app on top. Because Windows Store apps aren't fully encrypted, this means you can often take parts of an app that's separated out into libraries and build a new app from these libraries. This is something to consider when you build your app - if you are really good are separating your stuff into sub-libraries, you also make it easier for others to reuse your stuff. As an example let's download the Bing Maps Preview app and reverse it into an SDK and build our own 3D Map App.

When you installed the app, you will be able to access a folder with a name similar to the following with administrator rights:
"c:\Program Files\WindowsApps\Microsoft.Maps3DPreview_2.1.2326.2333_x64__8wekyb3d8bbwe\"

In here we'll find a lot of logic for the app, but the main one we are interested in is the "Bing.Maps" folder and the Bing.Maps dll+winmd. The folder is essentially the content and is image resources and shaders. The Bing Maps.dll and Winmd are C++ WinRT components. Since the dll is C++, the architecture will either be ARM, x86 or x64 depending on what PC you downloaded it on. In my case it's x64 so I should be able to build an extension sdk that will support 64 bit PCs from this alone. If I want to support more, I will have to install the app on a x86 or ARM PC and copy the dll from there as well (the other files are neutral and will be the same).

So let's first create the following folder : "Bing.Maps\1.0.0.0\".

Next, let's copy the "Bing.Maps" folder that has all the images and shaders into
    \Bing.Maps\1.0.0.0\Redist\CommonConfiguration\neutral\Bing.Maps\
Next copy the Bing.Maps.dll into (x64 if that's what you have, change/add ARM/x86 if your binary isn't x64)
    \Bing.Maps\1.0.0.0\Redist\CommonConfiguration\x64\Bing.Maps.dll
Lastly, copy the Bing.Maps.winmd into:
    \Bing.Maps\1.0.0.0\References\CommonConfiguration\neutral\Bing.Maps.winmd

Lastly we need to create a new file in \Bing.Maps\1.0.0.0\SDKManifest.xml to describe the SDK:

    <?xml version="1.0" encoding="utf-8" ?>
    <FileList
      xmlns:xsi="
http://www.w3.org/2001/XMLSchema-instance"
      xsi:noNamespaceSchemaLocation="SDKManifest.xsd"
      DisplayName="Bing Maps"
      ProductFamilyName="Bing.Maps"
      MinVSVersion="12.0"
      Identity="Bing.Maps, Version=1.0.0.0"
      MinToolsVersion="12.0"
      AppliesTo="WindowsAppContainer"
      SupportedArchitectures="x86;x64;ARM"
      DependsOn="Microsoft.VCLibs, version=12.0"
      SupportsMultipleVersions="Error">
        <File Reference="Bing.Maps.winmd" Implementation="Bing.Maps.dll" />
    </FileList>

Voila! We now have an ExtensionSDK. There's several ways you can 'install' this into Visual Studio. The simplest way is to copy the folder into your user folder under %USERPROFILE%\AppData\Local\Microsoft SDKs\<target platform>\v<platform version number>\ExtensionSDKs.
In this case %USERPROFILE%\AppData\Local\Microsoft SDKs\Windows\v8.1\ExtensionSDKs\

If you're building an installer you can also install it into
    %Program Files%\Microsoft SDKs\Windows\v8.1\ExtensionSDKs
Or specify a link to the location of the folder in a registry key:
    HKLM\Software\Microsoft\Microsoft SDKs\Windows\v8.1\ExtensionSDKs\Bing.Maps\1.0.0.0\

Lastly you can do this in your project file    by using the 'SDKReferenceDirectoryRoot' tag. Add the following right before the <Target Name="BeforeBuild"/> tag at the very bottom.

  <PropertyGroup>
    <SDKReferenceDirectoryRoot>c:\myfolder\my_sdks\;$(SDKReferenceDirectoryRoot)</SDKReferenceDirectoryRoot>
  </PropertyGroup>

Note that for the latter, the folder should point to a root extension sdk folder, meaning the SDK above must be located in a certain tree under this folder. In this case:
    c:\myfolder\my_sdks\Windows\v8.1\ExtensionSDKs\Bing.Maps

When you've done any of these install options, you can now get started building an app. Go to "Add References" and the Bing Maps entry should show up.

image

Now add the following XAML to your page:

        <bing:Map x:Name="map" xmlns:bing="using:Bing.Maps">
            <bing:Map.MapProjection>
                <bing:ThreeDimensionalMapProjection />
            </bing:Map.MapProjection>
        </bing:Map>

And in code-behind after "InitializeComponents":

            map.BaseLayers = Bing.Maps.BaseLayers.CreatePhotoRealisticOverlay();

Run the app and you should see a 3D globe!

image

Note: This Bing Maps SDK is not based on anything officially released but on a un-finished app. This is by all means a giant hack and only meant as an exercise to build an Extension SDK. Use this at your own risk and don’t attempt to publish any apps using it.

References:

Tags:

Windows Runtime | Windows Phone | XAML | Virtual Earth

Adding a platform target dropdown to Visual Studio

by Morten 9. September 2013 09:46

Lately I’ve been writing or using a lot of native libraries in my Windows Phone and Windows 8 apps. If you are using sqlite, Bing maps, or any other 3rd party native dependency in your .NET app, you’ve probably hit the same issue if your Visual Studio is configured for C# or VB.NET layout: There’s no quick way to tell if you’re compiling for x86, ARM or x64 or to change it. You’ll need to go to the Configuration Manager menu, and change it there:

image

It’s really annoying when switching devices and I forget to pick the right platform, or think I’m working on a different target that I am. If you configured your Visual Studio for C++, you will have noticed this has a second dropdown next to the release/debug dropdown where you can quickly glance what platform you’re targeting and can change it instantly.

image

Fortunately you can add this dropdown to your Visual Studio even if it was configured for .NET. Below is a video of the steps needed to add it to your toolbar:

Tags:

Slides from my IE Windows Unleashed session

by Morten 9. June 2013 22:05

This weekend I had the please of presenting at the Inland Empire's "Windows Unleashed Hackathon". As promised here's the slides from my session on code sharing between Windows Phone and Windows Store, and top 10 differences between them.

Thank you all for a great day. It was a blast!

Tags:

Decoding the IXamlMetadataProvider interface - Part 1

by Morten 30. May 2013 07:49

The WinRT XAML SDK holds a big secret. It’s even a secret why it’s a secret. But you’ll see several of forum posts with Microsoft staff hinting at this secret, but not following up with actual examples or sufficient documentation.

So what is this secret? Well let’s start with good old WPF, Silverlight and what else is dead. One of the issues with these frameworks has been performance, and one of the performance issues was converting XAML into running code at runtime. This requires a lot of reflection and was part of the performance problem. WinRT attempts to solve this by taking this hit during compile time. It basically generates metadata about the classes you use, and thereby avoids the reflection overhead. At first glance this is pretty clever but as I’ll show later can also have some major issues that require a lot of code using hardly documented interfaces to resolve.

This is my attempt to decode some of these interfaces. I’m not fully understanding all the bits myself yet, so this blogpost is partly to share what I found, but also my process for better understanding it.

So back to the big secret: IXamlMetadataProvider. This is the main interface that drives this type resolving at runtime, and for the most part this is done for you, and this is also where our journey will start, because we can take a peek at that work. Open any of your Windows Store XAML apps projects, turn on the “show all files”, and open up the secret \obj\[Config]\XamlTypeInfo.g.cs file.

image

The code will look something like this in the top:

image

Keep scrolling a bit down, and you’ll start seeing some string-based typename lookups, including the types you use in your app:

image

Now let’s try and create a new class and see what happens to this file. Let’s add the following class:

public class StringCollection : ObservableCollection<string> { } 

Rebuild, and check the auto generated file. You’ll notice that this class does not show up. This is because it’s not used in XAML or by anything else that is used in XAML. Next try declaring this collection as a resource in XAML:

<Grid.Resources>
    <local:StringCollection x:Key="coll" />
</Grid.Resources>

Let’s jump back and look at the CreateXamlType method that magically  just got updated with a whole lot of more code:

private Windows.UI.Xaml.Markup.IXamlType CreateXamlType(string typeName)
{
    XamlMetadataSample.XamlMetadataSample_XamlTypeInfo.XamlSystemBaseType xamlType = null;
    XamlMetadataSample.XamlMetadataSample_XamlTypeInfo.XamlUserType userType;

    switch (typeName)
    {
    case "Object":
        xamlType = new XamlMetadataSample.XamlMetadataSample_XamlTypeInfo.XamlSystemBaseType(typeName, typeof(object));
        break;

    case "String":
        xamlType = new XamlMetadataSample.XamlMetadataSample_XamlTypeInfo.XamlSystemBaseType(typeName, typeof(string));
        break;

    case "Int32":
        xamlType = new XamlMetadataSample.XamlMetadataSample_XamlTypeInfo.XamlSystemBaseType(typeName, typeof(int));
        break;

    case "Windows.UI.Xaml.Controls.Page":
        xamlType = new XamlMetadataSample.XamlMetadataSample_XamlTypeInfo.XamlSystemBaseType(typeName, typeof(Windows.UI.Xaml.Controls.Page));
        break;

    case "Windows.UI.Xaml.Controls.UserControl":
        xamlType = new XamlMetadataSample.XamlMetadataSample_XamlTypeInfo.XamlSystemBaseType(typeName, typeof(Windows.UI.Xaml.Controls.UserControl));
        break;

    case "XamlMetadataSample.StringCollection":
        userType = new XamlMetadataSample.XamlMetadataSample_XamlTypeInfo.XamlUserType(this, typeName, typeof(XamlMetadataSample.StringCollection), GetXamlTypeByName("System.Collections.ObjectModel.ObservableCollection<String>"));
        userType.Activator = Activate_0_StringCollection;
        userType.CollectionAdd = VectorAdd_0_StringCollection;
        xamlType = userType;
        break;

    case "System.Collections.ObjectModel.ObservableCollection<String>":
        userType = new XamlMetadataSample.XamlMetadataSample_XamlTypeInfo.XamlUserType(this, typeName, typeof(ObservableCollection<string>), GetXamlTypeByName("System.Collections.ObjectModel.Collection<String>"));
        AddToMapOfTypeToStandardName(typeof(ObservableCollection<string>),
                                            "System.Collections.ObjectModel.ObservableCollection<String>");
        userType.Activator = Activate_1_ObservableCollection;
        userType.CollectionAdd = VectorAdd_1_ObservableCollection;
        xamlType = userType;
        break;

    case "System.Collections.ObjectModel.Collection<String>":
        userType = new XamlMetadataSample.XamlMetadataSample_XamlTypeInfo.XamlUserType(this, typeName, typeof(Collection<string>), GetXamlTypeByName("Object"));
        AddToMapOfTypeToStandardName(typeof(Collection<string>),
                                            "System.Collections.ObjectModel.Collection<String>");
        userType.Activator = Activate_2_Collection;
        userType.CollectionAdd = VectorAdd_2_Collection;
        userType.AddMemberName("Count");
        AddToMapOfTypeToStandardName(typeof(int),
                                            "Int32");
        xamlType = userType;
        break;

    case "XamlMetadataSample.MainPage":
        userType = new XamlMetadataSample.XamlMetadataSample_XamlTypeInfo.XamlUserType(this, typeName, typeof(XamlMetadataSample.MainPage), GetXamlTypeByName("Windows.UI.Xaml.Controls.Page"));
        userType.Activator = Activate_3_MainPage;
        xamlType = userType;
        break;

    }
    return xamlType;
}

What just happened? The compiler detected that you want to use your StringCollection class, so it creates type resolvers for this, and ANYTHING else it depends on, including base classes and types for all their properties which is why  you also see string, int, object etc show up.

Now let’s try something else. Remove the resource we added, and instead add the following property to MainPage.xaml.cs

public StringCollection MyCollection { get; set; }

CreateXamlType doesn’t change, but instead take a look at CreateXamlMember that changes from this:

private IXamlMember CreateXamlMember(string longMemberName)
{
    XamlMetadataSample.XamlMetadataSample_XamlTypeInfo.XamlMember xamlMember = null;
    // No Local Properties
    return xamlMember;
}

to this:

private IXamlMember CreateXamlMember(string longMemberName)
{
    XamlMetadataSample.XamlMetadataSample_XamlTypeInfo.XamlMember xamlMember = null;
    XamlMetadataSample.XamlMetadataSample_XamlTypeInfo.XamlUserType userType;

    switch (longMemberName)
    {
    case "XamlMetadataSample.MainPage.MyCollection":
        userType = (XamlMetadataSample.XamlMetadataSample_XamlTypeInfo.XamlUserType)GetXamlTypeByName("XamlMetadataSample.MainPage");
        xamlMember = new XamlMetadataSample.XamlMetadataSample_XamlTypeInfo.XamlMember(this, "MyCollection", "XamlMetadataSample.StringCollection");
        xamlMember.Getter = get_0_MainPage_MyCollection;
        xamlMember.Setter = set_0_MainPage_MyCollection;
        break;
    }
    return xamlMember;
}

So because our MainPage control now has a new property, this gets reflected by the auto-generated code.

What about 3rd party control libraries then? How do these get included? Well let’s take a look. First create a new Windows Store Class Library, and add a new “MyCustomControl” templated control to it. You’ll note that this new project will have its own auto-generated magic code in it’s obj folder and that works just the same way as explained on top. Basically anything you use in your Themes\Generic.xaml or any other XAML file is getting code generated for it. No surprises there. But let’s add a reference to this project to our test project, and see what will happen to the apps’s XamlTypeInfo.g.cs file. Suddenly a new property “XamlTypeInfoProvider.OtherProviders” is added:

private List<IXamlMetadataProvider> OtherProviders
{
    get
    {
        if(_otherProviders == null)
        {
            _otherProviders = new List<IXamlMetadataProvider>();
            IXamlMetadataProvider provider;
            provider = new MyControlLibrary.MyControlLibrary_XamlTypeInfo.XamlMetaDataProvider() as IXamlMetadataProvider;
            _otherProviders.Add(provider); 
        }
        return _otherProviders;
    }
}

So your app’s metadata provider automatically “merges” other project’s providers in this autogenerated code. Just for fun, let’s try and create a new class that implements IXamlMetadataProvider and add to our controls library, and see what happens:

public class MyCustomMetadataProvider : IXamlMetadataProvider
{
    public IXamlType GetXamlType(string fullName)
    {
        throw new NotImplementedException();
    }

    public IXamlType GetXamlType(Type type)
    {
        throw new NotImplementedException();
    }

    public XmlnsDefinition[] GetXmlnsDefinitions()
    {
        throw new NotImplementedException();
    }
}

And the OtherProviders property now suddenly looks like this:

private List<IXamlMetadataProvider> OtherProviders
{
    get
    {
        if(_otherProviders == null)
        {
            _otherProviders = new List<IXamlMetadataProvider>();
            IXamlMetadataProvider provider;
            provider = new MyControlLibrary.MyCustomMetadataProvider() as IXamlMetadataProvider;
            _otherProviders.Add(provider); 
            provider = new MyControlLibrary.MyControlLibrary_XamlTypeInfo.XamlMetaDataProvider() as IXamlMetadataProvider;
            _otherProviders.Add(provider); 
        }
        return _otherProviders;
    }
}

So the auto-generated code automatically detected that my custom library has a second metadata provider embedded, and injects it into this list as well as the auto-generated one. So it looks like we should be able to provide our own implementations, which I’ll get back to later.

So what have we found so far? That all types that’s being used directly or indirectly in XAML is getting type information generated, and properties on controls are getting metadata generated for those. Great you might think, but why would you need to know about this? Well the devil is in the details. Let me repeat the first finding again:

“All types that’s being used directly or indirectly in XAML is getting type information generated”

But what if I’m not using a type at compile time but only at runtime?” you might ask. That’s an excellent question and this is actually very likely to happen if your ViewModel or Model returns a type not used anywhere directly or indirectly in XAML to begin with, or if you were to use the XamlReader to parse XAML at runtime. This is also where Windows Store Xaml development starts to get really tricky very fast, and while there’s a way around this, it’s definitely not a straightforward one. And I’ll leave you hanging here to ponder on that, while I get working on Part 2 of this blogpost where I’ll get back to the custom IXamlMetadataProviders…

Tags:

Windows Store apps | XAML

Building A Powerful Platform for Windows Store Mapping apps

by Morten 27. March 2013 09:26

When Microsoft announced WinRT at the Build conference in Anaheim, I instantly started researching and prototyping what this new platform could mean for the company I’m working for. The promise of integrating legacy native code with XAML and .NET seemed to finally be the exactly what I’ve been looking for. Also the tight integration between XAML and DirectX, something which is really complex to get working in WPF was intriguing, since we were often hitting the limit of what XAML could do.

We have a huge amount of native code that does a lot of advanced spatial analysis, advanced map rendering, spatial databases, etc. Even better was that most of it is written in a cross-platform way using C++ and was already running on Windows Classic, Linux, iOS, Android and several other platforms.

In hindsight I’m really amazed how quickly this work can go. Granted a lot of time was spent on researching, prototyping, ‘socializing the idea’ etc, but after we had the bases right, we were actually able to move very fast, and in less than 3 months create a whole new SDK geared for the Windows Store (albeit beta).

The things that made this go so fast was:

  1. We had lots of C++ code that was already written to be compiled cross-platform, so most of the development time was spent on exposing this via the WinRT interface and C++/CX.
  2. We chose to build a hybrid SDK based on both C++ and C#. This enabled us to port large amount of our existing C# code from our WPF and Silverlight SDKs. It also allowed us to not be limited by the inheritance limitations that WinRT has by simply creating .NET class libraries rather than WinRT class libraries, which in turn greatly simplifies the API for other developers.

Things that set us back:

  1. Our rendering engine only supported DirectX 9 and OpenGL. Windows Store apps require DirectX 11, which is quite different from v9, so a lot of work had to be done there, because we wanted to do it in a way that wasn’t being hurt by the least common denominator (ie. if DX11 supports a feature that DX9 or OpenGL doesn’t, it shouldn’t hold us back from using it). In the end, our map rendering engine became better because of it for all the platforms.
  2. The documentation on SurfaceImageSource (the glue behind DirectX and XAML) was very limited.
  3. Some time was spent on making sure the native code passes certification, although not too bad.

Several people both within the company, from Microsoft, MVPs etc has been extremely helpful getting us through those setbacks. Thank you! You know who you are (and yes I owe you beer :-)

So enough about that. Instead, I would really encourage you to go download our SDK. It’s actually free! Just go to our developers siteand hit the download button. You’ll be required to register/sign in – don’t worry – as far as I know we don’t spam :-)

Grab the download, install it, and create a new C# or VB.NET Windows Store app. Add a reference to the ArcGIS Runtime SDKs, set the build target to x86, x64 or ARM (AnyCPU won’t work since this has cool C++ code in its guts).

image

And now code away. There’s a few samples on how to get started with the API as well as a library reference on the developers site.  We know the documentation is a little slim at this point – we’re hard at work improving that. However we do have a getting started tutorial here: http://developers.arcgis.com/en/windows-store/guide/add-a-map-to-your-app.htm

In addition we have a set of samples in the form of a sample browser available today on GitHub: https://github.com/Esri/arcgis-samples-winstore

There’s also a toolkit with some controls here that you are encouraged to fork and contribute to: https://github.com/Esri/arcgis-toolkit-winstore

I did a short introduction to the API at our plenary about 4 mins into this video:

You can download the source code for the sample I built on stage on my github account here: https://github.com/dotMorten/WinStore-Routing-Sample

Go download and code away today, and ask questions and give us feedback in the forum.

Also please go read the official SDK release announcement here: http://blogs.esri.com/esri/arcgis/2013/03/25/arcgis-runtime-sdk-for-windows-store-apps-beta-is-available/

Tags:

Windows Store apps | Windows Runtime | GIS | ESRI | XAML

Hacking the Silverlight Unit Tests to support returning Task

by Morten 21. December 2012 15:05

The Silverlight/Windows Phone unit test framework has always supported running asynchronous tests – a feature that until recently wasn’t there in WPF without jumping some really ugly (and flaky) hoops. Basically you can write a silverlight and windows phone unit test like this:

[TestClass]
public class TestClass1 : SilverlightTest
{
    [TestMethod]
    [Asynchronous] 
public void Test1() { DispatcherTimer timer = new DispatcherTimer() { Interval = TimeSpan.FromSeconds(2) }; timer.Tick += (a, b) => { timer.Stop(); base.TestComplete(); }; timer.Start(); } }

The problem with this code though is that this is only for Silverlight and Windows Phone. If you are cross-compiling for multiple platforms and want to run on WPF this wouldn’t work. It’s also not pretty that you have to inherit from SilverlightTest, remember to decorate the class with [Asynchronous] as well as calling TestComplete. Even worse, if you forget to stop the timer, it would CRASH the entire test run. The unit test framework is a little flaky when it comes to a task accidentally completing twice (instead of reporting it as an error, it crashes the entire test run and you’ll never get your daily test report…).

With Visual Studio 2012 and .NET 4.5 we can now simply return an object of type ‘Task’ and we would be good to go. This is awesome for testing your new async/await based stuff that returns task. So in WPF you would simply return your task object. As an example, let’s say we have the following really advanced computing task:

public static Task<int> Compute(int input)
{
    TaskCompletionSource<int> tcs = new TaskCompletionSource<int>();
    DispatcherTimer timer = new DispatcherTimer() { Interval = TimeSpan.FromSeconds(2) };
    timer.Tick += (a, b) =>
    {
        timer.Stop();
        if (input <= 0)
            tcs.SetException(new ArgumentOutOfRangeException("Number must be greater than 0"));
        else 
            tcs.SetResult(input);
    };
    timer.Start();
    return tcs.Task;
}

Now to test this in .NET 4.5 (including Windows Store Apps) you can simply write the following unit test:

[TestClass] 
public class TestClass1
{
[TestMethod] public async Task Test42() { var result = await Utility.Compute(42); Assert.AreEqual(result, 42); }
}

Nice and simple. However in Silverlight and Windows Phone you would have to write the following instead (I highlighted the extra or changed code required):

[TestClass]
public class TestClass1 : SilverlightTest
{
    [TestMethod]
    [Asynchronous]
    public async void Test42()
    {
        var result = await Utility.Compute(42);
        Assert.AreEqual(result, 42);
        base.TestComplete();
    }
}

Wouldn’t it be nice if the unit test I just wrote for WPF would work as is in Silverlight and on Windows Phone? Of course you could create a SilverlightTest class that has an empty TestComplete method, define an AsynchronousAttribute just for fun, and sprinkle a compiler conditional around the void/Task return type, but that just feels messy to me.

Fortunately the unit test framework for Silverlight is open source, so it’s possible to hack it in there. There are two main places you will need to change, which I will go through here. Note this is based on changeset #80285.

In the file “\Microsoft.Silverlight.Testing\UnitTesting\UnitTestMethodContainer.cs” we add the highlighted code to the method that detects if the Asynchronous attribute is on a method:

private bool SupportsWorkItemQueue()
{
    if (_testMethod != null)
    {
        if (_testMethod.Method.ReturnType != null && 
            _testMethod.Method.ReturnType == typeof(System.Threading.Tasks.Task) ||
            _testMethod.Method.ReturnType.IsSubclassOf(typeof(System.Threading.Tasks.Task)))
            return true; //Task Support
        else
            return ReflectionUtility.HasAttribute(_testMethod, typeof(AsynchronousAttribute));
    }
    else if (MethodInfo != null)
    {
        return ReflectionUtility.HasAttribute(MethodInfo, typeof(AsynchronousAttribute));
    }
    else
    {
        return false;
    }
}

Next is modifying the Invoke method that executes your test, which is located in ‘Microsoft.Silverlight.Testing\Metadata\VisualStudio\TestMethod.cs’. This is where the main work is done to enable tasks to work:

public virtual void Invoke(object instance)
{
    _methodInfo.Invoke(instance, None);
}

This now changes to:

public virtual void Invoke(object instance, CompositeWorkItem workItem)
{
    var t = _methodInfo.Invoke(instance, None) as System.Threading.Tasks.Task;
    if (t != null)
    {
        if (t.IsFaulted)
        {
            throw t.Exception;
        }
        else if (!t.IsCompleted)
        {
            var context = System.Threading.SynchronizationContext.Current;
            t.ContinueWith(result =>
            {
                context.Post((d) =>
                {
                    if (result.IsFaulted)
                    {
                        Exception ex = result.Exception;
                        if (ex is AggregateException)
                            ex = ex.GetBaseException();
                        workItem.WorkItemException(ex);
                    }
                    else
                        workItem.WorkItemCompleteInternal();
                }, null);
            });
        }
    }
}

Basically it grabs the task that is returned and calls the code that TestComplete would have called or what a raised exception would have called in case the test raises an exception. Also note that we changed the signature of the method to give us the CompositeWorkItem we need to raise these events on. This change does affect quite a lot of other code, but it’s merely a matter of adding the same parameter there as well, and the only place that calls this method (which is the CompositeWorkItem) to set this parameter to ‘this’.

Now you can also write tests that tests for exceptions thrown. Often you don’t even need to await the result in those cases:

[TestMethod]
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public Task TestOutOfRange()
{
    return Utility.Compute(0);  //no need to await
}

[TestMethod]
public Task TestOutOfRange_Failure() //This test will fail
{
    return Utility.Compute(0);
}

And here’s what that looks like for the entire test run:

image

To make it easy on you, you can download the modified unit test framework source here.

…But EVEN better: Go vote for this to be part of the official toolkit here:  http://silverlight.codeplex.com/workitem/11457

Tags:

WPF | WPF vs Silverlight | Windows Phone | Windows Runtime | Silverlight

A Simple Way To Use App Simulator For App Purchases

by Morten 26. November 2012 15:06

When you are testing In-App purchasing in your Windows 8 app, you need to use “Windows.ApplicationModel.Store.CurrentAppSimulator” static class instead of “Windows.ApplicationModel.Store.CurrentApp”. This means you’ll end up writing a lot of code like this:

     var licenseInformation =
#if DEBUG
           Windows.ApplicationModel.Store.CurrentAppSimulator.LicenseInformation;
#else
           Windows.ApplicationModel.Store.CurrentApp.LicenseInformation;
#endif
//...
     string receipt = await
#if DEBUG
            Windows.ApplicationModel.Store.CurrentAppSimulator.
#else
            Windows.ApplicationModel.Store.CurrentApp.
#endif
            RequestProductPurchaseAsync(featureName, true)

Yes this gets ugly really quick. Here’s a neat little trick to get around that. Right below your using statements at the top of your file, simply add this alias mapping:

#if DEBUG 
    using Store = Windows.ApplicationModel.Store.CurrentAppSimulator; 
#else 
    using Store = Windows.ApplicationModel.Store.CurrentApp; 
#endif

And in your code you can now simply write:

     var licenseInformation = Store.LicenseInformation; 
     string receipt = await Store.RequestProductPurchaseAsync(featureName, true);

Tags:

Windows Runtime

The Windows Phone Quirks Mode And 3rd Party Libraries

by Morten 9. November 2012 08:10

With the new Windows Phone 8.0 OS a lot of things has changed with the new kernel and CLR, and in addition there are quite a few breaking changes to the SDK. However WP8 has a “quirks mode” that it uses to detect if an app was built for 7.1 (Mango), it will execute it as if it was running on a WP7.1 device. That means that if your app is using some of the features that has changed in WP8, it should continue to run with no problems (I have identified several compatibility issues though). This is great because the over 120,000 apps in the store today should (for the most part) work on your new WP8 device.

However if you upgrade your app and compile it for WP8, you will exit this quirks mode, and your app could potentially break if you are subject to any of the breaking changes. You can find a good list of the breaking changes here: http://msdn.microsoft.com/en-US/library/windowsphone/develop/jj206947(v=vs.105).aspx

Upgrading poses a big problem though: Most of you are probably relying on 3rd party libraries that haven’t been upgraded to or certified for WP8. The Quirks Mode is enabled for your entire app, and cannot run parts of your app in quirks mode, and other parts outside quirks mode. This means if your 3rd party library hits any of these breaking changes and you use it in a WP8 app, your app WILL break.

image

If you are a 3rd party library developer, you should test your library for compatibility. If you find any issues, you should probably release two versions, one for WP7 and one for WP8.

Of course if you don’t really need any of the new WP8 features, my recommendation is to stick to WP7.1; - at least until there’s a big enough user-base for WP8 and a small WP7.1 user-base.

Note: All this also applies to good old browser Silverlight which have had quirks mode for a long time, so this isn’t a new concept. This is actually the reason that the product I work on releases both Silverlight 4 and Silverlight 5 versions, because the Silverlight 4 assemblies causes problems when used in a Silverlight 5 app. We had a lot of customers still stuck on SL4 and others who wanted to use new SL5 features, so we chose to support both for some time. The same will be the case for WP7 which will be around for a while, and you might have to support both.

Tags:

Windows Phone

Why Windows Phone 8 Excites Me

by Morten 30. October 2012 11:00

I'm here at the build conference, where it was announced that we finally got access to the Windows Phone 8 SDK. I’ve been browsing the SDK reference, and found a bunch of stuff that I think is going to make this phone huge.
To me, it’s not about the new improved tile interface, the camera lenses or skype integration. It’s what’s under the hood that is really going to make a difference, allowing us to finally build amazing apps that sometimes were hard or flat out impossible.

So a lot of it is missing features that I felt has been holding back the WP7.5 platform (and will continue with 7.8 which is a sorry excuse of an update that’ll confuse consumers), but I can honestly say that I think the feature-set in the WP8 SDK is a home run and there’s nothing big missing from there that I need (even some stuff I didn’t think I need that I now do :-). I know some of these features are available on other platforms already (flamers move on), but the combination of all of these is what makes this all great.

Enterprise ready

We finally get a full enterprise story with your own “enterprise store”. Before WP8, the only option to deploy apps in the enterprise was developer unlock all the phones, or put them in the store as betas (that expires after 3 months) or make them publicly available but hidden behind a login. None of them was a very good solution. We now get a proper enterprise marketplace for easy deployment and update of enterprise apps.

Bluetooth devices

We now get access to bluetooth devices. This is huge and can spawn a new type of eco system. In my work area that means could mean super-high-precision GPS receivers and laser range finders just to start. But in other areas this could be for instance credit card readers and barcode scanners to do on-the-spot purchasing.

Background downloader

Allows you to queue up large downloads while your app is not running. Great for loading larger amounts of data that your app needs for a specific job or for being offline for extended time.

Hot-swappable storage

With hot-swappable storage you can quickly provision large amounts of data to bring with you in the field. Again this could be huge for the enterprise solution. Having to provision data over the air could be an issue even with the background downloader (think gigabytes of data). Imagine highly detailed maps for a specific region you’re about to enter – you bring the right SD card for that area, and someone else brings another SD card with data for their area.
And for those who just want to throw music on there and needs more space: It’s greatc for that too :-)

Direct3D

Direct3D support! We now get direct access to the GPU. This allows us to write high-performance rendering for games, maps, etc. Note: There’s no Direct2D support (but I’m sure someone will build that on top of D3D for us soon, since it really just an abstraction on top of the 3D libraries).

Native code support

We can now write/reuse/run native code on our smartphones. You might not want to write C++, but there are huge amounts of libraries today written in C++ that we can now use. Think of for instance the Sqlite Database. Where I work we have huge amounts of native libraries that has taken years to develop and would be near-impossible to port to .NET, not to mention they require the fastest possible processing of large amounts of data, and C++ is more or less unmatched for that purpose. This doesn’t mean you have to write your entire app in C++. It could just mean that you bring in a native library (like Sqlite) and code against it from C#. The integration is very similar to WinRT (in fact they call it WinPRT – ‘P’ for Phone, and shares a lot of libraries too). So you might never have to worry about native code, but you can still get the benefit of other 3rd parties’ hard work!

.NET

Having .NET (and C#/VB.NET) is not really a new feature, but having worked in the ISV space for many years, and delivering SDKs to smaller ISVs, I know how important it is to have a .NET SDK. Many smaller businesses often have a developer or two, and most of them I find to be .NET developers. The fact that they can write a quick app for their enterprise in an environment that are familiar to them will be huge. This is probably the biggest differentiator to all the other phone platforms.

 

 

New Windows Phone 8 SDKs (slide from Build Keynote)

Tags:

Windows Phone

About the author

Morten Nielsen

Silverlight MVP

Morten Nielsen
<--That's me
E-mail me Send mail

Twitter @dotMorten 

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright 2005-2014

Month List

Recent Comments

Comment RSS