This tutorial walks you through the process of creating a barcode scanner app for Android and iOS using the BarcodeScanning.Native.Maui package. This library leverages Google ML Kit on Android and Apple Vision on iOS to detect and decode barcodes.
To build our app, we’re going to follow these steps:
- Preparing the project
- Installing the NuGet package
- Initializing the plugin
- Adding the scanner UI
- Implementing barcode detection

Let’s get started!
Requirements
There are several options for developing .NET MAUI applications, including the ability to build and launch projects from the .NET CLI. Whatever method you choose, make sure you have .NET 9.0 installed for your development platform of choice. You’ll also need Microsoft’s build of OpenJDK.
⚠️ A note for Windows users: If you want to develop your app for iOS, additional setup is required, including having a Mac available as a build server. You can learn more about this in the .NET MAUI documentation. In this tutorial, we’ll assume you’re developing on a Mac and using the CLI.
If this is your first time developing a .NET MAUI application on your machine, execute the following command:
sudo dotnet workload install maui
Step 1: Prepare the project
First, create a new directory for your project …
mkdir barcode-scanner-maui
… and navigate into it.
cd barcode-scanner-maui
Then create the project with:
dotnet new maui --framework net9.0
Since we need access to the device cameras to scan barcodes, let’s add the necessary camera permissions for Android and iOS.
For Android, add the following to Platforms/Android/AndroidManifest.xml inside the <manifest>
element:
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.VIBRATE" />
For iOS, add the following to Platforms/iOS/Info.plist anywhere inside the <dict>
element.
<key>NSCameraUsageDescription</key>
<string>Grant camera access to scan barcodes.</string>
Step 2: Install the NuGet package
In your terminal, install the BarcodeScanning.Native.Maui package with the following command:
dotnet add package BarcodeScanning.Native.Maui --version 2.1.8
Step 3: Initialize the plugin
In MauiProgram.cs, include the namespace:
using BarcodeScanning;
Then register the barcode scanner in the app builder with .UseBarcodeScanning()
.
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.UseBarcodeScanning() // Add this line
// ...
}
Step 4: Add the scanner UI
At the top of MainPage.xaml, define the XML namespace.
xmlns:scanner="clr-namespace:BarcodeScanning;assembly=BarcodeScanning.Native.Maui"
Then replace the <ScrollView></ScrollView>
code with:
<scanner:CameraView
x:Name="BarcodeScanner"
CameraEnabled="True"
VibrationOnDetected="True"
AimMode="True"
OnDetectionFinished="CameraView_OnDetectionFinished"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"/>
Step 5: Implement barcode detection
Finally, in MainPage.xaml.cs, include the namespace …
using BarcodeScanning;
… and remove int count = 0;
and the OnCounterClicked()
method.
Inside the MainPage
class, add the following to make sure the app asks for camera access on startup:
protected override async void OnAppearing()
{
base.OnAppearing();
BarcodeScanner.CameraEnabled = true;
await Methods.AskForRequiredPermissionAsync();
}
Below, add the following to deactivate the camera on closing:
protected override void OnDisappearing()
{
base.OnDisappearing();
BarcodeScanner.CameraEnabled = false;
}
And below that, add the barcode detection event handler:
private async void CameraView_OnDetectionFinished(object sender, OnDetectionFinishedEventArg e)
{
if (e.BarcodeResults.Count > 0)
{
BarcodeScanner.PauseScanning = true;
foreach (var result in e.BarcodeResults)
{
await DisplayAlert("Scanned Barcode", result.RawValue, "OK");
}
BarcodeScanner.PauseScanning = false;
}
}
Now you can build and run your app with the following commands:
Android:
dotnet build -t:Run -f net9.0-android
iOS:
dotnet build -t:Run -f net9.0-ios

Disadvantages of using BarcodeScanning.Native.MAUI for scanning barcodes
The BarcodeScanning.Native.MAUI library is easy to integrate into .NET MAUI projects, making it a good choice for quick prototyping or personal projects.
However, it comes with a few drawbacks:
- A recurring issue arises when navigating between pages after using the barcode scanner. Developers report crashes or glitches when attempting to open a new page while the camera is still shutting down or consuming resources, resulting in forced closures or rendering issues in the main view.
- Problems can occur when initializing the camera scanner in specific lifecycle events (e.g.,
OnAppearing
) or navigating back to a page containing the scanner. This can lead to non-functioning scanners or UI elements failing to update properly. - Threading issues can arise when attempting to perform barcode detection while interacting with UI elements. Since UI operations require the main thread, improper threading can cause delays or crashes.
- The package’s reliance on Google ML Kit and Apple Vision ties applications to their updates and changes. Developers must adapt to new API versions or deprecated features, which can increase maintenance overhead.
For companies that heavily rely on barcode scanning in their business processes, we recommend using an enterprise-grade solution instead.
Building a .NET MAUI Barcode Scanner with the Scanbot SDK
We developed the Scanbot Barcode Scanner SDK to help enterprises overcome the hurdles presented by free barcode scanning software. Our goal was to have a developer-friendly solution available for a wide range of platforms that consistently delivers high-quality results – even in challenging circumstances.
With our dedicated .NET MAUI SDK, you can easily integrate barcode scanning functionalities into your cross-platform app. We’ll show you how to do it in a matter of minutes – thanks to the SDK’s Ready-to-Use UI!
First, we’re going to implement single-barcode scanning in our app. Afterwards, we’ll adapt the scanner to support multi-barcode scanning and implement an AR overlay.


We’ll achieve this in five steps:
- Preparing the .NET MAUI project
- Installing the Scanbot SDK
- Initializing the SDK
- Implementing single-barcode scanning
- Implementing multi-barcode scanning with AR overlay
Let’s get started!
Step 1: Prepare the .NET MAUI project
First, create a new directory for your project and navigate into it.
mkdir test-maui
cd test-maui
Then create the project with the following command:
dotnet new maui
Since we need access to the device camera to scan barcodes, let’s add the necessary camera permissions for Android and iOS.
For Android, add the following to Platforms/Android/AndroidManifest.xml inside the <manifest>
element:
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
For iOS, add the following to Platforms/iOS/Info.plist anywhere inside the <dict>
element:
<key>NSCameraUsageDescription</key>
<string>Please provide camera access.</string>
Step 2: Install the Scanbot SDK
In this tutorial, we’re using Scanbot Barcode Scanner SDK version 6.1.0. You can find the latest version in the SDK’s changelog.
Add the following code to the test-maui.csproj file in your project folder:
<ItemGroup>
<PackageReference Condition="$(TargetFramework.Contains('ios'))" Include="ScanbotBarcodeSDK.MAUI" Version="6.1.0" />
<PackageReference Condition="$(TargetFramework.Contains('android'))" Include="ScanbotBarcodeSDK.MAUI" Version="6.1.0" />
</ItemGroup>
Then run:
dotnet restore
💡 If there are package conflicts, add the appropriate <PackageReference>
tags to the project and make sure <PackageReference>
has NoWarn="NU1605"
added to it to suppress the related build error for that particular package.
Step 3: Initialize the SDK
In MauiProgram.cs, initialize the Barcode Scanner SDK by replacing the contents with the following code:
using Microsoft.Extensions.Logging;
using ScanbotSDK.MAUI;
namespace test_maui;
public static class MauiProgram
{
public const string LicenseKey = "";
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
});
#if DEBUG
builder.Logging.AddDebug();
#endif
SBSDKInitializer.Initialize(LicenseKey, new SBSDKConfiguration
{
EnableLogging = true,
ErrorHandler = (status, feature) =>
{
Console.WriteLine($"License error: {status}, {feature}");
}
});
return builder.Build();
}
}
This will set an empty license key, initialize the SDK, and enable logging and error handling.
💡 Without a license key, the Barcode Scanner SDK only runs for 60 seconds per session. This is more than enough for the purposes of this tutorial, but if you like, you can generate a license key using the <ApplicationId>
found in test-maui.csproj.
For the scanning components to work correctly in Android, you also need to add DependencyManager.RegisterActivity(this)
to the OnCreate
method in Platforms/Android/MainActivity.cs:
protected override void OnCreate(Bundle? savedInstanceState)
{
base.OnCreate(savedInstanceState);
ScanbotSDK.MAUI.DependencyManager.RegisterActivity(this);
}
💡 If there’s no OnCreate
method in your MainActivity.cs, add the above code snippet to the MainActivity
class.
Step 4: Implement single-barcode scanning
We’ll first implement single-barcode scanning in our .NET MAUI app.
In MainPage.xaml.cs, first add the necessary imports.
using ScanbotSDK.MAUI;
using ScanbotSDK.MAUI.Barcode;
Then replace the OnCounterClicked()
method with the following:
private async void StartBarcodeScanner(object sender, EventArgs e)
{
try
{
if (!ScanbotSDKMain.LicenseInfo.IsValid)
{
await DisplayAlert(title: "License invalid", message: "Trial license expired.", cancel: "Dismiss");
return;
}
// Create the default configuration object.
var configuration = new BarcodeScannerConfiguration();
var result = await ScanbotSDKMain.RTU.BarcodeScanner.LaunchAsync(configuration);
var barcodeAsText = result.Items.Select(barcode => $"{barcode.Type}: {barcode.Text}")
.FirstOrDefault() ?? string.Empty;
await DisplayAlert("Found barcode", barcodeAsText, "Finish");
}
catch (TaskCanceledException)
{
// For when the user cancels the action.
}
catch (Exception ex)
{
// For any other errors that occur.
Console.WriteLine(ex.Message);
}
}
This configures our barcode scanner with the default behavior and implements a text pop-up showing a barcode’s type and encoded data when scanned.
Now go to MainPage.xaml and edit the CounterBtn
so it calls our StartBarcodeScanner()
method when clicked.
<Button
x:Name="BarcodeScannerBtn"
Text="Scan Barcode"
SemanticProperties.Hint="Starts the process to scan a barcode"
Clicked="StartBarcodeScanner"
HorizontalOptions="Fill" />
Build and run the app to test the single-barcode scanning functionality.
For iOS:
dotnet build . -f net8.0-ios -t:Run -r ios-arm64
For Android:
dotnet build . -f net8.0-android -t:Run

In the next step, we’ll change the scanner’s behavior to scan multiple barcodes and display their values on the scanning screen using an AR overlay.
Step 5: Implement multi-barcode scanning with AR overlay
Go back to MainPage.xaml.cs and below var configuration = new BarcodeScannerConfiguration();
, create a new instance of the MultipleScanningMode
class and assign it to a variable usecase
.
var usecase = new MultipleScanningMode();
Then modify this object to enable the AR overlay, disable the automatic selection of barcodes as they enter the scanning area (requiring the user to select them manually instead), and disable the viewfinder (since having it doesn’t make much sense when using the AR overlay).
usecase.ArOverlay.Visible = true;
usecase.ArOverlay.AutomaticSelectionEnabled = false;
configuration.ViewFinder.Visible = false;
Finally, apply the configuration.
configuration.UseCase = usecase;
Your final MainPage.xaml.cs will look something like this:
using ScanbotSDK.MAUI;
using ScanbotSDK.MAUI.Barcode;
namespace test_maui;
public partial class MainPage : ContentPage
{
int count = 0;
public MainPage()
{
InitializeComponent();
}
private async void StartBarcodeScanner(object sender, EventArgs e)
{
try
{
if (!ScanbotSDKMain.LicenseInfo.IsValid)
{
await DisplayAlert(title: "License invalid", message: "Trial license expired.", cancel: "Dismiss");
return;
}
var configuration = new BarcodeScannerConfiguration();
var usecase = new MultipleScanningMode();
usecase.ArOverlay.Visible = true;
usecase.ArOverlay.AutomaticSelectionEnabled = false;
configuration.ViewFinder.Visible = false;
configuration.UseCase = usecase;
var result = await ScanbotSDKMain.RTU.BarcodeScanner.LaunchAsync(configuration);
var barcodeAsText = result.Items.Select(barcode => $"{barcode.Type}: {barcode.Text}")
.FirstOrDefault() ?? string.Empty;
await DisplayAlert("Found barcode", barcodeAsText, "Finish");
}
catch (TaskCanceledException)
{
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
Now build and run the app again and try out the new scanning behavior.

If you’re in need of some sample barcodes for testing purposes, we’ve got you covered:

💡 If you run into errors while building the Android app, try the command _dotnet build . -f net8.0-android -t:Run --no-incremental
.
The option --no-incremental
disables incremental building. When used, it forces a clean rebuild of the entire project, ignoring any previously built components.
Conclusion
🎉 Congratulations! You’ve successfully built a cross-platform barcode scanning app for iOS and Android with .NET MAUI!
The scanner is customizable and supports features like multi-barcode scanning and AR overlay. For more customization options, check out the RTU UI documentation and API references.
Should you have questions about this tutorial or ran into any issues, we’re happy to help! Just shoot us an email via tutorial-support@scanbot.io.
Happy scanning! 🤳