Categories
Bluetooth Xamarin

Changes coming in Xamarin Android BluetoothSocket

While debugging an app I came across this new message in the Output window:-

"Not wrapping exception of type Java.IO.IOException from method `Read`. This will change in a future release."

When working with an RFComm service on Android you use a BluetoothSocket which in turn owns two Streams – one for Input and one for Output. Currently when there is a failure such as a broken connection the Read or Write operation will throw a Java.IO.IOException even though these streams are exposed as regular .NET Streams. It looks like Microsoft plan to change this behaviour and I presume this will be to wrap the exception in the equivalent System.IO.IOException. This makes a lot of sense and will improve consistency with other .NET flavours but it is something you need to be aware of as it will require code changes in your exception handling.

Categories
Desktop Code Windows Xamarin

WPF Activity in Xamarin Forms

I’ve recently been working on extending an existing product written in Xamarin Forms to Windows desktop and this has meant learning a lot more about the WPF implementation. Originally Xamarin Forms was created for mobile platforms such as Android and iOS (and Windows Phone – more on that later) but has since expanded to desktop platforms such as macOS, GTK and WPF on Windows (UWP originally straddled mobile and desktop). WPF is a more recent addition to Xamarin Forms and so understandably the implementation is less mature. It does follow the native look and feel closely but I soon found quite a jarring omission.

Our app uses the ActivityIndicator to represent indeterminate activity. On Android et al. this displays a rotating circular spinner but on WPF it was using an indeterminate progress bar squashed into a rectangular space which looked odd. This is understandable as there is no native control in WPF. I then had a flash of deja vu when thinking about something I wrote some time ago for Windows Phone!

Windows Phone 8.1 introduced the WinRT application model (from Windows 8) alongside the existing Silverlight approach but there were some complications and some types of apps could only be written in Silverlight. I created a library called Charming which added some of the Windows 8 style APIs to the Silverlight app model. This was later expanded and became Pontoon. One of the APIs was a Silverlight ProgressRing control which looked just like the Windows 8 equivalent. The progress ring still regularly appears in the Windows shell and is implemented in UWP. Since Silverlight is a subset of WPF it was straightforward to port it into the Xamarin Forms WPF platform library and modify the renderer for ActivityIndicator. Voila! A nice native looking ActivityIndicator for Windows desktop apps. This has now been merged into the Xamarin Forms code and should appear in a preview release soon alongside the MediaElement that also got merged recently. Until it hits a stable release you can add it via InTheHand.Forms too.

Categories
Bluetooth Windows Xamarin

New Year, New 32feet.NET Library

I’ve been working away on the Bluetooth code for some time. I’d been meaning to modernise the code and build with .NET Standard and NuGet in mind and ideally support more platforms. However the project has stopped and started a few times and gone down a few dead ends.

I had planned to rework the library into a full implementation of the UWP API set for Windows.Devices.Bluetooth covering Bluetooth Classic and Bluetooth LE but while I got quite far and had a set of working code for Windows, Android and iOS I decided that that wasn’t the right approach. Some aspects are clearly tied to underlying Windows concepts – the whole device finding/picking process uses magic strings and is not intuitive from a purely Bluetooth perspective. Also there was no real need to integrate both Bluetooth Classic and Bluetooth LE into a single library because there was very little shareable code and these could be maintained separately.

Instead I decided to go with a much simpler option. Build a new library around fundamentally the same API which the library has used for 16 years with a few necessary tweaks, cutting out a few of the more complex features and making it easy to do the most common tasks with Bluetooth Classic. The Bluetooth LE functionality will be revisited in 2020 with a more logical cross-platform API and packaged in a separate NuGet package (but still part of the 32feet.NET project).

What has changed

The library has been renamed InTheHand.Net.Bluetooth to make clear it is a different package and also to make clear the focus as I’ll no longer be including the IrDA functionality. It includes .NET Standard, Classic .NET Desktop, Android and iOS versions. As you can imagine there will be no new version for .NET Compact Framework. The iOS version is not yet complete but will have some limitations as imposed by the platform. I’ll discuss the details further in a separate blog post because it does some fun things over Apple’s quirky API and should make cross-platform Bluetooth Classic a lot easier for iOS.

In due course it will be joined by UWP, Linux and macOS implementations. Linux will require reworking for BlueZ 5 and macOS will be built on top of the IOBluetooth and IOBluetoothUI framework wrappers which are slowly taking shape. Potentially there may be other platforms too, such as Tizen, and hopefully we can grow the community around the project to target other platforms.

There is no BluetoothListener support in this release but it will be included in future builds (except on iOS). 95% of 32feet.NET users are using BluetoothClient to connect out to other devices so this wasn’t a top priority for this release.

The SelectBluetoothDeviceDialog which was heavily tied to WinForms has been replaced with the BluetoothDevicePicker. This offers a similar level of functionality but in a way which feels comfortable from any UI stack and supports async/await.

DiscoverDevices again is vastly simplified to remove concepts which only make sense in the Win32 implementation. Instead this method is used to discover “live” devices in the vicinity. It is accompanied by the new property PairedDevices which offers a more efficient way of retrieving paired devices without doing a live discovery.

When I started working on a modified version of the library for Unity development there was an odd problem. The Sockets stack in the Mono runtime doesn’t correctly support Bluetooth sockets and so the workaround was to P/Invoke the native Sockets APIs directly. In order to simplify the code the Win32 version uses a single implementation which calls the relevant Win32 APIs rather than using System.Net.Sockets. The library defines its own version of NetworkStream to be able to provide a familiar API which also not being tied to .NET Sockets. This makes it easier to support other platforms such as Android where the underlying implementation is completely different but can be wrapped inside a familiar .NET Stream. All of this means that the desktop .NET version of the library will work for the Windows target of a Unity project.

Where is it going?

The aim with this new version is to have a modern code base able to run on the current spectrum of .NET platforms – From IoT devices, to mobile phones to desktop PCs. Alongside the current Bluetooth Classic library and the Bluetooth LE library I’m also planning for other technologies to join the 32feet.NET project all aimed at handling short range device to device communications.

View the project on GitHub

See the latest InTheHand.Net.Bluetooth NuGet package

Categories
Xamarin

MediaElement Enhancements

In the process of digging into a native exception when disposing the MediaElementRenderer on iOS I came across the closest thing I would get to the source of the problem.

Do not subclass AVPlayerViewController

Because the resulting stacktrace contains redacted elements there was no hope of fixing the issue, so in the end I decided to rewrite the renderer again using the original (non-FastRenderer) approach. The control now behaves correctly and can be created/disposed repeatedly without causing any unexpected problems. I can’t say you can notice any performance hit in not using a fast renderer for this. Though this may be more of a problem if you’re trying to use multiple instances of the control or have some frequently changing screen layout.

I was also able to fix a small issue on Android where depending on the aspect ratio of the video and the size allocated to the control the content may appear left-aligned rather than centered. The result is the latest version of the package on NuGet. At some point I may need to roll these changes into the Xamarin Forms Pull-Request although this seems to have lost all traction after 18-months and is now the second oldest open pull request in the Xamarin Forms project. For the foreseeable future it looks like I’ll be maintaining the standalone control.

Categories
Windows Xamarin

Xamarin Forms MediaElement now available on WPF

Continuing from my last post on macOS, there is now a MediaElement renderer for WPF in InTheHand.Forms 2.0.2019.913. The native control in WPF is a lot more limited and is missing two big features – no system provided transport controls, and no support for HTTPS sources. The latter is an unfortunate limitation though it looks as though this is being fixed for WPF on .NET Core.

A possible workaround for these limitations is to have the WPF renderer use the UWP MediaPlayerElement when running on Windows 10 1903 and above. This is currently available as a WPF control as part of the Windows Community Toolkit.

Categories
macOS Xamarin

Xamarin Forms MediaElement now available for macOS

As the Pull Request to Xamarin Forms continues in its holding pattern I thought about what else I can do with it. I had neglected the original codebase for a while but I’ve spent some more time with it recently providing some much needed updates. The latest which was added to NuGet today adds a whole new platform – macOS.

The functionality is almost exactly the same as that available on iOS with the exception of the KeepScreenOn property as I haven’t found the equivalent macOS APIs to implement this. The sample app code has been updated to include a macOS version demonstrating the basic functionality including toggling different Aspect settings.

Other recent updates include moving the dependencies to a more recent Xamarin Forms version and implementing fast renderers for iOS and Android.

I’ve begun back-porting the WPF renderer too and hope to add this soon. This will increase the platform coverage to Android, iOS, UWP, macOS and WPF. I haven’t really worked with Xamarin Forms on Tizen but this is another possibility for the future.

https://www.nuget.org/packages/InTheHand.Forms/

Categories
Bluetooth Xamarin

Xamarin macOS Binding Libraries

In creating an IOBluetooth binding for Xamarin Mac I learned about Objective Sharpie and binding libraries. There is little documentation on this but it is fairly similar to Xamarin iOS and for that there is a lot more source material. The output from Objective Sharpie gives you binding definitions which you can use in a dll project to produce a binding library you can then call from any other Xamarin dll or app. This was fine to a point but there are issues with some of the complex types used and these cannot always be marshalled automatically. This left me with an API with a few missing bits as I tried and failed to manually adjust the binding via trial and error.

The project sat around untouched for some time but recently I’ve begun to revive it and hope to sort out these bits so it can be released as a complete functioning API for Xamarin Mac. At first I thought I was going to have to create two libraries – one with the raw API calls and another with a clean API over the top but I had missed something buried in the docs and it turns out there is an easier solution.

When you have a binding library it will, by default, have two files – ApiDefinition.cs which contains all the API calls and has a Build action of BindingApiDefinition and a StructsAndEnums.cs which contains (well I’ll let you guess from the name) and this has a Build action of ObjcBindingCoreSource. When the classes are generated from the interface definitions in ApiDefinition.cs they are actually partial classes. This means you can extend them and have additional functionality built cleanly into the library. If you have a particularly messy API call you can mark it as internal and then surface it in a more friendly way from a partial class. To do this add another source file to the library project (I’ve called it Extra.cs because I saw that in a sample but the name isn’t important) and set the Build action to Compile. Here you’ll need to create a partial class with the same name and namespace as the “interface” you want to extend from ApiDefinition.cs, and then add methods, properties etc.

The first time I added this my build failed. I subsequently found out that there is one additional step to tell the binding compiler to ignore this file. Open the project properties, under Build select the Objective-C Binding Build page. Here in Additional btouch arguments box add -x:Extra.cs (or replace with your own filenames). This stops the initial binding compilation from using the partial class, which then gets built normally in the subsequent managed code build. The project should now build and expose the combined functionality. I did find that intellisense often gets confused when editing the partial class because there isn’t another definition of a partial class at this time (remember in ApiDefinition.cs it’s actually an interface). However it seems you can safely ignore this!

This in theory allows you to completely change the API surface which you expose to Xamarin from whatever you started with. I don’t want to go too crazy with IOBluetooth – my feeling is that it should match the native API with a few tweaks for C# naming conventions, using namespaces rather than huge class names, and .NET friendly types where appropriate. Objective Sharpie struggled with some of the enum/constant definitions and so these still require a bit of massaging. It should be obvious how it maps to the native API.

If you have feedback on the API or would like to get involved in getting the library up to release standard please let me know. All the current code is on GitHub in the IOBluetooth and IOBluetoothUI folders.

Categories
Xamarin

Update to Xamarin Forms MediaElement

Things are progressing with the Xamarin Forms Pull Request but it’s a big change and I’ve had feedback on how quickly (or not) it’s going. For this reason I’ve decided to post an update to InTheHand.Forms to port some of the advances and compile for Xamarin Forms 4.0. The new release is marked as a pre-release to avoid anyone automatically updating at this stage and hitting problems because there are a few API changes to ease the transition to the future official version.

https://www.nuget.org/packages/InTheHand.Forms/2.0.2019.613-pre

It takes advantage of fast renderers on iOS and Android and has a cleaner communication method between the control and the renderers. I haven’t changed the Source property which is still based on UWP style Uris for special file locations. I haven’t added a WPF renderer even though the Xamarin Forms version will have this (minus some missing platform functionality like HTTPS and overlaid media playback controls). There are some improvements to the API including a Volume property. The original PCL library is removed along with Windows 8.1 and Windows Phone platforms. I will probably continue to use this package as a method to test other renderers (e.g. Mac and Tizen) before embarking on another Pull Request to Xamarin Forms.

I think the plan with the Xamarin Forms pull request was to integrate in 4.1 but it hasn’t progressed into the current preview releases. I’ll keep you posted as I know more.

Categories
Xamarin

Xamarin Forms Fast Renderers – Part 2 Android

Following on from Part 1, this post will briefly discuss the Android approach to Fast Renderers. Again there isn’t really any documentation for control builders, but there are examples within the Xamarin Forms source to work from. Xamarin Android like iOS uses an IVisualElementRenderer interface which is very similar to the iOS equivalent. The differences are down to the different platforms approaches. For example the NativeView and ViewController of iOS are represented with the View and ViewGroup properties on Android. ViewGroup can return null, but if the control uses a ViewGroup derived class for laying out controls that can be returned.

There are some additional methods such as SetLabelFor(id) and UpdateLayout(). The first one supports the accessibility system on Android and allows a descriptive label to be added to another control. The latter calls a helper class the VisualElementTracker to help update the layout.

Beyond these things the concept is very much the same and you handle the same kind of interactions with the Element which is the platform agnostic representation of the control and its properties.

Categories
iOS Xamarin

Xamarin Forms Fast Renderers – Part 1 iOS

A Xamarin Forms Renderer provides the device-specific logic to display a Xamarin Forms control using platform-native UI. Traditionally this was done using the ViewRenderer<T,T> base class. What this actually creates in the UI hierarchy is two controls – the outer being a basic place-holder providing layout logic and the inner control being the desired native control (e.g. a UITextField in the case of an Entry on iOS).

This introduces overhead into the UI and complicates the layout logic as the whole page is arranged. The concept of a fast renderer does away with the enclosing ViewRenderer and instead requires you to implement an interface with the standard behaviour required by the Xamarin Forms layout system.

When I began re-writing my MediaElement for inclusion into Xamarin Forms I needed to replace the iOS renderer with a fast renderer but there was very little documentation on building a fast renderer. I found looking through the source for other renderers helpful. The Pages and WebView all use fast renderers in the current codebase.

On iOS this interface is IVisualElementRenderer and it exposes a number of properties, an event and a few methods.

Properties:-

  • Element – returns the Xamarin Forms element which this renderer represents
  • NativeView – returns the native UIView-based control
  • NativeViewController – returns the UIViewController which manages the View

Events:-

  • ElementChanged – raised when an Element is assigned to the renderer

Methods:-

  • GetDesiredSize – returns a SizeRequest from a set of constraints. The control can alter this to fit required content for example. An extension method for UIView provides GetSizeRequest which will calculate the SizeRequest based on the constraints and optional minimum width/height.
  • SetElement – assigns the Element and causes the ElementChanged event to be raised. You’ll also hook up the PropertyChanged event here to react to changes in the Element and apply them to the NativeView.
  • SetElementSize – updates the layout to fit a specific size. Normally you call Layout.LayoutChildIntoBoundingRegion() to perform this.

A secondary interface IEffectControlProvider provides a single method to register an effect with the View.

By looking at the existing in-box renderers I was able to understand how they are implemented and re-write the MediaElementRenderer to use this pattern. For reference the full code of the iOS renderer is here in GitHub.

Not all the renderers in iOS use the new approach, I imagine it will be some time before all the existing renderers are re-written. Currently UWP and other platforms still use the traditional approach. I’ll follow up with the Android equivalent soon.