Xamarin.iOS如何实现每日自动更改本地通知标题,周一设专属标题?
解决Xamarin.iOS中周一专属标题的重复本地通知问题
这个问题我之前做类似项目时也踩过坑——创建两个独立的通知请求确实会导致周一收到双份通知,其实只需要一个重复触发的通知请求,再配合动态修改通知内容的方式就能完美解决需求,具体分两步来操作:
一、创建基础的每日重复通知
首先我们只需要创建一个每天固定时间触发的重复通知,默认标题用非周一的通用标题即可:
// 初始化通知内容 var defaultContent = new UNMutableNotificationContent(); defaultContent.Title = "日常通知标题"; // 非周一显示的标题 defaultContent.Body = "你的通知内容"; defaultContent.Sound = UNNotificationSound.Default; // 设置触发时间:比如每天早上8点 var triggerTime = new NSDateComponents(); triggerTime.Hour = 8; triggerTime.Minute = 0; // 创建每日重复的触发器 var dailyTrigger = UNCalendarNotificationTrigger.CreateTrigger(triggerTime, repeats: true); // 创建唯一ID的请求,避免重复添加 var notificationRequest = UNNotificationRequest.FromIdentifier("DailyReminder", defaultContent, dailyTrigger); // 添加到通知中心 UNUserNotificationCenter.Current.AddNotificationRequest(notificationRequest, error => { if (error != null) { Console.WriteLine($"添加通知失败:{error.LocalizedDescription}"); } });
二、动态修改周一的通知标题
接下来要分APP前台和后台/锁屏两种情况处理,因为不同场景下修改通知内容的方式不一样:
1. APP前台时修改标题
在AppDelegate中实现UNUserNotificationCenterDelegate的WillPresentNotification方法,当APP在前台收到通知时,判断当前日期是否为周一,替换标题后再展示:
// 记得在FinishedLaunching里设置Delegate:UNUserNotificationCenter.Current.Delegate = this; [Export("userNotificationCenter:willPresentNotification:withCompletionHandler:")] public void WillPresentNotification(UNUserNotificationCenter center, UNNotification notification, Action<UNNotificationPresentationOptions> completionHandler) { var currentDate = NSDate.Now; var calendar = NSCalendar.CurrentCalendar; // iOS中Weekday=1是周日,2是周一,以此类推 var weekday = calendar.GetComponent(NSCalendarUnit.Weekday, currentDate); var mutableContent = notification.Content.MutableCopy() as UNMutableNotificationContent; if (weekday == 2) { mutableContent.Title = "周一专属标题"; } // 展示修改后的通知 completionHandler(UNNotificationPresentationOptions.Alert | UNNotificationPresentationOptions.Sound); }
2. 后台/锁屏时修改标题
如果APP在后台或者设备处于锁屏状态,系统会直接展示通知,这时候需要借助**通知服务扩展(Notification Service Extension)**来修改内容:
- 在你的Xamarin.iOS解决方案中添加一个新的「Notification Service Extension」项目;
- 在扩展的
NotificationService.cs中修改DidReceiveNotificationRequest方法:
using Foundation; using UserNotifications; namespace YourExtensionNamespace { [Register("NotificationService")] public class NotificationService : UNNotificationServiceExtension { Action<UNNotificationContent> ContentHandler { get; set; } UNMutableNotificationContent BestAttemptContent { get; set; } public override void DidReceiveNotificationRequest(UNNotificationRequest request, Action<UNNotificationContent> contentHandler) { ContentHandler = contentHandler; BestAttemptContent = (UNMutableNotificationContent)request.Content.MutableCopy(); // 判断是否为周一 var currentDate = NSDate.Now; var calendar = NSCalendar.CurrentCalendar; var weekday = calendar.GetComponent(NSCalendarUnit.Weekday, currentDate); if (weekday == 2) { BestAttemptContent.Title = "周一专属标题"; } // 提交修改后的通知内容 ContentHandler(BestAttemptContent); } public override void TimeWillExpire() { // 超时 fallback,展示当前内容 ContentHandler(BestAttemptContent); } } }
额外注意事项
- 记得在APP启动时请求通知权限,否则通知无法展示;
- iOS的
NSCalendarUnit.Weekday取值要注意:1=周日,2=周一,7=周六,别搞混了; - 通知服务扩展需要确保项目配置正确,无需额外配置推送权限,本地通知也能生效。
这样设置后,每天同一时间只会触发一个通知,周一自动替换为专属标题,完全不会出现重复通知的问题。
内容的提问来源于stack exchange,提问作者Seif Selmi
相关产品推荐
相关产品推荐

