Your UWP Push Notifications are now Toast

By | November 16, 2015

I recently pushed an update to the UWP I’ve published to the store at work. After installing the app on my 10581 Windows 10 device and using it all weekend, I was dismayed to see when I received a push notification the app didn’t do what it was supposed to do.

I dove in.

When using Template10, a sequence of events kicks off when your app is launched no matter what the trigger:

  1. OnLaunched is fired and intercepted by Template10’s Bootstrapper in OnLaunchedAsync() and handles the launched event of the app, and throws this down in to an internal method (InternalLaunchAsync).
  2. InternalLaunch initializes the frame (if the app wasn’t previously running) and does some other work.
  3. Frame Init triggers OnInitializedAsync which you may/may not have overridden to do some Shell work, etc.
  4. OnActivated is fired and intercepted by Template10’s Bootstrapper in OnActivatedAsync() and will re-initialize the frame if it’s needed or kick off OnStartAsync which is intended to be *the* only method you need to handle to react to your app being fired up; you’re required to override this as part of using Template10’s Bootstrapper.cs as the base for your Application class.
  5. In OnStartAsync() it’s advised to run Bootstrapper’s DetermineStartCause(args) to determine how your app was launched; Toast, Tile, other?

Let’s have a look at DetermineStartCause(args):

   1: public static AdditionalKinds DetermineStartCause(IActivatedEventArgs args)
   2: {
   3:     if (args is ToastNotificationActivatedEventArgs)
   4:         return AdditionalKinds.Toast;
   5:     var e = args as ILaunchActivatedEventArgs;
   6:     if (e?.TileId == DefaultTileID && string.IsNullOrEmpty(e?.Arguments))
   7:         return AdditionalKinds.Primary;
   8:     else if (e?.TileId != null && e?.TileId != DefaultTileID)
   9:         return AdditionalKinds.SecondaryTile;
  10:     else
  11:         return AdditionalKinds.Other;
  12: }

It’s pretty simple. At each step of the launch sequence, the args for how the app was executed are passed around. In here, we attempt to figure out the exact way it was launched based on the args’ concrete type or other properties.

Here is where Microsoft just broke your UWP and you didn’t even know. If you were using the non-adaptive toast templates, your args are no longer of type ToastNotificationActivatedEventArgs and instead are just plain old LaunchActivatedEventArgs. Furthermore, the .Kind property isn’t set to ToastNotification anymore either. I have noticed this in Windows 10 10581+ (mobile or desktop).

Turns out, we had some warning of this, to give MS a small leg to stand on as on this page back in July they wrote:

2015-11-16_1301

welp, it’s done!

If you want your UWP to properly handle toast notifications (y’know, like it used to) you must now be using adaptive templates when you push them.

Why was I using legacy templates? I found out early in our development cycle that the adaptive Tile templates didn’t do the peek image/text format correctly on mobile (no, I haven’t tested it since), so I just scrapped using Adaptive altogether. Furthermore, we’re using Urban Airship to handle pushing our notifications across many platforms, and they’ve got zero mention of support adaptive templates so I didn’t want to push the envelope.

Update: I’ve been advised that the recommended “workaround” for this particular issue is to throw something additional in to your launch arguments that signals it’s coming from toast if you’re going to use the legacy templates (eg: launch: “toast?<old arg>”) then parse the .Arguments property w/in your app to determine if you’re coming from toast or not. I’ve also been told that toasts have been this way since the start of Win10 of which I’m adamantly asserting is not the case; if you, too, got caught by this please speak up in the comments. Thanks!