Cordova for Windows 10 troubles

One of my recent tasks at work was to port a mobile web app to Windows 10 UWP. The app was built using Apache Cordova, and as Cordova and Microsoft worked together to support Windows 10, this should be pretty straightforward. Nobody really expected it to be as simple as it was advertised, and I was ready for the multi platform development troubles.

cordova platform add windows

First things first, go to Cordova website, read some documentation on how to add a platform and create a project to start working. Ok, platform added, Windows UWP project created and I was ready to start the app. After a few days (yes, days), of html and web problems solving I finally had the app running. Now this was just the web part of the app, without the native plugins that the app needed. Some of the plugins were available and some of them didn’t support Windows. For those we agreed to not use them at the moment, but there was one custom built plugin which we really needed to have – Parse SDK which was used for push notifications.

Parse

I used Parse SDK on native Windows (Phone) 8 applications before and knew how to work with Parse. The first problems started when I realized Cordova for Windows 10 is not using .NET C#/XAML, but JavaScript app. So the Parse .NET SDK couldn’t be used here. Ok, Parse also provides other SDKs as well as REST API for communication so I was ready to adapt. I went on by adding the JavaScript SDK to the app, but nope, it can’t be used on a client for push notifications. It simply doesn’t have the needed functionality like registering the device for receiving push notifications. The JavaScript SDK was built mainly for server side and Parse Cloud Code implementation.

Ok, but I knew this is a Windows UWP app, it should be able to execute some .NET code. I went on researching how to create a native Cordova plugin for Windows 10 and found out that although they were intended to be written in JavaScript using WinJS, there was also an option to have .NET native plugins written as Windows Runtime Component. Until then I wasn’t familiar with those kind of projects, after all I never really worked with multi-platform technologies, but rather developed native Windows apps. So this Windows Runtime Component is something like Class Library, but much more restrictive as it can be consumed by languages outside the .NET world. So I created one such project, added the Parse .NET SDK reference, and packed it all in a Cordova plugin. The app was working! Push notifications coming! Let me just mention Parse .NET SDK doesn’t support the Windows 10. But as it was open sourced recently I modified it a bit and was able to make it work eventually.

.NET native

Let’s pack this up and submit to the store, I said. Not so fast, Windows App Certification Kit replied. Apparently I was using some unsupported APIs coming from some suspicious .DLLs. A quick google search pointed that I wasn’t using .NET native compiler. It’s a new thing from Windows 10, in short it means apps are compiled to machine code and as such distributed to the store. Advantages being smaller app packages, faster downloads and installations. Ok, but why it wouldn’t use the .NET native, why do I need to enable it myself and where do I do it? I compared the .jsproj created by Cordova, and .csproj created by Visual Studio when you create a plain Windows 10 app from the template. The native app had a directive <UseDotNetNativeToolchain> which my Cordova app didn’t have. Now I wasn’t sure if that was intentionally missing as Cordova app wasn’t a .NET app, so maybe it didn’t even need the .NET compilation. But I tried with it and wow, the unsupported API error was gone. One small win for me against Cordova bugs.

Now I had the .appx package which was passing the WACK tests and went to submit it to the store. The Dev Center then said: “You cannot submit pre-compiled .NET Native packages. Please use .appxupload file for store submission”. Hm, Ok I know what the .appxupload file is, a simple zip with .appx file inside, but the Visual Studio didn’t create one for me. And for Windows 8 apps I used .appx files for store submission fine. Now how do I get the .appxupload manually? After quite a bit googling I found about MSBuild tool which is used internally by Visual Studio to create app packages. It was hard to find any related documentation on how to use it to produce .appxupload file, but some more googling I came across this blog post which helped me to finally create a .appxupload file. All right, store submission went fine (not immediately, but I’ll skip boring parts), the app was in store. Installed it, tried to get push notifications but no, they are not coming and device is not registering on Parse to receive them. Seems like my Parse plugin wasn’t working. Unpacking my .appxupload and .appx file inside it, I saw there were no Parse .DLLs inside. Somehow in debug build mode they are packed, but in release they are not. Here’s my StackOverflow question which remains unanswered at the time of writing this post which explains it a bit better. Team from Visual Studio Cordova Tools tried to answer but couldn’t really help me solve the issue.

HTTP to the rescue

I suspected the .DLLs couldn’t be used in Windows Runtime Component and .NET native combination, but never got any errors or found it documented anywhere. All the Windows Runtime Component plugin examples were rather simple and weren’t really helpful for my case. I tried to see what happens when I convert the Parse SDK to Windows Runtime component – it was bloody, red error symbols everywhere. It would be a project itself fixing it all up with no guarantee it would be possible and worked at all. Although I tried for quite some time to make this work in release mode as it did in debug, eventually I went by yet another approach – Parse REST API. Official documentation stated push notifications could be used only by native client SDKs. Device push notification registration was done by the SDK and Parse own logic on server side. Nevertheless, I tried to emulate the native SDK via the REST API by creating device installation objects “by force” (a HTTP POST request really). I didn’t expect it to work so simple, but it did! Device was registering fine, push notifications were working again. Ok so I implemented the device registration logic, a few methods regarding the channel manipulations that we needed and push notification handling in JavaScript and it was ready to go.

All right, finally I could get rid of all the .DLLs and .NET native troubles. I packed it all again, submission to the store went fine, and the app was working this time. I even tried to utilize native Cordova commands for project build, but with no luck. It’s so utterly broken that it messes up .appxmanifest file by unnecessarily changing the Application Id property to invalid value. That’s the sad state of Cordova for Windows 10, it’s not finished, undocumented, and not ready for production use. Cordova Tools for Visual Studio that’s advertised by Microsoft is not what would you expect, tools for building Windows apps using Cordova. Rather it is a Visual Studio extension which enables you to build Cordova based iOS and Android apps together with Windows in one IDE. That should not come as surprise, but just one more indicator that Microsoft now focuses (too much) on building iOS and Android apps while leaving Windows app development unfinished.