Unity IOS local push

Based on the built-in method of unity, IOS push
is initially planned to use timeZone to set the time zone. Later, when testing, I found that there is no difference between adding and not adding. IGameNotification is a data class for pushing messages. The code is very simple without introducing it here, but when
debugging , encountered many strange problems

fireDate is the time in the local time zone, the value of repeatCalendar should be set to ISO8601Calendar, otherwise it will not be received
When using BadgeNumber, there is no way to find and delete a single push message through the set user information (I feel that there is a bug in unity), so BadgeNumber is removed here
Before creating new push information, the old setting information needs to be removed

Because the system will not automatically judge whether it is a repeated setting, a new push message will be created every time NotificationServices.ScheduleLocalNotification is called, so you need to add code processing by yourself

#if UNITY_IOS
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using NotificationServices = UnityEngine.iOS.NotificationServices;
using NotificationType = UnityEngine.iOS.NotificationType;
using LocalNotification = UnityEngine.iOS.LocalNotification;
using NotificationSamples;

public class IoSLocalNotification : MonoBehaviour
{
    static string NotificationIdKey = "NotificationId";

    public void Init()
    {
        NotificationServices.RegisterForNotifications(
            NotificationType.Alert |
            NotificationType.Sound |
            NotificationType.Badge 
        );
    }

    public void ScheduleDayNotification(IGameNotification notification, string timeZone) {
        CreateScheduleNotification(notification, timeZone, UnityEngine.iOS.CalendarUnit.Day);
    }

    public void ScheduleWeekNotification(IGameNotification notification, string timeZone)
    {
        CreateScheduleNotification(notification, timeZone, UnityEngine.iOS.CalendarUnit.Week);
    }

    public void OnceNotification(IGameNotification notification, string timeZone)
    {
        CreateScheduleNotification(notification, timeZone, UnityEngine.iOS.CalendarUnit.Era);
    }

    void CreateScheduleNotification(IGameNotification notification, string timeZone, UnityEngine.iOS.CalendarUnit interval) {
        LocalNotification localNotification;
        if (notification.Id != null)
        {
            CancelLocalNotification(notification.Id.Value);
        }
        else
        {
            Debug.LogWarning("IOS ScheduleNotification id can't be null");
            return;
        }
        
        localNotification = new LocalNotification();
        IDictionary newDict = new Dictionary<string, string>();
        newDict.Add(NotificationIdKey , notification.Id.Value + "");
        localNotification.userInfo = newDict as IDictionary;

        localNotification.alertTitle = notification.Title;
        localNotification.alertBody = notification.Body;

        if(UnityEngine.iOS.CalendarUnit.Week == interval){
            localNotification.fireDate = (notification as NotificationSamples.iOS.IosGameNotification).RepeatWeekDeliveryTime;
        }else{
            localNotification.fireDate = notification.RepeatDeliveryTime.Value;
        }
        Debug.LogWarning("create notification " + localNotification.fireDate.ToString("yy-MM-dd-HH-mm-ss"));
        
        // localNotification.applicationIconBadgeNumber = 1;
        localNotification.alertAction = notification.Subtitle;
        localNotification.hasAction = true;
        // localNotification.timeZone = "GMT" + System.DateTime.Now.ToString("%z");
        localNotification.repeatInterval = interval;
        localNotification.repeatCalendar = UnityEngine.iOS.CalendarIdentifier.ISO8601Calendar;
        localNotification.soundName = LocalNotification.defaultSoundName;
        NotificationServices.ScheduleLocalNotification(localNotification);
    }
    

    public void CancelLocalNotification(int id)
    {
            LocalNotification[] allNotifications = NotificationServices.scheduledLocalNotifications;
             // Debug.Log("CancelLocalNotification.scheduledLocalNotifications------------id" + id + ", length " + allNotifications.Length);
             foreach(LocalNotification l in allNotifications)
             {
                    IDictionary userInfo = l.userInfo;
                    if (userInfo.Contains(NotificationIdKey))
                    {
                        if (userInfo[NotificationIdKey].Equals(id + ""))
                        {
                            Debug.Log("CancelLocalNotification alertTitle title is " + l.alertTitle + userInfo[NotificationIdKey]);
                            // l.applicationIconBadgeNumber = -1;
                            NotificationServices.CancelLocalNotification( l );
                        }    
                    }
             }

        Debug.Log("CancelLocalNotification.remain notification count is " + NotificationServices.scheduledLocalNotifications.Length);
    }

    
    public void CleanNotification()
    {
        Debug.Log("------------CleanNotification ");
        NotificationServices.CancelAllLocalNotifications();
        NotificationServices.ClearLocalNotifications();
         // LocalNotification[] allNotifications = NotificationServices.scheduledLocalNotifications;
    }

}


#endif

Notification data class, which is borrowed from the push data class in other three-party plug-ins in the project

namespace NotificationSamples
{
	/// <summary>
	/// Represents a notification that will be delivered for this application.
	/// </summary>
	public interface IGameNotification
	{
		/// <summary>
		/// Gets or sets a unique identifier for this notification.
		/// </summary>
		/// <remarks>
		/// <para>
		/// If null, will be generated automatically once the notification is delivered, and then
		/// can be retrieved afterwards.
		/// </para>
		/// <para>On some platforms, this might be converted to a string identifier internally.</para>
		/// </remarks>
		/// <value>A unique integer identifier for this notification, or null (on some platforms) if not explicitly set.</value>
		int? Id { get; set; }

		/// <summary>
		/// Gets or sets the notification's title.
		/// </summary>
		/// <value>The title message for the notification.</value>
		string Title { get; set; }

		/// <summary>
		/// Gets or sets the body text of the notification.
		/// </summary>
		/// <value>The body message for the notification.</value> 
		string Body { get; set; }

		/// <summary>
		/// Gets or sets a subtitle for the notification.
		/// </summary>
		/// <value>The subtitle message for the notification.</value>
		string Subtitle { get; set; }

		/// <summary>
		/// Gets or sets group to which this notification belongs.
		/// </summary>
		/// <value>A platform specific string identifier for the notification's group.</value>
		string Group { get; set; }

		/// <summary>
		/// Gets or sets the badge number for this notification. No badge number will be shown if null.
		/// </summary>
		/// <value>The number displayed on the app badge.</value>
		int? BadgeNumber { get; set; }

		/// <summary>
		/// Gets or sets time to deliver the notification.
		/// </summary>
		/// <value>The time of delivery in local time.</value>
		DateTime? DeliveryTime { get; set; }
		DateTime? RepeatDeliveryTime { get; set; }

		bool Repeat{get; set; }

		/// <summary>
		/// Gets whether this notification has been scheduled.
		/// </summary>
		/// <value>True if the notification has been scheduled with the underlying operating system.</value>
		bool Scheduled { get; }
		
		/// <summary>
		/// Notification small icon.
		/// </summary>
		string SmallIcon { get; set; }

		/// <summary>
		/// Notification large icon.
		/// </summary>
		string LargeIcon { get; set; }

		string Data {get; set;}
	}
}

ios data class

#if UNITY_IOS
using System;
using Unity.Notifications.iOS;
using UnityEngine;
using UnityEngine.Assertions;

namespace NotificationSamples.iOS
{
	/// <summary>
	/// iOS implementation of <see cref="IGameNotification"/>.
	/// </summary>
	public class IosGameNotification : IGameNotification
	{
		private readonly iOSNotification internalNotification;

		/// <summary>
		/// Gets the internal notification object used by the mobile notifications system.
		/// </summary>
		public iOSNotification InternalNotification => internalNotification;

		/// <inheritdoc />
		/// <remarks>
		/// Internally stored as a string. Gets parsed to an integer when retrieving.
		/// </remarks>
		/// <value>The identifier as an integer, or null if the identifier couldn't be parsed as a number.</value>
		public int? Id
		{
			get
			{
				if (!int.TryParse(internalNotification.Identifier, out int value))
				{
					Debug.LogWarning("Internal iOS notification's identifier isn't a number.");
					return null;
				}

				return value;
			}
			set
			{
				if (value == null)
				{
					throw new ArgumentNullException(nameof(value));
				}

				internalNotification.Identifier = value.Value.ToString();
			}
		}

		/// <inheritdoc />
		public string Title { get => internalNotification.Title; set => internalNotification.Title = value; }

		/// <inheritdoc />
		public string Body { get => internalNotification.Body; set => internalNotification.Body = value; }

		/// <inheritdoc />
		public string Subtitle { get => internalNotification.Subtitle; set => internalNotification.Subtitle = value; }

		/// <inheritdoc />
		/// <remarks>
		/// On iOS, this represents the notification's Category Identifier.
		/// </remarks>
		/// <value>The value of <see cref="CategoryIdentifier"/>.</value>
		public string Group { get => CategoryIdentifier; set => CategoryIdentifier = value; }

		/// <inheritdoc />
		public int? BadgeNumber
		{
			get => internalNotification.Badge != -1 ? internalNotification.Badge : (int?)null;
			set => internalNotification.Badge = value ?? -1;
		}

		/// <inheritdoc />
		public bool Scheduled { get; private set; }

		/// <inheritdoc />
		/// <remarks>
		/// <para>On iOS, setting this causes the notification to be delivered on a calendar time.</para>
		/// <para>If it has previously been manually set to a different type of trigger, or has not been set before,
		/// this returns null.</para>
		/// <para>The millisecond component of the provided DateTime is ignored.</para>
		/// </remarks>
		/// <value>A <see cref="DateTime"/> representing the delivery time of this message, or null if
		/// not set or the trigger isn't a <see cref="iOSNotificationCalendarTrigger"/>.</value>
		public DateTime? DeliveryTime
		{
			get
			{
				if (!(internalNotification.Trigger is iOSNotificationCalendarTrigger calendarTrigger))
				{
					return null;
				}

				DateTime now = DateTime.Now;
				var result = new DateTime
				(
					calendarTrigger.Year ?? now.Year,
					calendarTrigger.Month ?? now.Month,
					calendarTrigger.Day ?? now.Day,
					calendarTrigger.Hour ?? now.Hour,
					calendarTrigger.Minute ?? now.Minute,
					calendarTrigger.Second ?? now.Second,
					DateTimeKind.Local
				);

				return result;
			}
			set
			{
				if (!value.HasValue)
				{
					return;
				}

				DateTime date = value.Value.ToLocalTime();

				internalNotification.Trigger = new iOSNotificationCalendarTrigger
				{
					Year = date.Year,
					Month = date.Month,
					Day = date.Day,
					Hour = date.Hour,
					Minute = date.Minute,
					Second = date.Second
				};
			}
		}

		public DateTime? RepeatDeliveryTime
		{
			get
			{
				if (!(internalNotification.Trigger is iOSNotificationCalendarTrigger calendarTrigger))
				{
					return null;
				}

				DateTime now = DateTime.Now;
				var result = new DateTime
				(
					calendarTrigger.Year ?? now.Year,
					calendarTrigger.Month ?? now.Month,
					calendarTrigger.Day ?? now.Day,
					calendarTrigger.Hour ?? now.Hour,
					calendarTrigger.Minute ?? now.Minute,
					calendarTrigger.Second ?? now.Second,
					DateTimeKind.Local
				);
				return result;
			}
			set
			{
				if (!value.HasValue)
				{
					return;
				}

				DateTime date = value.Value.ToLocalTime();
				Debug.Log("repeat on " + date.Hour + ":" + date.Minute);
				internalNotification.Trigger = new iOSNotificationCalendarTrigger
				{
					// Year = date.Year,
					// Month = date.Month,
					// Day = date.Day,
					Hour = date.Hour,
					Minute = date.Minute,
					Second = date.Second,
					Repeats = true,
				};
				Repeat = true;
			}
		}

		DateTime repeatWeekDeliveryTime ;
		public DateTime RepeatWeekDeliveryTime
		{
			get
			{
				if(repeatWeekDeliveryTime == null)
					return DateTime.Now;
				else
					return repeatWeekDeliveryTime;
			}
			set
			{
				repeatWeekDeliveryTime = value;
				Repeat = true;
			}
		}


		bool repeat;

		public bool Repeat{
			get
			{
				return repeat;
			}
			set
			{
				repeat = value;
			}
		}

		/// <summary>
		/// The category identifier for this notification.
		/// </summary>
		public string CategoryIdentifier
		{
			get => internalNotification.CategoryIdentifier;
			set => internalNotification.CategoryIdentifier = value;
		}
	
		/// <summary>
		/// Does nothing on iOS.
		/// </summary>
		public string SmallIcon { get => null; set { } }
	
		/// <summary>
		/// Does nothing on iOS.
		/// </summary>
		public string LargeIcon { get => null; set { } }

		public string Data{
			get
			{
				return internalNotification.Data;
			}
			set
			{
				internalNotification.Data = value;
			}
		}

		/// <summary>
		/// Instantiate a new instance of <see cref="IosGameNotification"/>.
		/// </summary>
		public IosGameNotification()
		{
			internalNotification = new iOSNotification
			{
				ShowInForeground = false, // Deliver in foreground by default
				// ForegroundPresentationOption = (PresentationOption.Alert |
                //                             PresentationOption.Sound | PresentationOption.Badge),
			};
		}

		/// <summary>
		/// Instantiate a new instance of <see cref="IosGameNotification"/> from a delivered notification.
		/// </summary>
		/// <param name="internalNotification">The delivered notification.</param>
		internal IosGameNotification(iOSNotification internalNotification)
		{
			this.internalNotification = internalNotification;
		}

		/// <summary>
		/// Mark this notifications scheduled flag.
		/// </summary>
		internal void OnScheduled()
		{
			Assert.IsFalse(Scheduled);
			Scheduled = true;
		}

		public override string ToString()
		{
			return "Id : " + Id + ", Title : " + Title + ", Body : " + Body + ", Data : " + Data;
		}
	}
}
#endif

Guess you like

Origin blog.csdn.net/u011484013/article/details/105855997