Thursday, 30 July 2015

Page.Loaded Fails to Fire

Yesterday, we installed windows 10.

We tried out our app BouncingBalls and was surprised that the balls didn’t start bouncing, when they did on Windows 8.1

Even more oddly, if you opened the settings page, they would suddenly start bouncing.

Firing up the debugger, we found that Page.Loaded was not firing when we navigated to the main page.  The code we use is similar across all of our apps, but for some reason this particular app was not behaving.

After quite a bit of code hacking, we found it came down to the handling of the splash screen.

We add a handler for Splashscreen.Dismissed, and handle navigation to the main page (or another page depending on trial mode) from there.

In our OnLaunched handler, we called

Window.Current.Content = _launchframe;
Window.Current.Activate();

but we hadn’t yet navigated to a page, or set any content for our frame _launchframe.

In the Dismissed handler, we did this:

var nowarn = _launchFrame.Dispatcher.RunAsync( CoreDispatcherPriority.Normal, () => ContinueAfterSplash1());

And in ContinueAfterSplash1() we eventually call after a few async calls.

_launchFrame.Navigate(typeof(BouncingBalls.MainPage), args)

MainPage received an OnNavigatedTo call, but never received the Loaded event we wired up.

The solution?

In the end, we changed the code not to call Window.Current.Content until after we successfully navigated to the MainPage.

For whatever reason, that caused the Loaded event to fire every time.

How to install VS2015 Community

If you have more than one machine, you may not want to wait for every package to download over and over again.  Here’s how you can get an image on your PC

First head on over to https://www.visualstudio.com/downloads/download-visual-studio-vs

Click on Download Community Free, which will save a file onto your PC named vs_community.exe

Then open a command prompt and run the program with the /Layout argument.

That will download everything onto your PC.

Did you do this before the SDK was released?

I tried installing the standalone SDK, but unfortunately, that didn’t update VS2015 to include the Windows 10 portions.

However, I found that you could get the SDK by running the /Layout argument again and extracting to the same location.  If you then run the setup again, you’ll get the the options for installing the universal tools and the SDK.

I did this after I uninstalled VS2015 though.  You may not need to do that step.

After the download completes

Now just run the vs-community exe again and choose your installation options.

Tuesday, 21 April 2015

What Broke My App This Time? The XAML Editor

In one of my base classes, I implement a handler for a particular event.

The idea was that I have have a certain set of things I always want to do in my framework when the bottom appbar opens.

So I took one of the classes, typed Opened=”BottomAppBarOpened” into the xaml editor on the BottomAppBar, and then right clicked and chose Goto Definition.

That opens the code behind and implements the method.

I then cut the method from there, and pasted into the base class, changed it to a protected virtual, and thought “Bob’s my uncle” (he is, actually)

So, that was weeks ago.  Today, I was looking for that code, and clicked Goto Definition.

This time, I got a new private implementation (just like the first time, naturally), that hid the virtual function.

As a result, I’ve now changed my code so each class that has this, implements the method and calls the base class implementation.  It’s a shame the editor can’t see the inherited signatures, and jump to that instead.

It’s the Templates Stupid! (The joys of XAML)

I’ve been trying to solve some usability problems with text being too small to read on a 7 inch tablet for people who are ageing, and tried to increase the font size in my app.

Much to my dismay, that caused RadioButtons and CheckBoxes to align badly.

Eventually I tracked down the alignment problem to the alignment of the button or checkbox always being top in the template, while the content inherited it from the control.

 

I’ve published my updated templates as a Gist.

In addition, on 8.1 you may also want to set the content to be a TextBlock with TextLineBounds=Tight to get the best results.

Sunday, 29 March 2015

Most of my Windows 8 apps are broken. Yours probably are too.

Tonight, after a day of user testing an upcoming app, we ran into some crashes, and some undesirable behavior.

So, we set about trying to fix the problems.  So far so good.

One of the problems was the app needed to keep the display from timing out while running.

Enter DisplayRequest and it’s RequestActive and RequestRelease methods.  On a particular page in my app, I called RequestActive during OnNavigatedTo and RequestRelease during OnNavigatedFrom.

Unfortunately, we ran into trouble when we started playing with our suspend/resume handling.  They started throwing ArithmeticExceptions!

So, a quick check of the DisplayRequest Documentation shows some sample code with it catching exceptions.  As a result, I eventually decided to write a wrapper class to handle the outstanding requests, and follow he advice on that page.

  • Release all display requests when the app is suspended. If the display is still required to remain on, the app can create a new display request when it is reactivated.

To support this, we called RequestRelease for each time it had been requested active, and in the restore code, we call request active again.  Unfortunately that still didn’t work, as it turned out that OnNavigatedFrom was being called after we’d released everything in the Suspending call.  So, I went looking for trouble.

Usually when you look for trouble you can find it

Turns out, I wasn’t the only one with problems.

This discussion on the Suspension Manager points out the issue of things not being called in matching pairs.

And this advice about Saving and Restoring State in a Windows 8 XAML App shows that you only call SuspensionManager.RestoreAsync() in certain cases.  I expect that’s derived from the advice on this page about Application Lifecycle where they explicitly state “most apps don’t need to do anything when they are resumed”  The advice from Patterns and Practices is similarly broken.

And that combination is the cause of the bug.

Naturally, after 3 hours of research, I now no longer need my global class that manages the count of the number of DisplayRequest.ReleaseRequest and RequestActive calls I’ve made.

 

TL;DR

On a suspend your OnNavigatedFrom handler may be called, but on resume, OnNavigatedTo isn’t.  All sorts of paired handlers may not work as you expected.

You might want to look at OnNavigatingFrom instead but I’m still not convinced that’s correct either.

Thursday, 23 October 2014

Password incorrect for blogger.com

A few moments ago I tried to post a new entry for my blog, and found that the password was being denied.

What I needed to do was log into my google account, and the go to the security settings, and change the account permissions, particularly the access for less secure apps:

image

Changing this to enabled allowed it to work again.

When Bindings Fail, and text blocks show double quote greater than

Today I was tracking down a bug where my text block was showing “> (quote greater than) when the data context was null.

I’d run into this problem once before in a WPF application, but couldn’t remember what the resolution was. 

After playing around for awhile, with various things fixing the problem, but for no apparently good reason, I had another look at the XAML.  A really close look.

Here was the XAML:

<TextBlock Style="{StaticResource StrokeSummaryBigValue}" 
                          Text="{Binding Rating, Converter={StaticResource rating}}">"></TextBlock>


It looks like while typing, intellisense had entered an extra “> into the code, so that when the binding failed, it showed the text contained in the text block.


So there you have it, if you see this behavior, search your code for “>”>

Monday, 2 June 2014

Universal Apps: partial understanding

One of the ways to build a universal app is to use the partial keyword to allow you to split out functionality that must be different between platforms.

We tried this with our error reporting code, loosely based on LittleWatson.

There is good documentation here http://msdn.microsoft.com/en-us/library/wa80x488(v=vs.90).aspx on partial classes, but despite what it said we just couldn’t get it to work correctly.  So we concocted more and more bizarre ways to use partial, so that the program would compile, including partial methods (which unless implemented the compiler optimizes out).

In the end, it turned out to be nothing related to partial at all, that was preventing our methods from being called.  What had actually gone wrong was this:  We had inadvertently put half of the partial class in a different namespace, thereby making it invisible.  It’s no wonder we couldn’t find member fields in our main implementation.

Pitfalls of adding WP8.1 support to a universal app (Part 1 of N)

As part of our continuing port from Windows 8.1 to WP8.1 of Surface Level, I’ve just recently tracked down a problem thrown during suspension.

We’d already written quite a few classes that would act as a base class, and as a result, I implemented a partial method which I could call for certain tasks.  One of these tasks was registering our Suspension handler.

The bug I was seeing was an end of file reached while reading back our state file, which we use when we resume.  But there were two problems

1.  I kept getting odd suspension manager exceptions in my crash logs.
2.  The suspended handler never seemed to be called anyway.

Item 2 was the first to solve.  It appears that like W8.1, apps aren’t suspended when run in the debugger.  The only problem was, I couldn’t find the UI to shut it off.

Well, eventually I found it here on the Debug Location toolbar:

image

Clicking Suspend actually caused my suspension to run (twice in fact)

The first crash was caused by the state file being read only (a side effect of running suspension twice).  It turns out that when I added the WP8.1 project, the wizard had added a second call wiring up the suspension code, which I hadn’t spotted.  Removing the duplicate wiring allowed me to get suspension working properly.

String.Format and Cargo Cult Formatting

While working on a port of our Surface Level app to a universal app, I stumbled across some exceptions being thrown in a great matrix library I picked up from here:

http://blog.ivank.net/lightweight-matrix-class-in-c-strassen-algorithm-lu-decomposition.html

Internally, the code was eventually calling

String.Format("{0,5:0.00}", v);


and the bug was caused by a leading space while parsing.


I’ve noticed this string before in some of the Microsoft accelerometer samples, but never actually looked at what it did.


It turns out the ,5 makes the field right justified, filling 5 characters, and padding with spaces.  In all of my testing up to now, I never saw this, but somehow on the latest device, I saw a value of 0, which ended up with a leading space.


The bug has now been fixed by the author in another way, but it points out the importance of actually reading every line of code, and understanding it before you put something into a project.

Sunday, 1 June 2014

Why is documentation so terrible these days?

I’m recovering from ankle surgery after a low speed skiing accident that I had in February, and have decided to take the opportunity to port our Surface Level to Windows Phone 8.1 that I wrote while recovering from the initial accident.

I have about 8 weeks where I’m unable to drive, so will be working from home and very bored, so as a result, will have plenty of time for the project.

One of the things I’ve noticed both for my apps, and my job is that the documentation supplied by companies these days appears to be getting worse.  For instance, in my day job, I’m currently building an embedded system based on an STM32F4 microcontroller, and hooking it to a variety of WIFI modules on the market (the only reason for the variety is we keep coming to problems that aren’t documented, and then prevent us from using a particular module in our product).

I’m not sure if the documentation is intentionally bad so that competitors can’t find the weaknesses, or if the product is bad because it’s rushed to market, or if it’s just pure incompetence.

So, back to Surface Level.  While building the Windows Phone 8.1 version, I added back some code from the working Windows 8.1 version, including an AppBar

 

image

A quick check of the docs shows it works, but then when I run the program I get this:

A first chance exception of type 'Windows.UI.Xaml.Markup.XamlParseException' occurred in SurfaceLevel.WindowsPhone.exe

WinRT information: Cannot create instance of type '%0' [Line: 17 Position: 17]

Additional information: The text associated with this error code could not be found.

Well, that’s a helpful message.  Line 17 does in fact have this on it:

<AppBar x:Name="BottomBar" Opened="OnOpened">

But position 17 is at x:Name?!

If you do manage to get all the way down the page in the online version of the documentation, you might find this:

image

Oh, I see.  I can’t use it.

Then I tried to mirror the front camera, like I do on the Windows 8.1 version, like this:

mediaCaptureMgr.SetPreviewMirroring(selectedDeviceInformation != null ? (selectedDeviceInformation.EnclosureLocation.Panel == Windows.Devices.Enumeration.Panel.Front) : false);

That throws an exception, because the phone camera doesn’t support it (at least not on my phone), and there’s some helpful documentation in the remarks section:

Horizontal mirroring is useful for video conferencing or video chat applications, because the users typically want to see a reflected image of themselves. The non-mirrored view can look strange, because we are used to seeing ourselves in a mirror.

To mirror the preview video, apps should instead use the following method. Windows Store apps using JavaScript should use the msHorizontalMirror property of the video object. Windows Store apps using C++, C#, or Visual Basic should use the FlowDirection property on the CaptureElement.

SetPreviewMirroring can potentially be used as a performance optimization on some devices

So, we have a method that we shouldn’t use.

While the information is there, it takes at least 20 minutes to discover why things aren’t working by poring over the documentation for each and every method/function call, and my first language is American English.  I feel really sorry for people who aren’t native speakers.

Saturday, 31 May 2014

I don’t think the EU knows how the internet works

From January 2015, small software developers have a new administrative hassle to worry about: EU VAT

https://twitter.com/HMRCgovuk/status/472696531213381633

HMRC has issued guidance on the new VAT place of supply rules for digital services, coming into effect on 1 January (2015): http://ow.ly/xnvTt

If you’re VAT registered, and selling software B2C in the EU, you now have to account for VAT to the country where each individual belongs.  Have a read of section 1.5 of the above link, and see just how much fun this is going to be.

If you only get paid through an app store, you’re probably OK, as the app store will take the hit, but if like us you collect payments directly via PayPal, it’s going to become very difficult, unless we’re allowed to assume that the PayPal registered address is in fact the one that applies to the customer.  In that case, we can set a different rate of VAT for each country.

However, we still have to pay the VAT to each and every country it’s due to, instead of to a central EU body.  As a result, this will increase costs enormously selling outside of our home countries.  My prediction is that this will lead to a reduction in the amount of independent software available, as the overhead of filing in each country is not generally worth the returns from the sales to those countries.

VS2013.2 : One step forward, two steps back

We try to make it really easy to put together a new application by using the Export Template feature of VS2013 Pro.

Currently we have one template for all of our windows 8 apps, and another for our windows phone apps.

To start a new application, we use VS2013, and say File | New Project

Select our template and we’re off.  In that state we already have our view models, initialization and serialization frameworks, etc.  All of these are built from source files, and aren’t in a class library anywhere, and using templates makes it very quick to create a new independent branch.

We thought that with the advent of the new Universal Apps, we might be able to solve these problems once and for all, however, it isn’t working out like that.

The export template functionality is still there, but it doesn’t work.  You can export the shared project (but that doesn’t show up on the new project templates), and you can try to export either the WP or Windows Store projects, but they fail throwing an error about bad characters in the path.

So, from what I can see, we’ve lost this great functionality.

It appears that you could code up a template by hand by hacking through what’s in the universal app templates, but I’m not sure I can be bothered to at this stage.

With any luck, I’ll find a solution, and post it back here.

Saturday, 14 December 2013

WP7 Run Under Lock Screen Mystery

My son just returned from the Varsity Ski Trip, and used Skied Demon on a Windows Phone 7.  Now I know there aren’t many people out there who actually have one of these phones, and we rewrote the software to work while making phone calls on WP8, however, it still irks me when code we wrote doesn’t work for some of our customers.

The problem goes like this:

My son starts logging in the app, and then presses the power button to lock the screen and save power.

Later, he sees something that requires a photo and presses the camera button to wake up the phone.

After he backs out of the camera, he finds that the program is no longer running.

Of course, while on holiday, he had better things to do than tell his father an app isn’t working like he thinks it should be, but now he’s back, I’ve looked into the cause (30 minutes from bug report to investigation.  That’s how we like to treat all bug reports, so if one of our apps crashes, let us know, and we’ll investigate).

It turns out that the software is  getting a RootFrame_Obscured message, when he presses the lock screen.

When the camera button is pressed, an Application_Deactivated event is raised, my state is stored, and that’s the last my code ever sees of any execution time.

The program does have a background XNA thread for audio that’s raising a System.Threading.ThreadAbortException in Microsoft.Xna.Framework.dll before it exits however.

Any suggestions?

Sunday, 1 December 2013

NullReferenceException in AdDuplex

We recently switched over to AdDuplex in our trial apps to get some extra promotion, as using the Microsoft PubCenter.

Last night, while waiting around, I started playing with one of them, and found that the app would crash, with the following call stack when connected to BTOpenZone, but not logged in.

System.NullReferenceException
Object reference not set to an instance of an object.
   at AdDuplex.AdControl.OnNetworkManagerAdLoaded(Object sender, AdLoadedEventArgs e)
   at AdDuplex.Models.NetworkManager.OnAdLoaded(TextAdInfo newAd)
   at AdDuplex.Models.NetworkManager.<>c__DisplayClass2.<LoadNewAdCallback>b__0()

I vaguely remembered seeing an update to the AdDuplexW8 nuget package midway through my updates that said that it fixed a null reference problem.

Obviously, this was it.

So, if you’re not using AdDuplex.WindowsPhone version 2.8.0.4 or later, you’ll need to rebuild your apps and resubmit, or else your app too will crash.

Friday, 29 November 2013

Where’d my interface go?

One of the joys of modern development is that you get to work in pretty much any language there is.

I’ve been doing a lot of C# development lately (Phone, WinRT and WPF desktop), but occasionally have to drop back to some C++/MFC software.

Yesterday, I had to refactor some code, that made some glaring assumptions about it’s use (yes, I used reinterpret_cast to convert a CWnd derived object to a class derived from CPropertyPage so that I could call one of it’s public members).

So here’s what I did:

First, I declared an interface that represented exactly what I wanted to do:

interface IDoSomethingAwesome
{
public:
virtual void DoSomethingAwesome()=0;
};


Next, I modified my class, which needed to expose the interface


public class MyAwsomePropertyPage : 
public CPropertyPage, IDoSomethingAwesome
{
/// ... etc.
virtual void DoSomethingAwesome() override;
}


and provided an implementation in the class.


Then in an unrelated class, I made a call like this


CChildOfAwsome::SomeEventHander()
{
IDoSomethingAwesome *pInt = dynamic_cast<IDoSomethingAwesome>(GetParent());
if (pInt != NULL)
{
pInt->DoSomethingAwesome();
}
}


Only one problem:  pInt was always NULL!  That was odd, because looking at the pointer returned by GetParent() gave me an object that the debugger knew was of type MyAwesomePropertyPage, yet I couldn’t for the life of me figure out why this wasn’t working.


I started writing this up as a question on StackOverflow, but while doing so, ended up talking to the duck and discovered the error in my ways.


My C# had blinded me to the joys of C++ inheritance.


I had inadvertently declared my IDoSomethingAwesome interface not public.  As a result, asking for the interface dutifully returns null, as private inheritance is an implementation detail, and not visible in the inheritance tree.


So, the correct declaration is

public class MyAwsomePropertyPage : 
public CPropertyPage, public IDoSomethingAwesome
{
/// ... etc.
virtual void DoSomethingAwesome() override;
}

Friday, 22 November 2013

Tap My App! Share your App with NFC!

As part of the DVLUP challenges, you can gain up to 500 points by adding NFC to your app.

Thanksgiving’s coming up very soon, so I thought sharing our Wishbone application between Windows phones would be a really cool way to do it.

If you read the documentation, you’ll find something promising in the ProximityDevice.PublishBinary documentation named LaunchArgs.WriteTag

There are some magic parts to this documentation that are a little bit difficult to work out, as I’ll soon describe, so your journey down this route will be frought, and unfortunately, after a lot of pain, I finally realized that this would not work, as it only writes to static tags.

I’ve ordered some of them like this, and they’re in the post.  I can't wait for the fun I'll have with these, but I digress.

The important thing to realize is that there aren’t any static tags on your phone.  I for some reason thought that what was happening is that you could write to them from your code, and appear as a tag.  That is most definitely not true.

So how do you launch your app?

I’ve come up with a class that makes all of this really easy.  Here’s the code that I add to my Application_Launching event handler.

mgr = NFCManager.Default;
if (mgr.NFCSupportedOnDevice) {
mgr.DisplayName = "Wieser Software Wishbone";
mgr.AddAlternateIdentity(platform: "Windows",
appid: "WieserSoftwareLtd.BouncingBalls_38031z1jk36d6!BouncingBalls.App");
mgr.Enabled = true;
}


Now if you tap your WP8 app against a Windows Tablet with NFC, it will attempt to launch our BouncingBalls App (Wishbone does not yet have a W8 version, though it’s in the pipeline for a Tidy 250 XP in the double challenge)


The format of the appid is difficult to determine.  The first part before the “!” character can be found when editing Package.appxmanifest.


The second part is really badly documented.  It is in fact the name of the class that contains the entry point of your App.  Now, we obfuscate using EazFuscator, and as a result, the namespace and class names are probably obfuscated.


As a result, when you tap, and the app isn’t installed, the user is asked if they want to get the app from the store.


On the other hand, if the app is installed, nothing appears to happen.  I can’t decide if this is because my app doesn’t claim that it supports Proximity, or that it doesn’t support networking at the moment, so some investigation is still required.


-update-
After further investigation, it appears that the part after the ! should just say App in my case.


Full source code of the class is available here:


#define NFC_DEBUG_STATUS_MESSAGES
using System;
using System.Diagnostics;
using System.Threading;
using System.Windows;
using System.Windows.Threading;
using Windows.Networking.Proximity;

namespace Framework
{
public class NFCManager : IDisposable
{
static NFCManager _instance;
ProximityDevice _nfcdev;
DispatcherTimer dt;

[Conditional("NFC_DEBUG_STATUS_MESSAGES")]
private void Trace(string s)
{
Debug.WriteLine(s);
}

public void Dispose()
{
if (this == Interlocked.Exchange(ref _instance, null))
{
// this is us.
if (_nfcdev != null)
{
_nfcdev.DeviceDeparted -= _nfcdev_DeviceDeparted;
_nfcdev.DeviceArrived -= _nfcdev_DeviceArrived;
PeerFinder.AlternateIdentities.Clear(); // clear anything we added
Deployment.Current.Dispatcher.BeginInvoke(() => dt.Stop());
_nfcdev = null;
GC.SuppressFinalize(this);
}
}
}

~NFCManager()
{
if (_nfcdev != null) Dispose();
}

private NFCManager()
{
_nfcdev = ProximityDevice.GetDefault();
if (_nfcdev != null)
{
_nfcdev.DeviceArrived += _nfcdev_DeviceArrived;
_nfcdev.DeviceDeparted += _nfcdev_DeviceDeparted;
dt = new DispatcherTimer() { Interval = TimeSpan.FromSeconds(1) }; // tick once per second
dt.Tick += dt_Tick;
}
}

bool bPeerFinderRunning = false;
DateTime dtExpiry;
private void StartPeerFinder()
{
if (!Enabled) return;

if (bPeerFinderRunning) StopPeerFinder();
dtExpiry = DateTime.UtcNow.AddSeconds(15); // don't leave this on too long.
bPeerFinderRunning = true;
Deployment.Current.Dispatcher.BeginInvoke(() => dt.Start());
PeerFinder.Start();
Trace("Started Peerfinder");
}

private void StopPeerFinder()
{
if (Enabled && bPeerFinderRunning)
{
bPeerFinderRunning = false;
// now get onto UI thread to stop the timer
Deployment.Current.Dispatcher.BeginInvoke(() => dt.Stop());
PeerFinder.Stop();
Trace("Stopped Peerfinder");
}
}

// check if we've overrun, and if so, Switch it off.
void dt_Tick(object sender, EventArgs e)
{
if (dtExpiry < DateTime.UtcNow) StopPeerFinder();
}

// this runs on some arbitrary thread
void _nfcdev_DeviceDeparted(ProximityDevice sender)
{
StopPeerFinder();
}

// this runs on some arbitrary thread
void _nfcdev_DeviceArrived(ProximityDevice sender)
{
StartPeerFinder();
}

public static NFCManager Default
{
get
{
if (_instance == null)
{
_instance = new NFCManager();
}
return _instance;
}
}

public bool NFCSupportedOnDevice { get { return _nfcdev != null; } }

/// <summary>
/// Adds an alternate launch string, depending on your platform.
/// Sample values are for Windows 8
/// platform:"Windows", appid:"WieserSoftwareLtd.BouncingBalls_38031z1jk36d6!BouncingBalls.App"
/// where the part before the ! is your package ID, and the last part is the
/// namespace of your Application Object (full namespace). This is despite obfuscation.
///
/// For Windows Phone 8: The GUID is your app ID.
/// platform:"WindowsPhone", appid:"{41004b9e-eab4-4784-94d6-d1bdd219e4de}"
///
/// Don't add an alternate identity for the platform you're on, or you'll get an exception
/// </summary>
/// <param name="platform">see strings above</param>
/// <param name="appid">see strings above</param>
public void AddAlternateIdentity(string platform, string appid)
{
PeerFinder.AlternateIdentities.Add(platform, appid);
}

public string DisplayName
{
get { return PeerFinder.DisplayName; }
set { PeerFinder.DisplayName = value; }
}

private bool _bEnabled;
public bool Enabled {
get { return _bEnabled; }
set
{
if (!NFCSupportedOnDevice) throw new NotSupportedException("There is no NFC support on this device");
if (value != _bEnabled)
{
StopPeerFinder();
_bEnabled = value;
}
}
}
}
}


A couple of comments on the code:


First, you’ll need to enable ID_CAP_PROXIMITY on your app.


You’ll also note some code that uses a dispatcher timer that fires once a second once a device has come in range.  This code is there to switch it off if a connection isn’t made in time.


Have fun, and follow me on @WieserSoftware

Sunday, 17 November 2013

AdDuplex requires ID_CAP_PHONEDIALER

We’ve recently started using AdDuplex in our trial apps to get some extra promotion, as using the Microsoft PubCenter. 

We previously had the Microsoft Ad Control in the app, and it required a lot of capabilities that frankly I think scares off users.

So, I was very happy to learn that AdDuplex required only ID_CAP_NETWORKING

One of the apps we updated was a WP7 app, and as part of the submission Capabilities are automatically detected (this is no longer the case on WP8), and I was surprised that it flagged up ID_CAP_PHONEDIALER.  I suspected that I had done something wrong with remove of the old ad control.  ID_CAP_PHONEDIALER is added when you use the PhoneCallTask API

So I fired up JustDecomple from Telerik and did a search for that in my xap project.

Eventually, that led me to the AdDuplex.Models.NetworkManager class and it’s DisplayPhone method, which is called by AdDuplex.HandleAdClick

It turns out that if a phone number is supplied by the ad, that is the preferred mechanism for serving the ad!  I contacted AdDuplex about this, and I was told that the server currently will not serve these ads.

What DOES this mean for users of the control?

In the case that it does in the future, you will be pleased to know that your app will crash if you haven’t added the capability to your app if the user clicks on one of these links.  This also means that a man in the middle attack on AdDuplex’s servers could also cause your app to crash.

I contacted AdDuplex to ask about this and was told:

“We will consider removing the capability from the SDK. It’s only there for some future feature which is unlikely to materialize any time soon and we don’t actually want to serve ads like that. Thank you for bringing this to our attention.”

In the meantime, it’s still there in the latest November 14th update, 2.8.0.4

Saturday, 16 November 2013

Slider and IsDirectionReversed–Why doesn’t my app work on WP8 (part 6 of N)

Just when you thought all the bugs must have been ironed out by now, you stumble across a new one.

I’ve recently been updating all of my apps to Visual Studio 2013 so support will be simpler in future, and as a result started porting to WP8 from our old WP7 codebase.

Of course, everything is supposed to just work.  Today we’ll focus on the IsDirectionReversedProperty, which as will see should really be called IsDirectionReversedProperly!

Try sticking this in your WP app:

<Slider Orientation="Horizontal" Maximum="10" IsDirectionReversed="True" />

Can you see where this is going?

Now add Minimum="5" and be amazed that this slipped through testing.

It’s broken on the 720p emulator.  It’s broken on my Lumia 920 with GDR3.  It’s not broken in a WP7 app though.

So, I wonder how Microsoft can fix this out in the wild, (though it only seems to work in any kind of reasonable way if Minimum is set to 0).  Someone may be depending on this behavior.

Sunday, 10 November 2013

RateMyApp challenge on DVLUP code defects and gotchas

If you’re trying to run the RateMyApp challenge over at DVLUP (if you haven’t signed up, you should.  Click the link), you may be interested in a few problems I’ve stumbled across.

First, your app bar will still be active, even if the rating window is open. 

To fix that, you’ll need to wire up to the feedback controls VisibilityChanged event, and then in the handler, set

ApplicationBar.IsVisible = FeedbackOverlay.GetIsNotVisible(feedbackctrl);

Secondly, you’ll find that if you have any touch events, they may be handled as well.  This includes ListBox manipulation and scrolling, so you’ll need to turn that off in the handler too.

And finally, the bug.

If your app has multiple pages you’ll find that on the 5th and 10th run, your user will continue to be pestered every time you navigate back to the main page of your app.

To fix this, I suggest you do the following:

In FeedbackOverlay.xaml.cs add the following to the SetVisibility(bool visible) function inside the bottom of the else statement:

FeedbackHelper.Default.State = FeedbackState.Inactive;

If you don’t, the state will remain the same, even though the FeedbackOverlay was dismissed, so it will continue to be shown.

In addition, you must also change the yesButton_Click handler to SetVisibility(false) at the end of the function, rather than the beginning.