푸터 콘텐츠로 바로가기
동영상

C#에서 오류 수정을 설정하는 방법 | IronQR

ZXing.Net.MAUI에서 IronBarcode로의 마이그레이션

이 가이드는 .NET MAUI 개발자를 위해 ZXing .NET.MAUI에서IronBarcode로의 완벽한 마이그레이션 경로를 제공합니다. 이 문서에는 팀이 마이그레이션을 수행하는 이유, 의사 결정을 위한 기능 비교, 패키지 교체 및 프로젝트 파일 업데이트를 위한 단계, 주요 사용 패턴별 마이그레이션 전후 코드 예제, API 변환 참조, 전환 중에 발생하는 문제에 대한 문제 해결 섹션, 진행 상황 추적을 위한 마이그레이션 체크리스트, 그리고 마이그레이션을 통해 얻을 수 있는 결과 요약이 포함되어 있습니다.

ZXing .NET.MAUI에서 마이그레이션해야 하는 이유는 무엇일까요?

ZXing .NET.MAUI에서 다른 기술로 마이그레이션하기로 결정하는 것은 일반적으로 하나 이상의 구체적인 프로젝트 상황에 의해 촉발됩니다. 이는 스타일적인 선호가 아니라, 라이브러리의 아키텍처 또는 유지 관리 상태 때문에 요구 사항을 충족할 수 없는 경우입니다.

Windows MAUI는 지원되지 않습니다. ZXing .NET.MAUI는 Windows 카메라 구현을 제공하지 않으며, 향후 개발 계획도 공개되어 있지 않습니다. 이 라이브러리는 iOS 및 Android 플랫폼 카메라 API를 기반으로 구축되었습니다. 모바일 우선 개발을 시작하는 팀에서 흔히 발생하는 패턴처럼, MAUI 프로젝트가 초기 빌드 후 Windows 타겟을 추가하는 경우 ZXing .NET.MAUI는 해당 타겟을 전혀 지원할 수 없습니다. 임시 방편도, 대체 기능도, 해결 방법도 없습니다.

iPhone 15 Pro 자동 초점 문제: Redth/ZXing.Net.Maui 의 GitHub 이슈 트래커는 iPhone 15 Pro 및 Pro Max 장치(iPhone16,1iPhone16,2)가 CameraBarcodeReaderView 사용 시 바코드 감지를 위한 신뢰할 수 있는 초점을 달성하지 못한다는 것을 문서화합니다. 바코드는 카메라 프레임에 나타나지만, 자동 초점 시스템이 디코더가 결과를 추출할 수 있을 만큼 선명하게 초점을 맞추지 못합니다. 유일하게 문서화된 완화 방법은 사용자가 기기와 바코드 사이의 거리를 수동으로 조정하도록 안내하는 것인데, 이는 눈에 띄는 사용자 경험(UX) 안내와 사용자의 인내심을 필요로 하며, 주요 워크플로에서 허용 가능한 결과물이 아닙니다.

카메라 리소스 누수: CameraBarcodeReaderViewIDisposable를 구현하지 않습니다. 사용자가 스캔 페이지에서 다른 페이지로 이동할 때 카메라 리소스는 표준 해제 패턴을 통해 해제되지 않습니다. 문서화된 해결 방법은 IsDetecting = falseOnDisappearing()에 설정하는 것이며, 이는 영향을 줄일 수 있지만 카메라를 공식적으로 해제하지는 않습니다. 스캔 페이지를 자주 오가는 애플리케이션은 리소스 사용량이 누적되어 메모리 증가, 배터리 소모, 스캔 페이지로 돌아올 때 카메라 초기화 오류 등의 문제가 발생할 수 있습니다.

포맷 지정 오류 발생 시 오류 메시지 없음: ZXing .NET.MAUI는 스캔을 시작하기 전에 스캔할 모든 바코드 포맷을 선언해야 한다는 ZXing.Net의 요구 사항을 따릅니다. BarcodeReaderOptions.Formats에서 누락된 형식은 카메라 프레임에 명확하게 보일 때도 조용히 무시됩니다. 개발자가 예상하지 못한 바코드 형식에 기기를 가져다 대는 사용자는 오류를 표시하지 않습니다. 애플리케이션이 아무것도 감지하지 못하는 것입니다. 바코드 형식이 외부 공급업체, 고객 또는 제3자 시스템에 의해 제어되는 환경에서는 이러한 사소한 오류가 지속적인 지원 문제로 이어집니다.

발매 전-1.0 안정성: ZXing.Net.MAUI는 v0.7.4로 게시되었으며 NuGet에서는 안정적인 릴리스이지만, 여전히 시맨틱 버전 관리에 따라 1.0 이전입니다. 마이너 버전 API 변경은 1.0 이전에 가능하며 버그 수정 빈도는 커뮤니티 유지 관리자의 가용성에 따라 다르며, 상업적 지원 SLA는 없습니다. 의존성 감사나 소프트웨어 구성 분석 대상인 Enterprise 애플리케이션의 경우, 상업적 지원이 없는 커뮤니티 1.0 이전 라이브러리는 승인 과정을 통과하지 못할 수 있습니다.

근본적인 문제

구조적 문제는 CameraBarcodeReaderView가 개발자를 수동 라이프사이클 관리 및 고정된 형식 목록과 함께 카메라 중심의 이벤트 루프로 고정시킨다는 것입니다. iOS와 Android에서 알려진 바코드 형식과의 기본적인 카메라 스캐닝을 넘어서려면 아키텍처가 그 한계에 도달합니다.

// ZXing.Net.MAUI: event loop, format list, lifecycle boilerplate on every scan page
public partial class ScannerPage : ContentPage
{
    public BarcodeReaderOptions ReaderOptions { get; }

    public ScannerPage()
    {
        InitializeComponent();
        ReaderOptions = new BarcodeReaderOptions
        {
            Formats = BarcodeFormats.QRCode |
                      BarcodeFormats.Code128 |
                      BarcodeFormats.Ean13 |
                      BarcodeFormats.UpcA,
            TryHarder = true,
            AutoRotate = true
        };
        BindingContext = this;
    }

    private void OnBarcodesDetected(object sender, BarcodeDetectionEventArgs e)
    {
        MainThread.BeginInvokeOnMainThread(() =>
        {
            foreach (var barcode in e.Results)
                ResultLabel.Text = $"{barcode.Format}: {barcode.Value}";
        });
        CameraView.IsDetecting = false;
    }

    protected override void OnDisappearing()
    {
        base.OnDisappearing();
        CameraView.IsDetecting = false;  // Required — no Dispose() available
    }

    protected override void OnAppearing()
    {
        base.OnAppearing();
        CameraView.IsDetecting = true;
    }
}
// ZXing.Net.MAUI: event loop, format list, lifecycle boilerplate on every scan page
public partial class ScannerPage : ContentPage
{
    public BarcodeReaderOptions ReaderOptions { get; }

    public ScannerPage()
    {
        InitializeComponent();
        ReaderOptions = new BarcodeReaderOptions
        {
            Formats = BarcodeFormats.QRCode |
                      BarcodeFormats.Code128 |
                      BarcodeFormats.Ean13 |
                      BarcodeFormats.UpcA,
            TryHarder = true,
            AutoRotate = true
        };
        BindingContext = this;
    }

    private void OnBarcodesDetected(object sender, BarcodeDetectionEventArgs e)
    {
        MainThread.BeginInvokeOnMainThread(() =>
        {
            foreach (var barcode in e.Results)
                ResultLabel.Text = $"{barcode.Format}: {barcode.Value}";
        });
        CameraView.IsDetecting = false;
    }

    protected override void OnDisappearing()
    {
        base.OnDisappearing();
        CameraView.IsDetecting = false;  // Required — no Dispose() available
    }

    protected override void OnAppearing()
    {
        base.OnAppearing();
        CameraView.IsDetecting = true;
    }
}
Imports ZXing.Net.MAUI

Public Partial Class ScannerPage
    Inherits ContentPage

    Public ReadOnly Property ReaderOptions As BarcodeReaderOptions

    Public Sub New()
        InitializeComponent()
        ReaderOptions = New BarcodeReaderOptions With {
            .Formats = BarcodeFormats.QRCode Or
                       BarcodeFormats.Code128 Or
                       BarcodeFormats.Ean13 Or
                       BarcodeFormats.UpcA,
            .TryHarder = True,
            .AutoRotate = True
        }
        BindingContext = Me
    End Sub

    Private Sub OnBarcodesDetected(sender As Object, e As BarcodeDetectionEventArgs)
        MainThread.BeginInvokeOnMainThread(Sub()
                                               For Each barcode In e.Results
                                                   ResultLabel.Text = $"{barcode.Format}: {barcode.Value}"
                                               Next
                                           End Sub)
        CameraView.IsDetecting = False
    End Sub

    Protected Overrides Sub OnDisappearing()
        MyBase.OnDisappearing()
        CameraView.IsDetecting = False ' Required — no Dispose() available
    End Sub

    Protected Overrides Sub OnAppearing()
        MyBase.OnAppearing()
        CameraView.IsDetecting = True
    End Sub
End Class
$vbLabelText   $csharpLabel

IronBarcode 이벤트 루프를 버튼 탭 시 단일 비동기 호출로 대체하고, 형식 구성을 완전히 제거하며, 페이지에서 수명 주기 관리를 없앱니다.

// NuGet: dotnet add package IronBarcode
// IronBarcode: stateless, all platforms, auto-detection, no lifecycle boilerplate
using IronBarCode;

public partial class ScannerPage : ContentPage
{
    public ScannerPage() => InitializeComponent();

    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());
        ResultLabel.Text = results.FirstOrDefault()?.Value ?? "No barcode found";
    }
    // 아니요 OnAppearing / OnDisappearing needed
}
// NuGet: dotnet add package IronBarcode
// IronBarcode: stateless, all platforms, auto-detection, no lifecycle boilerplate
using IronBarCode;

public partial class ScannerPage : ContentPage
{
    public ScannerPage() => InitializeComponent();

    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());
        ResultLabel.Text = results.FirstOrDefault()?.Value ?? "No barcode found";
    }
    // 아니요 OnAppearing / OnDisappearing needed
}
Imports IronBarCode

Public Partial Class ScannerPage
    Inherits ContentPage

    Public Sub New()
        InitializeComponent()
    End Sub

    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())
                ResultLabel.Text = If(results.FirstOrDefault()?.Value, "No barcode found")
            End Using
        End Using
    End Sub
    ' 아니요 OnAppearing / OnDisappearing needed
End Class
$vbLabelText   $csharpLabel

IronBarcode와 ZXing .NET.MAUI: 기능 비교

기능 ZXing.Net.MAUI IronBarcode
릴리스 상태 안정적, pre-1.0 (v0.7.4) 안정적인 상용 릴리스
iOS MAUI 네 (아이폰 15 Pro 초점 문제 발생)
안드로이드 MAUI 예 (카메라 1.5.0 빌드 문제)
윈도우 MAUI 지원되지 않음
macOS MAUI 지원되지 않음
서버 측 / ASP.NET Core 아니요
라이브 카메라 뷰파인더 아니요 (MediaPicker 시스템 UI)
형식 지정이 필요합니다 아니요 (자동 감지, 50개 이상의 형식 지원)
카메라 수명주기 관리 수동(IsDetecting) 적용 안 됨
Dispose() 구현 아니요 해당 없음 — 상태 없음
아이폰 15 Pro 자동 초점 고장남 (기록됨) 적용 안 됨
PDF 바코드 추출 아니요
파일 경로 입력 아니요 (카메라만 해당)
손상된 바코드 복구 더 열심히 노력하세요 예 (머신러닝 기반)
바코드 생성 예 (.NET 통해)
상업적 지원 None
라이선스 MIT (무료) 상업적

빠른 시작

1단계: ZXing .NET.Maui.Controls를 제거하고 MauiProgram.cs를 정리합니다.

ZXing .NET.MAUI NuGet 패키지를 제거하세요.

dotnet remove package ZXing.Net.Maui.Controls
dotnet remove package ZXing.Net.Maui.Controls
SHELL

ZXing.Net.MAUI는 MauiProgram.cs에서 한 번의 등록 호출을 필요로 합니다. 이 줄이 있다면 삭제하세요:

// 제거하다 this line from MauiProgram.cs
builder.UseBarcodeReader();
// 제거하다 this line from MauiProgram.cs
builder.UseBarcodeReader();
$vbLabelText   $csharpLabel

이 호출을 지원하는 using ZXing.Net.Maui; 가져오기는 MauiProgram.cs에서 제거할 수도 있습니다.

2단계:IronBarcode설치

dotnet add package IronBarcode
dotnet add package IronBarcode
SHELL

.NET MAUI 바코드 스캐너 튜토리얼은 iOS를 위한 Info.plist 카메라 권한 항목과 Android를 위한 AndroidManifest.xml 권한 선언을 포함한 전체 프로젝트 구성을 다룹니다.

3단계: 네임스페이스 업데이트 및 라이선스 초기화

모든 파일에서 ZXing .NET.MAUI 네임스페이스 가져오기를 제거합니다.

// 제거하다 these from every .cs file that imported them
using ZXing.Net.Maui;
using ZXing.Net.Maui.Controls;
// 제거하다 these from every .cs file that imported them
using ZXing.Net.Maui;
using ZXing.Net.Maui.Controls;
Imports ZXing.Net.Maui
Imports ZXing.Net.Maui.Controls
$vbLabelText   $csharpLabel

IronBarcode 네임스페이스를 추가하고 애플리케이션 시작 시 라이선스 키를 초기화하세요. 적절한 위치는 바코드 작업이 수행되기 전에 MauiProgram.cs 또는 App.xaml.cs 입니다:

using IronBarCode;

// In MauiProgram.cs CreateMauiApp() or App.xaml.cs constructor
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
using IronBarCode;

// In MauiProgram.cs CreateMauiApp() or App.xaml.cs constructor
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
Imports IronBarCode

' In MauiProgram.vb CreateMauiApp() or App.xaml.vb constructor
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY"
$vbLabelText   $csharpLabel

코드 마이그레이션 예제

XAML 카메라 컨트롤 및 코드 비하인드 교체

CameraBarcodeReaderView XAML 컨트롤 및 이를 지원하는 코드비하인드는 주요 마이그레이션 대상입니다. 이번 업데이트에서는 페이지 레이아웃에서 카메라 뷰를 제거하고 이벤트 기반 스캔 방식을 버튼 트리거 방식의 비동기 캡처로 대체했습니다.

ZXing .NET.MAUI 접근 방식:

XAML:

<ContentPage xmlns:zxing="clr-namespace:ZXing.Net.Maui.Controls;assembly=ZXing.Net.MAUI.Controls">
    <StackLayout>
        <zxing:CameraBarcodeReaderView
            x:Name="CameraView"
            Options="{Binding ReaderOptions}"
            BarcodesDetected="OnBarcodesDetected"
            VerticalOptions="FillAndExpand" />
        <Label x:Name="ResultLabel" Text="Scanning..." />
    </StackLayout>
</ContentPage>
<ContentPage xmlns:zxing="clr-namespace:ZXing.Net.Maui.Controls;assembly=ZXing.Net.MAUI.Controls">
    <StackLayout>
        <zxing:CameraBarcodeReaderView
            x:Name="CameraView"
            Options="{Binding ReaderOptions}"
            BarcodesDetected="OnBarcodesDetected"
            VerticalOptions="FillAndExpand" />
        <Label x:Name="ResultLabel" Text="Scanning..." />
    </StackLayout>
</ContentPage>
XML

코드 비하인드:

using ZXing.Net.Maui;
using ZXing.Net.Maui.Controls;

public partial class ScannerPage : ContentPage
{
    public BarcodeReaderOptions ReaderOptions { get; }

    public ScannerPage()
    {
        InitializeComponent();
        ReaderOptions = new BarcodeReaderOptions
        {
            Formats = BarcodeFormats.QRCode | BarcodeFormats.Code128 | BarcodeFormats.Ean13,
            TryHarder = true,
            AutoRotate = true
        };
        BindingContext = this;
    }

    private void OnBarcodesDetected(object sender, BarcodeDetectionEventArgs e)
    {
        MainThread.BeginInvokeOnMainThread(() =>
        {
            foreach (var barcode in e.Results)
                ResultLabel.Text = $"{barcode.Format}: {barcode.Value}";
        });
        CameraView.IsDetecting = false;
    }

    protected override void OnDisappearing()
    {
        base.OnDisappearing();
        CameraView.IsDetecting = false;
    }

    protected override void OnAppearing()
    {
        base.OnAppearing();
        CameraView.IsDetecting = true;
    }
}
using ZXing.Net.Maui;
using ZXing.Net.Maui.Controls;

public partial class ScannerPage : ContentPage
{
    public BarcodeReaderOptions ReaderOptions { get; }

    public ScannerPage()
    {
        InitializeComponent();
        ReaderOptions = new BarcodeReaderOptions
        {
            Formats = BarcodeFormats.QRCode | BarcodeFormats.Code128 | BarcodeFormats.Ean13,
            TryHarder = true,
            AutoRotate = true
        };
        BindingContext = this;
    }

    private void OnBarcodesDetected(object sender, BarcodeDetectionEventArgs e)
    {
        MainThread.BeginInvokeOnMainThread(() =>
        {
            foreach (var barcode in e.Results)
                ResultLabel.Text = $"{barcode.Format}: {barcode.Value}";
        });
        CameraView.IsDetecting = false;
    }

    protected override void OnDisappearing()
    {
        base.OnDisappearing();
        CameraView.IsDetecting = false;
    }

    protected override void OnAppearing()
    {
        base.OnAppearing();
        CameraView.IsDetecting = true;
    }
}
Imports ZXing.Net.Maui
Imports ZXing.Net.Maui.Controls

Public Partial Class ScannerPage
    Inherits ContentPage

    Public ReadOnly Property ReaderOptions As BarcodeReaderOptions

    Public Sub New()
        InitializeComponent()
        ReaderOptions = New BarcodeReaderOptions With {
            .Formats = BarcodeFormats.QRCode Or BarcodeFormats.Code128 Or BarcodeFormats.Ean13,
            .TryHarder = True,
            .AutoRotate = True
        }
        BindingContext = Me
    End Sub

    Private Sub OnBarcodesDetected(sender As Object, e As BarcodeDetectionEventArgs)
        MainThread.BeginInvokeOnMainThread(Sub()
                                               For Each barcode In e.Results
                                                   ResultLabel.Text = $"{barcode.Format}: {barcode.Value}"
                                               Next
                                           End Sub)
        CameraView.IsDetecting = False
    End Sub

    Protected Overrides Sub OnDisappearing()
        MyBase.OnDisappearing()
        CameraView.IsDetecting = False
    End Sub

    Protected Overrides Sub OnAppearing()
        MyBase.OnAppearing()
        CameraView.IsDetecting = True
    End Sub
End Class
$vbLabelText   $csharpLabel

IronBarcode 접근 방식:

XAML:

<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>
<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>
XML

코드 비하인드:

// NuGet: dotnet add package IronBarcode
using IronBarCode;

public partial class ScannerPage : ContentPage
{
    public ScannerPage() => InitializeComponent();

    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 != null
            ? $"{first.Format}: {first.Value}"
            : "No barcode found";
    }

    // 아니요 OnAppearing or OnDisappearing required — no camera state exists between scans
}
// NuGet: dotnet add package IronBarcode
using IronBarCode;

public partial class ScannerPage : ContentPage
{
    public ScannerPage() => InitializeComponent();

    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 != null
            ? $"{first.Format}: {first.Value}"
            : "No barcode found";
    }

    // 아니요 OnAppearing or OnDisappearing required — no camera state exists between scans
}
Imports IronBarCode

Public Partial Class ScannerPage
    Inherits ContentPage

    Public Sub New()
        InitializeComponent()
    End Sub

    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 = New MemoryStream()
                Await stream.CopyToAsync(ms)

                Dim results = BarcodeReader.Read(ms.ToArray())
                Dim first = results.FirstOrDefault()
                ResultLabel.Text = If(first IsNot Nothing, $"{first.Format}: {first.Value}", "No barcode found")
            End Using
        End Using
    End Sub

    ' 아니요 OnAppearing or OnDisappearing required — no camera state exists between scans
End Class
$vbLabelText   $csharpLabel

zxing: XAML 네임스페이스, BarcodeReaderOptions 형식 목록, MainThread.BeginInvokeOnMainThread() 래퍼 및 두 라이프사이클 재정의는 완전히 제거됩니다. async 메서드의 지속은 호출한 컨텍스트에서 실행됩니다 — UI 이벤트 핸들러의 메인 스레드이므로 명시적으로 스레드 마샬링이 필요하지 않습니다.

형식 지정 제거

여러 페이지 또는 코드베이스의 스캔 시나리오 전반에 흩어진 모든 BarcodeReaderOptions 구성 블록은 삭제됩니다.IronBarcode사전 설정 없이 50개 이상의 지원되는 모든 형식에 대해 자동 형식 감지를 수행합니다.

ZXing .NET.MAUI 접근 방식:

// ZXing.Net.MAUI: every anticipated format must be listed explicitly
// Formats not listed here will silently fail to detect
var readerOptions = new BarcodeReaderOptions
{
    Formats = BarcodeFormats.QRCode |
              BarcodeFormats.DataMatrix |
              BarcodeFormats.Aztec |
              BarcodeFormats.Pdf417 |
              BarcodeFormats.Code128 |
              BarcodeFormats.Code39 |
              BarcodeFormats.Ean13 |
              BarcodeFormats.UpcA |
              BarcodeFormats.Codabar,
    TryHarder = true
};
// ZXing.Net.MAUI: every anticipated format must be listed explicitly
// Formats not listed here will silently fail to detect
var readerOptions = new BarcodeReaderOptions
{
    Formats = BarcodeFormats.QRCode |
              BarcodeFormats.DataMatrix |
              BarcodeFormats.Aztec |
              BarcodeFormats.Pdf417 |
              BarcodeFormats.Code128 |
              BarcodeFormats.Code39 |
              BarcodeFormats.Ean13 |
              BarcodeFormats.UpcA |
              BarcodeFormats.Codabar,
    TryHarder = true
};
' ZXing.Net.MAUI: every anticipated format must be listed explicitly
' Formats not listed here will silently fail to detect
Dim readerOptions As New BarcodeReaderOptions With {
    .Formats = BarcodeFormats.QRCode Or
               BarcodeFormats.DataMatrix Or
               BarcodeFormats.Aztec Or
               BarcodeFormats.Pdf417 Or
               BarcodeFormats.Code128 Or
               BarcodeFormats.Code39 Or
               BarcodeFormats.Ean13 Or
               BarcodeFormats.UpcA Or
               BarcodeFormats.Codabar,
    .TryHarder = True
}
$vbLabelText   $csharpLabel

IronBarcode 접근 방식:

// IronBarcode: no format configuration needed
// All formats are detected automatically on every read call
var results = BarcodeReader.Read(imageBytes);

// Optional: restrict to specific formats for performance tuning (not required for correctness)
var options = new BarcodeReaderOptions
{
    ExpectBarcodeTypes = BarcodeEncoding.QRCode | BarcodeEncoding.Code128
};
var tunedResults = BarcodeReader.Read(imageBytes, options);
// IronBarcode: no format configuration needed
// All formats are detected automatically on every read call
var results = BarcodeReader.Read(imageBytes);

// Optional: restrict to specific formats for performance tuning (not required for correctness)
var options = new BarcodeReaderOptions
{
    ExpectBarcodeTypes = BarcodeEncoding.QRCode | BarcodeEncoding.Code128
};
var tunedResults = BarcodeReader.Read(imageBytes, options);
Imports IronBarcode

' IronBarcode: no format configuration needed
' All formats are detected automatically on every read call
Dim results = BarcodeReader.Read(imageBytes)

' Optional: restrict to specific formats for performance tuning (not required for correctness)
Dim options As New BarcodeReaderOptions With {
    .ExpectBarcodeTypes = BarcodeEncoding.QRCode Or BarcodeEncoding.Code128
}
Dim tunedResults = BarcodeReader.Read(imageBytes, options)
$vbLabelText   $csharpLabel

IronBarcode 에서는 성능에 민감한 시나리오를 위해 형식 힌트를 제공하지만, 이는 선택 사항입니다. 옵션 객체에 나열되지 않은 형식의 바코드라도 감지되어 반환됩니다.

IsDetecting 라이프사이클 관리 제거

OnAppearingOnDisappearing 재정의는 CameraView.IsDetecting를 전환하기 위해 존재하는 모든 것은 제거됩니다. 이 메서드 재정의가 다른 페이지 라이프사이클 논리를 포함하고 있는 경우, 해당 논리를 보존하고 IsDetecting 라인만 제거하세요.

ZXing .NET.MAUI 접근 방식:

// Required boilerplate on every page — omitting this causes camera resource leaks
protected override void OnDisappearing()
{
    base.OnDisappearing();
    if (CameraView != null)
        CameraView.IsDetecting = false;
}

protected override void OnAppearing()
{
    base.OnAppearing();
    if (CameraView != null)
        CameraView.IsDetecting = true;
}
// Required boilerplate on every page — omitting this causes camera resource leaks
protected override void OnDisappearing()
{
    base.OnDisappearing();
    if (CameraView != null)
        CameraView.IsDetecting = false;
}

protected override void OnAppearing()
{
    base.OnAppearing();
    if (CameraView != null)
        CameraView.IsDetecting = true;
}
' Required boilerplate on every page — omitting this causes camera resource leaks
Protected Overrides Sub OnDisappearing()
    MyBase.OnDisappearing()
    If CameraView IsNot Nothing Then
        CameraView.IsDetecting = False
    End If
End Sub

Protected Overrides Sub OnAppearing()
    MyBase.OnAppearing()
    If CameraView IsNot Nothing Then
        CameraView.IsDetecting = True
    End If
End Sub
$vbLabelText   $csharpLabel

IronBarcode 접근 방식:

// Delete both methods if they contain only IsDetecting management.
// If they contain other logic, remove only the IsDetecting lines and keep the rest.
//IronBarcode is stateless — there is no camera view running between button taps.
// Delete both methods if they contain only IsDetecting management.
// If they contain other logic, remove only the IsDetecting lines and keep the rest.
//IronBarcode is stateless — there is no camera view running between button taps.
' Delete both methods if they contain only IsDetecting management.
' If they contain other logic, remove only the IsDetecting lines and keep the rest.
' IronBarcode is stateless — there is no camera view running between button taps.
$vbLabelText   $csharpLabel

Windows MAUI: 동일한 코드, 조건부 컴파일 없음

ZXing .NET.MAUI를 사용할 때, 프로젝트에 Windows 타겟을 추가하면 컴파일이 실패하거나 Windows 구현이 작성되지 않았기 때문에 플랫폼별 스텁이 필요했습니다.IronBarcode사용하면 iOS 및 Android에서 실행되는 동일한 코드를 수정 없이 Windows에서 컴파일하고 실행할 수 있습니다.

ZXing .NET.MAUI 접근 방식:

// Windows MAUI: either fails to compile or requires a platform-specific stub
// There is no documented path to Windows support
#if ANDROID || IOS
    // ZXing.Net.MAUI scanning — Windows has no implementation
#endif
// Windows MAUI: either fails to compile or requires a platform-specific stub
// There is no documented path to Windows support
#if ANDROID || IOS
    // ZXing.Net.MAUI scanning — Windows has no implementation
#endif
$vbLabelText   $csharpLabel

IronBarcode 접근 방식:

// NuGet: dotnet add package IronBarcode
// 아니요 platform conditionals — same code runs on iOS, Android, Windows, and macOS
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());
    ResultLabel.Text = results.FirstOrDefault()?.Value ?? "No barcode found";
}
// NuGet: dotnet add package IronBarcode
// 아니요 platform conditionals — same code runs on iOS, Android, Windows, and macOS
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());
    ResultLabel.Text = results.FirstOrDefault()?.Value ?? "No barcode found";
}
Imports System
Imports System.IO
Imports System.Linq
Imports IronBarCode

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())
            ResultLabel.Text = If(results.FirstOrDefault()?.Value, "No barcode found")
        End Using
    End Using
End Sub
$vbLabelText   $csharpLabel

Windows에서 MediaPicker.CapturePhotoAsync()는 Windows 파일 선택기에 매핑되어 사용자가 이미지 파일을 선택할 수 있도록 합니다 — 데스크탑 환경에 적합한 동작입니다. MAUI 데스크톱 바코드 가이드는 Windows 및 macOS용 MAUI 구성에 대해 자세히 설명합니다.

PDF 바코드 읽기 (새로운 기능)

ZXing .NET.MAUI는 PDF 문서에서 바코드를 읽는 API를 제공하지 않습니다. 마이그레이션을 통해 새롭게 요구되는 사항이라면 다음 패턴이 적용됩니다.

ZXing .NET.MAUI 접근 방식:

// ZXing.Net.MAUI: no API for PDF or file-based barcode reading
// Cannot fulfill this requirement — a separate library is required
// ZXing.Net.MAUI: no API for PDF or file-based barcode reading
// Cannot fulfill this requirement — a separate library is required
' ZXing.Net.MAUI: no API for PDF or file-based barcode reading
' Cannot fulfill this requirement — a separate library is required
$vbLabelText   $csharpLabel

IronBarcode 접근 방식:

// NuGet: dotnet add package IronBarcode
using IronBarCode;

// Read all barcodes from all pages of a PDF
var pdfResults = BarcodeReader.Read("invoice.pdf");
foreach (var barcode in pdfResults)
    Console.WriteLine($"Page {barcode.PageNumber}: {barcode.Format} — {barcode.Value}");

// Read from a user-selected file using MAUI 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 fileResults = BarcodeReader.Read(file.FullPath);
    foreach (var result in fileResults)
        ResultLabel.Text += $"\n{result.Format}: {result.Value}";
}
// NuGet: dotnet add package IronBarcode
using IronBarCode;

// Read all barcodes from all pages of a PDF
var pdfResults = BarcodeReader.Read("invoice.pdf");
foreach (var barcode in pdfResults)
    Console.WriteLine($"Page {barcode.PageNumber}: {barcode.Format} — {barcode.Value}");

// Read from a user-selected file using MAUI 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 fileResults = BarcodeReader.Read(file.FullPath);
    foreach (var result in fileResults)
        ResultLabel.Text += $"\n{result.Format}: {result.Value}";
}
Imports IronBarCode

' Read all barcodes from all pages of a PDF
Dim pdfResults = BarcodeReader.Read("invoice.pdf")
For Each barcode In pdfResults
    Console.WriteLine($"Page {barcode.PageNumber}: {barcode.Format} — {barcode.Value}")
Next

' Read from a user-selected file using MAUI 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 fileResults = BarcodeReader.Read(file.FullPath)
    For Each result In fileResults
        ResultLabel.Text &= $"\n{result.Format}: {result.Value}"
    Next
End Sub
$vbLabelText   $csharpLabel

PDF 바코드 읽기 워크플로 전체(다중 페이지 문서, 페이지 번호 메타데이터 및 혼합 형식 문서 포함)는 PDF에서 바코드 읽기 가이드 에 설명되어 있습니다.

ZXing .NET.MAUI API와IronBarcode매핑 참조

ZXing.Net.MAUI IronBarcode 노트
builder.UseBarcodeReader() 필요하지 않음 MauiProgram.cs에서 제거
using ZXing.Net.Maui; using IronBarCode; 네임스페이스 교체
using ZXing.Net.Maui.Controls; 필요하지 않음 제거하다
xmlns:zxing="clr-namespace:ZXing.Net.Maui.Controls;..." 필요하지 않음 XAML에서 제거
<zxing:CameraBarcodeReaderView> <Button> + MediaPicker.CapturePhotoAsync() 건축물 교체
Options="{Binding ReaderOptions}" 필요하지 않음 바인딩 제거
BarcodesDetected="OnBarcodesDetected" BarcodeReader.Read() 반환값 이벤트 → 비동기 반환
새 바코드 리더 옵션 { 형식 = BarcodeFormats.X \| ... } 필요하지 않음 자동 감지 기능이 형식 목록을 대체합니다.
BarcodeDetectionEventArgs e IEnumerable<BarcodeResult> 결과 전달 방식의 차이
e.Results BarcodeReader.Read() 반환값
barcode.Value result.Value 동일한 속성 이름
barcode.Format result.Format 동일한 속성 이름
BarcodeFormats.QRCode BarcodeEncoding.QRCode 열거형 이름 변경
BarcodeFormats.Code128 BarcodeEncoding.Code128 열거형 이름 변경
BarcodeFormats.Ean13 BarcodeEncoding.EAN13 열거형 이름 변경
BarcodeFormats.UpcA BarcodeEncoding.UPCA 열거형 이름 변경
CameraView.IsDetecting = false 필요하지 않음 OnDisappearing에서 제거
CameraView.IsDetecting = true 필요하지 않음 OnAppearing에서 제거
파일 입력 API 없음 BarcodeReader.Read("path/to/image.png") 새로운 기능
PDF 입력 API 없음 BarcodeReader.Read("document.pdf") 새로운 기능
iOS 및 Android 전용 iOS, 안드로이드, 윈도우, macOS, 서버 플랫폼 확장

일반적인 마이그레이션 문제와 해결책

문제 1: 라이브 뷰파인더에 상응하는 기능이 없음

ZXing.Net.MAUI: CameraBarcodeReaderView는 페이지 레이아웃에 연속적인 카메라 피드를 표시하여 사용자에게 스캔 피드백이 오버레이된 라이브 미리보기를 보여줍니다.

해결책:IronBarcode실시간 뷰파인더 제어 기능을 제공하지 않습니다. 대체 패턴은 MediaPicker.CapturePhotoAsync()을 사용하여 플랫폼 시스템 카메라 UI를 엽니다. 시스템 카메라는 자체적인 실시간 미리보기 및 초점 표시기를 제공합니다. 사용자가 이미지를 캡처하고 확인한 후 결과가 BarcodeReader.Read()로 전달됩니다. 만약 시스템 카메라 UI로 대체할 수 없는 지속적인 앱 내 뷰파인더가 필요한 UX 요소라면, 카메라 통합 레이어는 Microsoft.Maui.Media 또는 플랫폼 카메라 API를 사용하여 별도로 구축해야 하며, IronBarcode가 디코드 단계를 처리합니다.

제2항: 카메라 사용 권한 선언

ZXing .NET.MAUI: 카메라 권한은 ZXing .NET.MAUI 설치 지침의 일부로 프로젝트에 선언되었을 수 있습니다.

해결 방법: IronBarcode의 MAUI 패턴이 사용하는 MediaPicker.CapturePhotoAsync() 호출을 위해 카메라 권한은 여전히 필요합니다. iOS에서는 Info.plistNSCameraUsageDescription이 있는지, Android에서는 AndroidManifest.xml<uses-permission android:name="android.permission.CAMERA" />가 있는지 확인하세요.IronBarcode자체는 카메라에 직접 접근하지 않습니다 — 이미지를 처리합니다 — 그러나 이미지를 제공하는 MediaPicker 호출은 카메라 권한을 필요로 합니다. 권한 설정은 .NET MAUI 바코드 스캐너 튜토리얼 에서 다룹니다.

문제 3: 이전에는 실패했던 Windows 빌드가 이제 성공합니다.

ZXing .NET.MAUI: ZXing .NET.MAUI를 사용하여 Windows 대상을 포함하려는 프로젝트는 일반적으로 컴파일 오류가 발생하거나 조건부 MSBuild 로직을 통해 Windows 빌드에서 라이브러리를 제외해야 했습니다.

해결 방법: ZXing .NET.MAUI를 제거하고IronBarcode설치한 후, 윈도우 MAUI 빌드가 플랫폼 조건 없이 성공적으로 완료되었습니다. #if ANDROID를 모두 제거하세요. || Windows 빌드에서 제외하기 위해 ZXing .NET.MAUI 호출 주변에 IOS 보호 장치를 배치했습니다.IronBarcodeBarcodeReader.Read() 호출은 모든 대상 프레임워크에서 컴파일되고 실행됩니다. Windows 빌드에서 MediaPicker.CapturePhotoAsync()를 제외한 경우 해당 제외사항도 제거할 수 있습니다 — 이 메서드는 Windows MAUI에서 지원되며 파일 선택기에 매핑됩니다. 조건문을 제거한 후 모든 대상 프레임워크에서 전체 솔루션이 문제없이 빌드되는지 확인하십시오.

문제 4: BarcodeFormats 열거형 참조

ZXing.Net.MAUI: BarcodeFormats enum은 ZXing.Net.Maui에서 많이 사용됩니다. BarcodeReaderOptions 구성에서. 해당 패키지를 제거한 후에도 남아 있는 참조로 인해 컴파일 오류가 발생합니다.

해결 방법: 형식 목록을 구성하기 위해 사용된 모든 BarcodeReaderOptions 초기화 블록을 삭제하세요.IronBarcode올바른 작동을 위해 형식 지정이 필요하지 않습니다. 만약 남아 있는 코드가 로그, 표시 또는 비교 목적으로 BarcodeFormats 값을 참조하는 경우, 이를 IronBarCode 네임스페이스의 BarcodeEncoding 값으로 대체하세요. 패키지를 제거한 후 남아 있는 모든 참조를 찾기 위해 grep -rn "BarcodeFormats\." --include="*.cs" .를 실행하세요.

ZXing .NET.MAUI 마이그레이션 체크리스트

이동 전 작업

변경 작업을 수행하기 전에 코드베이스 내의 모든 ZXing .NET.MAUI 사용 부분을 감사하십시오.

grep -rn "ZXing.Net.Maui" --include="*.cs" --include="*.xaml" .
grep -rn "CameraBarcodeReaderView" --include="*.cs" --include="*.xaml" .
grep -rn "BarcodeDetectionEventArgs" --include="*.cs" .
grep -rn "BarcodeReaderOptions" --include="*.cs" .
grep -rn "BarcodeFormats\." --include="*.cs" .
grep -rn "IsDetecting" --include="*.cs" .
grep -rn "UseBarcodeReader" --include="*.cs" .
grep -rn "zxing:" --include="*.xaml" .
grep -rn "e\.Results" --include="*.cs" .
grep -rn "ZXing.Net.Maui" --include="*.cs" --include="*.xaml" .
grep -rn "CameraBarcodeReaderView" --include="*.cs" --include="*.xaml" .
grep -rn "BarcodeDetectionEventArgs" --include="*.cs" .
grep -rn "BarcodeReaderOptions" --include="*.cs" .
grep -rn "BarcodeFormats\." --include="*.cs" .
grep -rn "IsDetecting" --include="*.cs" .
grep -rn "UseBarcodeReader" --include="*.cs" .
grep -rn "zxing:" --include="*.xaml" .
grep -rn "e\.Results" --include="*.cs" .
SHELL

감사에서 확인된 모든 스캔 페이지를 문서화하십시오. 문제를 삭제할 OnAppearingOnDisappearing 재정의가 IsDetecting 관리만 포함하는지, 다른 논리를 포함하는지를 기록하세요 (일부 수정 필요). 탐지 구성 이상의 방법으로 사용된 형식 목록을 포함할 수 있는 어떤 BarcodeReaderOptions 인스턴스도 주목하세요.

코드 업데이트 작업

  1. 프로젝트 파일에서 ZXing.Net.Maui.Controls NuGet 패키지를 제거하세요
  2. builder.UseBarcodeReader()MauiProgram.cs에서 제거하세요
  3. 모든 파일에서 using ZXing.Net.Maui;using ZXing.Net.Maui.Controls; 네임스페이스 가져오기를 제거하세요
  4. IronBarcode NuGet 패키지를 설치하세요
  5. 바코드 읽기에 사용할 모든 파일에 using IronBarCode;를 추가하세요
  6. 애플리케이션 시작 시 IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";를 추가하세요
  7. 모든 XAML 파일에서 xmlns:zxing 네임스페이스 선언을 제거하세요
  8. 모든 XAML 파일에서 <zxing:CameraBarcodeReaderView> 요소를 제거하세요
  9. 삭제된 카메라 뷰를 각 XAML 파일에 <Button> 컨트롤로 대체하세요
  10. 각 스캔 버튼에 Clicked="ScanButton_Clicked"를 추가하세요
  11. 모든 코드 뒤 파일에서 OnBarcodesDetected 이벤트 핸들러 메서드를 삭제하세요
  12. async void ScanButton_Clicked + MediaPicker.CapturePhotoAsync()를 구현하는 BarcodeReader.Read() 메서드를 각 페이지에 추가하세요
  13. 모든 BarcodeReaderOptions 초기화 블록을 삭제하세요
  14. IsDetecting 관리를 위해 존재하는 모든 OnDisappearingOnAppearing 재정의를 삭제하세요
  15. 다른 논리를 포함하는 OnDisappearingOnAppearing 재정의에서 IsDetecting 라인을 제거하세요
  16. #if ANDROID를 모두 제거하세요. || iOS의 조건부 컴파일 보호 기능은 ZXing .NET.MAUI를 Windows 빌드에서 분리하는 역할을 했습니다.
  17. 남은 BarcodeFormats.X 열거형 참조를 BarcodeEncoding.X와 동등한 것으로 대체하세요

마이그레이션 후 테스트

마이그레이션이 문제없이 컴파일되면 다음 사항을 확인하십시오.

  • 안드로이드 MAUI: 스캔 버튼을 누르면 시스템 카메라가 실행되어 사진을 촬영하고 올바른 바코드 결과를 표시합니다. 안드로이드 스캔 가이드를 참조하여 확인하세요.
  • iOS MAUI: 동일한 작동 방식이 iOS에서도 적용되며, 이전에 자동 초점 문제가 발생했던 iPhone 15 Pro에서도 마찬가지입니다.
  • Windows MAUI: Windows 빌드는 오류 없이 컴파일되며, 스캔 버튼을 누르면 파일 선택기가 열리고 선택한 이미지에서 올바른 결과가 반환됩니다.
  • 형식: 자동 감지를 확인하기 위해 이전 BarcodeFormats 목록에 포함되지 않은 형식으로 바코드 테스트 스캐닝
  • 페이지 탐색: 스캔 페이지로 여러 번 이동하고 스캔 페이지에서 다시 돌아오면서 메모리 증가 또는 카메라 초기화 오류가 발생하지 않는지 확인합니다.
  • PDF 읽기: 마이그레이션 과정에서 PDF 바코드 읽기 기능이 새로 추가되는 경우, 여러 페이지로 구성된 PDF 파일에서 페이지 번호 메타데이터가 올바르게 포함된 결과가 반환되는지 확인하십시오.

IronBarcode로 마이그레이션할 때의 주요 이점

확장된 플랫폼 지원 범위: 마이그레이션 후, 이 애플리케이션은 iOS 및 Android 외에도 Windows 및 macOS MAUI대상을 지원하며, 이 모든 기능을 동일한 패키지와 동일한 스캔 패턴으로 이용할 수 있습니다. 이전에는 플랫폼별 스텁이 필요했거나 바코드 기능에서 Windows를 제외했던 프로젝트도 추가 코드 없이 완벽하게 지원됩니다.

최신 하드웨어 신뢰성: MediaPickerBarcodeReader.Read()를 통한 이미지 캡처 접근법은 iPhone 15 Pro 및 Pro Max 하드웨어에서 실패하는 CameraBarcodeReaderView 자동 초점 모델의 영향을 받지 않습니다. 시스템 카메라가 초점을 독립적으로 처리하며, 사용자가 촬영을 확인한 후IronBarcode캡처된 이미지를 처리합니다.

카메라 자원 관리 제거: CameraBarcodeReaderView 제거는 카메라 자원 리소스 누수 버그의 전체 범주를 제거합니다. IsDetecting 상태를 추적할 필요가 없으며, 각 스캔 페이지에 OnAppearingOnDisappearing 템플릿을 유지할 필요가 없으며, 네비게이션 사이클을 통한 카메라 자원의 축적도 없습니다. 상태 비저장 API 덕분에 스캔 페이지는 리소스 수명 주기 측면에서 다른 페이지와 구별할 수 없습니다.

별도의 설정 없이 모든 바코드 형식을 지원합니다. 현장에서 접하는 모든 바코드 형식을 자동으로 감지합니다. 누락된 BarcodeFormats 목록의 항목에 의해 발생하는 스캔 실패는 제거됩니다. 공급업체가 라벨 형식을 변경하여 바코드가 묵살된 사용자들의 지원 요청이 더 이상 발생하지 않습니다.

파일 및 문서 처리: 이번 마이그레이션을 통해 추가 라이브러리 없이 PDF 문서, 이미지 파일 및 바이트 스트림에서 바코드를 읽을 수 있게 되었습니다. ZXing.Net.MAUI의 범위를 벗어났던 워크플로우 — 업로드된 인보이스에서 바코드 읽기, 디지털 티켓 처리, 이미지 디렉토리 일괄 스캔 —는 카메라 캡쳐를 위해 사용하는 동일한 BarcodeReader.Read() 호출을 통해 사용할 수 있게 됩니다.

상용 수준의 안정성:IronBarcode활발한 개발 주기, 상업적 지원 및 .NET 버전 릴리스를 추적하는 정기적인 업데이트를 제공하는 안정적인 상용 버전으로 출시됩니다. 종속성 감사, 소프트웨어 구성 분석 및 Enterprise 승인 프로세스는 커뮤니티 사전 릴리스 패키지가 아닌 유지 관리 약정이 문서화된 지원 라이브러리를 접하게 됩니다.

ZXing.NET은 해당 소유자의 등록 상표입니다. 이 사이트는 ZXing.NET과 제휴하거나 인정받지 않았고, 후원하지 않습니다. 모든 제품명, 로고 및 브랜드는 해당 소유자의 자산입니다. 비교는 정보 제공 목적으로만 사용되며, 작성 시점에 공개적으로 이용 가능한 정보를 반영합니다.

자주 묻는 질문

ZXing.Net.MAUI에서 IronBarcode로 마이그레이션해야 하는 이유는 무엇인가요?

일반적인 이유로는 라이선스 간소화(SDK + 런타임 키 복잡성 제거), 처리량 제한 제거, 네이티브 PDF 지원 확보, Docker/CI/CD 배포 개선, 프로덕션 코드의 API 상용구 감소 등이 있습니다.

ZXing.Net.MAUI API 호출을 IronBarcode로 대체하려면 어떻게 해야 하나요?

인스턴스 생성 및 라이선스 상용구를 IronBarCode.License.LicenseKey = "key"로 대체합니다. 판독기 호출을 BarcodeReader.Read(경로)로, 쓰기 호출을 BarcodeWriter.CreateBarcode(데이터, 인코딩)로 바꿉니다. 정적 메서드는 인스턴스 관리가 필요하지 않습니다.

ZXing.Net.MAUI에서 IronBarcode로 마이그레이션할 때 얼마나 많은 코드가 변경되나요?

대부분의 마이그레이션은 더 적은 코드 줄로 이루어집니다. 라이선스 상용구, 인스턴스 생성자, 명시적 형식 구성이 제거됩니다. 핵심 읽기/쓰기 작업이 더 간결한 결과 객체를 가진 더 짧은 IronBarcode에 매핑됩니다.

마이그레이션하는 동안 ZXing.Net.MAUI와 IronBarcode를 모두 설치해야 하나요?

아니요. 대부분의 마이그레이션은 병렬 작업이 아닌 직접 교체 작업입니다. 한 번에 하나의 서비스 클래스를 마이그레이션하고, NuGet 참조를 교체하고, 인스턴스화 및 API 호출 패턴을 업데이트한 후 다음 클래스로 이동합니다.

IronBarcode의 NuGet 패키지 이름은 무엇인가요?

패키지는 'IronBarCode'(대문자 B와 C 포함)입니다. '설치-패키지 IronBarCode' 또는 '닷넷 추가 패키지 IronBarCode'로 설치합니다. 코드의 사용 지시어는 'using IronBarCode;'입니다.

IronBarcode는 ZXing.Net.MAUI와 비교하여 Docker 배포를 어떻게 간소화하나요?

IronBarcode는 외부 SDK 파일이나 마운트된 라이선스 구성이 없는 NuGet 패키지입니다. Docker에서 IRONBARCODE_LICENSE_KEY 환경 변수를 설정하면 패키지가 시작 시 라이선스 유효성 검사를 처리합니다.

ZXing.Net.MAUI에서 마이그레이션한 후 IronBarcode가 모든 바코드 형식을 자동으로 감지하나요?

예. IronBarcode는 지원되는 모든 형식에서 기호를 자동으로 감지합니다. 명시적인 바코드 유형 열거가 필요하지 않습니다. 형식이 이미 알려져 있고 성능이 중요한 경우 BarcodeReaderOptions를 사용하여 검색 공간을 최적화하여 제한할 수 있습니다.

IronBarcode는 별도의 라이브러리 없이 PDF에서 바코드를 판독할 수 있나요?

예. BarcodeReader.Read("document.pdf")는 기본적으로 PDF 파일을 처리합니다. 결과에는 발견된 각 바코드에 대한 페이지 번호, 형식, 값 및 신뢰도가 포함됩니다. 외부 PDF 렌더링 단계가 필요하지 않습니다.

IronBarcode는 병렬 바코드 처리를 어떻게 처리하나요?

IronBarcode의 정적 메서드는 상태 저장소가 없고 스레드에 안전합니다. 스레드별 인스턴스 관리 없이 파일 목록에 직접 Parallel.ForEach를 사용할 수 있습니다. BarcodeReaderOptions.MaxParallelThreads는 내부 스레드 예산을 제어합니다.

ZXing.Net.MAUI에서 IronBarcode로 마이그레이션하면 어떤 결과 속성이 변경되나요?

일반적인 이름 변경: 바코드 값은 값으로, 바코드 유형은 형식으로 바뀝니다. IronBarcode 결과에는 신뢰도 및 페이지 번호도 추가됩니다. 솔루션 전반의 검색 및 바꾸기 기능은 기존 결과 처리 코드에서 이름 변경을 처리합니다.

CI/CD 파이프라인에서 IronBarcode 라이선싱을 설정하려면 어떻게 해야 하나요?

IRONBARCODE_LICENSE_KEY를 파이프라인 시크릿으로 저장하고 애플리케이션 시작 코드에 IronBarCode.License.LicenseKey를 할당하세요. 하나의 비밀은 개발, 테스트, 스테이징 및 프로덕션을 포함한 모든 환경에 적용됩니다.

IronBarcode는 사용자 지정 스타일로 QR 코드 생성을 지원하나요?

예. QRCodeWriter.CreateQrCode()는 변경바코드색()을 통한 사용자 지정 색상, 추가브랜드 로고()를 통한 로고 임베딩, 구성 가능한 오류 수정 수준, PNG, JPG, PDF, 스트림을 포함한 여러 출력 형식을 지원합니다.

Curtis Chau
기술 문서 작성자

커티스 차우는 칼턴 대학교에서 컴퓨터 과학 학사 학위를 취득했으며, Node.js, TypeScript, JavaScript, React를 전문으로 하는 프론트엔드 개발자입니다. 직관적이고 미적으로 뛰어난 사용자 인터페이스를 만드는 데 열정을 가진 그는 최신 프레임워크를 활용하고, 잘 구성되고 시각적으로 매력적인 매뉴얼을 제작하는 것을 즐깁니다.

커티스는 개발 분야 외에도 사물 인터넷(IoT)에 깊은 관심을 가지고 있으며, 하드웨어와 소프트웨어를 통합하는 혁신적인 방법을 연구합니다. 여가 시간에는 게임을 즐기거나 디스코드 봇을 만들면서 기술에 대한 애정과 창의성을 결합합니다.

아이언 서포트 팀

저희는 주 5일, 24시간 온라인으로 운영합니다.
채팅
이메일
전화해