Shiny Client v4 - Windows Support, .NET 10, and a Ton of Improvements
It’s been a long road, but Shiny Client v4 is here. This is a major release that brings Windows support, moves to .NET 10, and packs in a significant number of fixes and enhancements across almost every module. Let’s dig in.
Windows Support
The headline feature of v4 — BluetoothLE, BLE Hosting, HTTP Transfers, and Locations all now work on Windows. Background support isn’t available yet on the Windows platform, but foreground scenarios are fully supported. This opens up a whole new set of use cases for desktop and kiosk applications built with .NET MAUI.
.NET 10
v4 enforces net10.0 target frameworks across the board. This is a breaking change, so make sure your projects are targeting .NET 10 before upgrading.
Configuration Extensions
HTTP Remote Configuration has been moved directly into Shiny.Extensions.Configuration. No more separate package — remote config is now a first-class citizen in the configuration stack.
Locations
Locations got a lot of love in this release, particularly on iOS where we’ve adopted the newer Apple APIs:
- iOS 18+ now uses
CLMonitorfor GPS — the modern replacement for the legacy location APIs - New geofence registration mechanics for iOS 17+ using the new
CLMonitorAPI - Geofence Manager RequestState now works correctly on the new CLMonitor API
- GPS background permission on iOS is now requested immediately instead of waiting
- GpsDelegate now has a boolean to detect if the device is stationary — useful for battery optimization and movement detection
- GpsDelegate batch fix — the base calculations could receive a batch and trigger multiple calculations. This is now a synchronized operation
- Android background location permission — no longer requests
ACCESS_BACKGROUND_LOCATIONunless realtime GPS with less than API 31 or standard background tracking is being used
HTTP Transfers
HTTP Transfers received some of the most impactful enhancements in v4:
- New transfer types — Transfers can now be
UploadMultipart,UploadRaw(body is raw bytes), orDownload. TheUploadRawtype is critical for sending directly to services like Azure Blob Storage - Azure Blob Storage helper —
AzureBlobStorageRequest.CreateForAzureBlobStoragestatic helper method makes it dead simple to queue uploads to Azure Blob Storage - New HttpTransferDelegate — allows you to set retries and detect denied authorization, enabling you to refresh your token and issue a new request
- Thread-safe HttpTransferMonitor — now uses a thread-safe
BindingList - Android file validation — uploads now verify the file exists before queuing, and download directories are checked before queuing
- iOS special character fix — filenames with special characters are now sent properly, along with improved form data upload
Push Notifications
- iOS raw notification data — you can now
#if IOSto get anAppleNotificationthat contains the rawNSDictionaryfor full access to the push payload - Azure Notification Hubs now supports template registrations for more flexible push scenarios
BluetoothLE
- ManagedScanResult now includes the full advertisement data, giving you access to native internals when you need them
- Improved manufacturer data parsing on Android
- BLE Delegate now reports proper status changes for adapter enabled state on Android
- Legacy scanning disabled on newer Android versions for better scan performance
- Multiple thread safety improvements for ManagedScan
- Peripheral cleanup on Android now matches iOS behavior for consistency
Jobs
- Android fix — successful jobs that run too long often had the Android completion handler already disposed. This has been resolved.
Upgrading
The main thing to watch for:
- Update your target frameworks to
net10.0 - If you were using the separate remote config package, switch to
Shiny.Extensions.Configuration - HTTP Transfer
Requesttypes have changed — review the newUploadMultipart,UploadRaw, andDownloadoptions
Check out the full release notes for every detail, and head over to our documentation to get started.
As always, feedback and contributions are welcome on GitHub.
comments powered by Disqus