【问题标题】:CloudKit Push Notifications didReceiveRemoteNotification never calledCloudKit 推送通知 didReceiveRemoteNotification 从未调用
【发布时间】:2015-09-30 22:19:11
【问题描述】:

我正在使用 CloudKit 存储用户数据,并希望在记录更改或创建新记录时获得推送通知。但它不起作用......

我像这样注册订阅

- (void) updateCloudSubscriptions {

    NSPredicate *allPredicate = [NSPredicate predicateWithFormat:@"TRUEPREDICATE"];
    CKSubscription *newOrUpdateSubscription = [[CKSubscription alloc]
        initWithRecordType:kMyRecordType predicate:allPredicate options:
        (CKSubscriptionOptionsFiresOnRecordCreation | CKSubscriptionOptionsFiresOnRecordUpdate)];
    CKNotificationInfo *newOrUpdateNotificationInfo = [CKNotificationInfo new];
    newOrUpdateNotificationInfo.shouldBadge = NO;
    newOrUpdateNotificationInfo.shouldSendContentAvailable = YES;
    newOrUpdateSubscription.notificationInfo = newOrUpdateNotificationInfo;

    CKDatabase *publicDatabase = [[CKContainer containerWithIdentifier:kMyContainerID] 
        publicCloudDatabase];
    [publicDatabase saveSubscription:newOrUpdateSubscription 
         completionHandler:^(CKSubscription *theSubscription, NSError *saveError) {
        if (saveError){
            //error handling
        }
        NSLog(@"Subscription created");
    }];
}

这成功了。在 CloudKit 仪表板上,订阅已正确创建

在我的 AppDelegate 中,我现在拥有以下内容:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    UIUserNotificationSettings *notificationSettings = [UIUserNotificationSettings settingsForTypes:
        (UIUserNotificationTypeNone | UIUserNotificationTypeAlert |
        UIUserNotificationTypeBadge | UIUserNotificationTypeSound) categories:nil];
    [application registerUserNotificationSettings:notificationSettings];
    [application registerForRemoteNotifications];
}

并实现了这些委托方法:

- (void)application:(UIApplication *)application
    didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    NSLog(@"%@ with token = %@", NSStringFromSelector(_cmd), deviceToken);
}


- (void)application:(UIApplication *)application
    didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
    NSLog(@"%@ with error = %@", NSStringFromSelector(_cmd), error);
}


- (void)application:(UIApplication *)application 
    didReceiveRemoteNotification:(NSDictionary *)userInfo {
    NSLog(@"%@", NSStringFromSelector(_cmd));
}

didRegisterForRemoteNotificationsWithDeviceToken使用令牌成功调用。但是didReceiveRemoteNotification 永远不会被调用。

我通过更改我的应用程序的 Mac 版本和 iPhone 版本的值对此进行了测试。两者都上传更改,但都不会触发通知。我也尝试直接在仪表板上更改值,但这也没有引起通知。

我在这里错过了什么?

如果相关:我使用的是带有 XCode 6.4 的 OS X 10.10

我激活了apsd 日志记录,但只收到这样的消息:

Jul 12 18:25:29 Mac.local apsd[44748]: APSMessageStore - Saving database.
Jul 12 18:25:29 Mac.local apsd[44748]: APSMessageStore - Destroying database.
Jul 12 18:25:29 Mac.local apsd[44748]: APSMessageStore - Closed database.
Jul 12 18:25:29 Mac.local apsd[44748]: APSMessageStore - Reopening database
Jul 12 18:25:29 Mac.local apsd[44748]: APSMessageStore - Initializing database on thread: <NSThread: 0x7f8f1bf80dd0>{number = 55, name = (null)}
Jul 12 18:25:29 Mac.local apsd[44748]: APSMessageStore - Enabling auto vacuum.
Jul 12 18:25:29 Mac.local apsd[44748]: APSMessageStore - Enabling WAL journal mode.
Jul 12 18:25:29 Mac.local apsd[44748]: APSMessageStore - Enabling Foreign Key support.

【问题讨论】:

  • 当前存在更新通知的 CloudKit 错误。您是否尝试过添加新记录的应用程序?有关更新错误的更多信息,请参阅forums.developer.apple.com/thread/7288
  • @EdwinVermeer 这很有趣。但是,我也没有收到有关创建记录的通知。
  • 在目标应用程序功能中,您是否为远程通知开启了后台模式?
  • 发送通知时你的应用在后台吗?
  • 该应用程序一直在前台,但我添加了后台功能,但没有成功。

标签: ios objective-c macos apple-push-notifications cloudkit


【解决方案1】:

2015 WWDC CloudKit Tips & Tricks video 指出,如果您想发送静默推送通知,您需要在您的 notificationInfo 字典中将shouldSendContentAvailable 设置为 true,如下所示:

let notificationInfo = CKNotificationInfo()
notificationInfo.shouldSendContentAvailable = true
subscription.notificationInfo = notificationInfo

【讨论】:

  • 非常感谢您!当应用程序在后台运行超过 4 个小时时,我一直在努力解决没有被调用的方法。
【解决方案2】:

您的通知注册对于 iOS 8 是正确的,但在 OS X 上,您必须使用 NSApplicationregisterForRemoteNotificationTypes: 方法,在 iOS 7 上,您必须使用 UIApplicationregisterForRemoteNotificationTypes: 方法。 Documentation:

应用必须注册 Apple 推送通知服务 (APN) 才能 接收应用程序的推送提供者发送的远程通知。在 iOS 8 中 之后,注册分为四个阶段:

  1. 注册您的应用支持使用的通知类型 注册用户通知设置:。
  2. 注册接收推送 通过 APNs 通过调用您的应用程序的通知 registerForRemoteNotifications 方法。
  3. 存储返回的设备令牌 由服务器发送给应用程序委托以成功注册,或 优雅地处理注册失败。
  4. 将设备令牌转发到 应用程序的推送提供程序。

(在 iOS 7 中,不是前两个步骤, 您通过调用 registerForRemoteNotificationTypes: 方法进行注册 UIApplication,在 OS X 中通过调用 registerForRemoteNotificationTypes:NSApplication的方法。)

同时实现didReceiveRemoteNotification:fetchCompletionHandler: 而不是didReceiveRemoteNotification

使用此方法为您的应用处理传入的远程通知。 与 application:didReceiveRemoteNotification: 方法不同,它是 仅当您的应用程序在前台运行时调用,系统 当您的应用在前台运行时调用此方法或 背景。此外,如果您启用了远程通知 后台模式,系统启动您的应用程序(或从 挂起状态),并在远程时将其置于后台状态 通知到达。但是系统不会自动 如果用户强制退出它,则启动您的应用程序。在这种情况下, 用户必须在系统之前重新启动您的应用程序或重新启动设备 尝试再次自动启动您的应用。

如果您希望通知唤醒您的应用,请务必编辑 Info.plist 并选中“启用后台模式”和“远程通知”复选框:

由于您想要一个静默通知,根据文档,您应该只将“内容可用”标志发送到 1,这是正确的。但也有其他用户在无提示通知方面存在问题,显然,将“声音”属性作为空字符串发送确实有帮助 (see this question),因此您可以尝试将 CKNotificationInfo.soundName 设置为空字符串。

【讨论】:

  • 感谢您的详细回答,巴里斯。我确实在 OS X 上正确注册了;我的问题中没有列出代码。我一直在 iOS 8 上测试,所以那里的注册应该是正确的。当我测试时,这些应用程序一直在前台,但我还添加了后台通知和didReceiveRemoteNotification:fetchCompletionHandler:,但它仍然没有被调用。对我来说这很神秘......
  • @codingFriend1 查看我的更新答案:尝试将CKNotificationInfo.soundName 设置为空字符串。也许它有帮助,它似乎对others...
  • 是的!那是丢失的拼图。必须设置soundName 才能接收通知。很抱歉,我花了这么长时间来验证这一点,而您只收到了一半的赏金。无论如何:非常感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 2014-08-06
  • 2013-01-21
  • 1970-01-01
  • 2020-10-13
  • 2015-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多