.NET 7 MAUI iOS前台无法接收推送通知问题求助
.NET MAUI iOS前台推送通知不响应的解决方法
核心问题分析
从Xamarin.Forms迁移到MAUI后,iOS前台推送无响应的主要原因在于:
- MAUI的
MauiUIApplicationDelegate生命周期处理逻辑与Xamarin的FormsApplicationDelegate存在差异 - 未确保
UNUserNotificationCenter的Delegate实例不被GC回收 - 未正确实现iOS 10+要求的
WillPresentNotification方法(前台显示通知的核心入口)
正确实现方案
以下是经过验证的代码实现,直接在AppDelegate中处理通知逻辑,避免Delegate被回收的问题:
[Register("AppDelegate")] public class AppDelegate : MauiUIApplicationDelegate, UNUserNotificationCenterDelegate { protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp(); public override bool FinishedLaunching(UIApplication app, NSDictionary options) { // 1. 请求通知权限(必须包含Alert/Sound等权限) UNUserNotificationCenter.Current.RequestAuthorization( UNAuthorizationOptions.Alert | UNAuthorizationOptions.Sound | UNAuthorizationOptions.Badge, (granted, error) => { if (granted) { // 在主线程注册远程通知 DispatchQueue.MainQueue.DispatchAsync(() => { UIApplication.SharedApplication.RegisterForRemoteNotifications(); }); } }); // 2. 将当前AppDelegate设置为通知中心Delegate,确保不会被GC回收 UNUserNotificationCenter.Current.Delegate = this; return base.FinishedLaunching(app, options); } // 获取DeviceToken(正常工作) [Export("application:didRegisterForRemoteNotificationsWithDeviceToken:")] public void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken) { // 转换token格式并发送到服务器 var token = deviceToken.Description.Trim('<', '>').Replace(" ", ""); Console.WriteLine($"Device Token: {token}"); } // 前台接收通知的核心方法,必须实现才能显示通知 [Export("userNotificationCenter:willPresentNotification:withCompletionHandler:")] public void WillPresentNotification(UNUserNotificationCenter center, UNNotification notification, Action<UNNotificationPresentationOptions> completionHandler) { // 根据iOS版本选择显示方式 var presentationOptions = UIDevice.CurrentDevice.CheckSystemVersion(14, 0) ? UNNotificationPresentationOptions.Banner | UNNotificationPresentationOptions.Sound : UNNotificationPresentationOptions.Alert | UNNotificationPresentationOptions.Sound; // 必须调用completionHandler,否则系统不会显示通知 completionHandler(presentationOptions); // 处理通知内容(如解析userInfo) var userInfo = notification.Request.Content.UserInfo; Console.WriteLine($"前台收到通知内容: {userInfo}"); } // 用户点击通知时触发(前台/后台均生效) [Export("userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:")] public void DidReceiveNotificationResponse(UNUserNotificationCenter center, UNNotificationResponse response, Action completionHandler) { // 处理通知点击逻辑 var userInfo = response.Notification.Request.Content.UserInfo; Console.WriteLine($"用户点击通知: {userInfo}"); // 必须调用completionHandler completionHandler(); } // 兼容iOS 10以下版本的旧通知接收方法(可选保留) [Export("application:didReceiveRemoteNotification:")] public void ReceivedRemoteNotification(UIApplication application, NSDictionary userInfo) { Console.WriteLine($"收到远程通知(旧API): {userInfo}"); } }
关键注意事项
- Delegate实例持有:必须将
UNUserNotificationCenter.Current.Delegate设置为长期存在的实例(如AppDelegate本身),避免使用临时创建的UserNotificationCenterDelegate对象(易被GC回收导致Delegate失效) - completionHandler调用:
WillPresentNotification和DidReceiveNotificationResponse中必须调用对应的completionHandler,这是iOS系统的强制要求,否则会导致通知处理异常 - 权限请求:启动时必须请求包含
Alert的通知权限,否则即使收到通知也无法在前台显示 - API版本兼容:iOS 10+已使用
UNUserNotificationCenter的Delegate方法替代旧的ReceivedRemoteNotification,前台通知只会触发WillPresentNotification
内容的提问来源于stack exchange,提问作者user3125174
相关产品推荐
相关产品推荐

