From 69a9a382d4c4132ca01b4dbd8ad4b1103cbe00fa Mon Sep 17 00:00:00 2001 From: Fadi George Date: Fri, 26 Jun 2026 11:48:41 -0700 Subject: [PATCH 1/9] refactor(core): enable nullable reference types --- ...gnalSDK.DotNet.Android.Core.Binding.csproj | 1 + .../AndroidLiveActivitiesManager.cs | 2 +- .../AndroidNotificationsManager.cs | 44 ++++----- .../AndroidOneSignal.cs | 17 ++-- .../AndroidUserManager.cs | 44 ++++----- .../OneSignalSDK.DotNet.Android.csproj | 1 + .../Utilities/ToNativeConversion.cs | 4 + OneSignalSDK.DotNet.Core/IOneSignal.cs | 2 +- .../InAppMessages/InAppMessageClickResult.cs | 8 +- .../Internal/Utilities/Json.cs | 8 +- .../Internal/Utilities/WrapperSDK.cs | 2 +- .../LiveActivities/ILiveActivities.cs | 2 +- .../Notifications/DisplayableNotification.cs | 44 ++++----- .../Notifications/Notification.cs | 96 +++++++++---------- .../Notifications/NotificationClickResult.cs | 6 +- .../OneSignalSDK.DotNet.iOS.Binding.csproj | 1 + .../OneSignalSDK.DotNet.iOS.csproj | 1 + .../Utilities/FromNativeConversion.cs | 52 +++++----- .../Utilities/ToNativeConversion.cs | 29 +++--- .../iOSLiveActivitiesManager.cs | 8 +- .../iOSNotificationsManager.cs | 58 +++++------ OneSignalSDK.DotNet.iOS/iOSUserManager.cs | 32 +++---- OneSignalSDK.DotNet/OneSignal.cs | 2 +- examples/demo-no-location/MainPage.xaml.cs | 14 +-- .../demo-no-location/demo-no-location.csproj | 2 +- examples/demo/Controls/DialogInputHelper.cs | 1 - .../NotificationServiceExtension.csproj | 3 +- examples/demo/demo.csproj | 2 +- 28 files changed, 243 insertions(+), 243 deletions(-) diff --git a/OneSignalSDK.DotNet.Android.Core.Binding/OneSignalSDK.DotNet.Android.Core.Binding.csproj b/OneSignalSDK.DotNet.Android.Core.Binding/OneSignalSDK.DotNet.Android.Core.Binding.csproj index 751d03dc..11839c8f 100644 --- a/OneSignalSDK.DotNet.Android.Core.Binding/OneSignalSDK.DotNet.Android.Core.Binding.csproj +++ b/OneSignalSDK.DotNet.Android.Core.Binding/OneSignalSDK.DotNet.Android.Core.Binding.csproj @@ -15,6 +15,7 @@ >28.0.3 class-parse + $(NoWarn);CS0618 true diff --git a/OneSignalSDK.DotNet.Android/AndroidLiveActivitiesManager.cs b/OneSignalSDK.DotNet.Android/AndroidLiveActivitiesManager.cs index 0366fdad..82640636 100644 --- a/OneSignalSDK.DotNet.Android/AndroidLiveActivitiesManager.cs +++ b/OneSignalSDK.DotNet.Android/AndroidLiveActivitiesManager.cs @@ -31,7 +31,7 @@ public void SetPushToStartToken(string activityType, string token) Console.WriteLine("OneSignal: SetPushToStartToken is available on iOS only"); } - public void SetupDefault(LiveActivitySetupOptions options = null) + public void SetupDefault(LiveActivitySetupOptions? options = null) { Console.WriteLine("OneSignal: SetupDefault is available on iOS only"); } diff --git a/OneSignalSDK.DotNet.Android/AndroidNotificationsManager.cs b/OneSignalSDK.DotNet.Android/AndroidNotificationsManager.cs index 6c74b3c3..992aa39e 100644 --- a/OneSignalSDK.DotNet.Android/AndroidNotificationsManager.cs +++ b/OneSignalSDK.DotNet.Android/AndroidNotificationsManager.cs @@ -190,38 +190,38 @@ as IDictionary public AndroidDisplayableNotification( Com.OneSignal.Android.Notifications.IDisplayableNotification displayableNotification, - string title, - string body, - string sound, - string launchUrl, + string? title, + string? body, + string? sound, + string? launchUrl, IList actionButtons, IDictionary additionalData, - string notificationId, - IList groupedNotifications = null, - BackgroundImageLayout backgroundImageLayout = null, - string templateId = null, - string templateName = null, - string groupKey = null, - string groupMessage = null, - string ledColor = null, + string? notificationId, + IList? groupedNotifications = null, + BackgroundImageLayout? backgroundImageLayout = null, + string? templateId = null, + string? templateName = null, + string? groupKey = null, + string? groupMessage = null, + string? ledColor = null, int? priority = null, - string smallIcon = null, - string largeIcon = null, - string bigPicture = null, - string collapseId = null, - string fromProjectNumber = null, - string smallIconAccentColor = null, + string? smallIcon = null, + string? largeIcon = null, + string? bigPicture = null, + string? collapseId = null, + string? fromProjectNumber = null, + string? smallIconAccentColor = null, int? lockScreenVisibility = null, int? androidNotificationId = null, int? badge = null, int? badgeIncrement = null, - string category = null, - string threadId = null, - string subtitle = null, + string? category = null, + string? threadId = null, + string? subtitle = null, float? relevanceScore = null, bool? mutableContent = null, bool? contentAvailable = null, - string interruptionLevel = null + string? interruptionLevel = null ) : base( title, diff --git a/OneSignalSDK.DotNet.Android/AndroidOneSignal.cs b/OneSignalSDK.DotNet.Android/AndroidOneSignal.cs index 78d46486..d65a9c47 100644 --- a/OneSignalSDK.DotNet.Android/AndroidOneSignal.cs +++ b/OneSignalSDK.DotNet.Android/AndroidOneSignal.cs @@ -15,14 +15,15 @@ namespace OneSignalSDK.DotNet.Android; public class AndroidOneSignal : IOneSignal { - /** These static references are not used, but we need to reference at least one class - * in the binding projects that are otherwised not referenced. If we did *not*, then - * the binding DLLs will not be included in the output bin directory. - */ - - private static Com.OneSignal.Android.InAppMessages.IInAppMessagesManager InAppMessagesBuildConfig; - private static Com.OneSignal.Android.Notifications.INotificationsManager NotificationsBuildConfig; - private static Com.OneSignal.Android.Location.ILocationManager LocationBuildConfig; + /** Retain binding assembly references so optional module DLLs are copied to output. */ +#pragma warning disable CS0169 + private static readonly Type[] BindingRetentionTypes = + { + typeof(Com.OneSignal.Android.InAppMessages.IInAppMessagesManager), + typeof(Com.OneSignal.Android.Notifications.INotificationsManager), + typeof(Com.OneSignal.Android.Location.ILocationManager), + }; +#pragma warning restore CS0169 public IUserManager User { get; } = new AndroidUserManager(); diff --git a/OneSignalSDK.DotNet.Android/AndroidUserManager.cs b/OneSignalSDK.DotNet.Android/AndroidUserManager.cs index 93e27649..5b4c4649 100644 --- a/OneSignalSDK.DotNet.Android/AndroidUserManager.cs +++ b/OneSignalSDK.DotNet.Android/AndroidUserManager.cs @@ -25,25 +25,11 @@ public void Initialize() ((AndroidPushSubscription)PushSubscription).Initialize(); } - public string OneSignalId - { - get - { - string id = OneSignalNative.User.OnesignalId; - return string.IsNullOrEmpty(id) ? null : id; - } - } + public string OneSignalId => OneSignalNative.User.OnesignalId ?? string.Empty; - public string ExternalId - { - get - { - string id = OneSignalNative.User.ExternalId; - return string.IsNullOrEmpty(id) ? null : id; - } - } + public string ExternalId => OneSignalNative.User.ExternalId ?? string.Empty; - public event EventHandler Changed; + public event EventHandler? Changed; public void AddAlias(string label, string id) => OneSignalNative.User.AddAlias(label, id); @@ -71,11 +57,15 @@ public void RemoveAliases(params string[] labels) => public void RemoveTags(params string[] keys) => OneSignalNative.User.RemoveTags(keys); - public IDictionary GetTags() => OneSignalNative.User.Tags; + public IDictionary GetTags() => + OneSignalNative.User.Tags ?? new Dictionary(); public void TrackEvent(string name, IDictionary? properties = null) { - OneSignalNative.User.TrackEvent(name, ToNativeConversion.DictToJavaMap(properties)); + OneSignalNative.User.TrackEvent( + name, + ToNativeConversion.DictToJavaMap(properties)! + ); } private sealed class InternalUserState : IUserState @@ -84,10 +74,10 @@ private sealed class InternalUserState : IUserState public string ExternalId { get; } - public InternalUserState(string onesignalId, string externalId) + public InternalUserState(string? onesignalId, string? externalId) { - OneSignalId = onesignalId; - ExternalId = externalId; + OneSignalId = onesignalId ?? string.Empty; + ExternalId = externalId ?? string.Empty; } } @@ -116,11 +106,11 @@ public void OnUserStateChange(Com.OneSignal.Android.User.State.UserChangedState public class AndroidPushSubscription : IPushSubscription { - public string Token => OneSignalNative.User.PushSubscription.Token; + public string Token => OneSignalNative.User.PushSubscription.Token ?? string.Empty; public bool OptedIn => OneSignalNative.User.PushSubscription.OptedIn; - public string Id => OneSignalNative.User.PushSubscription.Id; + public string Id => OneSignalNative.User.PushSubscription.Id ?? string.Empty; public event EventHandler? Changed; @@ -150,11 +140,11 @@ private sealed class InternalPushSubscriptionState : IPushSubscriptionState public bool OptedIn { get; } - public InternalPushSubscriptionState(string token, bool optedIn, string id) + public InternalPushSubscriptionState(string? token, bool optedIn, string? id) { - Token = token; + Token = token ?? string.Empty; OptedIn = optedIn; - Id = id; + Id = id ?? string.Empty; } } diff --git a/OneSignalSDK.DotNet.Android/OneSignalSDK.DotNet.Android.csproj b/OneSignalSDK.DotNet.Android/OneSignalSDK.DotNet.Android.csproj index a461b69e..78605e20 100644 --- a/OneSignalSDK.DotNet.Android/OneSignalSDK.DotNet.Android.csproj +++ b/OneSignalSDK.DotNet.Android/OneSignalSDK.DotNet.Android.csproj @@ -8,6 +8,7 @@ Library 21 enable + enable OneSignalSDK.DotNet.Android OneSignalSDK.DotNet.Android Resources diff --git a/OneSignalSDK.DotNet.Android/Utilities/ToNativeConversion.cs b/OneSignalSDK.DotNet.Android/Utilities/ToNativeConversion.cs index fad341f5..1caf397d 100644 --- a/OneSignalSDK.DotNet.Android/Utilities/ToNativeConversion.cs +++ b/OneSignalSDK.DotNet.Android/Utilities/ToNativeConversion.cs @@ -3,6 +3,8 @@ namespace OneSignalSDK.DotNet.Android.Utilities; +#pragma warning disable CA1422 // Java.Lang boxed types remain required for HashMap/ArrayList interop on minSdk 21. + /// /// Translation functions when translating from .NET SDK class types to their respective native SDK class types. /// @@ -171,3 +173,5 @@ public static Com.OneSignal.Android.Debug.LogLevel ToLogLevel(LogLevel logLevel) return javaList; } } + +#pragma warning restore CA1422 diff --git a/OneSignalSDK.DotNet.Core/IOneSignal.cs b/OneSignalSDK.DotNet.Core/IOneSignal.cs index 5929f8fb..3e9a265f 100644 --- a/OneSignalSDK.DotNet.Core/IOneSignal.cs +++ b/OneSignalSDK.DotNet.Core/IOneSignal.cs @@ -102,7 +102,7 @@ public interface IOneSignal /// login operation.Required when identity verification has been enabled. See /// Identity Verification | OneSignal /// - void Login(String externalId, String jwtBearerToken = null); + void Login(String externalId, String? jwtBearerToken = null); /// /// Logout the user previously logged in via . The diff --git a/OneSignalSDK.DotNet.Core/InAppMessages/InAppMessageClickResult.cs b/OneSignalSDK.DotNet.Core/InAppMessages/InAppMessageClickResult.cs index 721cae73..12b38c72 100644 --- a/OneSignalSDK.DotNet.Core/InAppMessages/InAppMessageClickResult.cs +++ b/OneSignalSDK.DotNet.Core/InAppMessages/InAppMessageClickResult.cs @@ -12,12 +12,12 @@ public class InAppMessageClickResult /// /// An optional action id defined for the action element /// - public string ActionId { get; } + public string? ActionId { get; } /// /// An optional URL that opens when the action takes place /// - public string Url { get; } + public string? Url { get; } /// /// Optional where the url will be launched @@ -30,8 +30,8 @@ public class InAppMessageClickResult public bool ClosingMessage { get; } public InAppMessageClickResult( - string actionId, - string url, + string? actionId, + string? url, InAppMessageActionUrlType urlTarget, bool closingMessage ) diff --git a/OneSignalSDK.DotNet.Core/Internal/Utilities/Json.cs b/OneSignalSDK.DotNet.Core/Internal/Utilities/Json.cs index 59d548d2..ebef0136 100644 --- a/OneSignalSDK.DotNet.Core/Internal/Utilities/Json.cs +++ b/OneSignalSDK.DotNet.Core/Internal/Utilities/Json.cs @@ -13,7 +13,7 @@ public static class Json /// /// A JSON string. /// An List<object>, a Dictionary<string, object>, a double, an integer,a string, null, true, or false - public static object Deserialize(string json) + public static object? Deserialize(string? json) { // save the string for debug information if (json == null) @@ -22,6 +22,7 @@ public static object Deserialize(string json) return Parser.Parse(json); } + #nullable disable sealed class Parser : IDisposable { const string WORD_BREAK = "{}[],:\""; @@ -362,6 +363,7 @@ TOKEN NextToken } } } + #nullable restore /// /// Converts a IDictionary / IList object or a simple type (string, int, etc.) into a JSON string @@ -373,6 +375,7 @@ public static string Serialize(object obj) return Serializer.Serialize(obj); } + #nullable disable sealed class Serializer { StringBuilder builder; @@ -393,9 +396,9 @@ public static string Serialize(object obj) void SerializeValue(object value) { + string asStr; IList asList; IDictionary asDict; - string asStr; if (value == null) { @@ -552,5 +555,6 @@ value is int } } } + #nullable restore } } diff --git a/OneSignalSDK.DotNet.Core/Internal/Utilities/WrapperSDK.cs b/OneSignalSDK.DotNet.Core/Internal/Utilities/WrapperSDK.cs index 4c808f0d..3d69a145 100644 --- a/OneSignalSDK.DotNet.Core/Internal/Utilities/WrapperSDK.cs +++ b/OneSignalSDK.DotNet.Core/Internal/Utilities/WrapperSDK.cs @@ -8,7 +8,7 @@ public static class WrapperSDK { public static string Type = "dotnet"; - public static string Version + public static string? Version { get { diff --git a/OneSignalSDK.DotNet.Core/LiveActivities/ILiveActivities.cs b/OneSignalSDK.DotNet.Core/LiveActivities/ILiveActivities.cs index 427b79c2..94e30e45 100644 --- a/OneSignalSDK.DotNet.Core/LiveActivities/ILiveActivities.cs +++ b/OneSignalSDK.DotNet.Core/LiveActivities/ILiveActivities.cs @@ -35,7 +35,7 @@ public interface ILiveActivitiesManager /// Only applies to iOS. /// /// An optional structure to provide for more granular setup options. - void SetupDefault(LiveActivitySetupOptions options = null); + void SetupDefault(LiveActivitySetupOptions? options = null); /// /// Start a new LiveActivity that is modelled by the default`DefaultLiveActivityAttributes` diff --git a/OneSignalSDK.DotNet.Core/Notifications/DisplayableNotification.cs b/OneSignalSDK.DotNet.Core/Notifications/DisplayableNotification.cs index f0b49579..e70d5fdf 100644 --- a/OneSignalSDK.DotNet.Core/Notifications/DisplayableNotification.cs +++ b/OneSignalSDK.DotNet.Core/Notifications/DisplayableNotification.cs @@ -9,38 +9,38 @@ namespace OneSignalSDK.DotNet.Core.Notifications public abstract class DisplayableNotification : Notification { public DisplayableNotification( - string title, - string body, - string sound, - string launchUrl, + string? title, + string? body, + string? sound, + string? launchUrl, IList actionButtons, IDictionary additionalData, - string notificationId, - IList groupedNotifications = null, - BackgroundImageLayout backgroundImageLayout = null, - string templateId = null, - string templateName = null, - string groupKey = null, - string groupMessage = null, - string ledColor = null, + string? notificationId, + IList? groupedNotifications = null, + BackgroundImageLayout? backgroundImageLayout = null, + string? templateId = null, + string? templateName = null, + string? groupKey = null, + string? groupMessage = null, + string? ledColor = null, int? priority = null, - string smallIcon = null, - string largeIcon = null, - string bigPicture = null, - string collapseId = null, - string fromProjectNumber = null, - string smallIconAccentColor = null, + string? smallIcon = null, + string? largeIcon = null, + string? bigPicture = null, + string? collapseId = null, + string? fromProjectNumber = null, + string? smallIconAccentColor = null, int? lockScreenVisibility = null, int? androidNotificationId = null, int? badge = null, int? badgeIncrement = null, - string category = null, - string threadId = null, - string subtitle = null, + string? category = null, + string? threadId = null, + string? subtitle = null, float? relevanceScore = null, bool? mutableContent = null, bool? contentAvailable = null, - string interruptionLevel = null + string? interruptionLevel = null ) : base( title, diff --git a/OneSignalSDK.DotNet.Core/Notifications/Notification.cs b/OneSignalSDK.DotNet.Core/Notifications/Notification.cs index 95df1d29..05d454fa 100644 --- a/OneSignalSDK.DotNet.Core/Notifications/Notification.cs +++ b/OneSignalSDK.DotNet.Core/Notifications/Notification.cs @@ -11,22 +11,22 @@ public class Notification /// /// The title displayed to the user. /// - public string Title { get; } + public string? Title { get; } /// /// The body displayed to the user. /// - public string Body { get; } + public string? Body { get; } /// /// The sound information specified when creating the notification. /// - public string Sound { get; } + public string? Sound { get; } /// /// The launch URL information specified when creating the notification. /// - public string LaunchUrl { get; } + public string? LaunchUrl { get; } /// /// The action buttons specified when creating the notification. @@ -42,45 +42,45 @@ public class Notification /// /// The OneSignal notification id. /// - public string NotificationId { get; } + public string? NotificationId { get; } /// /// When non-null this is a summary notification, and this contains the list of notifications this summarizes. /// - public IList GroupedNotifications { get; } + public IList? GroupedNotifications { get; } /// /// The background image layout information specified when creating the notification. /// - public BackgroundImageLayout BackgroundImageLayout { get; } + public BackgroundImageLayout? BackgroundImageLayout { get; } /// /// The id of the OneSignal tempalte that created this notification. If no template was used, /// this will be null. /// - public string TemplateId { get; } + public string? TemplateId { get; } /// /// The name of the OneSignal template that created this notification. If no template was /// used, this will be null. /// - public string TemplateName { get; } + public string? TemplateName { get; } #region Android /// /// (Android Only) The group key information specified when creating the notification. /// - public string GroupKey { get; } + public string? GroupKey { get; } /// /// (Android Only) The group message information specified when creating the notification. /// - public string GroupMessage { get; } + public string? GroupMessage { get; } /// /// (Android Only) The LED color information specified when creating the notification. /// - public string LedColor { get; } + public string? LedColor { get; } /// /// (Android Only) The priority information specified when creating the notification. @@ -90,32 +90,32 @@ public class Notification /// /// (Android Only) The small icon information specified when creating the notification. /// - public string SmallIcon { get; } + public string? SmallIcon { get; } /// /// (Android Only) The large icon information specified when creating the notification. /// - public string LargeIcon { get; } + public string? LargeIcon { get; } /// /// (Android Only) The big picture information specified when creating the notification. /// - public string BigPicture { get; } + public string? BigPicture { get; } /// /// (Android Only) The collapse ID specified when creating the notification. /// - public string CollapseId { get; } + public string? CollapseId { get; } /// /// (Android Only) The from project information specified when creating the notification. /// - public string FromProjectNumber { get; } + public string? FromProjectNumber { get; } /// /// (Android Only) The accent color of the small icon specified when creating the notification. /// - public string SmallIconAccentColor { get; } + public string? SmallIconAccentColor { get; } /// /// (Android Only) The lock screen visibility information specified when creating the notification. @@ -142,17 +142,17 @@ public class Notification /// /// (iOS Only) Show associated actions and buttons for the category. /// - public string Category { get; } + public string? Category { get; } /// /// The ID of the thread (group) this notification is within. /// - public string ThreadId { get; } + public string? ThreadId { get; } /// /// (iOS Only) The subtitle of the notification. /// - public string Subtitle { get; } + public string? Subtitle { get; } /// /// (iOS Only) The order the notification is shown for users that have chosen to receive your notifications as part @@ -173,42 +173,42 @@ public class Notification /// /// (iOS Only) When and how the notification is displayed. /// - public string InterruptionLevel { get; } + public string? InterruptionLevel { get; } #endregion iOS public Notification( - string title, - string body, - string sound, - string launchUrl, + string? title, + string? body, + string? sound, + string? launchUrl, IList actionButtons, IDictionary additionalData, - string notificationId, - IList groupedNotifications = null, - BackgroundImageLayout backgroundImageLayout = null, - string templateId = null, - string templateName = null, - string groupKey = null, - string groupMessage = null, - string ledColor = null, + string? notificationId, + IList? groupedNotifications = null, + BackgroundImageLayout? backgroundImageLayout = null, + string? templateId = null, + string? templateName = null, + string? groupKey = null, + string? groupMessage = null, + string? ledColor = null, Nullable priority = null, - string smallIcon = null, - string largeIcon = null, - string bigPicture = null, - string collapseId = null, - string fromProjectNumber = null, - string smallIconAccentColor = null, + string? smallIcon = null, + string? largeIcon = null, + string? bigPicture = null, + string? collapseId = null, + string? fromProjectNumber = null, + string? smallIconAccentColor = null, Nullable lockScreenVisibility = null, Nullable androidNotificationId = null, Nullable badge = null, Nullable badgeIncrement = null, - string category = null, - string threadId = null, - string subtitle = null, + string? category = null, + string? threadId = null, + string? subtitle = null, Nullable relevanceScore = null, Nullable mutableContent = null, Nullable contentAvailable = null, - string interruptionLevel = null + string? interruptionLevel = null ) { Title = title; @@ -254,19 +254,19 @@ public class ActionButton /// /// The ID of the action button specified when creating the notification. /// - public string Id { get; } + public string? Id { get; } /// /// The text displayed on the action button. /// - public string Text { get; } + public string? Text { get; } /// /// The icon displayed on the action button. /// - public string Icon { get; } + public string? Icon { get; } - public ActionButton(string id, string text, string icon) + public ActionButton(string? id, string? text, string? icon) { Id = id; Text = text; diff --git a/OneSignalSDK.DotNet.Core/Notifications/NotificationClickResult.cs b/OneSignalSDK.DotNet.Core/Notifications/NotificationClickResult.cs index ef768dbc..fde1393d 100644 --- a/OneSignalSDK.DotNet.Core/Notifications/NotificationClickResult.cs +++ b/OneSignalSDK.DotNet.Core/Notifications/NotificationClickResult.cs @@ -7,11 +7,11 @@ namespace OneSignalSDK.DotNet.Core.Notifications /// public class NotificationClickResult { - public string ActionId { get; } + public string? ActionId { get; } - public string Url { get; } + public string? Url { get; } - public NotificationClickResult(string actionId, string url) + public NotificationClickResult(string? actionId, string? url) { ActionId = actionId; Url = url; diff --git a/OneSignalSDK.DotNet.iOS.Binding/OneSignalSDK.DotNet.iOS.Binding.csproj b/OneSignalSDK.DotNet.iOS.Binding/OneSignalSDK.DotNet.iOS.Binding.csproj index 436c57d8..b0a34785 100644 --- a/OneSignalSDK.DotNet.iOS.Binding/OneSignalSDK.DotNet.iOS.Binding.csproj +++ b/OneSignalSDK.DotNet.iOS.Binding/OneSignalSDK.DotNet.iOS.Binding.csproj @@ -12,6 +12,7 @@ Resources OneSignalSDK.DotNet.iOS.Binding true + $(NoWarn);CS0114 true diff --git a/OneSignalSDK.DotNet.iOS/OneSignalSDK.DotNet.iOS.csproj b/OneSignalSDK.DotNet.iOS/OneSignalSDK.DotNet.iOS.csproj index 8c5fbac7..0c20e980 100644 --- a/OneSignalSDK.DotNet.iOS/OneSignalSDK.DotNet.iOS.csproj +++ b/OneSignalSDK.DotNet.iOS/OneSignalSDK.DotNet.iOS.csproj @@ -8,6 +8,7 @@ true Resources 12.2 + enable OneSignalSDK.DotNet.iOS OneSignalSDK.DotNet.iOS Resources diff --git a/OneSignalSDK.DotNet.iOS/Utilities/FromNativeConversion.cs b/OneSignalSDK.DotNet.iOS/Utilities/FromNativeConversion.cs index f6e3b385..da154990 100644 --- a/OneSignalSDK.DotNet.iOS/Utilities/FromNativeConversion.cs +++ b/OneSignalSDK.DotNet.iOS/Utilities/FromNativeConversion.cs @@ -1,7 +1,5 @@ using System.Collections.Generic; -using System.Text.Json; using Foundation; -using HomeKit; using OneSignalSDK.DotNet.Core; using OneSignalSDK.DotNet.Core.InAppMessages; using OneSignalSDK.DotNet.Core.Internal.Utilities; @@ -15,37 +13,31 @@ namespace OneSignalSDK.DotNet.iOS.Utilities; /// public static class FromNativeConversion { - public static Dictionary NSObjectToPureDict(NSObject nSObject) + public static Dictionary? NSObjectToPureDict(NSObject nSObject) { - if (nSObject == null) + var jsonString = SerializeToJsonString(nSObject); + if (jsonString == null) return null; - NSError error; - NSData jsonData = NSJsonSerialization.Serialize(nSObject, 0, out error); - NSString jsonNSString = NSString.FromData(jsonData, NSStringEncoding.UTF8); - string jsonString = jsonNSString.ToString(); + return Json.Deserialize(jsonString) as Dictionary; } - public static Dictionary NSDictToPureDict(NSDictionary nsDict) + public static Dictionary? NSDictToPureDict(NSDictionary nsDict) { - if (nsDict == null) + var jsonString = SerializeToJsonString(nsDict); + if (jsonString == null) return null; - NSError error; - NSData jsonData = NSJsonSerialization.Serialize(nsDict, 0, out error); - NSString jsonNSString = NSString.FromData(jsonData, NSStringEncoding.UTF8); - string jsonString = jsonNSString.ToString(); + return Json.Deserialize(jsonString) as Dictionary; } - public static Dictionary NSDictToPureStringDict(NSDictionary nsDict) + public static Dictionary? NSDictToPureStringDict(NSDictionary? nsDict) { - if (nsDict == null) + var jsonString = SerializeToJsonString(nsDict); + if (jsonString == null) return null; - NSError error; - NSData jsonData = NSJsonSerialization.Serialize(nsDict, 0, out error); - NSString jsonNSString = NSString.FromData(jsonData, NSStringEncoding.UTF8); - string jsonString = jsonNSString.ToString(); - return JsonSerializer.Deserialize>(jsonString); + + return Json.Deserialize(jsonString) as Dictionary; } public static Notification ToNotification(OneSignaliOS.OSNotification notification) @@ -53,7 +45,8 @@ public static Notification ToNotification(OneSignaliOS.OSNotification notificati Dictionary additionalDataXam = new Dictionary(); if (notification.AdditionalData != null) { - additionalDataXam = NSDictToPureDict(notification.AdditionalData); + additionalDataXam = + NSDictToPureDict(notification.AdditionalData) ?? additionalDataXam; } List actionButtonsXam = new List(); @@ -61,7 +54,7 @@ public static Notification ToNotification(OneSignaliOS.OSNotification notificati { foreach (NSObject actionButton in notification.ActionButtons) { - Dictionary actionButtonXam = NSObjectToPureDict(actionButton); + Dictionary? actionButtonXam = NSObjectToPureDict(actionButton); if (actionButtonXam != null) { actionButtonsXam.Add( @@ -123,4 +116,17 @@ public static InAppMessage ToInAppMessage(OneSignaliOS.OSInAppMessage inAppMessa { return new InAppMessage(messageId: inAppMessage.MessageId); } + + private static string? SerializeToJsonString(NSObject? nSObject) + { + if (nSObject == null) + return null; + + NSData jsonData = NSJsonSerialization.Serialize(nSObject, 0, out _); + if (jsonData == null) + return null; + + NSString? jsonNSString = NSString.FromData(jsonData, NSStringEncoding.UTF8); + return jsonNSString?.ToString(); + } } diff --git a/OneSignalSDK.DotNet.iOS/Utilities/ToNativeConversion.cs b/OneSignalSDK.DotNet.iOS/Utilities/ToNativeConversion.cs index 161a2fa0..2b000594 100644 --- a/OneSignalSDK.DotNet.iOS/Utilities/ToNativeConversion.cs +++ b/OneSignalSDK.DotNet.iOS/Utilities/ToNativeConversion.cs @@ -1,6 +1,5 @@ using System.Collections.Generic; using Foundation; -using HomeKit; using OneSignalSDK.DotNet.Core; using OneSignalSDK.DotNet.Core.Internal.Utilities; @@ -14,7 +13,7 @@ public static class NativeConversion public static NSDictionary DictToNSDict(IDictionary dict) { if (dict == null) - return null; + return new NSDictionary(); var keys = new NSString[dict.Count]; var values = new NSObject[dict.Count]; @@ -22,45 +21,41 @@ public static NSDictionary DictToNSDict(IDictionary(keys, values); - - return result; + return new NSDictionary(keys, values); } public static NSDictionary DictToNSDict(IDictionary dict) { if (dict == null) - return null; + return new NSDictionary(); var keys = new NSString[dict.Count]; var values = new NSString[dict.Count]; var index = 0; foreach (var entry in dict) { - keys[index] = NSString.FromData(entry.Key, NSStringEncoding.UTF8); - values[index] = NSString.FromData(entry.Value, NSStringEncoding.UTF8); + keys[index] = NSString.FromData(entry.Key, NSStringEncoding.UTF8)!; + values[index] = NSString.FromData(entry.Value, NSStringEncoding.UTF8)!; index++; } - var result = new NSDictionary(keys, values); - - return result; + return new NSDictionary(keys, values); } public static NSObject ListToNSObject(IList list) { if (list == null) - return null; + return new NSMutableArray(); var result = new NSMutableArray(); foreach (var item in list) { - result.Add(ObjectToNSObject(item)); + result.Add(ObjectToNSObject(item)!); } return result; @@ -81,11 +76,11 @@ public static NSObject ObjectToNSObject(object obj) } else if (obj is String stringItem) { - return NSString.FromData(stringItem, NSStringEncoding.UTF8); + return NSString.FromData(stringItem, NSStringEncoding.UTF8)!; } else { - return NSObject.FromObject(obj); + return NSObject.FromObject(obj)!; } } } diff --git a/OneSignalSDK.DotNet.iOS/iOSLiveActivitiesManager.cs b/OneSignalSDK.DotNet.iOS/iOSLiveActivitiesManager.cs index 1b63aca1..47d58dbe 100644 --- a/OneSignalSDK.DotNet.iOS/iOSLiveActivitiesManager.cs +++ b/OneSignalSDK.DotNet.iOS/iOSLiveActivitiesManager.cs @@ -44,7 +44,7 @@ public void RemovePushToStartToken(string activityType) return; } - NSError error; + NSError? error; OneSignalLiveActivityNative.RemovePushToStartToken(activityType, out error); if (error != null) @@ -61,7 +61,7 @@ public void SetPushToStartToken(string activityType, string token) return; } - NSError error; + NSError? error; OneSignalLiveActivityNative.SetPushToStartToken(activityType, token, out error); if (error != null) @@ -70,7 +70,7 @@ public void SetPushToStartToken(string activityType, string token) } } - public void SetupDefault(LiveActivitySetupOptions options = null) + public void SetupDefault(LiveActivitySetupOptions? options = null) { if (!UIDevice.CurrentDevice.CheckSystemVersion(16, 1)) { @@ -78,7 +78,7 @@ public void SetupDefault(LiveActivitySetupOptions options = null) return; } - LiveActivitySetupOptionsNative nativeOptions = null; + LiveActivitySetupOptionsNative? nativeOptions = null; if (options != null) { diff --git a/OneSignalSDK.DotNet.iOS/iOSNotificationsManager.cs b/OneSignalSDK.DotNet.iOS/iOSNotificationsManager.cs index 436593aa..68c2693a 100644 --- a/OneSignalSDK.DotNet.iOS/iOSNotificationsManager.cs +++ b/OneSignalSDK.DotNet.iOS/iOSNotificationsManager.cs @@ -22,9 +22,9 @@ public class iOSNotificationsManager : INotificationsManager public void Initialize() { - var _notificationsPermissionObserver = new InternalNotificationsPermissionObserver(this); - var _notificationsClickListener = new InternalNotificationsClickListener(this); - var _notificationsLifecycleListener = new InternalNotificationsLifecycleListener(this); + _notificationsPermissionObserver = new InternalNotificationsPermissionObserver(this); + _notificationsClickListener = new InternalNotificationsClickListener(this); + _notificationsLifecycleListener = new InternalNotificationsLifecycleListener(this); OneSignalNative.Notifications.AddPermissionObserver(_notificationsPermissionObserver); OneSignalNative.Notifications.AddForegroundLifecycleListener( @@ -143,9 +143,9 @@ Com.OneSignal.iOS.OSDisplayableNotification notification Dictionary additionalDataXam = new Dictionary(); if (notification.AdditionalData != null) { - additionalDataXam = FromNativeConversion.NSDictToPureDict( - notification.AdditionalData - ); + additionalDataXam = + FromNativeConversion.NSDictToPureDict(notification.AdditionalData) + ?? additionalDataXam; } List actionButtonsXam = new List(); @@ -153,7 +153,7 @@ Com.OneSignal.iOS.OSDisplayableNotification notification { foreach (NSObject actionButton in notification.ActionButtons) { - Dictionary actionButtonXam = + Dictionary? actionButtonXam = FromNativeConversion.NSObjectToPureDict(actionButton); if (actionButtonXam != null) { @@ -197,38 +197,38 @@ Com.OneSignal.iOS.OSDisplayableNotification notification public iOSDisplayableNotification( Com.OneSignal.iOS.OSDisplayableNotification displayableNotification, - string title, - string body, - string sound, - string launchUrl, + string? title, + string? body, + string? sound, + string? launchUrl, IList actionButtons, IDictionary additionalData, - string notificationId, - IList groupedNotifications = null, - BackgroundImageLayout backgroundImageLayout = null, - string templateId = null, - string templateName = null, - string groupKey = null, - string groupMessage = null, - string ledColor = null, + string? notificationId, + IList? groupedNotifications = null, + BackgroundImageLayout? backgroundImageLayout = null, + string? templateId = null, + string? templateName = null, + string? groupKey = null, + string? groupMessage = null, + string? ledColor = null, int? priority = null, - string smallIcon = null, - string largeIcon = null, - string bigPicture = null, - string collapseId = null, - string fromProjectNumber = null, - string smallIconAccentColor = null, + string? smallIcon = null, + string? largeIcon = null, + string? bigPicture = null, + string? collapseId = null, + string? fromProjectNumber = null, + string? smallIconAccentColor = null, int? lockScreenVisibility = null, int? androidNotificationId = null, int? badge = null, int? badgeIncrement = null, - string category = null, - string threadId = null, - string subtitle = null, + string? category = null, + string? threadId = null, + string? subtitle = null, float? relevanceScore = null, bool? mutableContent = null, bool? contentAvailable = null, - string interruptionLevel = null + string? interruptionLevel = null ) : base( title, diff --git a/OneSignalSDK.DotNet.iOS/iOSUserManager.cs b/OneSignalSDK.DotNet.iOS/iOSUserManager.cs index 35517d14..6b2d2ca5 100644 --- a/OneSignalSDK.DotNet.iOS/iOSUserManager.cs +++ b/OneSignalSDK.DotNet.iOS/iOSUserManager.cs @@ -18,7 +18,7 @@ public string Language public IPushSubscription PushSubscription { get; } = new iOSPushSubscription(); - private InternalUserChangedHandler _userChangedHandler; + private InternalUserChangedHandler? _userChangedHandler; public void Initialize() { @@ -27,15 +27,9 @@ public void Initialize() ((iOSPushSubscription)PushSubscription).Initialize(); } - public string OneSignalId - { - get => OneSignalNative.User.OnesignalId; - } + public string OneSignalId => OneSignalNative.User.OnesignalId ?? string.Empty; - public string ExternalId - { - get => OneSignalNative.User.ExternalId; - } + public string ExternalId => OneSignalNative.User.ExternalId ?? string.Empty; public event EventHandler? Changed; public void AddAlias(string label, string id) => @@ -68,7 +62,8 @@ public void AddTags(IDictionary tags) => public void RemoveTags(params string[] keys) => OneSignalNative.User.RemoveTags(keys); public IDictionary GetTags() => - FromNativeConversion.NSDictToPureStringDict(OneSignalNative.User.GetTags()); + FromNativeConversion.NSDictToPureStringDict(OneSignalNative.User.GetTags()) + ?? new Dictionary(); public void TrackEvent(string name, IDictionary? properties = null) { @@ -84,10 +79,10 @@ private sealed class InternalUserState : IUserState public string ExternalId { get; } - public InternalUserState(string onesignalId, string externalId) + public InternalUserState(string? onesignalId, string? externalId) { - OneSignalId = onesignalId; - ExternalId = externalId; + OneSignalId = onesignalId ?? string.Empty; + ExternalId = externalId ?? string.Empty; } } @@ -114,11 +109,12 @@ public override void OnUserStateDidChangeWithState(OSUserChangedState state) public class iOSPushSubscription : IPushSubscription { - public string Token => OneSignalNative.User.PushSubscription.Token; + public string Token => + OneSignalNative.User.PushSubscription.Token ?? string.Empty; public bool OptedIn => OneSignalNative.User.PushSubscription.OptedIn; - public string Id => OneSignalNative.User.PushSubscription.Id; + public string Id => OneSignalNative.User.PushSubscription.Id ?? string.Empty; public event EventHandler? Changed; @@ -148,11 +144,11 @@ private sealed class InternalPushSubscriptionState : IPushSubscriptionState public bool OptedIn { get; } - public InternalPushSubscriptionState(string token, bool optedIn, string id) + public InternalPushSubscriptionState(string? token, bool optedIn, string? id) { - Token = token; + Token = token ?? string.Empty; OptedIn = optedIn; - Id = id; + Id = id ?? string.Empty; } } diff --git a/OneSignalSDK.DotNet/OneSignal.cs b/OneSignalSDK.DotNet/OneSignal.cs index 3ca3580e..9f1bef1f 100644 --- a/OneSignalSDK.DotNet/OneSignal.cs +++ b/OneSignalSDK.DotNet/OneSignal.cs @@ -123,7 +123,7 @@ public static void Initialize(String appId) /// login operation.Required when identity verification has been enabled. See /// Identity Verification | OneSignal /// - public static void Login(String externalId, String jwtBearerToken = null) + public static void Login(String externalId, String? jwtBearerToken = null) { OneSignal.Default.Login(externalId, jwtBearerToken); } diff --git a/examples/demo-no-location/MainPage.xaml.cs b/examples/demo-no-location/MainPage.xaml.cs index b7021569..f6b1362e 100644 --- a/examples/demo-no-location/MainPage.xaml.cs +++ b/examples/demo-no-location/MainPage.xaml.cs @@ -57,7 +57,7 @@ private async void OnRequestPermissionClicked(object? sender, EventArgs e) } catch (Exception exception) { - await DisplayAlert("Permission Request Failed", exception.Message, "OK"); + await DisplayAlertAsync("Permission Request Failed", exception.Message, "OK"); } finally { @@ -69,7 +69,7 @@ private async void OnSendNotificationClicked(object? sender, EventArgs e) { if (IsPlaceholder(_appId)) { - await DisplayAlert( + await DisplayAlertAsync( "Configure OneSignal", "Set ONESIGNAL_APP_ID in .env before sending a test push.", "OK" @@ -79,7 +79,7 @@ await DisplayAlert( if (!OneSignal.Notifications.Permission) { - await DisplayAlert( + await DisplayAlertAsync( "Notifications Disabled", "Request notification permission before sending a test push.", "OK" @@ -90,7 +90,7 @@ await DisplayAlert( var pushSubscriptionId = OneSignal.User.PushSubscription.Id; if (string.IsNullOrWhiteSpace(pushSubscriptionId)) { - await DisplayAlert( + await DisplayAlertAsync( "No Push Subscription", "Allow notifications, then wait for a push ID.", "OK" @@ -104,16 +104,16 @@ await DisplayAlert( var response = await SendTestNotificationAsync(pushSubscriptionId); if (response.IsSuccessStatusCode) { - await DisplayAlert("Sent", "Test notification requested.", "OK"); + await DisplayAlertAsync("Sent", "Test notification requested.", "OK"); return; } var message = await response.Content.ReadAsStringAsync(); - await DisplayAlert("Send Failed", message, "OK"); + await DisplayAlertAsync("Send Failed", message, "OK"); } catch (Exception exception) { - await DisplayAlert("Send Failed", exception.Message, "OK"); + await DisplayAlertAsync("Send Failed", exception.Message, "OK"); } finally { diff --git a/examples/demo-no-location/demo-no-location.csproj b/examples/demo-no-location/demo-no-location.csproj index 194ac88f..59c80cd9 100644 --- a/examples/demo-no-location/demo-no-location.csproj +++ b/examples/demo-no-location/demo-no-location.csproj @@ -19,7 +19,7 @@ 14.2 + >15.0 26.0 diff --git a/examples/demo/Controls/DialogInputHelper.cs b/examples/demo/Controls/DialogInputHelper.cs index b382634b..8c7f7a60 100644 --- a/examples/demo/Controls/DialogInputHelper.cs +++ b/examples/demo/Controls/DialogInputHelper.cs @@ -205,7 +205,6 @@ internal static Button ActionButton(string text, string? automationId = null) => FontSize = 14, BorderWidth = 0, BorderColor = Colors.Transparent, - Shadow = null, Padding = new Thickness(12, 8), AutomationId = automationId ?? string.Empty, }; diff --git a/examples/demo/NotificationServiceExtension/NotificationServiceExtension.csproj b/examples/demo/NotificationServiceExtension/NotificationServiceExtension.csproj index 26b79f90..fa02421b 100644 --- a/examples/demo/NotificationServiceExtension/NotificationServiceExtension.csproj +++ b/examples/demo/NotificationServiceExtension/NotificationServiceExtension.csproj @@ -12,7 +12,8 @@ ("No service extension record found for app" / UNErrorDomain 1904), silently dropping mutable-content pushes — i.e. no image attachments. --> - 14.2 + 15.0 + enable