unity IOS本地推送

Posted 天涯过客TYGK

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了unity IOS本地推送相关的知识,希望对你有一定的参考价值。

基于unity自带方法,实现ios推送
最初打算使用timeZone设置时区,后来测试的时候,发现添加和不添加没什么区别,IGameNotification是一个推送消息的数据类,这里不做介绍
代码很简单,但是调试的时候,遇到很多奇怪的问题

fireDate是本地时区时间,repeatCalendar的值要设置为ISO8601Calendar,要不然收不到
使用BadgeNumber的时候,没办法通过设置的用户信息去查找删除单条推送信息(感觉unity这里存在bug),所以这里就去掉了BadgeNumber
在创建新的推送信息之前,需要把旧的设置信息移除掉

因为系统不会自动判断是否是重复设置,每调用一次NotificationServices.ScheduleLocalNotification,就会创建一条新的推送信息,所以需要自己添加代码处理

#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数据类,这个借用的是项目中其他三方插件中的推送数据类

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 Repeatget; 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 数据类

#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

以上是关于unity IOS本地推送的主要内容,如果未能解决你的问题,请参考以下文章

unity IOS本地推送

零基础教你Unity接入IOS原生本地推送 文末源码

Firebase Analytics iOS/Unity 推送通知?

如何在 Unity(C#,目前针对 iOS)中设置每周重复推送通知?

iOS推送之本地推送

iOS本地推送