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

Xiao Ling - Jul 14 '22 - - Dev Community

Last week, we created a Xamarin.Forms Barcode QR code scanner for Android and iOS. Xamarin.Forms is not the end for developing cross-platform mobile apps in C#, because .NET MAUI is on the way. Microsoft mentions that .NET MAUI is the evolution of Xamarin.Forms, and it supports both mobile and desktop development. Since .NET MAUI is coming soon, this article will show you how to implement .NET MAUI barcode QR code scanner by porting Xamarin.Forms project.

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.

*.csproj File Updates

To create a .NET MAUI project, you need to install Visual Studio 2022 Preview beforehand.

A new .NET MAUI project scaffold contains templates for Windows, macOS, Tizen, Android and iOS. We only keep Android and iOS frameworks in csproj file.

<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>
Enter fullscreen mode Exit fullscreen mode

NuGet Package Installation

.NET MAUI NuGet packages

  • SkiaSharp

    SkiaSharp is used to draw pictures and overlay. We install SkiaSharp.Views.Maui.Controls instead of SkiaSharp.Views.Forms via NuGet Package Manager.

  • Dynamsoft Barcode Reader

    Dynamsoft Barcode Reader is used to decode barcode and QR code.

    Xamarin barcode QR code SDK

    Both of the Android and iOS SDKs are not built with .NET 6.0. After attempting the installation, we noticed that the Xamarin Android barcode SDK is compatible with .NET MAUI project, but installing Xamarin iOS barcode SDK returns compatibility errors.

    Xamarin .NET MAUI compatibility issue

    So in the following paragraphs, the barcode QR code scanning function is only available in Android app. All the same logic code in iOS app is commented out.

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);
}
Enter fullscreen mode Exit fullscreen mode

Whereas in .NET MAUI, we use partial classes and partial methods.

public partial class BarcodeQRCodeService
{
    public partial void InitSDK(string license);
    public partial BarcodeQrData[] DecodeFile(string filePath);
}
Enter fullscreen mode Exit fullscreen mode

The corresponding implementation is as follows:

Xamarin.Forms

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;
    }
}

Enter fullscreen mode Exit fullscreen mode

.NET MAUI

public partial class BarcodeQRCodeService
{
    public partial void InitSDK(string license)
    {
        ...
    }

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

Change namespaces for content pages

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

MAUI content page

The xmlns is changed to http://schemas.microsoft.com/dotnet/2021/maui and the xmlns:skia is changed to clr-namespace:SkiaSharp.Views.Maui.Controls;assembly=SkiaSharp.Views.Maui.Controls.

Xamarin.Forms

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"
Enter fullscreen mode Exit fullscreen mode

.NET MAUI

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"
Enter fullscreen mode Exit fullscreen mode

Change namespaces for custom renderers

We also need to change the namespaces for custom renderers.

Android

- using Xamarin.Forms;
- using Xamarin.Forms.Platform.Android.FastRenderers;
+ using Microsoft.Maui.Controls.Compatibility;
+ using Microsoft.Maui.Controls.Compatibility.Platform.Android.FastRenderers;
Enter fullscreen mode Exit fullscreen mode

iOS

- using Xamarin.Forms;
- using Xamarin.Forms.Platform.iOS;
+ using Microsoft.Maui.Controls.Compatibility;
+ using Microsoft.Maui.Controls.Handlers.Compatibility;
Enter fullscreen mode Exit fullscreen mode

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();
    }
}
Enter fullscreen mode Exit fullscreen mode

Video Demo

Watch the video to see how the .NET MAUI barcode QR code scanner work.

.NET MAUI Issues

AVCaptureDevice.DevicesWithMediaType returns null

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;
Enter fullscreen mode Exit fullscreen mode

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"/>
Enter fullscreen mode Exit fullscreen mode

Source Code

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

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Terabox Video Player