Client Releases
4.0.0 - TBD
Section titled “4.0.0 - TBD”    Fix   Android  
Successful jobs that run too long often tend to have Android completion already disposed
  BREAKING    Chore    
Target frameworks now enforce net9.0-ios18.0 and net9-android35.0
 Configuration Extensions
Section titled “Configuration Extensions”   Enhancement      
HTTP Remote configuration has been moved directly into Shiny.Extensions.Configuration
 Locations
Section titled “Locations”    Fix   Android  
Don’t request ACCESS_BACKGROUND_LOCATION unless realtime GPS request and less than API level 31 OR standard location background tracking is being requested
     Fix     
The base GpsDelegate calculations could receive a batch and trigger multiple calculations.  This has been made into a synchronized operation
    Enhancement      
GpsDelegate now has a boolean to detect if stationary
    Enhancement   iOS   
iOS 18+ now uses CLMonitor for GPS
    Enhancement      
New geofence registration mechanics for iOS 17+
    Enhancement   iOS   
You can now IFDEF IOS to get an AppleNotification that contains the raw NSDictionary
    Enhancement      
Azure Notification Hubs now allow template registrations
 HTTP Transfers
Section titled “HTTP Transfers”    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
 Beacons
Section titled “Beacons”    Fix     
ManagedScan now uses thread safe BindingList
 BluetoothLE
Section titled “BluetoothLE”   Enhancement      
ManagedScanResult is now passed with the full advertisement data in case user needs access to native internals
    Enhancement    Android  
Improved manufacturer data parsing in ad data
     Fix     
ManagedScan now uses thread safe BindingList
     Fix   Android  
BLE scan now disables legacy scanning for new android versions
     Fix   Android  
BLE Delegate was not responding with Available when adapter was reenabled
 3.3.4 - April 22, 2024
Section titled “3.3.4 - April 22, 2024”BluetoothLE
Section titled “BluetoothLE”    Fix   Android  
Disable legacy scanner on newer Android versions
     Fix   Android  
ManagedScanResult now has a property for the raw advertisement data
     Fix   Android  
Additional thread safety on managed scan events
 3.3.3 - April 8, 2024
Section titled “3.3.3 - April 8, 2024”- 
Fix AndroidOnEntry intent action was not being defaulted if not set
- 
Enhancement AndroidOnReceived now sends an AndroidPushNotification which gives you access to the native message as well as helper methods to send the notification if in the foreground
public class MyPushDelegate : IPushDelegate{    public void OnReceived(PushNotification notification)    {#if ANDROID        var android = (AndroidPushNotification)notification;        // android.NativeMessage;        var builder = android.CreateNotificationBuilder();        android.SendNotification(1, builder);#endif    }}3.3.2 - March 29, 2024
Section titled “3.3.2 - March 29, 2024”- 
Enhancement AndroidAbility to set a custom push intent instead of the Shiny static string
- 
EnhancementEnsure OnRegistered is always called
3.3.1 - March 26, 2024
Section titled “3.3.1 - March 26, 2024”- 
Fix AndroidIPushDelegate.OnRegistered was being called twice during IPushManager.RequestAccess calls
- 
Fix AndroidIPushDelegate.OnRegistered was not passing provider token
3.3.0 - March 18, 2024
Section titled “3.3.0 - March 18, 2024”
- 
FixObservableList index out of range
HTTP Transfers
Section titled “HTTP Transfers”- 
Enhancement iOSAllow fine tuned control of the nsurlsessionconfiguration and the mutable native request on iOS via implementing (& registering) INativeConfigurator
BluetoothLE
Section titled “BluetoothLE”- 
Fix AndroidIBleDelegate now reports adapter state properly
- 
Fix AndroidUnsubscribing from a connection may be temporarily unstable if sub/unsub is performed rapidly
- 
Fix AndroidReduce logging severity for characteristic events
- 
FixCharacteristic extension (GetAllCharacteristics) was only returning characteristics from last service
Local Notifications
Section titled “Local Notifications”- 
BREAKING EnhancementPushDelegate now contains an OnUnRegistered event
- 
BREAKING EnhancementPushDelegate.OnTokenRefreshed has been renamed to OnNewToken to be more concise as to its purpose
- 
Enhancement AndroidFirebase will not attempt to initialize if it done by other libraries like Firebase Crashlytics
- 
EnhancementMicrosoft.Azure.NotificationHubs updated to 4.2.0 for FCMv1 parameter which is set as default now
- 
EnhancementIPushManager now access NativeRegistrationToken which is useful for debugging purposes
Speech Recognition
Section titled “Speech Recognition”- 
BREAKING EnhancementThis module is now deprecated since Community Toolkit also has an offering in this space
AppCenter Logging
Section titled “AppCenter Logging”- 
BREAKING EnhancementAppCenter has officially announced they are shutting down in 2025, so this library has been removed
3.2.4 - February 3, 2024
Section titled “3.2.4 - February 3, 2024”- 
Enhancement iOSIPushManager.RequestAccess now return AccessState.Unsupported on the simulator instead of letting an exception be thrown
- 
EnhancementOld extensions for tags added back to IPushManager
3.2.3 - January 18, 2024
Section titled “3.2.3 - January 18, 2024”HTTP Transfers
Section titled “HTTP Transfers”- 
Fix AndroidEnsure HTTP transfer foreground service does start multiple times
- 
Fix AndroidCheck for the presence of FOREGROUND_SERVICE_DATA_SYNC on API 34
- 
Enhancement AndroidAbility to configure intent action during registration
3.2.2 - January 3, 2024
Section titled “3.2.2 - January 3, 2024”Locations
Section titled “Locations”- 
Enhancement AndroidReplace deprecated location request used in Android GPS request
Local Notifications
Section titled “Local Notifications”- 
FixCrash tapping local notification on iOS earlier than 16 when accessing FilterCriteria
Push - Azure Notification Hubs
Section titled “Push - Azure Notification Hubs”3.2.1 - December 19, 2023
Section titled “3.2.1 - December 19, 2023”   Enhancement    Android  
Use ServiceCompat to start and stop android foreground service
 Locations
Section titled “Locations”    Fix   Android  
Ensure post_notifications permissions is also requested
 Configuration
Section titled “Configuration”   Enhancement      
You can now pass environment variable to configuration that will allow to use file name likes appsettings.apple.debug.json
 AppCenter Logging
Section titled “AppCenter Logging”   Enhancement      
Support for scopes
 3.2.0 - December 8, 2023
Section titled “3.2.0 - December 8, 2023” BREAKING  Enhancement      
Moving from .NET 7 to .NET 8
  BREAKING  Enhancement      
Target moved from monoandroid 12 to monoandroid 13 classic
    Enhancement      
BLE, BLE Hosting, GPS, & Geofencing managers now allow you to check current permissions without requesting
 Locations
Section titled “Locations”    Fix   Android  
GPS won’t always auto-restart post reboot
 BLE Hosting
Section titled “BLE Hosting”    Fix   Android  
Managed BLE Services won’t always auto-restart post reboot
 3.1.2 - November 7, 2023
Section titled “3.1.2 - November 7, 2023”   Enhancement    Android  
No longer emits notification for “foreground” service on older Android versions
 Local Notifications
Section titled “Local Notifications”   Enhancement    Android  
Using AndroidNotification, you can now set the android specific Category
     Fix     
Base Job was not calculating runtime difference properly
 3.1.1 - November 1, 2023
Section titled “3.1.1 - November 1, 2023”Locations
Section titled “Locations”    Fix   Android  
GPS Foreground Service start/stop fix
 Local Notifications
Section titled “Local Notifications”    Fix   Android  
Listen to activity.OnCreate intents
 3.1.0 - October 26, 2023
Section titled “3.1.0 - October 26, 2023”   Enhancement    Android  
Android OnCreate events are now hookable through standard lifecycle interfaces
     Fix     
Connectivity.WhenInternetStatusChanged will now prevent repeated firing if the value hasn’t changed
 HTTP Transfers
Section titled “HTTP Transfers”    Fix   Android  
More aggressive retrying of transfers in queue
     Fix   Android  
Appropriate amount of wizardary applied to remove foreground service notifications
    Enhancement   iOS   
IPushDelegate can now add IApplePushDelegate on Apple platforms to manage certain specific return values (UIBackgroundFetchResult & UIPresentationOptions) - Example below
     Fix   Android  
OnEntry now responds to OnCreate for new activities
 #if IOSusing UIKit;using UserNotifications;#endif
public partial class MyPushDelegate : Shiny.Push.IPushDelegate{    // .. left empty for brevity}
#if IOSpublic partial class MyPushDelegate : Shiny.Push.IApplePushDelegate{    // this is executed only in the foreground    public UNNotificationPresentationOptions? GetPresentationOptions(PushNotification notification)    {        return UNNotificationPresentationOptions.Alert;    }
    // executed for all content-available notifications    public UIBackgroundFetchResult? GetFetchResult(PushNotification notification)    {        return UIBackgroundFetchResult.NewData;    }}#endif3.0.1 - September 19, 2023
Section titled “3.0.1 - September 19, 2023”    Fix     
Race condition when subscribed to ShinySubject based subjects (HTTP Transfers)
     Fix  iOS   
Provider push token is now returned by PushManager.RequestAccess instead of native token
 3.0.0 - September 5, 2023
Section titled “3.0.0 - September 5, 2023”- Shiny.Hosting.Maui initial integration package created (Example how to setup shown below)
 BREAKING        
Don’t use the Shiny package any longer.  It contains all of the source generator stuff that is no longer needed as part of v3.
  BREAKING        
IShinyStartup is gone - we now have a new HostBuilder pattern to allow classic to align with MAUI/NET6.  Use extensions methods to build on this for classic/non-MAUI setups
  BREAKING        
IShinyModule is gone - use extensions methods instead
    Enhancement      
IShinyStartupTask and INotifyPropertyChanged persistent services are now registered using the service collection extension .AddShinyService during your bootstrapping
    Enhancement      
New hosting model that is meant to carry Shiny forward to other platforms and improve on the original ShinyHost model.  It also allows us to move to other platforms outside of MAUI
    Enhancement      
New internal lifecycle processor
    Enhancement      
Any Shiny library that uses an Android foreground service (Beacon Monitoring, GPS, HTTP Transfers) now has a new mechanism that allows for FULL control over the persistent notification
    Enhancement      
Repositories and other “fatty” code has been moved out of Shiny.Core where possible
 Configuration
Section titled “Configuration”- Configuration is now part of the core library
EnhancementNow loads platform specific json assets like appsettings.android.json, appsettings.ios.json, appsettings.maccatalyst.json, & appsettings.apple.json
Notifications
Section titled “Notifications”   Enhancement    Android  
Android 13 Support for new POST_NOTIFICATION permissions
    Enhancement      
OS specific configuration for Android and iOS
    Enhancement      
Ability to customize actual native notification before it is sent/queued
    Enhancement      
Improved sound customization via new channel flag - Channel.Sound = ChannelSound.Custom|High|Default|None
    Enhancement    Android  
Android 13 Support for new POST_NOTIFICATION permissions
    Enhancement      
Now works on new xplat lifecycle management from Core
    Enhancement      
nternally rewritten to make architecture easier going forward - firebase, azure, etc all become plugins on top of native instead of full implementations
 Locations
Section titled “Locations”   Enhancement      
You can now control location manager properties like ActivityType and ShowsBackgroundLocationIndicator via AppleLocationConfiguration service
    Enhancement    Android  
To configure the foreground service notification, your IGpsDelegate can also implement IAndroidForegroundServiceDelegate with ANDROID preprocessor directives
 BluetoothLE
Section titled “BluetoothLE”   Enhancement    Android  
RequestAccess(bool connect) now allows you to additionally request access to GATT connections (defaults to true).  This allows Shiny to use Android API 31 properly.  It will always ask for scan permissions.
  BREAKING      Android  
Adapter control is no longer support through the Shiny API, but you do have raw access to the native adapter if needed
  BREAKING        
Managed scan now require you to set scan configuration values in Start instead of the constructor & property setters
  BREAKING        
The API has been simplified and no longer requires you to maintain (and refresh) instances of services/characteristics/descriptors
  BREAKING        
Managed peripheral is now gone.  This functionality is now built into the main API.
  BREAKING  Enhancement    Android  
Android MTU requests are moved to the IPeripheral.Connect(AndroidConnectionConfig)
 BluetoothLE Hosting
Section titled “BluetoothLE Hosting”   Enhancement    Android  
 RequestAccess now exists - you can specifically target your permissions to take advantage of Android API 31
    Enhancement      
All characteristic hooks are now async
    Enhancement      
New “managed” model for characteristics
    Enhancement      
Advertise iBeacons is now supported - it exists here instead of Shiny.Beacons because all of the advertising code is here
 HTTP Transfers
Section titled “HTTP Transfers”   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
 Beacons
Section titled “Beacons”   Enhancement    Android  
To configure the foreground service notification on beacon monitoring, your IBeaconMonitorDelegate can also implement IAndroidForegroundServiceDelegate with ANDROID preprocessor directives
  BREAKING     iOS   
We no longer support the background fetch style (old) job management - only bgtasks will be used going forward
 Libraries that will not move to v3
Section titled “Libraries that will not move to v3”- Shiny.NFC
- Shiny.Sensors
MAUI Setup
Section titled “MAUI Setup”- Install Shiny.Hosting.Maui
- Install the nuget package(s) shown above each comment below to get that functionality
- Ensure you add UseShiny as shown below
using Shiny;
namespace Sample;
public static class MauiProgram{    public static MauiApp CreateMauiApp()    {        var builder = MauiApp            .CreateBuilder()            .UseMauiApp<App>()            // THIS IS REQUIRED TO BE DONE FOR SHINY TO RUN            .UseShiny();
        // shiny.locations        builder.Services.AddGps<SampleGpsDelegate>();        builder.Services.AddGeofencing<SampleGeofenceDelegate>();        builder.Services.AddMotionActivity();
        // shiny.notifications        builder.Services.AddNotifications<SampleNotificationDelegate>();
        // shiny.bluetoothle        builder.Services.AddBluetoothLE<SampleBleDelegate>();
        // shiny.bluetoothle.hosting        builder.Services.AddBluetoothLeHosting();
        // shiny.beacons        builder.Services.AddBeaconRanging();        builder.Services.AddBeaconMonitoring<SampleBeaconMonitorDelegate>();
        // shiny.net.http        builder.Services.AddHttpTransfers<SampleHttpTransferDelegate>();
        // shiny.speechrecognition        builder.Services.AddSpeechRecognition();
        // shiny.push        builder.Services.AddPush<SamplePushDelegate>();
        // shiny.jobs        builder.Services.AddJob(typeof(SampleJob));        builder.Services.AddJobs(); // not required if using above
        // shiny.core - startup task & persistent service registration        builder.Services.AddShinyService<StartupTask>();
        // shiny.push        builder.Services.AddPush<SamplePushDelegate>();
        // or shiny.push.firebasemessaging        builder.Services.AddPushFirebaseMessaging<SamplePushDelegate>();
        // or shiny.push.azurenotificationhubs        builder.Services.AddPushAzureNotificationHubs<SamplePushDelegate>();
        return builder.Build();    }}New Android Foreground Service Notification Customization
Section titled “New Android Foreground Service Notification Customization”// ex. this is using a GPS background delegatepublic class MyGpsDelegate : Shiny.Locations.IGpsDelegate#if ANDROID    , Shiny.IAndroidForegroundServiceDelegate#endif{    // .. implementation details left out for brevity
#if ANDROID    public void Configure(Android.NotificationCompat.Builder builder)    {        var builder = new NotificationCompat.Builder(this.Context, "gps");        builder.SetContentTitle("GPS");        builder.SetContentText("GPS is running in the background");        builder.SetSmallIcon(Resource.Drawable.ic_launcher_foreground);        builder.SetPriority((int)NotificationCompat.PriorityHigh);        builder.SetCategory(NotificationCompat.CategoryService);    }#endif}