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, usematrixscan-ar-net-android(fornet*-android) ormatrixscan-ar-net-ios(fornet*-ios) instead. The MAUIBarcodeArViewis a completely different class (Scandit.DataCapture.Barcode.Ar.UI.Maui.BarcodeArViewderiving fromMicrosoft.Maui.Controls.View) with bindable properties and noCreate(parentView, ...)factory — patterns from the per-TFM skills will not compile here. - Fetch the SDK version from NuGet before editing the
.csproj. WebFetchhttps://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 anddotnet restorewill fail withNU1103if the pinned version isn't published. Use the same version for all four packages. - Android
SupportedOSPlatformVersionmust be ≥24. The MAUI template defaults to21, which is below Scandit's Android AAR minimum and fails the build withuses-sdk:minSdkVersion 21 cannot be smaller than version 24 declared in library. Bump the.csprojvalue to24.0as part of the integration. iOS minimum is15.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.csbuilder 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 withAddBarcodeArView()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 MAUIView(XAML control), notIDisposable. There is noBarcodeArView.Create(parentView, barcodeAr, dataCaptureContext, settings, cameraSettings)factory in MAUI — that signature lives in the per-TFMScandit.DataCapture.Barcode.Ar.UInamespace. The MAUI control lives inScandit.DataCapture.Barcode.Ar.UI.Mauiand is declared in XAML; wire it via bindable properties (DataCaptureContext,BarcodeAr,BarcodeArViewSettings, optionalCameraSettings,HighlightProvider,AnnotationProvider). WritingBarcodeArView.Create(...)in MAUI code-behind is a compile error.- XAML namespace for
BarcodeArViewisclr-namespace:Scandit.DataCapture.Barcode.Ar.UI.Maui;assembly=ScanditBarcodeCaptureMaui. Noteassembly=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, andBarcodeArViewSettingsare 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 anddotnet buildis clean. Settingx:Name="barcodeArView"is not enough; the bindable properties are what wire the mode and context to the control. The page'sBindingContext(view model orthis) must exposeDataCaptureContext,BarcodeAr, andBarcodeArViewSettingsproperties of the matching types.BarcodeArViewbindable properties for context / mode / settings / camera areBindingMode.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()inMainApplication.OnCreateorAppDelegate.FinishedLaunching. The MAUI builder extensions (UseScanditCore/UseScanditBarcode) call those initializers themselves. This is different from the non-MAUImatrixscan-ar-net-android/matrixscan-ar-net-iosskills, which require manual initialization for SDK 8.0+. In a MAUI app, theMainApplication/AppDelegateonly need to forward toMauiProgram.CreateMauiApp()— leave them as the MAUI template generates them. - MAUI lifecycle is
OnAppearing/OnDisappearing— and you must forward bothOnResume/OnPauseandStart/Stopinto theBarcodeArView. The canonical pattern isOnAppearing→barcodeArView.OnResume(); barcodeArView.Start();andOnDisappearing→barcodeArView.Stop(); barcodeArView.OnPause();. TheOnResume()/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. BarcodeArViewqueues commands until the handler attaches. The MAUI control has an internalConcurrentQueue<PendingCommand>and avolatile bool isHandlerReadyflag — callingStart(),Stop(),Pause(),Reset(),OnResume(), orOnPause()before the handler has connected is safe: the command is queued and replayed onHandlerReady. This is the opposite of the per-TFM skills, where callingStart()before the view is in the resumed state is a no-op. There is a publicHandlerReadyevent you can subscribe to if you need to wait for handler readiness explicitly, but for normalOnAppearing-driven flows you do not.ShouldShowMacroModeControlandMacroModeControlPositionare NOT exposed on the cross-platform MAUIBarcodeArView. They exist on the iOS nativeBarcodeArViewMauiWrapper(passthrough to the underlyingUI.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 nobarcodeArView.ShouldShowMacroModeControl = truegetter/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, thematrixscan-ar-net-iosskill is the better fit if macro is a hard requirement.IBarcodeArListenerhas only one method:OnSessionUpdated(BarcodeAr, BarcodeArSession, IFrameData). There are noOnObservationStarted/OnObservationStoppedcallbacks like the Kotlin/SwiftBarcodeArListenerinterface 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 receivesBarcodeArEventArgswithBarcodeAr,Session, andFrameData.AddListener(IBarcodeArListener)still works for parity with other platforms. OnSessionUpdated/SessionUpdatedruns on a background recognition thread on both platforms. Dispatch any UI update viaMainThread.BeginInvokeOnMainThread(() => …)orMainThread.InvokeOnMainThreadAsync(...)— notRunOnUiThread(Android-specific) and notDispatchQueue.MainQueue.DispatchAsync(iOS-specific).- Provider interfaces are async, not callback-based.
IBarcodeArHighlightProvider.HighlightForBarcodeAsync(Barcode)returnsTask<IBarcodeArHighlight?>andIBarcodeArAnnotationProvider.AnnotationForBarcodeAsync(Barcode)returnsTask<IBarcodeArAnnotation?>. Do not look for aCallbackparameter or acallback.OnData(...)method — they don't exist in the .NET binding. ReturnTask.FromResult<IBarcodeArHighlight?>(null)(ornullfrom anasyncmethod) to suppress the highlight/annotation for a given barcode. - Provider setters are
BindingMode.TwoWayand can be assigned at any time (unlike context/mode/settings which areOneTime). You can assign them in XAML via{Binding HighlightProvider}on the view model, or imperatively in code-behind viathis.BarcodeArView.HighlightProvider = …. Both patterns are supported. - Highlight and annotation constructors take only
Barcode— noContext/UIViewargument. Usenew BarcodeArRectangleHighlight(barcode),new BarcodeArCircleHighlight(barcode, BarcodeArCircleHighlightPreset.Dot),new BarcodeArInfoAnnotation(barcode),new BarcodeArStatusIconAnnotation(barcode),new BarcodeArPopoverAnnotation(barcode, buttons). Passing aContext/UIViewControlleris 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). BarcodeArSettingsdoes not expose anEnabledtoggle —BarcodeAritself has noEnabledproperty either. To pause/resume tracking, usebarcodeArView.Pause()/barcodeArView.Start().BarcodeArViewSettingsis minimal in .NET. Only three properties:SoundEnabled(defaulttrue),HapticEnabled(defaulttrue),DefaultCameraPosition(defaultWorldFacing). Do not invent properties likeTriggerButtonCollapseTimeout,InactiveStateTimeout,ToastSettings, orDefaultMiniPreviewSize— those are SparkScan, not BarcodeAr.BarcodeArFeedbacklives inScandit.DataCapture.Barcode.Ar.Feedbackand has twoCore.Common.Feedback.Feedbackproperties:ScannedandTapped. The empty constructornew BarcodeArFeedback()produces a feedback object with both events silent — assigning it tobarcodeAr.Feedbackdisables the default beep/vibration. To restore defaults, use the staticBarcodeArFeedback.DefaultFeedback. (Note: it's a static property in .NET, not the KotlinBarcodeArFeedback.defaultFeedback()method or the SwiftBarcodeArFeedback.default()method.)- Tap interactions on highlights are exposed as the
HighlightForBarcodeTappedevent on the MAUIBarcodeArView(EventHandler<HighlightForBarcodeTappedEventArgs>). There is noUiListener/UIDelegateproperty on the .NETBarcodeArView— the nativeBarcodeArViewUiListener/BarcodeArViewUIDelegateare surfaced as a C# event instead. Event args exposeBarcodeAr,Barcode, andHighlight. The event subscription is gated by#if __ANDROID__ || __IOS__inside the MAUI control — on unsupported TFMs theadd/removeaccessors are silent no-ops, so subscribing from cross-platform code is always safe to compile. barcodeAr.Feedbackis a property (get/set);ApplySettingsAsync(BarcodeArSettings)returns aTask.BarcodeAr.RecommendedCameraSettingsis a static property, not a method (the Kotlin SDK exposesBarcodeAr.createRecommendedCameraSettings()— in .NET it's a getter).- No
BarcodeArFilter/SetBarcodeFilterin the .NET API tree. The Kotlin/iOSsetBarcodeFilter(...)method (added in 8.1) is not surfaced ondotnet.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>()andawait Permissions.RequestAsync<Permissions.Camera>(). MAUI's permission system takes care ofPermissions.Cameraon both platforms — but on iOS the project still needs theNSCameraUsageDescriptionstring set inPlatforms/iOS/Info.plist. On Android, MAUI addsandroid.permission.CAMERAautomatically whenPermissions.Camerais requested at build time (it can also be added toPlatforms/Android/AndroidManifest.xmlexplicitly). There is noCameraPermissionActivityhelper 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
Feedbackobjects (vibration + sound) onBarcodeArFeedback, 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 afterintegration.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:
| Topic | Resource |
|---|---|
| Get Started (Android target) | Get Started (.NET for Android) |
| Get Started (iOS target) | Get Started (.NET for iOS) |
| Advanced topics (custom highlights, custom annotations, tap interactions, popovers, filter) | Android Advanced Configurations · iOS Advanced Configurations |
| Migration between major SDK versions | Android: 7 → 8 · iOS: 7 → 8 |
| Full API reference | BarcodeAr API (.NET Android) · BarcodeAr API (.NET iOS) |
Scandit publishes the .NET API reference per underlying TFM (
dotnet.androidanddotnet.ios). For MAUI projects, both pages apply — the cross-platformBarcodeAr/BarcodeArSettings/ provider / highlight / annotation surface is identical between them, but platform-specific notes are documented on the per-TFM page. The MAUI-specific surface (theScandit.DataCapture.Barcode.Ar.UI.Maui.BarcodeArViewXAML control, theUseScanditBarcode(c => c.AddBarcodeArView())builder extension, and theOnAppearing/OnDisappearinglifecycle 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, staticRecommendedCameraSettings,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 methodOnSessionUpdated(BarcodeAr, BarcodeArSession, IFrameData). (NoOnObservation*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), staticDefaultFeedback(defaults),Scanned/Tapped(Core.Common.Feedback.Feedback),Dispose.BarcodeArViewSettings—SoundEnabled(defaulttrue),HapticEnabled(defaulttrue),DefaultCameraPosition(defaultWorldFacing).HighlightForBarcodeTappedEventArgs—BarcodeAr,Barcode,Highlight(IBarcodeArHighlight).- Highlights:
IBarcodeArHighlight : IDisposable,IBarcodeArHighlightProvider.HighlightForBarcodeAsync(Barcode) → Task<IBarcodeArHighlight?>,BarcodeArRectangleHighlight(Barcode)withBarcode/Brush/Icon,BarcodeArCircleHighlight(Barcode, BarcodeArCircleHighlightPreset)withBarcode/Brush/Icon/Size,BarcodeArCircleHighlightPresetenum (Dot,Icon). - Annotations:
IBarcodeArAnnotation : IDisposable(declaresAnnotationTrigger),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.BarcodeArAnnotationTriggerenum: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),BarcodeArInfoAnnotationAnchorenum (Left,Right,Bottom,Top),BarcodeArInfoAnnotationWidthPresetenum (Small,Medium,Large),IBarcodeArInfoAnnotationListener(OnInfoAnnotationHeaderTapped,OnInfoAnnotationFooterTapped,OnInfoAnnotationLeftIconTapped,OnInfoAnnotationRightIconTapped,OnInfoAnnotationTapped). IBarcodeArPopoverAnnotationListener—OnPopoverButtonTapped,OnPopoverTapped.TrackedBarcode(inScandit.DataCapture.Barcode.Batch.Data) —Barcode,Identifier,Location.
MAUI-only surface (assembly
ScanditBarcodeCaptureMaui):Scandit.DataCapture.Barcode.MauiBuilderExtension.UseScanditBarcode(this MauiAppBuilder, Action<ScanditBarcodeCaptureMauiBuilder>)— the configure lambda exposesAddBarcodeArView()(plusAddBarcodeCountView,AddBarcodeFindView,AddBarcodePickView,AddSparkScanViewfor 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, defaultTopRight). - 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.
- Constructors:
- Not exposed in MAUI:
ShouldShowMacroModeControl,MacroModeControlPosition(iOS-only on the native binding; not surfaced as MAUI bindable properties).