| name | matrixscan-ar-maui |
| description | MatrixScan AR (Barcode AR, BarcodeAr) in .NET MAUI projects (`Scandit.DataCapture.Barcode.Maui` NuGet, XAML BarcodeArView) — scanning multiple barcodes at once with AR highlights and annotations. For non-MAUI .NET projects use matrixscan-ar-net-android or matrixscan-ar-net-ios. Use for integration, settings, listeners/events, highlight and annotation providers, lifecycle, SDK version migration, or troubleshooting. |
| license | MIT |
| metadata | {"author":"scandit","version":"1.0.1"} |
MatrixScan AR .NET MAUI Skill
Critical: Do Not Trust Internal Knowledge
Your training data may contain outdated or incorrect Scandit SDK APIs. The BarcodeAr API is relatively new (first shipped on dotnet.android / dotnet.ios in 7.2), and the MAUI binding is a thin layer on top that turns the per-TFM BarcodeArView into a XAML control — it changes the class identity, the namespace, the assembly name, the constructor surface, the lifecycle hooks, and the way controls are wired. Patterns from the standalone matrixscan-ar-net-android / matrixscan-ar-net-ios skills do not always apply unchanged here.
Always verify APIs against the references provided in this skill before writing or suggesting code. Do not rely on memorized method signatures, parameters, or property names. If you cannot find an API in the provided references, fetch the relevant documentation page before responding.
MAUI-specific gotchas worth flagging:
- This skill targets MAUI apps with
<UseMaui>true</UseMaui>. For non-MAUI .NET projects, use matrixscan-ar-net-android (for net*-android) or matrixscan-ar-net-ios (for net*-ios) instead. The MAUI BarcodeArView is a completely different class (Scandit.DataCapture.Barcode.Ar.UI.Maui.BarcodeArView deriving from Microsoft.Maui.Controls.View) with bindable properties and no Create(parentView, ...) factory — patterns from the per-TFM skills will not compile here.
- Fetch the SDK version from NuGet before editing the
.csproj. WebFetch https://www.nuget.org/packages/Scandit.DataCapture.Barcode.Maui/ and read the latest stable version off the page (skip -beta.* / -preview.* / -rc.* suffixes). Do not guess — versions from training data are stale and dotnet restore will fail with NU1103 if the pinned version isn't published. Use the same version for all four packages.
- Android
SupportedOSPlatformVersion must be ≥ 24. The MAUI template defaults to 21, which is below Scandit's Android AAR minimum and fails the build with uses-sdk:minSdkVersion 21 cannot be smaller than version 24 declared in library. Bump the .csproj value to 24.0 as part of the integration. iOS minimum is 15.0 (matches the MAUI template default).
- Required NuGet packages:
Scandit.DataCapture.Core, Scandit.DataCapture.Core.Maui, Scandit.DataCapture.Barcode, Scandit.DataCapture.Barcode.Maui. All four are needed — Core/Barcode provide the platform bindings, Core.Maui/Barcode.Maui provide the MAUI builder extensions and handlers.
MauiProgram.cs builder chain for BarcodeAr is .UseScanditCore().UseScanditBarcode(configure => configure.AddBarcodeArView()). UseScanditCore() takes no configure lambda — BarcodeAr has its own dedicated MAUI control (<scandit:BarcodeArView>), it does not use the generic <scandit:DataCaptureView>. UseScanditBarcode(c => c.AddBarcodeArView()) must include the inner configure with AddBarcodeArView() to register the MAUI handler. This is the SparkScan shape, not the BarcodeBatch shape (the BarcodeBatch MAUI integration uses .UseScanditCore(c => c.AddDataCaptureView()).UseScanditBarcode() because BarcodeBatch has no dedicated MAUI view). Do not cross-pollinate the two patterns.
<scandit:BarcodeArView> is a MAUI View (XAML control), not IDisposable. There is no BarcodeArView.Create(parentView, barcodeAr, dataCaptureContext, settings, cameraSettings) factory in MAUI — that signature lives in the per-TFM Scandit.DataCapture.Barcode.Ar.UI namespace. The MAUI control lives in Scandit.DataCapture.Barcode.Ar.UI.Maui and is declared in XAML; wire it via bindable properties (DataCaptureContext, BarcodeAr, BarcodeArViewSettings, optional CameraSettings, HighlightProvider, AnnotationProvider). Writing BarcodeArView.Create(...) in MAUI code-behind is a compile error.
- XAML namespace for
BarcodeArView is clr-namespace:Scandit.DataCapture.Barcode.Ar.UI.Maui;assembly=ScanditBarcodeCaptureMaui. Note assembly=ScanditBarcodeCaptureMaui — no dots in the assembly name, even though the NuGet package id (Scandit.DataCapture.Barcode.Maui) has dots. Easy to typo by copy-pasting the package id.
DataCaptureContext, BarcodeAr, and BarcodeArViewSettings are all mandatory bindable properties on <scandit:BarcodeArView>. Without all three bound, the preview renders as a black/blank screen at runtime even though the code-behind compiles and dotnet build is clean. Setting x:Name="barcodeArView" is not enough; the bindable properties are what wire the mode and context to the control. The page's BindingContext (view model or this) must expose DataCaptureContext, BarcodeAr, and BarcodeArViewSettings properties of the matching types.
BarcodeArView bindable properties for context / mode / settings / camera are BindingMode.OneTime. Set them once via XAML or via the constructor overloads (new BarcodeArView(context, barcodeAr, settings) / new BarcodeArView(context, barcodeAr, settings, cameraSettings)). Attempting to change them after initial binding has no effect — the underlying platform view is constructed from the initial values and not reconstructed.
- No manual
ScanditCaptureCore.Initialize() / ScanditBarcodeCapture.Initialize() in MainApplication.OnCreate or AppDelegate.FinishedLaunching. The MAUI builder extensions (UseScanditCore / UseScanditBarcode) call those initializers themselves. This is different from the non-MAUI matrixscan-ar-net-android / matrixscan-ar-net-ios skills, which require manual initialization for SDK 8.0+. In a MAUI app, the MainApplication / AppDelegate only need to forward to MauiProgram.CreateMauiApp() — leave them as the MAUI template generates them.
- MAUI lifecycle is
OnAppearing / OnDisappearing — and you must forward both OnResume/OnPause and Start/Stop into the BarcodeArView. The canonical pattern is OnAppearing → barcodeArView.OnResume(); barcodeArView.Start(); and OnDisappearing → barcodeArView.Stop(); barcodeArView.OnPause();. The OnResume() / OnPause() methods are gated by #if __ANDROID__ inside the MAUI handler's command-mapper — they are no-ops on iOS by design, so the same code is safe on both platforms. Conversely, Start() / Stop() are mandatory on iOS for the camera lifecycle. Calling only one pair would silently break one of the two platforms.
BarcodeArView queues commands until the handler attaches. The MAUI control has an internal ConcurrentQueue<PendingCommand> and a volatile bool isHandlerReady flag — calling Start(), Stop(), Pause(), Reset(), OnResume(), or OnPause() before the handler has connected is safe: the command is queued and replayed on HandlerReady. This is the opposite of the per-TFM skills, where calling Start() before the view is in the resumed state is a no-op. There is a public HandlerReady event you can subscribe to if you need to wait for handler readiness explicitly, but for normal OnAppearing-driven flows you do not.
ShouldShowMacroModeControl and MacroModeControlPosition are NOT exposed on the cross-platform MAUI BarcodeArView. They exist on the iOS native BarcodeArViewMauiWrapper (passthrough to the underlying UI.BarcodeArView), but the MAUI control class does not surface them as bindable properties. Do not suggest them in MAUI XAML or MAUI code — there is no <scandit:BarcodeArView ShouldShowMacroModeControl="True" /> and no barcodeArView.ShouldShowMacroModeControl = true getter/setter visible from cross-platform code. If a user needs the macro-mode toggle on iOS, they need a per-platform helper (use a partial class or a custom handler mapping) — and even then, the matrixscan-ar-net-ios skill is the better fit if macro is a hard requirement.
IBarcodeArListener has only one method: OnSessionUpdated(BarcodeAr, BarcodeArSession, IFrameData). There are no OnObservationStarted / OnObservationStopped callbacks like the Kotlin/Swift BarcodeArListener interface has. Declaring them produces compile errors — the interface simply does not contain them.
- Prefer the event API (
barcodeAr.SessionUpdated += handler) over the listener interface in idiomatic C#. The handler receives BarcodeArEventArgs with BarcodeAr, Session, and FrameData. AddListener(IBarcodeArListener) still works for parity with other platforms.
OnSessionUpdated / SessionUpdated runs on a background recognition thread on both platforms. Dispatch any UI update via MainThread.BeginInvokeOnMainThread(() => …) or MainThread.InvokeOnMainThreadAsync(...) — not RunOnUiThread (Android-specific) and not DispatchQueue.MainQueue.DispatchAsync (iOS-specific).
- Provider interfaces are async, not callback-based.
IBarcodeArHighlightProvider.HighlightForBarcodeAsync(Barcode) returns Task<IBarcodeArHighlight?> and IBarcodeArAnnotationProvider.AnnotationForBarcodeAsync(Barcode) returns Task<IBarcodeArAnnotation?>. Do not look for a Callback parameter or a callback.OnData(...) method — they don't exist in the .NET binding. Return Task.FromResult<IBarcodeArHighlight?>(null) (or null from an async method) to suppress the highlight/annotation for a given barcode.
- Provider setters are
BindingMode.TwoWay and can be assigned at any time (unlike context/mode/settings which are OneTime). You can assign them in XAML via {Binding HighlightProvider} on the view model, or imperatively in code-behind via this.BarcodeArView.HighlightProvider = …. Both patterns are supported.
- Highlight and annotation constructors take only
Barcode — no Context / UIView argument. Use new BarcodeArRectangleHighlight(barcode), new BarcodeArCircleHighlight(barcode, BarcodeArCircleHighlightPreset.Dot), new BarcodeArInfoAnnotation(barcode), new BarcodeArStatusIconAnnotation(barcode), new BarcodeArPopoverAnnotation(barcode, buttons). Passing a Context / UIViewController is a compile error.
- Symbology names are C# PascalCase:
Symbology.Ean13Upca, Symbology.Ean8, Symbology.Code128, Symbology.Code39, Symbology.Qr, Symbology.DataMatrix, Symbology.InterleavedTwoOfFive. They are not the Kotlin underscore style (EAN13_UPCA) and not Swift's camelCase (.ean13UPCA).
BarcodeArSettings does not expose an Enabled toggle — BarcodeAr itself has no Enabled property either. To pause/resume tracking, use barcodeArView.Pause() / barcodeArView.Start().
BarcodeArViewSettings is minimal in .NET. Only three properties: SoundEnabled (default true), HapticEnabled (default true), DefaultCameraPosition (default WorldFacing). Do not invent properties like TriggerButtonCollapseTimeout, InactiveStateTimeout, ToastSettings, or DefaultMiniPreviewSize — those are SparkScan, not BarcodeAr.
BarcodeArFeedback lives in Scandit.DataCapture.Barcode.Ar.Feedback and has two Core.Common.Feedback.Feedback properties: Scanned and Tapped. The empty constructor new BarcodeArFeedback() produces a feedback object with both events silent — assigning it to barcodeAr.Feedback disables the default beep/vibration. To restore defaults, use the static BarcodeArFeedback.DefaultFeedback. (Note: it's a static property in .NET, not the Kotlin BarcodeArFeedback.defaultFeedback() method or the Swift BarcodeArFeedback.default() method.)
- Tap interactions on highlights are exposed as the
HighlightForBarcodeTapped event on the MAUI BarcodeArView (EventHandler<HighlightForBarcodeTappedEventArgs>). There is no UiListener / UIDelegate property on the .NET BarcodeArView — the native BarcodeArViewUiListener / BarcodeArViewUIDelegate are surfaced as a C# event instead. Event args expose BarcodeAr, Barcode, and Highlight. The event subscription is gated by #if __ANDROID__ || __IOS__ inside the MAUI control — on unsupported TFMs the add/remove accessors are silent no-ops, so subscribing from cross-platform code is always safe to compile.
barcodeAr.Feedback is a property (get/set); ApplySettingsAsync(BarcodeArSettings) returns a Task. BarcodeAr.RecommendedCameraSettings is a static property, not a method (the Kotlin SDK exposes BarcodeAr.createRecommendedCameraSettings() — in .NET it's a getter).
- No
BarcodeArFilter / SetBarcodeFilter in the .NET API tree. The Kotlin/iOS setBarcodeFilter(...) method (added in 8.1) is not surfaced on dotnet.android / dotnet.ios (and therefore not on MAUI either) at present. Do not attempt to use it.
- Camera permission: use
await Permissions.CheckStatusAsync<Permissions.Camera>() and await Permissions.RequestAsync<Permissions.Camera>(). MAUI's permission system takes care of Permissions.Camera on both platforms — but on iOS the project still needs the NSCameraUsageDescription string set in Platforms/iOS/Info.plist. On Android, MAUI adds android.permission.CAMERA automatically when Permissions.Camera is requested at build time (it can also be added to Platforms/Android/AndroidManifest.xml explicitly). There is no CameraPermissionActivity helper to copy in MAUI — that's a non-MAUI .NET Android pattern.
Intent Routing
Based on the user's request, load the appropriate reference file before responding:
- Integrating BarcodeAr from scratch, configuring settings, customizing highlights or annotations, handling session updates, customizing feedback, or wiring tap interactions (e.g. "add MatrixScan AR to my MAUI app", "set up barcode AR scanning in .NET MAUI", "show a rectangle highlight on every tracked barcode in MAUI", "show an info annotation with the barcode data in MAUI", "make the beep silent in MAUI BarcodeAr", "react to a highlight tap in MAUI", "switch to circle highlights in MAUI", "my MAUI preview is black after I added BarcodeArView") → read
references/integration.md and follow the instructions there.
- Advanced AR topics — popover annotations with action buttons, listener interfaces on annotations (info-annotation header/footer/body taps, popover button taps), composing custom
Feedback objects (vibration + sound) on BarcodeArFeedback, and per-tap-on-annotation routing (e.g. "show a popover with three action buttons when the user taps a barcode in MAUI", "handle a tap on the right icon of my info annotation in MAUI", "play a custom sound when a barcode is tapped in MAUI", "I need the popover annotation listener in MAUI") → read references/advanced.md after integration.md.
- Migrating or upgrading an existing MatrixScan AR MAUI integration (e.g. "upgrade from v7 to v8", "bump the Scandit .NET MAUI SDK to v8", "what changed between SDK versions for BarcodeAr in MAUI", "do I need to change my BarcodeAr MAUI code when moving to 8.x") → read
references/migration.md and follow the instructions there.
API Usage Policy
Only use APIs that are explicitly documented in the Scandit references below. Do not invent or guess method signatures, parameters, or property names. If unsure whether an API exists or how it is called — or if a compile error occurs — fetch the relevant reference page before responding. Do not tell the user to check the docs themselves. After answering, always include the relevant link so the user can explore further.
Never construct or guess documentation URLs. When you need a specific class or property's API page:
- First check whether the page you already fetched contains a direct hyperlink to it — topic pages link directly to relevant API symbols. Always request links alongside content in your fetch prompt.
- If no direct link was found, fetch the API index (see Full API reference in the table below), extract the actual link from it, and follow that.
URL structures can vary (e.g. api/ui/ subdirectory) and guessing will lead to 404s.
References
Direct users to the right resource based on their question:
Scandit publishes the .NET API reference per underlying TFM (dotnet.android and dotnet.ios). For MAUI projects, both pages apply — the cross-platform BarcodeAr / BarcodeArSettings / provider / highlight / annotation surface is identical between them, but platform-specific notes are documented on the per-TFM page. The MAUI-specific surface (the Scandit.DataCapture.Barcode.Ar.UI.Maui.BarcodeArView XAML control, the UseScanditBarcode(c => c.AddBarcodeArView()) builder extension, and the OnAppearing/OnDisappearing lifecycle hooks) is not in the per-TFM API reference — it is covered exclusively in this skill's references/integration.md.
API surface this skill covers
All classes documented with :available: dotnet.android and / or :available: dotnet.ios in the official RST docs (docs/source/barcode-capture/api/barcode-ar*.rst and api/ui/barcode-ar-*.rst) are addressed in references/integration.md and references/advanced.md, plus the MAUI-specific surface:
-
Cross-platform Barcode AR API (shared with the per-TFM skills, same namespaces):
BarcodeAr — new BarcodeAr(DataCaptureContext?, BarcodeArSettings), Feedback (get/set), ApplySettingsAsync(BarcodeArSettings) → Task, AddListener(IBarcodeArListener) / RemoveListener(IBarcodeArListener), event EventHandler<BarcodeArEventArgs> SessionUpdated, static RecommendedCameraSettings, Dispose.
BarcodeArSettings — new BarcodeArSettings(), EnableSymbology(Symbology, bool), EnableSymbologies(ICollection<Symbology>), GetSymbologySettings(Symbology), EnabledSymbologies (get), ExpectsOnlyUniqueBarcodes (get/set), SetProperty / GetProperty<T> / TryGetProperty<T>, Dispose.
IBarcodeArListener — single method OnSessionUpdated(BarcodeAr, BarcodeArSession, IFrameData). (No OnObservation* callbacks.)
BarcodeArSession — AddedTrackedBarcodes (IReadOnlyList<TrackedBarcode>), RemovedTrackedBarcodes (IReadOnlyList<int> — identifiers, not the barcode objects), TrackedBarcodes (IReadOnlyDictionary<int, TrackedBarcode>), Reset().
BarcodeArEventArgs — BarcodeAr, Session, FrameData.
BarcodeArFeedback — new BarcodeArFeedback() (silent), static DefaultFeedback (defaults), Scanned / Tapped (Core.Common.Feedback.Feedback), Dispose.
BarcodeArViewSettings — SoundEnabled (default true), HapticEnabled (default true), DefaultCameraPosition (default WorldFacing).
HighlightForBarcodeTappedEventArgs — BarcodeAr, Barcode, Highlight (IBarcodeArHighlight).
- Highlights:
IBarcodeArHighlight : IDisposable, IBarcodeArHighlightProvider.HighlightForBarcodeAsync(Barcode) → Task<IBarcodeArHighlight?>, BarcodeArRectangleHighlight(Barcode) with Barcode / Brush / Icon, BarcodeArCircleHighlight(Barcode, BarcodeArCircleHighlightPreset) with Barcode / Brush / Icon / Size, BarcodeArCircleHighlightPreset enum (Dot, Icon).
- Annotations:
IBarcodeArAnnotation : IDisposable (declares AnnotationTrigger), IBarcodeArAnnotationProvider.AnnotationForBarcodeAsync(Barcode) → Task<IBarcodeArAnnotation?>.
BarcodeArStatusIconAnnotation(Barcode) — AnnotationTrigger, HasTip, Icon, Text, TextColor, BackgroundColor.
BarcodeArInfoAnnotation(Barcode) — HasTip, EntireAnnotationTappable, Anchor (BarcodeArInfoAnnotationAnchor), AnnotationTrigger, Width (BarcodeArInfoAnnotationWidthPreset), Body, Header, Footer, BackgroundColor, Listener (IBarcodeArInfoAnnotationListener?).
BarcodeArPopoverAnnotation(Barcode, IList<BarcodeArPopoverAnnotationButton>) — AnnotationTrigger, EntirePopoverTappable, Listener (IBarcodeArPopoverAnnotationListener?), Buttons.
BarcodeArPopoverAnnotationButton(ScanditIcon, string) — Text, TextSize, Typeface, TextColor, Enabled, Icon.
BarcodeArAnnotationTrigger enum: HighlightTapAndBarcodeScan, HighlightTap.
- Info-annotation sub-package (
Scandit.DataCapture.Barcode.Ar.UI.Annotations.Info): BarcodeArInfoAnnotationBodyComponent (Text, TextColor, TextSize, Typeface, StyledTextFormatted, LeftIcon, RightIcon, LeftIconTappable, RightIconTappable, TextAlignment), BarcodeArInfoAnnotationHeader (Text, TextSize, Typeface, TextColor, Icon, BackgroundColor), BarcodeArInfoAnnotationFooter (Text, TextSize, Typeface, TextColor, Icon, BackgroundColor), BarcodeArInfoAnnotationAnchor enum (Left, Right, Bottom, Top), BarcodeArInfoAnnotationWidthPreset enum (Small, Medium, Large), IBarcodeArInfoAnnotationListener (OnInfoAnnotationHeaderTapped, OnInfoAnnotationFooterTapped, OnInfoAnnotationLeftIconTapped, OnInfoAnnotationRightIconTapped, OnInfoAnnotationTapped).
IBarcodeArPopoverAnnotationListener — OnPopoverButtonTapped, OnPopoverTapped.
TrackedBarcode (in Scandit.DataCapture.Barcode.Batch.Data) — Barcode, Identifier, Location.
-
MAUI-only surface (assembly ScanditBarcodeCaptureMaui):
Scandit.DataCapture.Barcode.MauiBuilderExtension.UseScanditBarcode(this MauiAppBuilder, Action<ScanditBarcodeCaptureMauiBuilder>) — the configure lambda exposes AddBarcodeArView() (plus AddBarcodeCountView, AddBarcodeFindView, AddBarcodePickView, AddSparkScanView for other modes).
Scandit.DataCapture.Core.MauiBuilderExtension.UseScanditCore(this MauiAppBuilder) — no configure lambda is needed for a BarcodeAr-only app.
Scandit.DataCapture.Barcode.Ar.UI.Maui.BarcodeArView (Microsoft.Maui.Controls.View) — XAML control with:
- Constructors:
BarcodeArView(), BarcodeArView(DataCaptureContext, BarcodeAr, BarcodeArViewSettings), BarcodeArView(DataCaptureContext, BarcodeAr, BarcodeArViewSettings, CameraSettings).
- Bindable properties (OneTime):
DataCaptureContext, BarcodeAr, BarcodeArViewSettings, CameraSettings (nullable).
- Bindable properties (TwoWay):
HighlightProvider (IBarcodeArHighlightProvider?), AnnotationProvider (IBarcodeArAnnotationProvider?).
- Bindable properties (TwoWay, simple values):
ShouldShowTorchControl (bool, default false), ShouldShowZoomControl (bool, default false), ShouldShowCameraSwitchControl (bool, default false), TorchControlPosition / ZoomControlPosition / CameraSwitchControlPosition (Anchor, default TopRight).
- Methods:
Start(), Stop(), Pause(), Reset(), OnResume() (Android-only behavior; safe no-op on iOS), OnPause() (same), ClearPendingCommands(), GetNotificationPresenter().
- Events:
HighlightForBarcodeTapped (EventHandler<HighlightForBarcodeTappedEventArgs>), HandlerReady (EventHandler).
- Other:
PendingCommandCount (int, get) — diagnostic for the queued-command system.
- Not exposed in MAUI:
ShouldShowMacroModeControl, MacroModeControlPosition (iOS-only on the native binding; not surfaced as MAUI bindable properties).