TechStrap.Client.Maui 0.4.6

dotnet add package TechStrap.Client.Maui --version 0.4.6
                    
NuGet\Install-Package TechStrap.Client.Maui -Version 0.4.6
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="TechStrap.Client.Maui" Version="0.4.6" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="TechStrap.Client.Maui" Version="0.4.6" />
                    
Directory.Packages.props
<PackageReference Include="TechStrap.Client.Maui" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add TechStrap.Client.Maui --version 0.4.6
                    
#r "nuget: TechStrap.Client.Maui, 0.4.6"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package TechStrap.Client.Maui@0.4.6
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=TechStrap.Client.Maui&version=0.4.6
                    
Install as a Cake Addin
#tool nuget:?package=TechStrap.Client.Maui&version=0.4.6
                    
Install as a Cake Tool

TechStrap.Client.Maui

Device and app metadata capture and a submit-ticket helper for .NET MAUI apps, on top of TechStrap.Client. It reads the app version, platform, connectivity and (optionally) display and battery state through MAUI Essentials and attaches them to the ticket as metadata.

Install

dotnet add package TechStrap.Client.Maui

Register

Register the client and the helper in one call, usually in MauiProgram.cs. The first delegate configures the client (use a Public key; see Privacy), the second one switches on opt-in device context.

services.AddTechStrapMaui(
    client =>
    {
        client.BaseAddress = new Uri("https://support.example.com/");
        client.ApiKey = "<public key from configuration>";
    },
    context =>
    {
        context.IncludeDisplay = true;
    });

Submit

Resolve IMauiTicketSubmitter in a page or view model and send a MauiTicketDraft. The helper adds the device context to the ticket's metadata. Supply a stable idempotency key if you may retry the same ticket.

var submitter = services.GetRequiredService<IMauiTicketSubmitter>();
Result<SubmitTicketResponse> result = await submitter.SubmitAsync(
    new MauiTicketDraft("Crash on startup", "Steps: open the app, tap Sync.", "user@example.com")
    {
        IdempotencyKey = Guid.NewGuid().ToString("N"),
    },
    ct);

if (!result.IsSuccess)
{
    // result.Errors holds the code and message of each failure (see the error codes in TechStrap.Client).
}

A retry of the same ticket must reuse the same IdempotencyKey, or it can create a second ticket. The Result is the one TechStrap.Client returns, with the same error codes.

What is collected

Defaults are collected while IncludeDeviceContext is true (the default). The extras are collected only when the matching option is switched on. Each field is read on its own: a field that cannot be read is skipped silently.

Key Source Default or extra
app.name IAppInfo.Name Default
app.version IAppInfo.VersionString Default
app.build IAppInfo.BuildString Default
app.package IAppInfo.PackageName Default
os.platform IDeviceInfo.Platform Default
os.version IDeviceInfo.VersionString Default
device.manufacturer IDeviceInfo.Manufacturer Default
device.model IDeviceInfo.Model Default
device.idiom IDeviceInfo.Idiom Default
device.type IDeviceInfo.DeviceType Default
locale Current culture name Default
timezone Local time zone id Default
network.access IConnectivity.NetworkAccess (Android needs the ACCESS_NETWORK_STATE permission) Default
display.width IDeviceDisplay.MainDisplayInfo Extra (IncludeDisplay)
display.height IDeviceDisplay.MainDisplayInfo Extra (IncludeDisplay)
display.density IDeviceDisplay.MainDisplayInfo, invariant culture, for example "2.625" Extra (IncludeDisplay)
display.orientation IDeviceDisplay.MainDisplayInfo Extra (IncludeDisplay)
battery.state IBattery.State (Android needs BATTERY_STATS) Extra (IncludeBattery)
battery.level IBattery.ChargeLevel as a rounded whole percent; left out when the level is negative (Android needs BATTERY_STATS) Extra (IncludeBattery)

Android permissions: ACCESS_NETWORK_STATE for network.access, BATTERY_STATS for the battery fields. Without the permission the field is skipped, not an error.

iOS: display values may be missing when SubmitAsync runs off the UI thread (UIKit's thread check). IncludeDisplay is opt-in and a failure never crashes the app, so submit from the UI thread when you need them.

Privacy

The helper never collects advertising or device ids, location, contacts, an IP address or user names. The table above is the whole set, and IncludeDeviceContext = false turns it all off.

A key inside an app can be extracted by anyone who has the app, so use a Public key only and never a Trusted key. The metadata an app sends under a Public key is stored but flagged as untrusted on the server: treat it as a hint, not as proof.

To redact a value, set DeviceContextOptions.Redact, a Func<string, string, string?> called with the key and the value of each collected field. Return a changed value to replace it, or null to drop the field. The draft's own Metadata does not pass through it.

Limits

  • The collected keys (up to 19) count toward the 50 metadata keys a ticket may carry, so an app can rely on 31 of its own.
  • A key of the table above (or any key in TicketMetadataKeys) in the draft's Metadata is ignored: the collected value, or none, is sent.
  • A blank value is skipped, a value is cut to 1000 characters, a key is at most 64 characters.
  • A blank key or a key longer than 64 characters in the draft's Metadata also fails locally with metadata-invalid and nothing is sent.
  • More than 50 keys, or more than 16,000 characters of serialized metadata, fails locally with the code metadata-invalid and nothing is sent.

Compatibility

Targets plain net10.0 and depends on Microsoft.Maui.Essentials, not on the MAUI workload. Consumers need MAUI >= 10.0.0. The package is AOT-compatible. PHASE-11d adds attachments; the app owns picking and screenshot capture. Actual opening uses the platform implementation in your MAUI app.

More: https://github.com/Syntax-Circus/techstrap/blob/main/docs/development/CLIENT-SDK.md

Source and issues: https://github.com/Syntax-Circus/techstrap

Selected files

var attachment = selectedFile.ToTicketAttachment("text/plain");
var draft = new MauiTicketDraft("Sync failed", "See the attached log.", "user@example.com")
{
    IdempotencyKey = submissionKey,
    Attachments = new[] { attachment },
};
var result = await submitter.SubmitAsync(draft, ct);

selectedFile is your app's Microsoft.Maui.Storage.FileResult. Explicit MIME type is optional when the selection provides one. Keep the selection accessible and unchanged during retries; every attempt calls OpenReadAsync and the SDK disposes its stream. If access expires, select again and retry with the same key. The app owns permissions, picking and capture; nothing is captured automatically. Files are independent of device-metadata redaction.

Requires an attachment-capable server (PHASE-11d). Limits and errors match TechStrap.Client. MauiTicketDraft.Attachments is an optional init property, preserving existing constructor and deconstruction signatures. Portable tests cover adaptation and forwarding; verify actual opening on supported devices.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.4.6 0 10/18/2026
0.4.5 38 10/16/2026
0.4.4 36 10/16/2026
0.4.3 44 10/16/2026
0.4.2 87 10/10/2026
0.4.1 85 10/10/2026
0.4.0 82 10/10/2026
0.3.0-rc.1 53 10/10/2026
0.2.2 86 10/10/2026
0.2.1 86 10/9/2026
0.2.0 83 10/8/2026
0.1.0 80 10/8/2026