Migrating from BarcodeScanning.Native.Maui to IronBarcode
Niniejszy przewodnik przedstawia kompletną ścieżkę migracji z BarcodeScanning.Native.Maui do IronBarcode, obejmującą zastąpienie wzorca zdarzeń kamery, zmiany przestrzeni nazw, przykłady migracji kodu oraz obsługę scenariuszy, których BarcodeScanning.Native.Maui nie jest w stanie obsłużyć — Windows MAUI, wprowadzanie plików i PDF, przetwarzanie po stronie serwera oraz generowanie kodów kreskowych.
Dlaczego warto przejść z BarcodeScanning.MAUI
Zespoły migrujące z BarcodeScanning.Native.Maui zgłaszają następujące wyzwałącze:
Wymagany cel Windows MAUI: BarcodeScanning.Native.Maui obsługuje natywne interfejsy API systemów iOS i Android. Nie ma implementacji dla systemu Windows i nie jest ona planowana. Jeśli Twoja aplikacja MAUI jest przeznaczona dla systemów Windows, iOS i Android, potrzebujesz biblioteki, która działa na wszystkich trzech platformach bez konieczności tworzenia odgałęzień specyficznych dla danej platformy.
Dodano plik lub dane wejściowe w formacie PDF do wymagań: BarcodeScanning.Native.Maui akceptuje wyłącznie klatki z kamery na żywo. Gdy użytkownicy muszą przesłać obraz z galerii lub gdy punkt końcowy po stronie serwera musi wyodrębnić BARCODE-y z plików PDF, biblioteka nie oferuje żadnej ścieżki kodu. Każdy scenariusz dotyczący plików lub BarCodes w formacie PDF wymaga innego narzędzia.
Dane UPC-A w systemie iOS były błędne w środowisku produkcyjnym: framework Apple Vision zwraca 13 cyfr dla BARCODE-ów UPC-A (kodowanie EAN-13). BarcodeScanning.Native.Maui przekazuje to bez poprawek. Gdyby kody UPC-A były przechowywane z zerem na początku, mogłoby to spowodować niepostrzeżone zakłócenia w rejestrach zapasów, wyszukiwaniu w punktach sprzedaży lub integracji łańcucha dostaw.IronBarcode zwraca prawidłową 12-cyfrową wartość UPC-A bez konieczności ręcznej normalizacji.
Skanowanie PDF417 było zawodne: W dokumentacji biblioteki na GitHubie PDF417 jest opisany jako "bardzo problematyczny — większość skanów nigdy nie dochodzi do skutku". W przypadku etykiet wysyłkowych, praw jazdy i kart pokładowych stanowi to bezpośrednią przeszkodę.
Wymagane generowanie: BarcodeScanning.Native.Maui nie może generować kodów kreskowych.IronBarcode generuje kody Code128, QR, DataMatrix i inne formaty jako pliki graficzne lub tablice bajtów.
Wprowadzenie przetwarzania po stronie serwera: BarcodeScanning.Native.Maui to kontrolka interfejsu użytkownika kamery — nie może działać w procesie serwera. Gdy oprócz skanowania mobilnego wymagane jest odczytywanie kodów kreskowych po stronie serwera,IronBarcode obsługuje obie strony za pomocą tego samego pakietu i tego samego interfejsu API.
Podstawowy problem
BarCodeScanning.Native.Maui całkowicie wiąże odczyt kodów kreskowych z modelem zdarzeń na żywo z kamery. W momencie, gdy jakikolwiek wymóg wykracza poza ten model, biblioteka nie oferuje nic:
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 akceptuje dowolne dane wejściowe — zdjęcia z aparatu, pliki, PDF, tablice bajtów — i działa na każdej platformie:
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 a BarcodeScanning.MAUI: Porównanie funkcji
| Funkcja | BarcodeScanning.MAUI | IronBarcode |
|---|---|---|
| Odczytywanie klatek z kamery na żywo | Tak — kontrolka CameraView | Nie (użyj MediaPicker do przechwycenia, a następnie odczytania) |
| Wizjer aparatu w aplikacji | Tak — w czasie rzeczywistym, w sposób ciągły | Nie — korzysta z interfejsu użytkownika aparatu systemowego za pośrednictwem MediaPicker |
| Odczyt z pliku graficznego | Nie | Tak — BarcodeReader.Read(path) |
| Odczyt z tablicy bajtów | Nie | Tak — BarcodeReader.Read(bytes) |
| Odczyt z strumienia | Nie | Tak — BarcodeReader.Read(stream) |
| Czytaj z pliku PDF | Nie | Tak — BarcodeReader.Read(pdf) |
| Generowanie BarCode | Nie | Tak — BarcodeWriter + QRCodeWriter |
| Obsługa Windows MAUI | Nie | Tak |
| Obsługa iOS MAUI | Tak | Tak |
| Obsługa MAUI w systemie Android | Tak | Tak |
| Obsługa macOS MAUI | Brak dokumentacji | Tak |
| Po stronie serwera / ASP.NET | Nie | Tak |
| Docker / Azure / AWS Lambda | Nie | Tak |
| Dokładność iOS UPC-A | Zwraca 13 cyfr (błąd), wymaga ręcznej normalizacji | Zwraca poprawny 12-cyfrowy kod UPC-A |
| Niezawodność PDF417 | "Większość skanów nigdy nie ma miejsca" (zgłoszenia na GitHubie) | Obsługiwane |
| Wykrywanie wielu kodów BarCode | Tak (wiele na ramkę za pomocą e.BarcodeResults) | Tak (opcja ExpectMultipleBarcodes) |
| Kontrola prędkości czytania | None | ReadingSpeed.Faster / Balanced / Detailed / ExtremeDetail |
| Licencja | MIT (open source, bezpłatne) | Wersja komercyjna — Lite 749 USD, Plus 1499 USD, Professional 2999 USD, Unlimited 5999 USD |
| Obsługa platformy .NET Framework | Nie (tylko MAUI) | Tak — .NET Framework 4.6.2+ |
Szybki start: Migracja z BarcodeScanning.MAUI do IronBarcode
Krok 1: Zastąp pakiet NuGet
Usuń BarcodeScanning.Native.Maui:
dotnet remove package BarcodeScanning.Native.Maui
Zainstaluj IronBarcode:
dotnet add package IronBarcode
Krok 2: Aktualizacja przestrzeni nazw
Usuń przestrzeń nazw BarcodeScanning ze wszystkich plików:
// Remove
using BarcodeScanning;Imports BarcodeScanningDodaj przestrzeń nazw IronBarcode:
// Add
using IronBarCode;Imports IronBarCodeW plikach XAML usuń deklarację przestrzeni nazw XML scanner::
<!-- Remove this line from ContentPage attributes -->
xmlns:scanner="clr-namespace:BarcodeScanning;assembly=BarcodeScanning.Native.Maui"
Krok 3: Inicjalizacja licencji
Dodaj inicjalizację licencji przy starcie aplikacji — w MauiProgram.cs lub App.xaml.cs:
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";Imports IronBarCode
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY"Przykłady migracji kodu
Skanowanie kamerą: CameraView do MediaPicker
Kontrola CameraView zapewniał celownik o rzeczywistym podglądzie z ciągłym wykrywaniem ramek. Zamiennik IronBarcode używa MediaPicker MAUI do otwarcia systemowej kamery, zrobienia zdjęcia i przetworzenia wynikowego obrazu.
Podejście 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>
Podejście BarcodeScanning.MAUI — kod źródłowy:
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 SubPodejście 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>
Podejście IronBarcode— kod źródłowy:
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 SubTen kod działa na systemach iOS, Android i Windows MAUI bez żadnych rozgałęzień specyficznych dla danej platformy. Doświadczenie użytkownika zmienia się z podglądu na żywo w aplikacji na natywny ekran aparatu platformy — odpowiedni dla większości aplikacji biznesowych. Przewodnik użytkownika IronBarcode MAUI zawiera informacje o dodatkowych opcjach konfiguracyjnych.
Obsługa wielu BarCodes w jednym skanowaniu
Podejście 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 SubPodejście 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 mówi użytkownikowi, aby kontynuował skanowanie po znalezieniu pierwszego kodu kreskowego. Bez tej opcji wywołanie zwraca wynik przy pierwszym dopasowaniu, co jest szybsze w przypadku scenariuszy z jednym BARCODE-em.
Poprawka iOS UPC-A: Usunięcie obejścia normalizacji
Jeśli w Twoim kodzie występuje obejście dotyczące zer wiodących w kodach UPC-A, usuń je całkowicie.IronBarcode zwraca prawidłową 12-cyfrową wartość bez żadnej ręcznej interwencji.
Podejście BarcodeScanning.MAUI — zastosowane obejście:
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 SubPodejście IronBarcode— nie wymaga żadnych obejść:
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 SubUsuń wszelkie dopasowania dla BarcodeFormats.Upca sparowanego z Substring(1) — ten kod jest nieaktywny po migracji.
Dodanie obsługi plików i formatu PDF
BarcodeScanning.Native.Maui nie ma odpowiednika dla plików lub danych wejściowych w formacie PDF. Jeśli jest to nowe wymaganie, które ma zostać spełnione w momencie migracji:
Podejście BarcodeScanning.MAUI:
// Nie equivalent exists — BarcodeScanning.Native.Maui cannot read from files or PDFs
Podejście 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 SubDokumentacja dotycząca odczytu plików PDF w IronBarcode obejmuje obsługę wielostronicowych plików PDF oraz wybór zakresu stron.
Przetwarzanie BarCodes po stronie serwera
Jeśli twoja aplikacja ma backend API ASP.NET, który również wymaga przetwarzania kodów kreskowych, to samo wywołanie BarcodeReader.Read() działa tam bez modyfikacji. BarcodeScanning.Native.Maui nie ma odpowiednika po stronie serwera.
Podejście BarcodeScanning.MAUI:
// Nie equivalent exists — BarcodeScanning.Native.Maui is a camera UI control
// and cannot run in a server process
Podejście 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 FunctionTen sam pakiet, to samo API, to samo działanie — na urządzeniach mobilnych i serwerach.
Generowanie BarCodes
BarcodeScanning.Native.Maui nie posiada API do generowania.IronBarcode generuje wiele formatów.
Podejście BarcodeScanning.MAUI:
// Nie equivalent exists — BarcodeScanning.Native.Maui cannot generate barcodes
Podejście 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()Dokumentacja dotycząca generowania kodów kreskowych IronBarcode obejmuje wszystkie obsługiwane formaty i opcje stylizacji.
BarcodeScanning.MAUI API do dokumentacji IronBarcode Mapping Reference
| BarcodeScanning.Native.Maui | IronBarcode |
|---|---|
CameraView kontrola XAML | Usuń — użyj Button + MediaPicker.CapturePhotoAsync() |
OnDetectionFinished zdarzenie | BarcodeReader.Read(imageBytes) wartość zwracana |
OnDetectionFinishedEventArg e | IEnumerable wynik z BarcodeReader.Read() |
e.BarcodeResults | Wartość zwrotna BarcodeReader.Read() |
e.BarcodeResults.FirstOrDefault() | results.FirstOrDefault() |
barcode.DisplayValue | result.Value |
barcode.BarcodeFormat | result.Format |
BarcodeFormats="All" | Wykrywane automatycznie — nie wymaga konfiguracji |
CameraEnabled="True" | await MediaPicker.CapturePhotoAsync() |
| Tylko iOS + Android | iOS, Android, Windows, macOS MAUI |
| Brak pliku wejściowego | BarcodeReader.Read(filePath) |
| Brak pliku PDF | BarcodeReader.Read("document.pdf") |
| Brak generacji | BarcodeWriter.CreateBarcode() / QRCodeWriter.CreateQrCode() |
| iOS UPC-A zwraca 13 cyfr | Zwraca prawidłowe 12 cyfr — nie jest wymagana normalizacja |
| PDF417 zawodny | Obsługiwane |
Typowe problemy związane z migracją i ich rozwiązania
Problem 1: Utrata funkcji podglądu na żywo
BarcodeScanning.MAUI: Kontrola CameraView osadzała podgląd kamery bezpośrednio w stronie MAUI. Użytkownicy mogli zobaczyć obraz z kamery i skierować ją na BarCode — wykrywanie odbywało się automatycznie, bez konieczności naciskania przycisku.
Rozwiązanie: MediaPicker.CapturePhotoAsync() pokazuje ekran kamery platformy zamiast tego. W przypadku większości procesów biznesowych jest to dopuszczalne. W aplikacjach konsumenckich, które wymagają ciągłego podglądu na żywo, ramki z kamery mogą być przekazywane bezpośrednio do 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 SubWymaga to podłączenia źródła klatek z kamery oddzielnie od IronBarcode. Zanim zdecydujesz się na tę opcję, zastanów się, czy podgląd na żywo jest naprawdę potrzebny, czy wystarczy interfejs użytkownika kamery systemowej.
Problem 2: Zmiany nazw właściwości i enumów w e.BarcodeResults
BarcodeScanning.MAUI: barcode.DisplayValue zwraca rozszyfrowany ciąg znaków; barcode.BarcodeFormat zwraca wartość wyliczania z biblioteki BarcodeScanning.
Rozwiązanie: Zamień DisplayValue na result.Value i barcode.BarcodeFormat na result.Format. Schemat iteracji jest taki sam:
// 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)
NextProblem 3: Marshaling wątków dla aktualizacji interfejsu użytkownika
BarcodeScanning.MAUI: OnDetectionFinished działa w tle, więc wszystkie aktualizacje interfejsu użytkownika wymagają MainThread.BeginInvokeOnMainThread().
Rozwiązanie: Z wzorcem MediaPicker + async, kontynuacja po await zwraca się w kontekście wywołania — zazwyczaj na głównym wątku. Opakowania MainThread.BeginInvokeOnMainThread() wokół wyświetlania wyników można zazwyczaj usunąć, upraszczając kod obsługi.
Problem 4: Uprawnienia kamery MAUI
BarcodeScanning.MAUI: Pakiet dodaje automatycznie uprawnienia do kamer do AndroidManifest.xml i Info.plist jako część konfiguracji.
Rozwiązanie: Przy użyciu IronBarcode z MediaPicker, standardowe uprawnienia do kamer MAUI muszą być obecne ręcznie. Są to te same uprawnienia, których potrzebuje każda aplikacja MAUI dla MediaPicker.CapturePhotoAsync() i zazwyczaj są już ustawione. Zweryfikuj, że android.permission.CAMERA jest zadeklarowane w AndroidManifest.xml i NSCameraUsageDescription jest ustawione w Info.plist przed testowaniem na urządzeniu.
Lista kontrolna migracji BarcodeScanning.MAUI
Zadania przed migracją
Przed wprowadzeniem jakichkolwiek zmian należy przeprowadzić następujące wyszukiwania, aby znaleźć wszystkie wystąpienia BarcodeScanning.Native.Maui:
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" .
Dokumentuj każde trafienie. Zauważ, które pliki zawierają użycie XAML CameraView (wymagają zmian w XAML) w porównaniu do tych, które zawierają tylko zmiany w kodzie. Zidentyfikuj wszelkie obejścia normalizacji UPC-A, które należy usunąć po migracji.
Zadania związane z aktualizacją kodu
- Usuń pakiet
BarcodeScanning.Native.MauiNuGet - Zainstaluj pakiet
IronBarcodeNuGet - Dodaj
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";wMauiProgram.cslubApp.xaml.cs - Zamień
using BarcodeScanning;nausing IronBarCode;we wszystkich plikach.cs - Usuń deklaracje przestrzeni nazw
xmlns:scanner="..."z wszystkich plików XAML - Zamień kontrolki
scanner:CameraVieww XAML naButtonuruchamiającyMediaPicker.CapturePhotoAsync() - Usuń połączenia zdarzeń
OnDetectionFinished="..."z XAML - Zamień obsługę zdarzeń
OnDetectionFinishedna obsługę przycisków kliknięciaasyncużywającBarcodeReader.Read() - Zamień
barcode.DisplayValuenaresult.Valuewszędzie - Zamień
barcode.BarcodeFormatnaresult.Formatwszędzie - Usuń wszystkie obejścia normalizacji
BarcodeFormats.Upca+Substring(1) - Dodaj
ExpectMultipleBarcodes = truedoBarcodeReaderOptions, gdzie wcześniej wykrywanie wielokrotnego kodu kreskowego polegało nae.BarcodeResultszwracającym wiele elementów - Usuń opakowania
MainThread.BeginInvokeOnMainThread()z kodu wyświetlania wyników, gdzie asynchroniczny wzorzec czyni je zbędnymi - Zweryfikuj uprawnienia kamer
AndroidManifest.xmliInfo.plistsą obecne
Testy po migracji
- Sprawdź, czy skanowanie BarCode w systemie iOS działa, a wartości UPC-A są zwracane jako 12-cyfrowe ciągi znaków bez zer wiodących
- Sprawdź, czy skanowanie BarCode'ów w systemie Android generuje prawidłowe wartości dla wszystkich formatów używanych w aplikacji
- Sprawdź, czy skanowanie BarCode w Windows MAUI działa, jeśli Windows jest celem kompilacji
- Przetestuj skanowanie kodów PDF417 na prawdziwych etykietach wysyłkowych, prawach jazdy lub kartach pokładowych, jeśli są one używane
- Przetestuj scenariusze z wieloma kodami kreskowymi z
ExpectMultipleBarcodes = truei potwierdź, że wszystkie kody kreskowe na obrazie są zwracane - Zweryfikuj, czy skanowanie wybieracza plików (
BarcodeReader.Read(filePath)) działa na wszystkich celach MAUI - Sprawdź odczyt BarCode z plików PDF, jeśli była to nowa funkcja dodana wraz z migracją
- Potwierdź, że serwerowa
BarcodeReader.Read()produkuje poprawne wyniki, jeśli dodano komponent backendowy - Uruchom wszystkie istniejące testy automatyczne i porównaj wyniki wartości BarCode z wartościami bazowymi sprzed migracji
Kluczowe korzyści wynikające z migracji do IronBarcode
**Pełna obsługa Windows MAUI:**IronBarcode działa na wszystkich czterech platformach MAUI — iOS, Android, Windows i macOS — przy użyciu tego samego kodu i tego samego pakietu. Żadne specyficzne dla platformy wdrożenie kodu kreskowego nie jest potrzebne dla Windows, i żadne bloki #if WINDOWS nie są wymagane w kodzie aplikacji.
Każde Źródło Wejściowe: BarcodeReader.Read() akceptuje ścieżki plików, tablice bajtów, strumienie i dokumenty PDF. Każdy scenariusz związany z kodami kreskowymi — przechwytywanie przez kamerę, przesyłanie plików, obraz z galerii, przetwarzanie plików PDF po stronie serwera — wykorzystuje tę samą metodę statyczną z tym samym typem wyniku.
**Prawidłowe wartości UPC-A:**IronBarcode zwraca prawidłową 12-cyfrową wartość UPC-A na iOS bez żadnego kodu normalizującego w aplikacji. Historyczne dane UPC-A zapisane z zerem wiodącym z powodu działania BarcodeScanning.Native.Maui nie wpływają na dokładność wartości odczytanych po migracji.
Niezawodny PDF417: PDF417 jest w pełni obsługiwany i odczytywany w sposób niezawodny. Etykiety wysyłkowe, prawa jazdy i karty pokładowe są skanowane bez ograniczenia "większość skanów nigdy nie ma miejsca", opisanego w zgłoszeniach na GitHubie dotyczących BarcodeScanning.Native.Maui.
Generowanie Kodów Kreskowych: BarcodeWriter.CreateBarcode() i QRCodeWriter.CreateQrCode() generują Code128, QR, DataMatrix i inne formaty jako pliki PNG lub tablice bajtów. Generowanie i odczyt są dostępne w tym samym pakiecie bez dodatkowych zależności.
Wdrożenie Serwerowe: To samo wywołanie BarcodeReader.Read() działa w ASP.NET, Azure Functions, kontenerach Docker i AWS Lambda. Logika kodów kreskowych na urządzeniach mobilnych i serwerach może korzystać z tego samego interfejsu API, obsługiwać ten sam format i generować ten sam typ wyników bez konieczności utrzymywania dwóch oddzielnych implementacji kodów kreskowych.

Curtis Chau posiada tytuł licencjata z informatyki (Uniwersytet Carleton) i specjalizuje się w front-endowym rozwoju, z ekspertką w Node.js, TypeScript, JavaScript i React. Pasjonuje się tworzeniem intuicyjnych i estetycznie przyjemnych interfejsów użytkownika, Curtis cieszy się pracą z nowoczesnymi frameworkami i tworzeniem dobrze zorganizowanych, atrakcyjnych wizualnie podręczników.