This is Part 6 of my "VB Win10 Apps" series. (Everything applies to C# as well, of course).
- Part 1: getting started
- Part 2: issues with common libraries - JSON.Net, SignalR, SharpDX, SQLite, LiveSDK
- Part 3: design-time data in XAML
- Part 4: references
- Part 5: projects, targets, libraries
- > Part 6: porting from 8.1 universal to Win10
- Part 7: porting from phone8.1 to phone8.1 + Win10 using Shared Projects
- Part 8: getting started with win2d accelerated graphics
- Part ?: ... (please let me know what you'd like me to write about next!)
Today I worked on porting from an 8.1 universal app, to Win10. I ported the simple app we built in this tutorial series - which showed how to share code and assets in 8.1 universal apps, local+roaming settings, in-app purchases, SharpDX audio, and calling into platform-specific APIs.
- Watch live coding screencast: porting from 8.1 universal to Win10 [37mins]
- The "before" source code is here: https://github.com/ljw1004/blog/tree/master/PortToWin10/App1_Original
- The "after" source code is here: https://github.com/ljw1004/blog/tree/master/PortToWin10/App1_Final_JustWin10
This video format a bit of an experiment. I tried it as a "live coding screencast" - you'll see everything I did, as I did them, rather than just the edited highlights. (I wanted to make something that you could follow along too, and I wanted to make sure I was telling the complete unvarnished truth.) Sorry for the muddy audio in the first two minutes - I'll fix that up next time. Please let me know if this format is worth doing again in future, or if you prefer just to read bullet lists. Of course I've also written the bullet list at the bottom of this post...
Before you start: For this app I did some "market analysis" and concluded that it was only worth supporting Win10 for my app, rather than also supporting Win8/8.1 and Phone8.1. (Why? There's no use supporting Win8/8.1 users since the of them will upgrade to Win10.Desktop. As for supporting Phone8.1, this could go either way, so in today's post I pretend that Phone8.1 isn't cost-effective for me to support). Please read tomorrow's post as well, "Part 7: porting from phone8.1 to phone8.1 + Win10 using Shared Projects" - that post supposes it is cost-effective to continue supporting Phone8.1, and goes into a lot more real-world details about the porting process, and demonstrates some brilliant app-startup-time wins.
Bullet list of "gotchas" when porting
- Start with File>New>UWP, and then copy+paste. Or what I did, AddNewProject>UWP, and copy+paste, and then delete the old projects.
- Lots of folks try to take their existing project and tweak it's .vbproj/.csproj. They always face lots of hard-to-diagnose problems down the line. Please just start with File>New, and copy+paste all the files you need. If you disregard my advice, here are a few things to watch out for:
- The only way you'll ever upgrade a .vbproj/.csproj is by (1) do File>New>UWP, (2) do a line-by-line comparison of this fresh .vbproj/.csproj with your old one, and add/remove entries as needed, (3) do the same with your packages.config file, and also project.json if needed.
- NuGet support is different. It won't work to use your existing NuGet packages. You'll have to uninstall them all, then switch your project to UWP, then reinstall all the NuGet packages.
- AnyCPU no longer exists for apps. You can continue to use AnyCPU for libraries (and that's the recommended way to distribute them). But for apps, it has to be x86|x64|ARM. Use x86 for all your development since that's easiest.
- CurrentApp.LicenseInformation currently has a bug in Win10 where it throws an exception if the app isn't associated with the store. (And you can't associate apps with the store yet in VS2015 RC). The CurrentApp.LicenseInformation but will be fixed by Win10 RTM, and you will be able to associate an app with the store in VS2015 RTM. For now I worked around by just using try/catch.
- Every existing Win8.1 app will run fine on Win10.Desktop. And every existing WinPhone8.1 app will fine on Win10.Mobile. Or at least that's the idea of how things are meant to be.
- Adaptive code. We used to do platform-specific code either with Platform Abstraction Layers (if in PCL) or with #ifdef (if in SharedProjects). The new way to do this is with adaptivity-checks. First you have to AddReference>WindowsUniversal and add "Mobile Extension SDK" and "Desktop Extension SDK". Next, add a NuGet reference to this package: https://github.com/ljw1004/blog/blob/master/Analyzers/PlatformSpecificAnalyzer/ReadMe.md. If you see "TypeLoadException" then it's caused by a missing adaptivity-check, and the analyzer will help it.
- Full-screen stuff has new APIs.
- In Phone8.1 you used to call ApplicationView.SetDesiredBoundsMode(UseCoreWindow), and StatusBar.HideAsync(). These APIs are still present. But you can instead also use the new Win10 API "ApplicationView.TryEnterFullScreen". This will make the app go full-screen, i.e. every single pixel on screen owned by the app, regardless if it's Win10.Desktop windowed mode, or tablet mode, or Win10.Mobile.
- When in Win10.Desktop tablet mode, if the tablet rotates and the app re-orients, you have to handle Windows.SizeChanged (not Page.SizeChanged).
- There are a bunch more bugs relating to full-screen and tablet mode still present in the latest 10134 build of Win10.Desktop and 10080 build of Win10.Mobile, so we can't finish that work.
- Copy+paste was hard to remember to hook everything up! I forgot a lot of stupid things - forgot to hook up all the events (e.g. App.Resuming, MainPage.SizeChanged). If I'd done them all by using the VB Handles keyword then it would have been easier.
- Copy+paste was hard to remember to copy assets! I used to have assets in a PCL called "App1_Common". I moved them into my main Win10 app. Code which loads assets used to load them from "ms-appx:///App1_Common/Assets/pic1.png". It now has to load them from just "Asstets/pic1.png"
- SharpDX. I can't use the old SharpDX toolkit. Instead, for UWP, I have to switch to SharpDX 3.0 and abandon the (now-deprecated) SharpDX toolkit.
- Test in Release build once an hour. Release build uses the new ".NET Native" compiler - which compiles your app direct into highly optimized native code. Mostly, .NET Native should just be a transparent optimization step (apart from taking 2+ minutes to build). But it's early days still, and if you build once an hour then you'll get on top of any Release-mode issues.
- Package.appxmanifest BackgroundColor="transparent". The default template uses a BackgroundColor of #464646. But users on Mobile always expect app icons to be "transparent", i.e. to use the user's current theme accent color as the icon background. So you should change this. On Desktop, it will also have the theme accent color. This color is supposed to be used for splashscreen too, but it's not working at the moment.
- App.xaml RequestedTheme. The default when you do File>New is RequestedTheme="Light", which picks light theme on both Mobile and Desktop. If you delete this directive, then it will use the user's light/dark theme preference on Mobile, and will pick Light for Desktop.