Guide for generating code that uses Shiny.NET HTTP Transfers for background uploads and downloads on iOS/Android
Background HTTP upload and download management for .NET MAUI (iOS & Android) using native platform transfer APIs.
Use this skill when the user needs to:
| Item | Value |
|---|---|
| NuGet | Shiny.Net.Http |
| Namespace | Shiny.Net.Http |
| Platforms | iOS, Android |
| DI Setup |
services.AddHttpTransfers<TDelegate>() |
The registration extension method lives in the Shiny namespace and is available on IServiceCollection.
In your MauiProgram.cs:
using Shiny;
builder.Services.AddHttpTransfers<MyHttpTransferDelegate>();
Create a class that implements IHttpTransferDelegate (or inherits from the abstract HttpTransferDelegate base class for built-in retry logic):
using Shiny.Net.Http;
public class MyHttpTransferDelegate : HttpTransferDelegate
{
public MyHttpTransferDelegate(
ILogger<MyHttpTransferDelegate> logger,
IHttpTransferManager manager
) : base(logger, manager, maxErrorRetries: 3) { }
public override Task OnCompleted(HttpTransferRequest request)
{
// Handle successful transfer completion
return Task.CompletedTask;
}
// Optional: override for 401 handling
protected override Task<HttpTransferRequest?> OnAuthorizationFailed(
HttpTransferRequest request, int retries)
{
// Return a new request with refreshed auth headers, or null to cancel
return Task.FromResult<HttpTransferRequest?>(null);
}
}
On Android, the delegate must also implement IAndroidForegroundServiceDelegate:
#if ANDROID
public partial class MyHttpTransferDelegate : IAndroidForegroundServiceDelegate
{
public void Configure(AndroidX.Core.App.NotificationCompat.Builder builder)
{
builder
.SetContentTitle("File Transfer")
.SetContentText("Transferring files in the background");
}
}
#endif
When generating code that uses Shiny HTTP Transfers, follow these conventions:
IHttpTransferManager via dependency injection; never instantiate directly.HttpTransferRequest requires 4 positional parameters: Identifier, Uri, TransferType, LocalFilePath:
var request = new HttpTransferRequest(
"my-download",
"https://example.com/file.zip",
TransferType.Download,
Path.Combine(FileSystem.AppDataDirectory, "file.zip")
);
await transferManager.Queue(request);
Identifier for each HttpTransferRequest so individual transfers can be tracked and cancelled.LocalFilePath points to an existing file before queuing.UseMeteredConnection = false to restrict large transfers to Wi-Fi only.TransferType: UploadMultipart for form-based uploads, UploadRaw for streaming the file body directly, Download for downloads.WhenUpdateReceived() for a global stream of all transfer updates.WatchTransfer(identifier) extension method to observe a single transfer that completes or errors.WatchCount() to reactively display the number of active transfers.HttpTransferMonitor -- call Start() to begin monitoring and bind to the Transfers collection of HttpTransferObject items. These implement INotifyPropertyChanged.TransferHttpContent.FromJson(obj) to attach a JSON body to an upload.TransferHttpContent.FromFormData(...) to attach form-encoded data.AzureBlobStorageUploadRequest for Azure Blob Storage uploads -- call .WithBlobContainer(tenant, container) or .WithCustomUri(uri), configure auth via .WithSasToken() or .WithSharedKeyAuthorization(), then call .Build() to get an HttpTransferRequest.AppleHttpTransferRequest (inherits HttpTransferRequest) when Apple-specific options are needed (e.g., AllowsConstrainedNetworkAccess, AllowsCellularAccess, AssumesHttp3Capable).HttpClient extension methods Upload(...) and Download(...) which return IObservable<TransferProgress> with real-time progress.INativeConfigurator implementation to customize NSUrlSessionConfiguration and NSMutableUrlRequest objects before they are sent.HttpTransferDelegate provides built-in retry and 401-handling logic. Only implement IHttpTransferDelegate directly if you need full control.request.AssertValid() to check the request is well-formed before calling Queue().HttpTransferMonitor to UI, pass a scheduler (e.g., RxApp.MainThreadScheduler or SynchronizationContext.Current) to Start().HttpTransferMonitor implements IDisposable. Dispose it when the page or view model is torn down.UseMeteredConnection = false for large files so the system waits for an unmetered (Wi-Fi) connection.