Skip to content
Client v5: BLE, BLE Hosting, HTTP, Jobs - Linux, MacOS, & Blazor Support! Full AOT, RX on BLE only & MANY other features! Power up!

HTTP Transfers Releases

Fix Android
AddHttpTransfers<TDelegate>() now registers the platform HttpTransferManager on Android instead of the in-process HttpClientHttpTransferManager, so transfers run inside the dataSync foreground service (HttpTransferService) under OS ownership. This fixes two field issues: transfers stalling or being lost when the app is backgrounded or the process is killed (the service now redelivers its intent and re-arms whenever pending transfers exist), and a queue wedge where a transfer queued while the loop was draining stuck in Pending until the next Queue() call. Windows keeps the managed manager; iOS/Mac Catalyst are unchanged. Note: Android 14+ requires FOREGROUND_SERVICE_DATA_SYNC in the app manifest or the service start throws SecurityException.
Enhancement Android
New opt-in HttpTransferService.UseShortService = true promotes the Android foreground service as FOREGROUND_SERVICE_TYPE_SHORT_SERVICE (Android 14+) instead of dataSync. This drops the FOREGROUND_SERVICE_DATA_SYNC permission and the Google Play policy declaration dataSync requires, at the cost of a ~3-minute promotion window — a fit for burst-transfer apps and a bad fit for long downloads, hence opt-in. The default is unchanged, and Android 13-and-lower devices ignore the flag.
Fix Android
HttpTransferService now implements Service.onTimeout (both the API 34 shortService overload and the API 35 typed one). Android 15 put dataSync on a ~6-hour daily budget delivered through the same callback; an unhandled timeout previously produced an ANR (“A foreground service of … did not stop within its timeout”). The service now logs and stops cleanly on timeout, leaving pending transfers in the repository so the existing machinery re-arms the service on the next Queue() or app start.
Fix Android
Fixed a startup deadlock (Android ANR) that occurred when an app registered an IHttpTransferDelegate — such as one derived from the HttpTransferDelegate base class — that depends on IHttpTransferManager. The managed HttpClientHttpTransferProcess eagerly injected IEnumerable<IHttpTransferDelegate> in its constructor, forming a circular dependency (HttpClientHttpTransferManager → HttpClientHttpTransferProcess → delegates → IHttpTransferManager) that the DI container’s AddSingletonAsImplementedInterfaces factory forwarders hid from cycle detection, deadlocking the singleton root-cache lock during host build. Delegates are now resolved lazily from IServiceProvider at execution time (matching the Apple implementation), breaking the cycle. No public API changes.
Feature
IHttpTransferManager now exposes Pause(identifier) and Resume(identifier). Pause stops a transfer without cancelling it - the transfer stays queued and reports HttpTransferState.Paused. Downloads resume from where they left off (HTTP Range on the managed platforms, native NSUrlSessionTask.Suspend()/Resume() on iOS/Mac Catalyst). Uploads are stopped but not resumable, so resuming an upload restarts it from the beginning. A user-paused transfer is no longer auto-resumed on app relaunch.
Feature Blazor
Pause/Resume on Blazor WASM is best-effort: a queued transfer is marked paused so the Service Worker drain skips it, and resume re-queues it. An already in-flight Service Worker fetch() cannot be aborted (it runs to completion), and downloads are not resumable (whole-Blob fetch), so a resumed download restarts.
Enhancement
Resumable downloads are confirmed across all managed platforms (Android, Windows, Linux, macOS, plain .NET) via HTTP Range (206 Partial ContentFileMode.Append); iOS resumes natively through the background NSUrlSession. Partial files are preserved on pause and only deleted on cancel.
Enhancement
The managed transfer loop now obtains its HttpClient from IHttpClientFactory via a named client (HttpClientHttpTransferProcess.HttpClientName = "Shiny.Net.Http") instead of constructing one directly - consistent with Shiny.Data.Sync. Apps can configure it (timeouts, default headers, primary handler, Polly, etc.) with services.AddHttpClient("Shiny.Net.Http").ConfigureHttpClient(...) after registering transfers. Applies to Android, Windows, Linux, macOS, and plain .NET (iOS/Mac Catalyst use NSUrlSession).
Fix iOS
Background NSUrlSession is no longer nulled out when the in-flight transfer count reaches zero. Dropping the reference without invalidating could lead to a duplicate-identifier crash (A background URLSession with identifier X already exists!) the next time a transfer was queued, or silently swap the delegate instance the system held.
Fix iOS
IHandleEventsForBackgroundUrl.Handle now compares the incoming sessionIdentifier against the manager’s session identifier (returning false on mismatch) and forces the NSUrlSession to materialize before storing the completion handler, so the delegate is wired up before the OS redelivers background events after a launch.
Rx removed. IHttpTransferManager no longer exposes WhenUpdateReceived(), WatchCount(), or any other IObservable<T> members. Subscribe to the new C# events UpdateReceived and CountChanged instead. WatchTransfer(identifier) now returns Task<HttpTransferResult> directly (await it, no Subscribe). The HttpClient.Upload/Download foreground helpers return Task and accept an Action<TransferProgress>? onProgress callback.
Enhancement
Non-iOS HTTP transfer processes consolidated into a single managed HttpClientHttpTransferProcess. Android, Windows, Linux, macOS, and plain .NET now share one driver; the platform-specific Android HttpTransferProcess and Windows HttpTransferProcess have been removed.
Feature
Plain .NET (base TFM) support — Shiny.Net.Http now ships a managed HttpClientHttpTransferManager for Linux, macOS, and any non-iOS/Android/Windows .NET host. Backed by HttpClient + IConnectivity, the loop wakes immediately on connectivity changes and supports resumable downloads via HTTP Range requests (206 Partial ContentFileMode.Append). Uploads always restart on failure. A default JSON filesystem repository is registered automatically so queued transfers survive process restarts. Cancelled downloads clean up partial files on disk. Register with services.AddHttpClientTransfers<TDelegate>(), and supply an IConnectivity implementation (e.g. AddConnectivity() from Shiny.Core.Linux or Shiny.Core.Blazor).
Enhancement Android
Background transfers now run on the same unified managed HttpClient + IConnectivity loop as the other non-iOS platforms (hosted inside the existing foreground service), bringing resumable downloads via HTTP Range requests to Android.
Feature
New Shiny.Net.Http.Blazor package — background HTTP transfers for Blazor WebAssembly using the Service Worker Background Sync API. Queued transfers are persisted to IndexedDB and drained by a Service Worker via fetch() even while the browser tab is closed (where supported). Download bodies are stored back in IndexedDB; the C# manager reconciles results and fires IHttpTransferDelegate callbacks when the tab reopens. Registered via services.AddBlazorHttpTransfers<TDelegate>(). Ship the bundled ./_content/Shiny.Net.Http.Blazor/http-transfer-sw.js SW or importScripts it from your own service worker. v1 limitations: downloads are not resumable (SW fetches return a whole Blob); upload bodies are base64-bridged through JS interop; Background Sync is Chromium-only (Firefox/Safari fall back to foreground drain).
Enhancement
RemoteFileName property on AzureBlobStorageUploadRequest allows overriding the uploaded file name
Enhancement
Azure Blob Storage URI now includes the file path
Enhancement
AWS S3 support added
Feature
Windows support added (No Background Support at this time)
Fix
HttpTransferMonitor now uses thread safe BindingList
Fix Android
File uploads now check to make sure file exists before queuing and downloads directories are checked to ensure they exist before queuing
Fix iOS
Send filenames with special characters properly and improved form data upload
Enhancement
Transfers can now be UploadMultipart, UploadRaw (body is raw bytes), or Download - this necessary for sending directly to Azure Blob Storage
Enhancement
AzureBlobStorageRequest.CreateForAzureBlobStorage static helper method
Enhancement
New HttpTransferDelegate allows you to set retries and detect denied authorization allowing you to refresh your token and issue a new request
Enhancement iOS
Allow fine tuned control of the nsurlsessionconfiguration and the mutable native request on iOS via implementing (& registering) INativeConfigurator
Fix Android
Ensure HTTP transfer foreground service does start multiple times
Fix Android
Check for the presence of FOREGROUND_SERVICE_DATA_SYNC on API 34
Fix Android
More aggressive retrying of transfers in queue
Fix Android
Appropriate amount of wizardary applied to remove foreground service notifications
Fix
Race condition when subscribed to ShinySubject based subjects
Enhancement
Rewritten API makes it easier than ever to monitor metrics of your transfers
Enhancement Android
Now supports persistent progress notifications
Enhancement
You can pass AppleHttpTransferRequest & AndroidHttpTransferRequest to the HttpTransferManager to customize the native request