diff --git a/OneSignalExample/Assets/OneSignal/CHANGELOG.md b/OneSignalExample/Assets/OneSignal/CHANGELOG.md index b5f0ccd8e..c5659cce6 100644 --- a/OneSignalExample/Assets/OneSignal/CHANGELOG.md +++ b/OneSignalExample/Assets/OneSignal/CHANGELOG.md @@ -7,10 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Fixed - iOS build post processor will determine extension's imported OneSignalXCFramework from the package's dependencies xml +- iOS callbacks for the `NotificationPermissionChanged` event will no longer cause an il2cpp exception ### Changed - Added AndroidManifest with location permissions to the example app to display `PromptLocation` - `InstallEdm4uStep` now imports version [1.2.169](https://github.com/googlesamples/unity-jar-resolver/releases/tag/v1.2.169) of [EDM4U](https://github.com/googlesamples/unity-jar-resolver) - Log an error in the example app when `RequiresPrivacyConsent` is attempted to be set to false from true +- Internal state mappings on iOS now rely on class defined objects over dynamic Dictionary types ## [3.0.0-beta.5] ### Changed diff --git a/com.onesignal.unity.ios/Runtime/OneSignalIOS.Callbacks.cs b/com.onesignal.unity.ios/Runtime/OneSignalIOS.Callbacks.cs index ccd1f0c3f..04cb38034 100644 --- a/com.onesignal.unity.ios/Runtime/OneSignalIOS.Callbacks.cs +++ b/com.onesignal.unity.ios/Runtime/OneSignalIOS.Callbacks.cs @@ -48,20 +48,24 @@ private static (Later proxy, int hashCode) _setupProxy() { WaitingProxies[hashCode] = proxy; return (proxy, hashCode); } - - [AOT.MonoPInvokeCallback(typeof(BooleanResponseDelegate))] - private static void BooleanCallbackProxy(int hashCode, bool response) { - if (WaitingProxies[hashCode] is Later later) + + private static void ResolveCallbackProxy(int hashCode, TResponse response) { + if (!WaitingProxies.ContainsKey(hashCode)) + return; + + if (WaitingProxies[hashCode] is Later later) later.Complete(response); + WaitingProxies.Remove(hashCode); } + [AOT.MonoPInvokeCallback(typeof(BooleanResponseDelegate))] + private static void BooleanCallbackProxy(int hashCode, bool response) + => ResolveCallbackProxy(hashCode, response); + [AOT.MonoPInvokeCallback(typeof(StringResponseDelegate))] - private static void StringCallbackProxy(int hashCode, string response) { - if (WaitingProxies[hashCode] is Later later) - later.Complete(response); - WaitingProxies.Remove(hashCode); - } + private static void StringCallbackProxy(int hashCode, string response) + => ResolveCallbackProxy(hashCode, response); /* * Global Callbacks @@ -134,19 +138,8 @@ private static void _onInAppMessageClicked(string response) [AOT.MonoPInvokeCallback(typeof(StateListenerDelegate))] private static void _onPermissionStateChanged(string current, string previous) { - if (!(Json.Deserialize(current) is Dictionary currState)) { - SDKDebug.Error("Could not deserialize current permission state"); - return; - } - - if (!(Json.Deserialize(previous) is Dictionary prevState)) { - SDKDebug.Error("Could not deserialize previous permission state"); - return; - } - - var curr = (NotificationPermission)currState["status"]; - var prev = (NotificationPermission)prevState["status"]; - + var curr = JsonUtility.FromJson(current); + var prev = JsonUtility.FromJson(previous); _instance.NotificationPermissionChanged?.Invoke(curr, prev); } diff --git a/com.onesignal.unity.ios/Runtime/OneSignalIOS.Interface.cs b/com.onesignal.unity.ios/Runtime/OneSignalIOS.Interface.cs index 4f303b55a..11e16221d 100644 --- a/com.onesignal.unity.ios/Runtime/OneSignalIOS.Interface.cs +++ b/com.onesignal.unity.ios/Runtime/OneSignalIOS.Interface.cs @@ -28,9 +28,6 @@ using System.Runtime.InteropServices; namespace OneSignalSDK { - /// - /// - /// public sealed partial class OneSignalIOS : OneSignal { /* * Global callbacks diff --git a/com.onesignal.unity.ios/Runtime/OneSignalIOS.Mappings.cs b/com.onesignal.unity.ios/Runtime/OneSignalIOS.Mappings.cs new file mode 100644 index 000000000..73f42dc08 --- /dev/null +++ b/com.onesignal.unity.ios/Runtime/OneSignalIOS.Mappings.cs @@ -0,0 +1,80 @@ +/* + * Modified MIT License + * + * Copyright 2022 OneSignal + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * 1. The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * 2. All copies of substantial portions of the Software may only be used in connection + * with services provided by OneSignal. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +using System; + +namespace OneSignalSDK { + public sealed partial class OneSignalIOS : OneSignal { + [Serializable] private sealed class DeviceState { + public long notificationPermissionStatus; + + public string userId; + public string pushToken; + public bool isSubscribed; + public bool isPushDisabled; + + public string emailUserId; + public string emailAddress; + public bool isEmailSubscribed; + + public string smsUserId; + public string smsNumber; + public bool isSMSSubscribed; + + public static implicit operator PushSubscriptionState(DeviceState source) + => new PushSubscriptionState { + userId = source.userId, + pushToken = source.pushToken, + isSubscribed = source.isSubscribed, + isPushDisabled = source.isPushDisabled, + }; + + public static implicit operator EmailSubscriptionState(DeviceState source) + => new EmailSubscriptionState { + emailUserId = source.emailUserId, + emailAddress = source.emailAddress, + isSubscribed = source.isEmailSubscribed, + }; + + public static implicit operator SMSSubscriptionState(DeviceState source) + => new SMSSubscriptionState { + smsUserId = source.smsUserId, + smsNumber = source.smsNumber, + isSubscribed = source.isSMSSubscribed, + }; + } + + [Serializable] private sealed class NotificationPermissionState { + public long status; + public bool provisional; + public bool hasPrompted; + + public static implicit operator NotificationPermission(NotificationPermissionState source) + => (NotificationPermission)source.status; + } + } +} \ No newline at end of file diff --git a/com.onesignal.unity.ios/Runtime/OneSignalIOS.Mappings.cs.meta b/com.onesignal.unity.ios/Runtime/OneSignalIOS.Mappings.cs.meta new file mode 100644 index 000000000..5de7e1718 --- /dev/null +++ b/com.onesignal.unity.ios/Runtime/OneSignalIOS.Mappings.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 60256e1ba9474730ac255a1e9da4ce74 +timeCreated: 1643996576 \ No newline at end of file diff --git a/com.onesignal.unity.ios/Runtime/OneSignalIOS.cs b/com.onesignal.unity.ios/Runtime/OneSignalIOS.cs index a11f1eefa..be9d39082 100644 --- a/com.onesignal.unity.ios/Runtime/OneSignalIOS.cs +++ b/com.onesignal.unity.ios/Runtime/OneSignalIOS.cs @@ -28,6 +28,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using UnityEngine; namespace OneSignalSDK { public sealed partial class OneSignalIOS : OneSignal { @@ -45,61 +46,19 @@ public sealed partial class OneSignalIOS : OneSignal { public override NotificationPermission NotificationPermission { get { - if (Json.Deserialize(_getDeviceState()) is Dictionary deviceState) { - if (deviceState["notificationPermissionStatus"] is long status) - return (NotificationPermission) status; - } - - SDKDebug.Error("Could not deserialize device state for permissions"); - return NotificationPermission.NotDetermined; + var deviceState = JsonUtility.FromJson(_getDeviceState()); + return (NotificationPermission)deviceState.notificationPermissionStatus; } } - public override PushSubscriptionState PushSubscriptionState { - get { - if (Json.Deserialize(_getDeviceState()) is Dictionary deviceState) { - return new PushSubscriptionState { - userId = deviceState["userId"] as string, - pushToken = deviceState["pushToken"] as string, - isSubscribed = (bool) deviceState["isSubscribed"], - isPushDisabled = (bool) deviceState["isPushDisabled"], - }; - } - - SDKDebug.Error("Could not deserialize device state for push"); - return null; - } - } + public override PushSubscriptionState PushSubscriptionState + => JsonUtility.FromJson(_getDeviceState()); - public override EmailSubscriptionState EmailSubscriptionState { - get { - if (Json.Deserialize(_getDeviceState()) is Dictionary deviceState) { - return new EmailSubscriptionState { - emailUserId = deviceState["emailUserId"] as string, - emailAddress = deviceState["emailAddress"] as string, - isSubscribed = (bool) deviceState["isEmailSubscribed"], - }; - } - - SDKDebug.Error("Could not deserialize device state for email"); - return null; - } - } + public override EmailSubscriptionState EmailSubscriptionState + => JsonUtility.FromJson(_getDeviceState()); - public override SMSSubscriptionState SMSSubscriptionState { - get { - if (Json.Deserialize(_getDeviceState()) is Dictionary deviceState) { - return new SMSSubscriptionState { - smsUserId = deviceState["smsUserId"] as string, - smsNumber = deviceState["smsNumber"] as string, - isSubscribed = (bool) deviceState["isSMSSubscribed"], - }; - } - - SDKDebug.Error("Could not deserialize device state for sms"); - return null; - } - } + public override SMSSubscriptionState SMSSubscriptionState + => JsonUtility.FromJson(_getDeviceState()); public override LogLevel LogLevel { get => _logLevel;