You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xamarin iOS本地推送通知非调试及发布后无法正常工作求助

iOS本地推送在正式环境失效的问题排查与解决

我来帮你梳理这个Xamarin.Forms iOS本地推送的问题——调试正常但正式运行/发布后失效,大概率是权限配置、API兼容性或者委托时机的问题,咱们一步步来排查:


1. 先移除不必要的Background Modes配置

你当前勾选了Background fetch并设置了后台刷新间隔,但本地推送完全不需要这个权限。多余的后台模式可能会让系统对App的后台行为做额外限制,甚至在App Store审核时带来预期外的影响。建议:

  • 取消Info.plist里Background Modes下的Background fetch勾选
  • 删除UIApplication.SharedApplication.SetMinimumBackgroundFetchInterval(...)这句代码

2. 修正UNUserNotificationCenter委托的设置时机

iOS 10+的通知逻辑依赖UNUserNotificationCenterDelegate,但你的代码里是在授权请求之后才设置委托,这会导致部分通知回调无法被捕获。调整代码顺序:

public override bool FinishedLaunching(UIApplication app, NSDictionary options) {
    try {
        // 先设置委托,再处理授权
        UNUserNotificationCenter.Current.Delegate = new UserNotificationCenterDelegate();

        try {
            if (UIDevice.CurrentDevice.CheckSystemVersion(10, 0)) {
                UNUserNotificationCenter.Current.RequestAuthorization(UNAuthorizationOptions.Alert | UNAuthorizationOptions.Sound | UNAuthorizationOptions.Badge, (granted, error) => {
                    if (granted) {
                        InvokeOnMainThread(UIApplication.SharedApplication.RegisterForRemoteNotifications);
                    }
                });
            } 
            // 以下是旧版本兼容代码...
        } catch (Exception ex) {
            UIAlertView avAlert = new UIAlertView("FinishedLaunching Push Notification Exception", ex.Message, null, "OK", null);
            avAlert.Show();
        }
        LoadApplication(new MessengerClient.App());
    } catch (Exception ex) {
        NativeHelper.SendUnhandledException(ex, NativeHelper.iOS + ": FinishedLaunching");
    }
    return base.FinishedLaunching(app, options);
}

3. 确保UserNotificationCenterDelegate实现完整

你没有贴出这个委托的代码,但它是iOS 10+通知正常工作的核心。如果App在前台运行,必须在WillPresentNotification里明确允许通知展示;后台点击通知也需要在DidReceiveNotificationResponse里处理回调。示例实现:

public class UserNotificationCenterDelegate : UNUserNotificationCenterDelegate
{
    // 处理App前台收到通知的逻辑
    public override void WillPresentNotification(UNUserNotificationCenter center, UNNotification notification, Action<UNNotificationPresentationOptions> completionHandler)
    {
        // 允许弹窗、声音、角标展示
        completionHandler(UNNotificationPresentationOptions.Alert | UNNotificationPresentationOptions.Sound | UNNotificationPresentationOptions.Badge);
    }

    // 处理用户点击通知的逻辑
    public override void DidReceiveNotificationResponse(UNUserNotificationCenter center, UNNotificationResponse response, Action completionHandler)
    {
        // 这里可以添加通知点击后的业务逻辑
        completionHandler();
    }
}

4. 替换废弃的UILocalNotification API

UILocalNotification在iOS 10之后已经被官方废弃,虽然调试时兼容,但正式环境可能出现兼容性问题。建议改用新的UNNotificationRequest API:

// 替换你原来的通知调度代码
public void ScheduleLocalNotification(string title, string contentText)
{
    if (UIDevice.CurrentDevice.CheckSystemVersion(10, 0))
    {
        var content = new UNMutableNotificationContent();
        content.Title = title;
        content.Body = contentText;
        content.Sound = UNNotificationSound.Default;
        content.Badge = NSNumber.FromInt32(1);

        // 1秒后触发通知
        var trigger = UNTimeIntervalNotificationTrigger.CreateTrigger(1, false);
        var requestId = "LocalNotification_" + Guid.NewGuid().ToString();
        var request = UNNotificationRequest.FromIdentifier(requestId, content, trigger);
        
        UNUserNotificationCenter.Current.AddNotificationRequest(request, (error) =>
        {
            if (error != null)
            {
                // 这里可以添加错误日志记录
            }
        });
    }
    else
    {
        // 兼容iOS 9及以下的旧逻辑
        UILocalNotification notification = new UILocalNotification();
        notification.FireDate = NSDate.FromTimeIntervalSinceNow(1);
        notification.AlertAction = title;
        notification.AlertBody = contentText;
        notification.AlertTitle = title;
        notification.SoundName = UILocalNotification.DefaultSoundName;
        notification.ApplicationIconBadgeNumber = 1;
        UIApplication.SharedApplication.ScheduleLocalNotification(notification);
    }
}

5. 正式环境下主动检查通知权限

调试时权限可能已经授予,但用户从App Store下载后可能拒绝了权限。可以在App启动后主动检查并引导用户开启:

public void CheckNotificationPermission()
{
    if (UIDevice.CurrentDevice.CheckSystemVersion(10, 0))
    {
        UNUserNotificationCenter.Current.GetNotificationSettings((settings) =>
        {
            InvokeOnMainThread(() =>
            {
                if (settings.AuthorizationStatus != UNAuthorizationStatus.Authorized)
                {
                    var alert = new UIAlertController("需要通知权限", "请在设置中开启通知权限以接收提醒", UIAlertControllerStyle.Alert);
                    alert.AddAction(UIAlertAction.Create("去设置", UIAlertActionStyle.Default, (action) =>
                    {
                        UIApplication.SharedApplication.OpenUrl(new NSUrl(UIApplication.OpenSettingsUrlString));
                    }));
                    alert.AddAction(UIAlertAction.Create("取消", UIAlertActionStyle.Cancel, null));
                    
                    // 获取当前根控制器展示弹窗
                    var rootVC = UIApplication.SharedApplication.KeyWindow.RootViewController;
                    rootVC.PresentViewController(alert, true, null);
                }
            });
        });
    }
}

6. 检查Release模式编译设置

确保Release模式下没有优化掉通知相关代码:

  • 检查项目属性的编译选项,关闭"Link all assemblies"(如果开启的话,可能会误删通知依赖的API)
  • 确认通知授权、调度的代码在Release模式下正常编译执行

按照以上步骤调整后,应该能解决正式环境下本地推送失效的问题。

内容的提问来源于stack exchange,提问作者Vivek Patel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 00:07:39