Migrating from BarcodeScanning.Native.Maui to IronBarcode
Este guia fornece um caminho de migração completo do BarcodeScanning.Native.Maui para o IronBarcode, abrangendo a substituição do padrão de eventos da câmera, alterações de namespace, exemplos de migração de código e o tratamento de cenários que o BarcodeScanning.Native.Maui não consegue abordar — MAUI do Windows, entrada de arquivos e PDFs, processamento no servidor e geração de códigos de barras.
Por que migrar do BarcodeScanning.MAUI?
Equipes que migraram do BarcodeScanning.Native.Maui relatam os seguintes problemas:
É necessário o alvo MAUI para Windows: BarcodeScanning.Native.Maui encapsula as APIs nativas do iOS e do Android. Não possui implementação para Windows e nenhuma está planejada. Se seu aplicativo MAUI for destinado ao Windows, além de iOS e Android, você precisará de uma biblioteca que funcione em todas as três plataformas sem ramificações específicas para cada uma.
Adicionado recurso de entrada de arquivo ou PDF: BarcodeScanning.Native.Maui aceita apenas frames de câmera ao vivo. Quando os usuários precisam carregar uma imagem de sua galeria ou quando um endpoint do lado do servidor precisa extrair códigos de barras de PDFs, a biblioteca não oferece nenhum caminho de código para isso. Cada cenário com código de barras, seja em formato de arquivo ou PDF, requer uma ferramenta diferente.
Os dados UPC-A do iOS estavam incorretos em produção: a estrutura Vision da Apple retorna 13 dígitos para códigos de barras UPC-A (codificação EAN-13). BarcodeScanning.Native.Maui repassa isso sem correção. Se os códigos UPC-A estivessem sendo armazenados com um zero à esquerda, os registros de estoque, as consultas em pontos de venda ou as integrações da cadeia de suprimentos poderiam ter sido interrompidos silenciosamente. O IronBarcode retorna o valor UPC-A correto de 12 dígitos sem necessidade de normalização manual.
A digitalização do PDF417 era pouco confiável: o próprio documento de problemas do GitHub da biblioteca descreve o PDF417 como "muito problemático — a maioria das digitalizações nunca ocorre". Para etiquetas de envio, carteiras de motorista e cartões de embarque, isso representa um bloqueio direto.
Foi necessária a geração de código de barras: BarcodeScanning.Native.Maui não consegue gerar códigos de barras. O IronBarcode gera códigos Code128, QR, DataMatrix e outros formatos como arquivos de imagem ou matrizes de bytes.
Processamento do lado do servidor introduzido: BarcodeScanning.Native.Maui é um controle de interface de usuário da câmera — ele não pode ser executado em um processo do servidor. Quando a leitura de código de barras no servidor é necessária juntamente com a leitura em dispositivos móveis, o IronBarcode abrange ambas as funcionalidades com o mesmo pacote e a mesma API.
O problema fundamental
O BarcodeScanning.Native.Maui integra totalmente a leitura de código de barras ao modelo de eventos da câmera ao vivo. Não momento em que qualquer requisito ficar fora desse modelo, a biblioteca não oferece nada:
private void OnBarcodeDetected(object sender, OnDetectionFinishedEventArg e)
{
var barcode = e.BarcodeResults.FirstOrDefault();
if (barcode != null)
ResultLabel.Text = barcode.DisplayValue;
}Private Sub OnBarcodeDetected(sender As Object, e As OnDetectionFinishedEventArg)
Dim barcode = e.BarcodeResults.FirstOrDefault()
If barcode IsNot Nothing Then
ResultLabel.Text = barcode.DisplayValue
End If
End SubO IronBarcode aceita qualquer tipo de entrada de dados — captura de câmera, arquivo, PDF, matriz de bytes — e funciona em todas as plataformas:
using IronBarCode;
private async void ScanBarcodeButton_Clicked(object sender, EventArgs e)
{
var photo = await MediaPicker.CapturePhotoAsync();
if (photo == null) return;
using var stream = await photo.OpenReadAsync();
using var ms = new MemoryStream();
await stream.CopyToAsync(ms);
var results = BarcodeReader.Read(ms.ToArray());
ResultLabel.Text = results.FirstOrDefault()?.Value ?? "No barcode found";
}Imports IronBarCode
Private Async Sub ScanBarcodeButton_Clicked(sender As Object, e As EventArgs)
Dim photo = Await MediaPicker.CapturePhotoAsync()
If photo Is Nothing Then Return
Using stream = Await photo.OpenReadAsync()
Using ms As New MemoryStream()
Await stream.CopyToAsync(ms)
Dim results = BarcodeReader.Read(ms.ToArray())
ResultLabel.Text = If(results.FirstOrDefault()?.Value, "No barcode found")
End Using
End Using
End Sub##IronBarcode vs BarcodeScanning.MAUI: Comparação de Recursos
| Recurso | BarcodeScanning.MAUI | IronBarcode |
|---|---|---|
| Leitura de quadros da câmera ao vivo | Sim — Controle CameraView | Não (use o MediaPicker para capturar e depois ler) |
| visor da câmera no aplicativo | Sim — contínuo em tempo real | Não — utiliza a interface de utilizador da câmara do sistema através do MediaPicker. |
| Ler a partir de um arquivo de imagem | Não | Sim — BarcodeReader.Read(path) |
| Ler de um array de bytes | Não | Sim — BarcodeReader.Read(bytes) |
| Leia a partir do fluxo | Não | Sim — BarcodeReader.Read(stream) |
| Leia a partir do PDF | Não | Sim — BarcodeReader.Read(pdf) |
| Geração de código de barras | Não | Sim — BarcodeWriter + QRCodeWriter |
| Suporte ao MAUI do Windows | Não | Sim |
| Suporte a MAUI no iOS | Sim | Sim |
| Suporte ao Android MAUI | Sim | Sim |
| Suporte ao macOS MAUI | Não documentado | Sim |
| Lado do servidor / ASP.NET | Não | Sim |
| Docker / Azure / AWS Lambda | Não | Sim |
| Precisão do código UPC-A do iOS | Retorna 13 dígitos (erro), requer normalização manual. | Retorna o código UPC-A correto de 12 dígitos. |
| Confiabilidade do PDF417 | "A maioria das varreduras nunca ocorre" (problemas do GitHub ) | Apoiado |
| Detecção de múltiplos códigos de barras | Sim (múltiplos por quadro via e.BarcodeResults) | Sim (opção ExpectMultipleBarcodes) |
| Controle de velocidade de leitura | None | ReadingSpeed.Faster / Balanced / Detailed / ExtremeDetail |
| Licença | MIT (código aberto, gratuito) | Comercial — Lite $999, Plus $1.499, Professional $2.999, Ilimitado $5.999 |
| Suporte ao .NET Framework | Não (apenas MAUI) | Sim — .NET Framework 4.6.2 ou superior |
Guia de Início Rápido: Migração do BarcodeScanning.MAUI para o IronBarcode
Passo 1: Substitua o pacote NuGet
Remover BarcodeScanning.Native.Maui:
dotnet remove package BarcodeScanning.Native.Maui
Instale o IronBarcode:
dotnet add package IronBarcode
Etapa 2: Atualizar Namespaces
Remova o namespace BarcodeScanning de todos os arquivos:
// Remove
using BarcodeScanning;Imports BarcodeScanningAdicione o namespace IronBarcode:
// Add
using IronBarCode;Imports IronBarCodeNos arquivos XAML, remova a declaração do namespace XML scanner::
<!-- Remove this line from ContentPage attributes -->
xmlns:scanner="clr-namespace:BarcodeScanning;assembly=BarcodeScanning.Native.Maui"
Etapa 3: Inicializar a licença
Adicione a inicialização da licença na inicialização do aplicativo — em MauiProgram.cs ou App.xaml.cs:
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";Imports IronBarCode
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY"Exemplos de migração de código
Varredura da câmera: da visualização da câmera ao seletor de mídia
O controle CameraView fornecia um visor em tempo real com detecção contínua de quadros. A substituição do IronBarcode usa MediaPicker do MAUI para abrir a câmera do sistema, capturar uma foto e processar a imagem resultante.
Abordagem BarcodeScanning.MAUI — XAML:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:scanner="clr-namespace:BarcodeScanning;assembly=BarcodeScanning.Native.Maui">
<StackLayout>
<scanner:CameraView x:Name="CameraView"
OnDetectionFinished="OnBarcodeDetected"
CameraEnabled="True"
BarcodeFormats="All"
VerticalOptions="FillAndExpand" />
<Label x:Name="ResultLabel" Text="Waiting for scan..." />
</StackLayout>
</ContentPage>
Abordagem BarcodeScanning.MAUI — código subjacente:
using BarcodeScanning;
private void OnBarcodeDetected(object sender, OnDetectionFinishedEventArg e)
{
var barcode = e.BarcodeResults.FirstOrDefault();
if (barcode != null)
MainThread.BeginInvokeOnMainThread(() =>
ResultLabel.Text = barcode.DisplayValue);
}Imports BarcodeScanning
Private Sub OnBarcodeDetected(sender As Object, e As OnDetectionFinishedEventArg)
Dim barcode = e.BarcodeResults.FirstOrDefault()
If barcode IsNot Nothing Then
MainThread.BeginInvokeOnMainThread(Sub()
ResultLabel.Text = barcode.DisplayValue
End Sub)
End If
End SubAbordagem IronBarcode— XAML:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui">
<StackLayout>
<Button Text="Scan Barcode" Clicked="ScanButton_Clicked" />
<Label x:Name="ResultLabel" Text="Tap to scan..." />
</StackLayout>
</ContentPage>
Abordagem IronBarcode— código subjacente:
using IronBarCode;
private async void ScanButton_Clicked(object sender, EventArgs e)
{
var photo = await MediaPicker.CapturePhotoAsync();
if (photo == null) return;
using var stream = await photo.OpenReadAsync();
using var ms = new MemoryStream();
await stream.CopyToAsync(ms);
var results = BarcodeReader.Read(ms.ToArray());
var first = results.FirstOrDefault();
ResultLabel.Text = first?.Value ?? "No barcode found";
}Imports IronBarCode
Imports System.IO
Imports System.Linq
Private Async Sub ScanButton_Clicked(sender As Object, e As EventArgs)
Dim photo = Await MediaPicker.CapturePhotoAsync()
If photo Is Nothing Then Return
Using stream = Await photo.OpenReadAsync()
Using ms As New MemoryStream()
Await stream.CopyToAsync(ms)
Dim results = BarcodeReader.Read(ms.ToArray())
Dim first = results.FirstOrDefault()
ResultLabel.Text = If(first?.Value, "No barcode found")
End Using
End Using
End SubEste código funciona em iOS, Android e MAUI do Windows sem qualquer ramificação específica da plataforma. A experiência do usuário muda de um visor integrado ao aplicativo para a tela nativa da câmera da plataforma — adequada para a maioria das aplicações empresariais. O guia de leitura IronBarcode MAUI aborda opções de configuração adicionais.
Processamento de múltiplos códigos de barras por leitura
Abordagem BarcodeScanning.MAUI:
private void OnBarcodeDetected(object sender, OnDetectionFinishedEventArg e)
{
foreach (var barcode in e.BarcodeResults)
{
MainThread.BeginInvokeOnMainThread(() =>
Console.WriteLine($"Found: {barcode.DisplayValue}"));
}
}Private Sub OnBarcodeDetected(sender As Object, e As OnDetectionFinishedEventArg)
For Each barcode In e.BarcodeResults
MainThread.BeginInvokeOnMainThread(Sub()
Console.WriteLine($"Found: {barcode.DisplayValue}")
End Sub)
Next
End SubAbordagem do IronBarcode:
using IronBarCode;
private async void ScanButton_Clicked(object sender, EventArgs e)
{
var photo = await MediaPicker.CapturePhotoAsync();
if (photo == null) return;
using var stream = await photo.OpenReadAsync();
using var ms = new MemoryStream();
await stream.CopyToAsync(ms);
var options = new BarcodeReaderOptions
{
Speed = ReadingSpeed.Balanced,
ExpectMultipleBarcodes = true
};
var results = BarcodeReader.Read(ms.ToArray(), options);
foreach (var result in results)
Console.WriteLine($"{result.Format}: {result.Value}");
}Imports IronBarCode
Imports System.IO
Private Async Sub ScanButton_Clicked(sender As Object, e As EventArgs)
Dim photo = Await MediaPicker.CapturePhotoAsync()
If photo Is Nothing Then Return
Using stream = Await photo.OpenReadAsync()
Using ms As New MemoryStream()
Await stream.CopyToAsync(ms)
Dim options As New BarcodeReaderOptions With {
.Speed = ReadingSpeed.Balanced,
.ExpectMultipleBarcodes = True
}
Dim results = BarcodeReader.Read(ms.ToArray(), options)
For Each result In results
Console.WriteLine($"{result.Format}: {result.Value}")
Next
End Using
End Using
End SubExpectMultipleBarcodes = true instrui o leitor a continuar a digitalização após encontrar o primeiro código de barras. Sem essa opção, a chamada retorna na primeira correspondência, o que é mais rápido para cenários com um único código de barras.
Correção para o código UPC-A no iOS: Remova a solução alternativa de normalização.
Se o seu código-fonte utiliza a solução alternativa para o zero à esquerda do código UPC-A, remova-a completamente. O IronBarcode retorna o valor correto de 12 dígitos sem qualquer intervenção manual.
Abordagem BarcodeScanning.MAUI — solução alternativa implementada:
private void OnBarcodeDetected(object sender, OnDetectionFinishedEventArg e)
{
var barcode = e.BarcodeResults.FirstOrDefault();
if (barcode == null) return;
var value = barcode.DisplayValue;
// Workaround: Apple Vision returns 13 digits for UPC-A
if (barcode.BarcodeFormat == BarcodeFormats.Upca && value.Length == 13)
value = value.Substring(1);
ProcessBarcode(value, barcode.BarcodeFormat.ToString());
}Private Sub OnBarcodeDetected(sender As Object, e As OnDetectionFinishedEventArg)
Dim barcode = e.BarcodeResults.FirstOrDefault()
If barcode Is Nothing Then Return
Dim value = barcode.DisplayValue
' Workaround: Apple Vision returns 13 digits for UPC-A
If barcode.BarcodeFormat = BarcodeFormats.Upca AndAlso value.Length = 13 Then
value = value.Substring(1)
End If
ProcessBarcode(value, barcode.BarcodeFormat.ToString())
End SubAbordagem IronBarcode— sem necessidade de soluções alternativas:
using IronBarCode;
private async void ScanButton_Clicked(object sender, EventArgs e)
{
var photo = await MediaPicker.CapturePhotoAsync();
if (photo == null) return;
using var stream = await photo.OpenReadAsync();
using var ms = new MemoryStream();
await stream.CopyToAsync(ms);
var results = BarcodeReader.Read(ms.ToArray());
var first = results.FirstOrDefault();
if (first == null) return;
// result.Value is the correct 12-digit UPC-A — no normalization needed
ProcessBarcode(first.Value, first.Format.ToString());
}Imports IronBarCode
Imports System.IO
Imports System.Linq
Imports System.Threading.Tasks
Private Async Sub ScanButton_Clicked(sender As Object, e As EventArgs)
Dim photo = Await MediaPicker.CapturePhotoAsync()
If photo Is Nothing Then Return
Using stream = Await photo.OpenReadAsync()
Using ms As New MemoryStream()
Await stream.CopyToAsync(ms)
Dim results = BarcodeReader.Read(ms.ToArray())
Dim first = results.FirstOrDefault()
If first Is Nothing Then Return
' result.Value is the correct 12-digit UPC-A — no normalization needed
ProcessBarcode(first.Value, first.Format.ToString())
End Using
End Using
End SubExclua quaisquer correspondências de BarcodeFormats.Upca emparelhadas com Substring(1) — este código está inativo após a migração.
Adicionando suporte a arquivos e PDFs
O módulo BarcodeScanning.Native.Maui não possui equivalente para entrada de arquivos ou PDFs. Se este for um novo requisito a ser atendido no momento da migração:
Abordagem BarcodeScanning.MAUI:
// Não equivalent exists — BarcodeScanning.Native.Maui cannot read from files or PDFs
Abordagem do IronBarcode:
using IronBarCode;
// Read from a file the user picked with FilePicker
private async void ReadFileButton_Clicked(object sender, EventArgs e)
{
var file = await FilePicker.PickAsync(new PickOptions
{
PickerTitle = "Select image or PDF"
});
if (file == null) return;
var results = BarcodeReader.Read(file.FullPath);
foreach (var result in results)
ResultLabel.Text += $"\n{result.Format}: {result.Value}";
}
// Read barcodes from a PDF directly — no intermediate image step
private void ReadPdfBarcodes()
{
var results = BarcodeReader.Read("shipment-manifest.pdf");
foreach (var result in results)
Console.WriteLine($"{result.Format}: {result.Value}");
}Imports IronBarCode
' Read from a file the user picked with FilePicker
Private Async Sub ReadFileButton_Clicked(sender As Object, e As EventArgs)
Dim file = Await FilePicker.PickAsync(New PickOptions With {
.PickerTitle = "Select image or PDF"
})
If file Is Nothing Then Return
Dim results = BarcodeReader.Read(file.FullPath)
For Each result In results
ResultLabel.Text &= vbCrLf & $"{result.Format}: {result.Value}"
Next
End Sub
' Read barcodes from a PDF directly — no intermediate image step
Private Sub ReadPdfBarcodes()
Dim results = BarcodeReader.Read("shipment-manifest.pdf")
For Each result In results
Console.WriteLine($"{result.Format}: {result.Value}")
Next
End SubA documentação de leitura de PDFs do IronBarcode abrange o suporte a PDFs com várias páginas e a seleção de intervalo de páginas.
Processamento de código de barras no servidor
Se sua aplicação tiver uma API ASP.NET de backend que também precisa de processamento de código de barras, a mesma chamada BarcodeReader.Read() é executada lá sem modificações. BarcodeScanning.Native.Maui não possui equivalente no lado do servidor.
Abordagem BarcodeScanning.MAUI:
// Não equivalent exists — BarcodeScanning.Native.Maui is a camera UI control
// and cannot run in a server process
Abordagem do IronBarcode:
using IronBarCode;
// ASP.NET endpoint — reads barcodes from an uploaded file
[HttpPost("scan")]
public async Task<IActionResult> ScanBarcode(IFormFile file)
{
using var ms = new MemoryStream();
await file.CopyToAsync(ms);
var results = BarcodeReader.Read(ms.ToArray());
var values = results.Select(r => new { r.Value, Format = r.Format.ToString() });
return Ok(values);
}Imports IronBarCode
Imports Microsoft.AspNetCore.Mvc
Imports System.IO
Imports System.Threading.Tasks
' ASP.NET endpoint — reads barcodes from an uploaded file
<HttpPost("scan")>
Public Async Function ScanBarcode(file As IFormFile) As Task(Of IActionResult)
Using ms As New MemoryStream()
Await file.CopyToAsync(ms)
Dim results = BarcodeReader.Read(ms.ToArray())
Dim values = results.Select(Function(r) New With {Key .Value = r.Value, Key .Format = r.Format.ToString()})
Return Ok(values)
End Using
End FunctionO mesmo pacote, a mesma API, o mesmo comportamento — tanto em dispositivos móveis quanto em servidores.
Gerando Códigos de Barra
BarcodeScanning.Native.Maui não possui uma API de geração. O IronBarcode gera múltiplos formatos.
Abordagem BarcodeScanning.MAUI:
// Não equivalent exists — BarcodeScanning.Native.Maui cannot generate barcodes
Abordagem do IronBarcode:
using IronBarCode;
// QR code
QRCodeWriter.CreateQrCode("https://example.com/product/12345", 500)
.SaveAsPng("qr.png");
// Code128 barcode sized to specific dimensions
BarcodeWriter.CreateBarcode("ITEM-98765", BarcodeEncoding.Code128)
.ResizeTo(400, 100)
.SaveAsPng("label.png");
// Get bytes for returning from an API or storing in a database
byte[] barcodeBytes = BarcodeWriter.CreateBarcode("ITEM-98765", BarcodeEncoding.Code128)
.ToPngBinaryData();Imports IronBarCode
' QR code
QRCodeWriter.CreateQrCode("https://example.com/product/12345", 500) _
.SaveAsPng("qr.png")
' Code128 barcode sized to specific dimensions
BarcodeWriter.CreateBarcode("ITEM-98765", BarcodeEncoding.Code128) _
.ResizeTo(400, 100) _
.SaveAsPng("label.png")
' Get bytes for returning from an API or storing in a database
Dim barcodeBytes As Byte() = BarcodeWriter.CreateBarcode("ITEM-98765", BarcodeEncoding.Code128) _
.ToPngBinaryData()A documentação de geração do IronBarcode abrange todos os formatos e opções de estilo suportados.
Referência de mapeamento da API BarcodeScanning.MAUI para IronBarcode
| BarcodeScanning.Native.Maui | IronBarcode |
|---|---|
Controle XAML CameraView | Remover — use Button + MediaPicker.CapturePhotoAsync() |
Evento OnDetectionFinished | Valor de retorno BarcodeReader.Read(imageBytes) |
OnDetectionFinishedEventArg e | Resultado IEnumerable de BarcodeReader.Read() |
e.BarcodeResults | Valor de retorno de BarcodeReader.Read() |
e.BarcodeResults.FirstOrDefault() | results.FirstOrDefault() |
barcode.DisplayValue | result.Value |
barcode.BarcodeFormat | result.Format |
BarcodeFormats="All" | Detecção automática — nenhuma configuração necessária |
CameraEnabled="True" | await MediaPicker.CapturePhotoAsync() |
| Somente iOS e Android | iOS, Android, Windows, macOS MAUI |
| Nenhum arquivo de entrada | BarcodeReader.Read(filePath) |
| Sem entrada de PDF | BarcodeReader.Read("document.pdf") |
| Nenhuma geração | BarcodeWriter.CreateBarcode() / QRCodeWriter.CreateQrCode() |
| O código UPC-A do iOS retorna 13 dígitos. | Retorna os 12 dígitos corretos — sem necessidade de normalização. |
| PDF417 não confiável | Apoiado |
Problemas e soluções comuns em migrações
Problema 1: Experiência do visor em tempo real perdida
BarcodeScanning.MAUI: O controle CameraView incorporava uma visualização de câmera em tempo real diretamente na página do MAUI. Os usuários podiam visualizar a imagem da câmera e apontar para um código de barras — a detecção ocorria automaticamente, sem que nenhum botão fosse pressionado.
Solução: MediaPicker.CapturePhotoAsync() mostra a tela da câmera da plataforma em vez disso. Para a maioria dos fluxos de trabalho empresariais, isso é aceitável. Para aplicativos de consumidor que requerem uma pré-visualização ao vivo contínua, os quadros da câmera podem ser passados diretamente para BarcodeReader.Read():
using IronBarCode;
// Continuous scanning: pass camera frame bytes to BarcodeReader.Read()
// (frame capture depends on your MAUI camera frame source)
private void ProcessCameraFrame(byte[] frameBytes)
{
var results = BarcodeReader.Read(frameBytes);
if (results.Any())
{
var first = results.First();
MainThread.BeginInvokeOnMainThread(() =>
ResultLabel.Text = first.Value);
}
}Imports IronBarCode
' Continuous scanning: pass camera frame bytes to BarcodeReader.Read()
' (frame capture depends on your MAUI camera frame source)
Private Sub ProcessCameraFrame(frameBytes As Byte())
Dim results = BarcodeReader.Read(frameBytes)
If results.Any() Then
Dim first = results.First()
MainThread.BeginInvokeOnMainThread(Sub()
ResultLabel.Text = first.Value
End Sub)
End If
End SubIsso requer a conexão de uma fonte de imagem da câmera separadamente do IronBarcode. Antes de optar por essa solução, avalie se uma pré-visualização ao vivo é realmente necessária ou se a interface de usuário da câmera do sistema é suficiente.
Problema 2: Alterações no nome da propriedade e na enumeração de e.BarcodeResults
BarcodeScanning.MAUI: barcode.DisplayValue retorna a string decodificada; barcode.BarcodeFormat retorna um valor de enumeração da biblioteca BarcodeScanning.
Solução: Substitua DisplayValue por result.Value e barcode.BarcodeFormat por result.Format. O padrão de iteração é o mesmo:
// Before
foreach (var barcode in e.BarcodeResults)
Console.WriteLine(barcode.DisplayValue);
// After
var results = BarcodeReader.Read(imageBytes);
foreach (var result in results)
Console.WriteLine(result.Value);' Before
For Each barcode In e.BarcodeResults
Console.WriteLine(barcode.DisplayValue)
Next
' After
Dim results = BarcodeReader.Read(imageBytes)
For Each result In results
Console.WriteLine(result.Value)
NextProblema 3: Serialização de threads para atualizações da interface do usuário
BarcodeScanning.MAUI: OnDetectionFinished dispara em um thread de fundo, então todas as atualizações de UI requerem MainThread.BeginInvokeOnMainThread().
Solução: Com o padrão MediaPicker + async, a continuação após await retorna no contexto de chamada — tipicamente o thread principal. Os wrappers MainThread.BeginInvokeOnMainThread() em torno da exibição de resultados podem geralmente ser removidos, simplificando o código do manipulador.
Problema 4: Permissões da câmera MAUI
BarcodeScanning.MAUI: O pacote adiciona permissões de câmera a AndroidManifest.xml e Info.plist automaticamente como parte de sua configuração.
Solução: Com IronBarcode usando MediaPicker, as permissões padrão de câmera do MAUI devem estar presentes manualmente. Estas são as mesmas permissões que qualquer aplicativo MAUI precisa para MediaPicker.CapturePhotoAsync() e geralmente já estão no lugar. Verifique se android.permission.CAMERA está declarado em AndroidManifest.xml e NSCameraUsageDescription está definido em Info.plist antes de testar no dispositivo.
Lista de verificação de migração para leitura de código de barras MAUI
Tarefas pré-migração
Execute estas pesquisas para encontrar todos os usos de BarcodeScanning.Native.Maui antes de fazer qualquer alteração:
grep -rn "using BarcodeScanning" --include="*.cs" .
grep -rn "using BarcodeScanning" --include="*.xaml" .
grep -rn "CameraView" --include="*.cs" .
grep -rn "CameraView" --include="*.xaml" .
grep -rn "OnDetectionFinished" --include="*.cs" .
grep -rn "OnDetectionFinishedEventArg" --include="*.cs" .
grep -rn "e\.BarcodeResults" --include="*.cs" .
grep -rn "DisplayValue" --include="*.cs" .
grep -rn "BarcodeFormats\.Upca" --include="*.cs" .
grep -rn "scanner:" --include="*.xaml" .
Documente cada acerto. Observe quais arquivos contêm uso de XAML CameraView (exigem mudanças em XAML) versus quais contêm apenas mudanças no code-behind. Identifique quaisquer soluções alternativas para a normalização do código UPC-A que devam ser excluídas após a migração.
Tarefas de atualização de código
- Remova o pacote NuGet
BarcodeScanning.Native.Maui - Instale o pacote NuGet
IronBarcode - Adicione
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";emMauiProgram.csouApp.xaml.cs - Substitua
using BarcodeScanning;porusing IronBarCode;em todos os arquivos.cs - Remova declarações de namespace
xmlns:scanner="..."de todos os arquivos XAML - Substitua controles
scanner:CameraViewem XAML por umButtonque acioneMediaPicker.CapturePhotoAsync() - Remova a fiação de eventos
OnDetectionFinished="..."do XAML - Substitua manipuladores de eventos
OnDetectionFinishedpor manipuladores de clique de botãoasyncusandoBarcodeReader.Read() - Substitua
barcode.DisplayValueporresult.Valueem todo lugar - Substitua
barcode.BarcodeFormatporresult.Formatem todo lugar - Exclua todas as soluções alternativas de normalização
BarcodeFormats.Upca+Substring(1) - Adicione
ExpectMultipleBarcodes = trueaBarcodeReaderOptionsonde a detecção de múltiplos códigos de barras estava anteriormente confiando eme.BarcodeResultsretornando múltiplos itens - Remova wrappers
MainThread.BeginInvokeOnMainThread()do código de exibição de resultados onde o padrão assíncrono os torna desnecessários - Verifique se as permissões de câmera
AndroidManifest.xmleInfo.plistestão presentes
Testes pós-migração
- Verificar se a leitura de código de barras no iOS funciona e se os valores UPC-A são retornados como sequências de 12 dígitos sem zeros à esquerda.
- Verificar se a leitura de código de barras no Android produz valores corretos para todos os formatos usados no aplicativo.
- Verifique se a leitura de código de barras MAUI do Windows funciona caso o Windows seja um destino de compilação.
- Teste a digitalização do PDF417 comparando-a com etiquetas de envio reais, carteiras de habilitação ou cartões de embarque, caso sejam utilizados.
- Teste cenários de múltiplos códigos de barras com
ExpectMultipleBarcodes = truee confirme se todos os códigos de barras em uma imagem são retornados - Verifique se a varredura do seletor de arquivos (
BarcodeReader.Read(filePath)) funciona em todos os alvos do MAUI - Verificar a leitura de código de barras em PDF caso essa seja uma nova funcionalidade adicionada durante a migração.
- Confirme se
BarcodeReader.Read()no lado do servidor produz resultados corretos se um componente de backend foi adicionado - Execute todos os testes automatizados existentes e compare os valores de saída dos códigos de barras com os valores de referência anteriores à migração.
Principais benefícios da migração para o IronBarcode
Suporte completo ao MAUI do Windows: o IronBarcode funciona em todas as quatro plataformas MAUI — iOS, Android, Windows e macOS — usando o mesmo código e o mesmo pacote. Nenhuma implementação específica de plataforma para códigos de barras é necessária para Windows, e nenhum blocos #if WINDOWS são necessários no código do aplicativo.
Qualquer Fonte de Entrada: BarcodeReader.Read() aceita caminhos de arquivos, arrays de bytes, streams e documentos PDF. Qualquer cenário de código de barras — captura por câmera, upload de arquivo, imagem da galeria, processamento de PDF no servidor — usa o mesmo método estático com o mesmo tipo de resultado.
Valores UPC-A corretos: O IronBarcode retorna o valor UPC-A correto de 12 dígitos no iOS sem qualquer código de normalização no aplicativo. Os dados históricos de UPC-A armazenados com um zero à esquerda devido ao comportamento do BarcodeScanning.Native.Maui não afetam a precisão dos valores lidos após a migração.
PDF417 confiável: O PDF417 é totalmente compatível e realiza leituras confiáveis. Etiquetas de envio, carteiras de motorista e cartões de embarque são escaneados sem a limitação de "a maioria das leituras nunca ocorre", documentada nos problemas do GitHub do BarcodeScanning.Native.Maui.
Geração de Código de Barras: BarcodeWriter.CreateBarcode() e QRCodeWriter.CreateQrCode() geram Code128, QR, DataMatrix e outros formatos como arquivos PNG ou arrays de bytes. A geração e a leitura estão disponíveis no mesmo pacote, sem dependências adicionais.
Implantação no Lado do Servidor: A mesma chamada BarcodeReader.Read() é executada em ASP.NET, Azure Functions, contêineres Docker e AWS Lambda. A lógica de código de barras para dispositivos móveis e servidores pode compartilhar a mesma API, o mesmo suporte a formatos e o mesmo tipo de resultado, sem a necessidade de manter duas implementações de código de barras separadas.

Curtis Chau é bacharel em Ciência da Computação (Universidade Carleton) e se especializa em desenvolvimento front-end, com experiência em Node.js, TypeScript, JavaScript e React. Apaixonado por criar interfaces de usuário intuitivas e esteticamente agradáveis, Curtis gosta de trabalhar com frameworks modernos e criar manuais bem estruturados e visualmente atraentes.