Porting Xamarin.Forms Barcode QR Code Scanner to .NET MAUI

Porting Steps for .NET MAUI Barcode QR Code Scanner

Although you can refer to Migrating from Xamarin.Forms (Preview), to avoid encountering lots of build errors, it is better to create a new .NET MAUI project and migrate project configuration and code step by step.

<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net6.0-android;net6.0-ios</TargetFrameworks>
<OutputType>Exe</OutputType>
<RootNamespace>BarcodeQrScanner</RootNamespace>
<UseMaui>true</UseMaui>
<SingleProject>true</SingleProject>
</Project>

NuGet Package Installation

  • SkiaSharp
  • Dynamsoft Barcode Reader

Code Updates

Migrating code from Xamarin.Forms to .NET MAUI is not as easy as expected. Let’s go through the changes.

Invoke platform code

To invoke specific platform APIs, we use interface in Xamarin.Forms.

public interface IBarcodeQRCodeService
{
Task<int> InitSDK(string license);
Task<BarcodeQrData[]> DecodeFile(string filePath);
}
public partial class BarcodeQRCodeService
{
public partial void InitSDK(string license);
public partial BarcodeQrData[] DecodeFile(string filePath);
}
public class BarcodeQRCodeService: IBarcodeQRCodeService
{
Task<int> IBarcodeQRCodeService.InitSDK(string license)
{
...
TaskCompletionSource<int> taskCompletionSource = new TaskCompletionSource<int>();
taskCompletionSource.SetResult(0);
return taskCompletionSource.Task;
}

Task<BarcodeQrData[]> IBarcodeQRCodeService.DecodeFile(string filePath)
{
...
TaskCompletionSource<BarcodeQrData[]> taskCompletionSource = new TaskCompletionSource<BarcodeQrData[]>();
taskCompletionSource.SetResult(output);
return taskCompletionSource.Task;
}
}
public partial class BarcodeQRCodeService
{
public partial void InitSDK(string license)
{
...
}

public partial BarcodeQrData[] DecodeFile(string filePath)
{
BarcodeQrData[] output = null;
...
return output;
}
}

Change namespaces for content pages

The content page template is different between Xamarin.Forms and .NET MAUI.

xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:skia="clr-namespace:SkiaSharp.Views.Forms;assembly=SkiaSharp.Views.Forms"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:skia="clr-namespace:SkiaSharp.Views.Maui.Controls;assembly=SkiaSharp.Views.Maui.Controls"

Change namespaces for custom renderers

We also need to change the namespaces for custom renderers.

- using Xamarin.Forms;
- using Xamarin.Forms.Platform.Android.FastRenderers;
+ using Microsoft.Maui.Controls.Compatibility;
+ using Microsoft.Maui.Controls.Compatibility.Platform.Android.FastRenderers;
- using Xamarin.Forms;
- using Xamarin.Forms.Platform.iOS;
+ using Microsoft.Maui.Controls.Compatibility;
+ using Microsoft.Maui.Controls.Handlers.Compatibility;

Register handlers

The final step is to configure SkiaSharp and custom renderers in MauiProgram.cs to make them work.

using Microsoft.Maui.Controls.Compatibility.Hosting;
using SkiaSharp.Views.Maui.Controls.Hosting;

namespace BarcodeQrScanner;

public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder.UseSkiaSharp()
.UseMauiApp<App>()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
}).UseMauiCompatibility()
.ConfigureMauiHandlers((handlers) => {

#if ANDROID
handlers.AddCompatibilityRenderer(typeof(CameraPreview), typeof(BarcodeQrScanner.Platforms.Android.CameraPreviewRenderer));
#endif

#if IOS
handlers.AddHandler(typeof(CameraPreview), typeof(BarcodeQrScanner.Platforms.iOS.CameraPreviewRenderer));
#endif
});


return builder.Build();
}
}

.NET MAUI Issues

If you try to use AVCaptureDevice.DevicesWithMediaType to get the iOS camera devices, you will find it returns null in .NET MAUI. You can use AVCaptureDevice.Devices to return all the devices and then filter the ones you want.

- var videoDevices = AVCaptureDevice.DevicesWithMediaType(AVMediaTypes.Video.ToString()); 
+ AVCaptureDevice[] videoDevices = AVCaptureDevice.Devices;

Label text cannot display full string

This issue is weird. The default text length seems to affect the label text display. A temporary workaround is to set the default text with many spaces.

<Label FontSize="18"
FontAttributes="Bold"
x:Name="ResultLabel"
Text=" "
TextColor="Red"
HorizontalOptions="Center"
VerticalOptions="Center"/>

Source Code

https://github.com/yushulx/maui-barcode-qrcode-scanner

--

--

Manager of Dynamsoft Open Source Projects | Tech Lover

Love podcasts or audiobooks? Learn on the go with our new app.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Xiao Ling

Xiao Ling

Manager of Dynamsoft Open Source Projects | Tech Lover