It’s been a few months since I did a NuGet release but lots has been going on in the code in the mean time. The focus this year has been less about harmonising Windows APIs across versions (although that’s still there of course), but widening the functionality to the Xamarin platforms. The result is that the vast majority of the APIs are now available across Android, iOS, Windows (UWP and 8.1) and Windows Phone (8.0, 8.1 Silverlight and 8.1 WinRT). In many cases I’ve added “light-up” support allowing Windows 10 functionality to be called from Windows (and Phone) 8.1 projects. This means you can write for maximum compatibility but take advantage of new features where available. The two packages are:-
As the name suggests the UI library separates out stuff which uses UI and so you can just use the former in a background task without worrying about dragging in UI dependencies.
The APIs are all modelled on UWP, the only difference being the root namespace is InTheHand rather than Windows and async methods return Task<T> rather than IAsyncOperation<T>.
The Core library features many namespaces around ApplicationModel – Interrogate app package metadata, make calls, send SMS and Emails, interact with Clipboard and Sharing. Beyond this are classes which take away the need to know which APIs to call on which platform – interrogate display properties, check network connectivity, read and write files and settings. This version extends the support for settings by supporting roaming settings on iOS just like Windows does – except these settings are roamed across the iCloud infrastructure rather than OneDrive. It’s important to add here that these settings only roam for devices on that specific platform type – Windows and iOS roaming data exist in separate worlds so data roamed from your iPhone Xamarin app won’t roam to your Windows laptop.
AnalyticsInfo is available and can report the OS version on iOS/Android and Windows 10. This is supported in the 8.1 libraries if running on the newer OS version. DisplayRequest allows your app to ask the device to keep the screen on – for example for a reader or video player. PowerManager gives you battery information.
Over in the InTheHand.UI library there are Badge and Toast notification APIs (Badge is not supported on Android). BadgeNotificationCreator and ToastNotificationCreator helper classes make it easy to create these notifications without having to deal with XML templates on Windows. A MessageDialog and a StatusBar which allows you to toggle a standard busy animation. On Windows there is also a unified SettingsPane API which uses the best available appearance depending on platform.
Going forwards I’m looking at removing the Windows Phone 8.0 (and possibly 8.1 Silverlight) target to simplify things and would be interested in any feedback on that. As always all the code is on GitHub:-
Xamarin Forms offers a NavigationPage control which allows you to do linear navigation and integrates with the native Back button on Android and Windows. However from the individual Page it isn’t possible to tell how you arrived at the page. I had a situation in a project where I needed to know whether a page appeared via a forward or backward navigation. The Page control doesn’t have an equivalent to the OnNavigatedTo / OnNavigatedFrom methods that Windows has.
I therefore came up with an implementation by writing a custom NavigationPage and adding an interface which a Page could optionally implement to expose the OnNavigatedTo / OnNavigatedFrom methods.
To add the functionality you merely need to replace the code (probably in App.cs) which initializes your NavigationPage to e.g.
MainPage = new InTheHand.Forms.NavigationPage2(new FirstPage());
Then in the page you add the interface:-
public partial class FirstPage : ContentPage, IPageNavigation
An add an implementation of these methods. Visual Studio can generate these for you but remember by default these will throw NotImplementedExceptions
public void OnNavigatedTo(InTheHand.Forms.NavigationEventArgs args)
StatusLabel.Text = "Navigated forward to this page from " + (args.Page == null ? "<unknownpage>" : args.Page.GetType().ToString());
StatusLabel.Text = "Navigated backward to this page from " + (args.Page == null ? "<unknownpage>" : args.Page.GetType().ToString());
The sample project on GitHub demonstrates a simple scenario with three pages and multiple ways of navigating between them. Each shows a status label showing how the user navigated to the page. Because it hooks into the NavigationPage it isn’t linked to any controls you set up to programmatically navigate, nor does it matter if a back navigation was initiated by a hardware back button, or a programmatic navigation.
I have a Xamarin project which outputs Windows, iOS and Android apps. Since the latest Xamarin update I just couldn’t get it to build my IPA file. It told me to check the project configuration – I haven’t changed the configuration and it all looks fine…
When the project was created several Solution configurations were created – AppStore, AdHoc along with the usual Release/Debug. This was always a pain as you’d have to switch from Release to AppStore to build the iOS version for release. It turns out what has changed in this release is that Release now builds a store-ready IPA file and the AppStore configuration is now broken (and therefore redundant). By switching to Release I was able to build and submit a signed IPA to the store. The only other change is that IPA files are now output into timestamped subfolders on the build machine. You can use the “Show IPA file on Build Server” to display the actual location in Finder.
There are limitations to the write-once run everywhere approach of Xamarin Forms. One of these is the subtle difference in Button behaviour across platforms. One of our testers pointed out that you could rapidly tap a Button on Android and the handler would be called multiple times. Since the Tap was initiating a page navigation this would lead to multiple copies of the page being added to the back-stack.
The workaround necessary is simply to add a timeout to ensure that the Tap event is not handled more frequently than a specified timeout. We chose 500ms but your use-case may vary. I created a renderer derived from the built-in ButtonRender and searched a way to intercept tap events. It turns out that a lot of the methods which can be overridden are never called but I found a solution through the excitingly named OnFilterTouchEventForSecurity. The resulting renderer code is included in the following Gist and can be added to your Android project to enforce this behaviour.
Yesterday Microsoft announced that the Xamarin platform (the ability to run C# apps on iOS and Android) would be free with all versions of Visual Studio 2015 Update 2. This is great news and takes away a barrier for developers to use their .NET skills to write cross-platform apps.
We’ve had a number of free libraries for Xamarin for a while so I just wanted to post a quick reminder:-
Charming Apps – Provides consistent UWP style APIs you can call across iOS, Android and Windows platforms for many common tasks. From reading the app manifest properties at runtime through to UI elements and integration with platform functions like SMS, Email etc.
Xamarin Forms Maps Windows Renderers – Currently Xamarin Forms Maps only has renderers for iOS, Android and Windows Phone Silverlight. This package adds renderers for WinRT and UWP platforms.
Device Picker – Currently only supporting Windows platforms this adds a UWP style device picker to Windows Phone 8.1 and Windows 8.1 projects.
We’re continuing to extend the Charming apps libraries and will monitor as Xamarin Forms evolves…
It’s possible that with last week’s announcement Windows may no longer be the Cinderella alongside iOS and Android in the Xamarin Forms world. For the moment there are gaps to be filled and one of these is in Maps support.
Xamarin Forms Maps has only (so far) shipped with a renderer for Windows Phone Silverlight apps. Some time ago I released a Windows Phone 8.1 Renderer via NuGet. The source is on GitHub here. Subsequently Windows 8 and Windows 10 support has been added. The latest stable NuGet package includes the Windows Phone 8.1 and Windows 10 UWP renderers. I decided not to include Windows 8.1 because it is a more complicated deployment as it requires the Bing Maps Extension SDK and has to be built for a specific architecture rather than a single “Any CPU” library.
This new version is built against the latest Xamarin Forms Maps component (v2.1.0). It has some bug fixes around MoveToRegion and Clicked events for Pins. A future update will add support for IsShowingUser. Once again a single line of code is required in your Windows project App.xaml.cs to initialize the support, after which the map renderer and geocoder will just work:-
The token can be substituted with null for debugging purposes (the map control will display a banner).