当前位置: 首页 > 知识库问答 >
问题:

iOS10 UNUserNotificationCenter代表未调用。推送通知不工作

段溪叠
2023-03-14

为了在iOS10中获得推送通知而拼命工作。当前设置:

func应用程序(_应用程序:UIApplication, didFinishLaunchingwith Options启动选项:[UIApplication ationLaunchOptionsKey: any]?)-

if #available(iOS 10.0, *) {

            let center = UNUserNotificationCenter.current()
            center.delegate = self
            center.requestAuthorization(options: [.alert, .badge, .sound]) { (granted, error) in

                if error == nil {
                    print("DID REQUEST THE NOTIFICATION")
                    UIApplication.shared.registerForRemoteNotifications()
                }
            }
            print("DID SET DELEGATE")
        }

func应用程序中(_应用程序:UIApplication, didRegsterForRemote teNotificationsSusDeviceToken deviceToken: Data)

print("DID REGISTER FOR A REMOTE NOTIFICATION AND THE TOKEN IS \(deviceToken.base64EncodedString())"           
let request = UpdatePushNotificationSubscription_Request(deviceToken: deviceToken)
updatePushNotificationSubscriptionWorker.updateSubscription(request)

我已经检查了令牌是否正确上传到后端,它确实匹配。

我还实施了:

    @available(iOS 10.0, *)
    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {

        print("GOT A NOTIFICATION")

    }


    @available(iOS 10.0, *)
    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {

        //This is for the user tapping on the notification
        print("GOT A NOTIFICATION")
    }

我已经为所有目标设定了权利,并启用了推送:

现在,当我试图从后端发送消息时,设备没有收到任何消息。没有召集代表。不知道我做错了什么。Push适用于iOS9和android设备。有没有关于我可能做错了什么的指示?


共有3个答案

武睿
2023-03-14

我为此挣扎了一整天。有时我会收到通知,有时不会,但我永远无法获得要触发的userNotificationCenter(u:willPresent:completionHandler:)回调。

结果发现有两个问题。首先,我仍然有点困惑:我的目标部署版本设置为11.0,但我的项目设置为10.0。将项目更改为11.0是第一步。我不完全理解这一点,但10.0和11.0之间的通知处理可能有一些不同?

第二部分是通知中心代表。我注意到苹果在文档中的注释:-

重要的

在应用程序完成启动之前,必须将代理对象分配给UnuseNotificationCenter对象。例如,在iOS应用程序中,必须在应用程序委托的应用程序(:willFinishLaunchingWithOptions:)或应用程序(:didFinishLaunchingWithOptions:)方法中分配它。在调用这些方法后分配委托可能会导致错过传入的通知。

我在一个单独的“notification manager”类中进行了设置,回调也位于该类中(作为代理协议实现)。我在app delegate中将其实例化为一个实例变量,假设它会很早创建,不会引起问题。

我乱搞了一会儿实例化等,但只有当我在我的应用程序(_: didFinishLaunchingSusOptions:)方法中设置委托并在应用程序委托中实现委托回调时,我才设法修复它。

所以我的代码基本上变成了:-

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

    // You MUST do this HERE and nowhere else!
    UNUserNotificationCenter.current().delegate = self

    // other stuff

    return true
}

extension AppDelegate: UNUserNotificationCenterDelegate {

    // These delegate methods MUST live in App Delegate and nowhere else!

    @available(iOS 10.0, *)
    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        if let userInfo = notification.request.content.userInfo as? [String : AnyObject] {
        }
        completionHandler(.alert)
    }

    @available(iOS 10.0, *)
    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
        if let userInfo = response.notification.request.content.userInfo as? [String : AnyObject] {
        }
        completionHandler()
    }
}
仲孙俊贤
2023-03-14

尝试让您的AppReadate类实现UNUserNotificationCenter Readate协议,而不是实现该协议的单独类。

我为代表单独上了一节课,但它不起作用。这是我的代码运行时的样子:

import UIKit
import UserNotifications

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {

var window: UIWindow?

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application 

    UIApplication.shared.registerForRemoteNotifications()

    let center = UNUserNotificationCenter.current()
    center.delegate = self //DID NOT WORK WHEN self WAS MyOtherDelegateClass()

    center.requestAuthorization(options: [.alert, .sound, .badge]) {
        (granted, error) in
            // Enable or disable features based on authorization.
            if granted {
                // update application settings
            }
    }

    return true
}

func userNotificationCenter(_ center: UNUserNotificationCenter,
                            willPresent: UNNotification,
                            withCompletionHandler: @escaping (UNNotificationPresentationOptions)->()) {
    withCompletionHandler([.alert, .sound, .badge])
}

func userNotificationCenter(_ center: UNUserNotificationCenter,
                            didReceive: UNNotificationResponse,
                            withCompletionHandler: @escaping ()->()) {
    withCompletionHandler()
}

// and so forth for your other AppDelegate stuff
柯鸿云
2023-03-14

这个答案与iOS 10有关,使用的是UserNotifications框架。

您需要一个类来符合UnuseNotificationCenterDelegate协议。不管你是仅仅为此创建一个新类,还是将它添加到你的AppDelegate类中。不过我还是建议创建一个专门的课程。为了回答这个问题,我们假设您为它创建了一个UserNotificationController类。

该类可以有以下方法:

可选的func userNotificationCenter(_center: UNUserNotificationCenter, will当前通知: UNNotify, with CompletionHandler完成处理:@逃逸(UNNotificationPresentationOptions)-

可选func userNotificationCenter(center:UNUserNotificationCenter,didReceive response:UNNotificationResponse,withCompletionHandler completionHandler:@escaping()-

然后在AppDelegate中。应用程序(:didFinishLaunchingWithOptions:)方法,您需要在UnuseNotificationCenter上设置委托。current()对象到UserNotificationController类的实例。您可能需要使用共享实例。

向用户请求授权以启用通知,使用UNUserNotificationCenter.requestAuthoration(选项:CompletionHandler:)方法,并在CompletionHandler中,检查授予的值。如果true,则通过调用UIApplication.shared.registerForRemote te通知()注册远程通知。

现在,当应用程序收到推送通知时,可能会发生几种不同的情况。我试着在这里列出最常见的病例。

本地通知:

如果应用程序在前台,应用程序将调用UserNotificationController. userNotificationCenter(_: will Present: with CompletionHandler:)

如果应用程序在后台(运行或不运行),则在用户点击通知之前不会调用任何内容,此时,应用程序将打开并调用UserNotificationController。userNotificationCenter(uquo:didReceive:withCompletionHandler:)

远程通知:

有效载荷的内容将影响发生的情况。有效载荷有三种情况,a)只有正常的警报徽章,和声音选项b)包括可用内容选项(设置为1true)c)包括可变内容选项(设置为1true)。另外,从技术上讲,还有一种方法(d),即既有可用的内容,也有可变的内容,但这两种情况都会触发。

对于a)只需警报声音徽章信息:

这与本地通知的工作原理相同。

对于b)可用内容==true:

如果应用程序位于前台,UserNotificationController。调用userNotificationCenter(u:willPresent:withCompletionHandler:)

如果应用程序在后台(无论是否运行),AppDelegate。调用的是应用程序(u:didReceiveEmotentification:fetchCompletionHandler:),而不是UserNotificationController类中的任何方法。

对于c)可变内容==true:

如果您已将UNNotificationServiceExtension添加到您的应用程序中,它将处理通知并可以修改内容。无论您的主应用程序的状态如何,都会发生这种情况。如果(可选修改的)通知被用户点击,它就会像上面的本地通知一样处理。

如果没有UNNotificationServiceExpress,通知将被视为上面的正常远程通知。

补充说明:

使用可变内容时,必须在有效负载中包含警报信息,否则系统会将其视为不可变的,不会调用UnnotificationService Extension。修改后的通知必须仍然包含警报信息,否则将使用原始通知负载。遗憾的是,没有办法阻止用户看到通知。

当使用可用的内容时,如果用户在上次使用时强制退出应用程序,系统将不会重新启动应用程序或调用AppDelegate。应用程序(didReceiveEmotentification:fetchCompletionHandler:)。尽管它仍将显示任何警报,播放声音,并按照有效负载中的指示更新徽章。

 类似资料:
  • 我为沙盒iOS设置了推送通知,它们曾经工作过,但由于某种原因目前不工作。这是来自云观察日志的错误AWS SNS: 这是我的发送代码(AWS Lambda调用此代码): Lambda方法的返回数据: 我已经将问题缩小到不与我的lambda方法关联,因为我试图发布到直接从SNS控制台创建的endpoint。我还想知道为什么这个旧的实现在过去,一个月或两个月前,仍然有效,而现在不再有效。我认为这可能与过

  • 在我的iOS应用程序中,我需要通知用户远程设备上的一些紧急事件。无论应用程序的状态如何,用户都需要获得警报:如果应用程序处于前台、后台模式,甚至被杀死。 根据Apple文档,只有“voip”后台模式允许“保持活动”功能在后台与服务器保持连接。但“voip”模式只允许用于真正的voip应用程序,我的应用程序不提供任何voip服务。因此,我认为我的案例的唯一选择是使用Apple推送通知。 当用户的iO

  • 在这件事上被困了好几天。所以,我使用这个包来实现本地推送通知: https://github.com/zo0r/react-native-push-notification 我可以像这样获得本地计划通知: 我想在用户点击通知和应用程序打开时调用一个函数。为了实现以下目标,我在我的pp.js中这样做了: 但是,函数不会被调用。 我已经回答了以下几个问题,但是运气不好。 在通知上的本机消息推送不触发

  • 问题内容: 我正在使用第一个Android应用程序来使用Google Cloud Messaging(GCM)服务进行推送通知。我已经可以从服务器应用程序成功发送消息,并将消息的内容记录在客户端应用程序的GCMIntentService类中的onMessage事件中。但是,我在设备上看不到任何视觉信息,表明已收到消息。我希望该消息会出现在手机的下拉通知列表中,就像iPhone一样。是否必须手动编码

  • 首先,我想声明我一直在研究推送通知和web通知之间的关系,但我有点困惑。 我从这里读到PWAs的推送通知在Safari上的iOS(iPhone)不起作用:从PWA向iOS发送推送通知 然而,如果iPhone用户使用的是Chrome,这是否意味着它们可以工作呢?或者推送通知在任何浏览器上对iPhone中的PWAs都不起作用? 这就把我带到了web通知。web通知在后台对PWAs起作用吗?我的问题是w

  • 这是舱单 这是我的注册令牌类 这是我的Firebase服务类