我正在使用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.
答案 0 :(得分:12)
2015 WWDC CloudKit Tips & Tricks video指出,如果要发送静默推送通知,则需要在notificationInfo字典上将shouldSendContentAvailable
设置为true,如下所示:
let notificationInfo = CKNotificationInfo()
notificationInfo.shouldSendContentAvailable = true
subscription.notificationInfo = notificationInfo
答案 1 :(得分:6)
您的通知注册对于iOS 8是正确的,但在OS X上,您必须使用registerForRemoteNotificationTypes:
NSApplication
方法,而在iOS 7上使用registerForRemoteNotificationTypes:
UIApplication
方法。 Documentation:
应用必须向Apple推送通知服务(APN)注册 接收应用推送提供商发送的远程通知。在iOS 8中 注册后有四个阶段:
- 注册您的应用支持使用的通知类型 registerUserNotificationSettings :.
- 注册接收推送 通过调用您的应用程序通过APN发送通知 registerForRemoteNotifications方法。
- 存储返回的设备令牌 成功注册到服务器的app委托,或 妥善处理注册失败。
- 转发设备令牌 应用程序的推送提供商。
醇>(在iOS 7中,而不是前两个步骤, 您通过调用registerForRemoteNotificationTypes:方法注册 UIApplication,在OS X中通过调用 registerForRemoteNotificationTypes:NSApplication的方法。)
同时实施didReceiveRemoteNotification:fetchCompletionHandler:
而不是didReceiveRemoteNotification
:
使用此方法处理应用的传入远程通知。 与应用程序不同:didReceiveRemoteNotification:方法,即 只有当您的应用程序在前台即系统中运行时才会调用 当您的应用在前台运行或运行时调用此方法 背景。此外,如果您启用了远程通知 在后台模式下,系统启动你的应用程序(或从中唤醒它) 暂停状态)并将其置于远程时的后台状态 通知到了。但是,系统不会自动进行 如果用户强行退出,请启动您的应用。在那种情况下, 用户必须重新启动应用程序或在系统之前重新启动设备 尝试再次自动启动您的应用。
如果您希望通知唤醒您的应用,请务必编辑Info.plist
并检查&#34;启用背景模式&#34;和#34;远程通知&#34;复选框:
由于您需要一个无声通知,根据文档,您应该只发送&#34; content-available&#34;标志为1,这样才对。但是还有其他用户在使用静音通知方面存在问题,显然,发送&#34;声音&#34;属性作为空字符串确实有帮助(see this question),因此您可以尝试将CKNotificationInfo.soundName
设置为空字符串。