Migrating from BarcodeScanning.Native.Maui to IronBarcode
Esta guía proporciona una ruta de migración completa desde BarcodeScanning.Native.Maui a IronBarcode, que abarca la sustitución del patrón de eventos de la cámara, los cambios de espacio de nombres, ejemplos de migración de código y el manejo de escenarios que BarcodeScanning.Native.Maui no puede abordar: Windows MAUI, entrada de archivos y PDF, procesamiento del lado del servidor y generación de códigos de barras.
¿Por qué migrar desde BarcodeScanning.MAUI?
Los equipos que migran desde BarcodeScanning.Native.Maui informan de los siguientes desencadenantes:
Se requiere Windows MAUI como plataforma de destino: BarcodeScanning.Native.Maui encapsula las API nativas de iOS y Android. No tiene implementación para Windows ni está previsto que la tenga. Si tu aplicación MAUI está dirigida a Windows, además de iOS y Android, necesitas una biblioteca que funcione en las tres plataformas sin necesidad de ramificaciones específicas para cada una.
Entrada de archivos o PDF añadida a los requisitos: BarcodeScanning.Native.Maui solo acepta fotogramas de cámara en directo. Cuando los usuarios necesitan subir una imagen desde su galería, o cuando un punto final del servidor necesita extraer códigos de barras de archivos PDF, la biblioteca no ofrece ninguna ruta de código. Cada escenario de código de barras de archivos o PDF requiere una herramienta diferente.
Los datos UPC-A de iOS eran erróneos en producción: el marco Vision de Apple devuelve 13 dígitos para los códigos de barras UPC-A (codificación EAN-13). BarcodeScanning.Native.Maui lo transmite sin corregir. Si los códigos UPC-A se almacenaban con un cero inicial, los registros de inventario, las consultas en los puntos de venta o las integraciones de la cadena de suministro podrían haberse visto afectados silenciosamente. IronBarcode devuelve el valor UPC-A correcto de 12 dígitos sin necesidad de normalización manual.
El escaneo del PDF417 no era fiable: el propio documento de incidencias de la biblioteca en GitHub describe el PDF417 como "muy problemático: la mayoría de los escaneos no se realizan". Esto supone un bloqueo directo para etiquetas de envío, permisos de conducir y tarjetas de embarque.
Generación necesaria: BarcodeScanning.Native.Maui no puede generar códigos de barras. IronBarcode genera códigos Code128, QR, DataMatrix y otros formatos como archivos de imagen o matrices de bytes.
Se ha introducido el procesamiento del lado del servidor: BarcodeScanning.Native.Maui es un control de interfaz de usuario de la cámara; no puede ejecutarse en un proceso de servidor. Cuando se requiere la lectura de códigos de barras en el servidor junto con el escaneo móvil, IronBarcode cubre ambos lados con el mismo paquete y la misma API.
El problema fundamental
BarcodeScanning.Native.Maui vincula la lectura de códigos de barras completamente al modelo de eventos de la cámara en vivo. En el momento en que cualquier requisito queda fuera de ese modelo, la biblioteca no ofrece 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 SubIronBarcode acepta cualquier tipo de entrada de datos (captura de cámara, archivo, PDF, matriz de bytes) y funciona en todas las 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 SubIronBarcode vs BarcodeScanning.MAUI: Comparación de funciones
| Característica | BarcodeScanning.MAUI | IronBarcode |
|---|---|---|
| Lectura de fotogramas de la cámara en directo | Sí — Control de CameraView | No (utiliza MediaPicker para capturar y luego leer) |
| visor de la cámara en la aplicación | Sí, en tiempo real y continuo. | No, utiliza la interfaz de usuario de la cámara del sistema a través de MediaPicker. |
| Leer desde archivo de imagen | No | Sí — BarcodeReader.Read(path) |
| Leer desde una matriz de bytes | No | Sí — BarcodeReader.Read(bytes) |
| Leer desde la transmisión | No | Sí — BarcodeReader.Read(stream) |
| Leer desde PDF | No | Sí — BarcodeReader.Read(pdf) |
| Generación de BarCodes | No | Sí — BarcodeWriter + QRCodeWriter |
| Compatibilidad con Windows MAUI | No | Sí |
| Compatibilidad con iOS MAUI | Sí | Sí |
| Compatibilidad con Android MAUI | Sí | Sí |
| Compatibilidad con macOS MAUI | No documentado | Sí |
| Servidor / ASP.NET | No | Sí |
| Docker / Azure / AWS Lambda | No | Sí |
| Precisión del código UPC-A de iOS | Devuelve 13 dígitos (error), requiere normalización manual. | Devuelve el código UPC-A correcto de 12 dígitos. |
| Fiabilidad del PDF417 | "La mayoría de los escaneos nunca se realizan" (problemas de GitHub ) | Se admite |
| Detección de múltiples códigos de barras | Sí (múltiples por cuadro a través de e.BarcodeResults) | Sí (ExpectMultipleBarcodes opción) |
| Control de velocidad de lectura | None | ReadingSpeed.Faster / Balanced / Detailed / ExtremeDetail |
| Licencia | MIT (código abierto, gratuito) | Comercial: Lite $999, Plus $1,499, Professional $2,399, Ilimitado $4,799 |
| Compatibilidad con .NET Framework | No (solo MAUI) | Sí — .NET Framework 4.6.2+ |
Inicio rápido: Migración de BarcodeScanning.MAUI a IronBarcode
Paso 1: Sustituir el paquete NuGet
Eliminar BarcodeScanning.Native.Maui:
dotnet remove package BarcodeScanning.Native.Maui
Instalar IronBarcode:
dotnet add package IronBarcode
Paso 2: Actualizar los espacios de nombres
Elimine el espacio de nombres BarcodeScanning de todos los archivos:
// Remove
using BarcodeScanning;Imports BarcodeScanningAgregue el espacio de nombres IronBarcode :
// Add
using IronBarCode;Imports IronBarCodeEn archivos XAML, elimine la declaración del espacio de nombres XML scanner::
<!-- Remove this line from ContentPage attributes -->
xmlns:scanner="clr-namespace:BarcodeScanning;assembly=BarcodeScanning.Native.Maui"
Paso 3: Inicializar licencia
Agregue la inicialización de la licencia al inicio de la aplicación — en MauiProgram.cs o App.xaml.cs:
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";Imports IronBarCode
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY"Ejemplos de migración de código
Escaneo de cámara: CameraView a MediaPicker
El control CameraView proporcionaba un visor en tiempo real con detección continua de cuadros. El reemplazo de IronBarcode utiliza MediaPicker de MAUI para abrir la cámara del sistema, capturar una foto y procesar la imagen resultante.
Escaneo de códigos de barras. Enfoque 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>
Enfoque de BarcodeScanning.MAUI — código subyacente:
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 SubEnfoque 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>
Enfoque de IronBarcode : código subyacente:
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 se ejecuta en iOS, Android y Windows MAUI sin necesidad de bifurcaciones específicas de la plataforma. La experiencia del usuario cambia de un visor integrado en la aplicación a la pantalla de la cámara nativa de la plataforma, lo cual resulta apropiado para la mayoría de las aplicaciones empresariales. La guía de lectura de IronBarcode MAUI cubre opciones de configuración adicionales.
Manejo de múltiples códigos de barras por escaneo
Escaneo de códigos de barras. Enfoque 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 SubEnfoque de 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 indica al lector que continúe escaneando después de encontrar el primer código de barras. Sin esta opción, la llamada devuelve el resultado en la primera coincidencia, lo que resulta más rápido en escenarios con un solo código de barras.
Solución para iOS UPC-A: Eliminar la solución alternativa de normalización
Si su código fuente utiliza la solución alternativa del cero inicial en el código UPC-A, elimínela por completo. IronBarcode devuelve el valor correcto de 12 dígitos sin ninguna intervención manual.
Enfoque de BarcodeScanning.MAUI: solución 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 SubEnfoque IronBarcode : no se necesita ninguna solución alternativa:
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 SubElimine cualquier coincidencia de BarcodeFormats.Upca emparejado con Substring(1) — ese código está inactivo después de la migración.
Agregar compatibilidad con archivos y PDF
BarcodeScanning.Native.Maui no tiene un equivalente para la entrada de archivos o PDF. Si se trata de un nuevo requisito que se cumple en el momento de la migración:
Escaneo de códigos de barras. Enfoque MAUI:
// No equivalent exists — BarcodeScanning.Native.Maui cannot read from files or PDFs' No equivalent exists — BarcodeScanning.Native.Maui cannot read from files or PDFsEnfoque de 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 SubLa documentación de IronBarcode sobre la lectura de archivos PDF abarca la compatibilidad con archivos PDF de varias páginas y la selección de rangos de páginas.
Procesamiento de códigos de barras del lado del servidor
Si su aplicación tiene una API ASP.NET de backend que también necesita procesamiento de códigos de barras, la misma llamada BarcodeReader.Read() se ejecuta allí sin modificaciones. BarcodeScanning.Native.Maui no tiene un equivalente del lado del servidor.
Escaneo de códigos de barras. Enfoque MAUI:
// No equivalent exists — BarcodeScanning.Native.Maui is a camera UI control
// and cannot run in a server process' No equivalent exists — BarcodeScanning.Native.Maui is a camera UI control
' and cannot run in a server processEnfoque de 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 FunctionEl mismo paquete, la misma API, el mismo comportamiento, tanto en dispositivos móviles como en servidores.
Generación de códigos de barras
BarcodeScanning.Native.Maui no tiene API de generación. IronBarcode genera múltiples formatos.
Escaneo de códigos de barras. Enfoque MAUI:
// No equivalent exists — BarcodeScanning.Native.Maui cannot generate barcodes' No equivalent exists — BarcodeScanning.Native.Maui cannot generate barcodesEnfoque de 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()La documentación de generación de IronBarcode abarca todos los formatos compatibles y las opciones de estilo.
Referencia de mapeo de la API de BarcodeScanning.MAUI a IronBarcode
| BarcodeScanning.Native.Maui | IronBarcode |
|---|---|
CameraView control de XAML | Eliminar — use Button + MediaPicker.CapturePhotoAsync() |
Evento de OnDetectionFinished | Valor de retorno de 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" | Detección automática: no requiere configuración. |
CameraEnabled="True" | await MediaPicker.CapturePhotoAsync() |
| Solo iOS y Android | iOS, Android, Windows, macOS MAUI |
| No se permite la entrada de archivos. | BarcodeReader.Read(filePath) |
| No se permite la entrada de archivos PDF. | BarcodeReader.Read("document.pdf") |
| Ninguna generación | BarcodeWriter.CreateBarcode() / QRCodeWriter.CreateQrCode() |
| El código UPC-A de iOS devuelve 13 dígitos. | Devuelve los 12 dígitos correctos; no se necesita normalización. |
| PDF417 poco fiable | Se admite |
Problemas comunes de migración y soluciones
Problema 1: Se pierde la experiencia del visor en directo
BarcodeScanning.MAUI: El control CameraView integraba una vista previa de cámara en tiempo real directamente en la página MAUI. Los usuarios podían ver la imagen de la cámara y apuntar a un código de barras; la detección se producía automáticamente sin necesidad de pulsar ningún botón.
Solución: MediaPicker.CapturePhotoAsync() muestra en su lugar la pantalla de la cámara de la plataforma. Para la mayoría de los flujos de trabajo empresariales, esto es aceptable. Para aplicaciones de consumo que requieren una vista previa en vivo continua, los cuadros de la cámara pueden pasarse directamente a 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 SubEsto requiere conectar una fuente de fotogramas de la cámara por separado de IronBarcode. Antes de optar por esta opción, evalúe si realmente se necesita una vista previa en tiempo real o si la interfaz de usuario de la cámara del sistema es suficiente.
Problema 2: Cambios en el nombre de la propiedad y la enumeración de e.BarcodeResults
BarcodeScanning.MAUI: barcode.DisplayValue devuelve la cadena decodificada; barcode.BarcodeFormat devuelve un valor de enumeración de la biblioteca BarcodeScanning.
Solución: Reemplace DisplayValue por result.Value y barcode.BarcodeFormat por result.Format. El patrón de iteración es el mismo:
// 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: Gestión de subprocesos para actualizaciones de la interfaz de usuario
BarcodeScanning.MAUI: OnDetectionFinished se dispara en un hilo de fondo, por lo que todas las actualizaciones de UI requieren MainThread.BeginInvokeOnMainThread().
Solución: Con el patrón MediaPicker + async, la continuación después de await regresa en el contexto de llamada — típicamente el hilo principal. Los envoltorios MainThread.BeginInvokeOnMainThread() alrededor de la visualización del resultado pueden eliminarse generalmente, simplificando el código del manejador.
Problema 4: Permisos de la cámara de MAUI
BarcodeScanning.MAUI: El paquete añade permisos de cámara a AndroidManifest.xml y Info.plist automáticamente como parte de su configuración.
Solución: Con IronBarcode utilizando MediaPicker, los permisos estándar de cámara MAUI deben estar presentes manualmente. Estos son los mismos permisos que necesita cualquier aplicación MAUI para MediaPicker.CapturePhotoAsync() y típicamente ya están en su lugar. Verifique que android.permission.CAMERA esté declarado en AndroidManifest.xml y NSCameraUsageDescription esté configurado en Info.plist antes de probar en el dispositivo.
Lista de verificación de migración de MAUI para escaneo de códigos de barras
Tareas previas a la migración
Ejecute estas búsquedas para encontrar todos los usos de BarcodeScanning.Native.Maui antes de realizar cualquier cambio:
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" .
Documenta cada golpe. Tenga en cuenta qué archivos contienen el uso de XAML CameraView (requieren cambios en XAML) frente a los que solo contienen cambios de código-behind. Identifique cualquier solución alternativa de normalización UPC-A que deba eliminarse después de la migración.
Tareas de actualización de código
- Eliminar el paquete NuGet
BarcodeScanning.Native.Maui - Instalar el paquete NuGet
IronBarcode - Agregar
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";enMauiProgram.csoApp.xaml.cs - Reemplace
using BarcodeScanning;porusing IronBarCode;en todos los archivos.cs - Elimine las declaraciones de espacio de nombres
xmlns:scanner="..."de todos los archivos XAML - Reemplace los controles
scanner:CameraViewen XAML con unButtonque dispareMediaPicker.CapturePhotoAsync() - Elimine el cableado de eventos
OnDetectionFinished="..."de XAML - Reemplace los manejadores de eventos
OnDetectionFinishedcon manejadores de clic de botónasyncusandoBarcodeReader.Read() - Reemplace
barcode.DisplayValueporresult.Valueen todo el documento - Reemplace
barcode.BarcodeFormatporresult.Formaten todo el documento - Elimine todos los atajos de normalización
BarcodeFormats.Upca+Substring(1) - Agregue
ExpectMultipleBarcodes = trueaBarcodeReaderOptionsdonde la detección de múltiples códigos de barras previamente dependía dee.BarcodeResultsdevolviendo múltiples ítems - Quite los envoltorios
MainThread.BeginInvokeOnMainThread()del código de visualización de resultados donde el patrón asincrónico los hace innecesarios - Verifique que los permisos de cámara
AndroidManifest.xmlyInfo.plistestén presentes
Pruebas posteriores a la migración
- Verificar que el escaneo de códigos de barras de iOS funcione y que los valores UPC-A se devuelvan como cadenas de 12 dígitos sin ceros iniciales.
- Verificar que el escaneo de códigos de barras de Android produzca valores correctos para todos los formatos utilizados en la aplicación.
- Verifica que el escaneo de códigos de barras de Windows MAUI funcione si Windows es un destino de compilación.
- Pruebe el escaneo PDF417 comparándolo con etiquetas de envío reales, licencias de conducir o tarjetas de embarque, si se utilizan.
- Pruebe escenarios de múltiples códigos de barras con
ExpectMultipleBarcodes = truey confirme que todos los códigos de barras en una imagen sean devueltos - Verifique que el escaneo del selector de archivos (
BarcodeReader.Read(filePath)) funcione en todos los objetivos MAUI - Verifique la lectura del código de barras PDF si esta fue una nueva funcionalidad agregada junto con la migración.
- Confirme que
BarcodeReader.Read()del lado del servidor produce resultados correctos si se agregó un componente backend - Ejecute las pruebas automatizadas existentes y compare los resultados de los códigos de barras con las líneas base previas a la migración.
Principales ventajas de migrar a IronBarcode
Compatibilidad total con MAUI para Windows: IronBarcode funciona en los cuatro sistemas operativos MAUI (iOS, Android, Windows y macOS) utilizando el mismo código y el mismo paquete. No se necesita una implementación de código de barras específica para la plataforma en Windows, y no se requieren bloques #if WINDOWS en el código de la aplicación.
Cualquier Fuente de Entrada: BarcodeReader.Read() acepta rutas de archivos, arreglos de bytes, flujos y documentos PDF. Cualquier escenario relacionado con códigos de barras (captura de cámara, carga de archivos, imagen de galería, procesamiento de PDF en el servidor) utiliza el mismo método estático con el mismo tipo de resultado.
Valores UPC-A correctos: IronBarcode devuelve el valor UPC-A correcto de 12 dígitos en iOS sin necesidad de ningún código de normalización en la aplicación. Los datos históricos UPC-A almacenados con un cero inicial debido al comportamiento de BarcodeScanning.Native.Maui no afectan la precisión de los valores leídos después de la migración.
PDF417 fiable: PDF417 es totalmente compatible y se lee de forma fiable. Las etiquetas de envío, los permisos de conducir y las tarjetas de embarque se escanean sin la limitación de que "la mayoría de los escaneos nunca ocurren", documentada en los problemas de GitHub de BarcodeScanning.Native.Maui.
Generación de Códigos de Barras: BarcodeWriter.CreateBarcode() y QRCodeWriter.CreateQrCode() generan Code128, QR, DataMatrix y otros formatos como archivos PNG o arreglos de bytes. La generación y la lectura están disponibles desde el mismo paquete sin dependencias adicionales.
Despliegue en el Servidor: La misma llamada BarcodeReader.Read() se ejecuta en ASP.NET, Funciones Azure, contenedores Docker, y AWS Lambda. La lógica de códigos de barras para dispositivos móviles y servidores puede compartir la misma API, la misma compatibilidad de formatos y el mismo tipo de resultado sin necesidad de mantener dos implementaciones de códigos de barras separadas.

Curtis Chau tiene una licenciatura en Ciencias de la Computación (Carleton University) y se especializa en el desarrollo front-end con experiencia en Node.js, TypeScript, JavaScript y React. Apasionado por crear interfaces de usuario intuitivas y estéticamente agradables, disfruta trabajando con frameworks modernos y creando manuales bien estructurados y visualmente atractivos.