- (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 = %@",error); } - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo { NSLog(@"%@",NSStringFromSelector(_cmd)); }
didRegisterForRemoteNotificationsWithDeviceTokenis使用令牌成功调用.但是didReceiveRemoteNotification从未被调用.
我通过改变我的应用程序的Mac版本和iPhone版本上的值进行了测试.两者都上传更改,但都不会触发通知.我也尝试在仪表板上直接更改值,但也不会导致通知.
我在这里缺少什么?
如果相关:我在OS X 10.10与XCode 6.4
我激活了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.
解决方法
An app must register with Apple Push Notification service (APNs) to
receive remote notifications sent by the app’s push provider. In iOS 8
and later,registration has four stages:
- Register the notification types your app supports using
registerUserNotificationSettings:.- Register to receive push
notifications via APNs by calling your app’s
registerForRemoteNotifications method.- Store the device token returned
to the app delegate by the server for a successful registration,or
handle registration failure gracefully.- Forward the device token to
the app’s push provider.(In iOS 7,instead of the first two steps,
you register by calling the registerForRemoteNotificationTypes: method
of UIApplication,and in OS X by calling the
registerForRemoteNotificationTypes: method of NSApplication.)
还要实现didReceiveRemoteNotification:fetchCompletionHandler:
而不是didReceiveRemoteNotification:
Use this method to process incoming remote notifications for your app.
Unlike the application:didReceiveRemoteNotification: method,which is
called only when your app is running in the foreground,the system
calls this method when your app is running in the foreground or
background. In addition,if you enabled the remote notifications
background mode,the system launches your app (or wakes it from the
suspended state) and puts it in the background state when a remote
notification arrives. However,the system does not automatically
launch your app if the user has force-quit it. In that situation,the
user must relaunch your app or restart the device before the system
attempts to launch your app automatically again.
如果要通知您唤醒应用程序,请确保编辑Info.plist并检查“启用后台模式”和“远程通知”复选框:
由于您想要一个静默的通知,根据文档,您应该只发送“内容可用”标志为1,这是正确的.但是还有其他用户在安静的通知中出现问题,显然,将“声音”属性作为空字符串发送帮助(see this question),所以您可以尝试将CKNotificationInfo.soundName设置为空字符串.