我正在编写一个使用CloudKit的小应用程序.出于某种原因,当有与查询匹配的新记录时,应用程序不会收到任何通知.有没有人能够使这个功能工作?
我在应用程序中创建了新记录,但也在CloudKit仪表板中创建了新记录.记录非常简单,只有一个整数字段.
创建记录:
CKRecord *record = [[CKRecord alloc] initWithRecordType:kSISCloudKitRecordTypeTest];
record[@"value"] = @1;
[self.publicDatabase saveRecord:record completionHandler:^(CKRecord *record, NSError *error)
{
// this call succeeds, no error.
}];
Run Code Online (Sandbox Code Playgroud)
注册通知:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[application registerForRemoteNotifications];
}
Run Code Online (Sandbox Code Playgroud)
创建订阅:
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"value = 1"];
CKSubscription *subscription = [[CKSubscription alloc]
initWithRecordType:kSISCloudKitRecordTypeTest
predicate:predicate
options:CKSubscriptionOptionsFiresOnRecordCreation];
CKNotificationInfo *notificationInfo = [CKNotificationInfo new];
notificationInfo.alertLocalizationKey = @"LOCAL_NOTIFICATION_KEY";
notificationInfo.soundName = @"Party.aiff";
notificationInfo.shouldBadge = YES;
subscription.notificationInfo = notificationInfo;
[self.publicDatabase saveSubscription:subscription
completionHandler:^(CKSubscription *subscription, NSError *error)
{
// this succeeds as …Run Code Online (Sandbox Code Playgroud) 到目前为止,我无法订阅工作.(在我的设备上收到推送通知,订阅似乎已成功创建)
我一直在玩[CloudKitAtlas] [1].我在该自述文件的自述文件中做了它所说的内容:
要求
建立
- iOS 8.0 SDK和Xcode 6
- 在iCloud中启用CloudKit授权(来自功能)
- 更改容器名称以在开发者帐户中设置容器
我能够启动应用程序,它成功注册远程通知:
2014-06-09 11:15:17.712 CloudKitAtlas [841:220562]已注册使用令牌的推送通知:
我也能够创建记录,查询和订阅:
2014-06-09 11:15:21.966 CloudKitAtlas [841:220934]订阅了Item
如果我转到仪表板,我会看到几个订阅.但是当我创建新记录时没有任何反应,回调:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)info
Run Code Online (Sandbox Code Playgroud)
永远不会执行(注意:我在iPhone 5S上运行应用程序,而不是在模拟器上运行)
我正在使用带有显式bundle id(没有通配符)的调试签名,对于这个app id我也创建了相应的推送通知证书,虽然我只是下载它们,因为我与这些文件无关.
更新15/06/14显然这是苹果方面的一个错误,让我们等几个星期. https://developer.apple.com/library/content/samplecode/CloudAtlas/Introduction/Intro.html#//apple_ref/doc/uid/TP40014599
更新18/05/15
如果有人想知道很久以前Apple已经解决了这个问题,现在它就像魅力一样,虽然你需要做一些考虑:
Run Code Online (Sandbox Code Playgroud)UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes: UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert categories:nil];[application registerUserNotificationSettings:settings];
就这样
我想建立一个简单的CKSubscription通知我一个recordType被创建,怎么样?
publish-subscribe push-notification ios8 cloudkit cksubscription
如果我尝试使用以下代码订阅CloudKit:
NSPredicate *truePredicate = [NSPredicate predicateWithValue:YES];
CKSubscription *itemSubscription = [[CKSubscription alloc] initWithRecordType:RecordType
predicate:truePredicate
options:CKSubscriptionOptionsFiresOnRecordCreation | CKSubscriptionOptionsFiresOnRecordUpdate | CKSubscriptionOptionsFiresOnRecordDeletion];
CKNotificationInfo *notification = [[CKNotificationInfo alloc] init];
notification.alertBody = @"Item Added/Updated/Deleted!";
itemSubscription.notificationInfo = notification;
[self.publicDatabase saveSubscription:itemSubscription completionHandler:^(CKSubscription *subscription, NSError *error) {
if (error) {
// In your app, handle this error appropriately.
NSLog(@"An error occured in %@: %@", NSStringFromSelector(_cmd), error);
} else {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:subscription.subscriptionID forKey:kSubscriptionID];
[defaults synchronize];
}
}];
Run Code Online (Sandbox Code Playgroud)
我有时会收到此错误:
CKError 0x17558460:"服务器拒绝请求"(15/2000); server message ="内部服务器错误"; uuid = …
我在公共CloudKit数据库中创建订阅时遇到问题.在为第一个iCloud用户保存订阅时,代码工作正常,但是对于第二个iCloud用户尝试为相同的记录类型保存稍微不同的订阅失败.
这是保存订阅的代码(Swift中的答案也很好):
CKNotificationInfo *info = [[CKNotificationInfo alloc] init];
info.shouldSendContentAvailable = YES;
CKReference *ref = [[CKReference alloc] initWithRecordID:_ckUserID action:CKReferenceActionNone];
NSPredicate *pred = [NSPredicate predicateWithFormat:@"user == %@", ref];
NSString *subId = [NSString stringWithFormat:@"access-%@", _ckUserID.recordName];
CKSubscription *sub = [[CKSubscription alloc] initWithRecordType:@"access" predicate:pred subscriptionID:subId options:CKSubscriptionOptionsFiresOnRecordCreation | CKSubscriptionOptionsFiresOnRecordUpdate | CKSubscriptionOptionsFiresOnRecordDeletion];
sub.zoneID = [CKRecordZone defaultRecordZone].zoneID;
sub.notificationInfo = info;
CKModifySubscriptionsOperation *op = [[CKModifySubscriptionsOperation alloc] initWithSubscriptionsToSave:@[ sub ] subscriptionIDsToDelete:nil];
op.modifySubscriptionsCompletionBlock = ^(NSArray<CKSubscription *> *savedSubscriptions, NSArray<NSString *> *deletedSubscriptionIDs, NSError *operationError) {
if (operationError) {
RMLogError(@"Error trying to update user's …Run Code Online (Sandbox Code Playgroud) CKSubscriptiondoc说:当记录修改导致订阅触发时,服务器会向具有该订阅的所有设备发送推送通知,但对原始更改记录的设备除外.
让我们假设我有两个设备:device 1并device 2从不同的iCloud帐户登录.假设两个设备都订阅了某个记录类型的记录删除.
device 1创建一个记录,然后device 1删除它然后device 2得到通知 - 这是按照DOC,但..device 1创建一个记录然后device 2删除它然后device 2得到通知 - 我认为它不符合DOC,并且它不做任何感觉,device 2删除它所以device 1应该通知在设备1和设备2上设置订阅
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
application.registerUserNotificationSettings(UIUserNotificationSettings(forTypes: .Alert, categories: nil))
application.registerForRemoteNotifications()
let defaultContainer = CKContainer.defaultContainer()
let publicDatabase = defaultContainer.publicCloudDatabase
publicDatabase.fetchAllSubscriptionsWithCompletionHandler({subscriptions, error in
if error == nil {
if subscriptions.count == 0 …Run Code Online (Sandbox Code Playgroud) 我已经尝试了很多东西,似乎无法重置来自cloudKit的通知的徽章数量.有没有其他人遇到过这个问题.这是我尝试过的:
1)将徽章计数本地设置为0
application.applicationIconBadgeNumber = 0; (temporarily removes the badge count).
Run Code Online (Sandbox Code Playgroud)
没运气...
2)调用服务器以清除徽章计数
CKModifyBadgeOperation *oper = [[CKModifyBadgeOperation alloc] initWithBadgeValue:0];
[oper start];
Run Code Online (Sandbox Code Playgroud)
没运气...
3)拉入所有通知更改并将其全部标记为已读
NSMutableArray *array = [NSMutableArray array];
CKFetchNotificationChangesOperation *operation = [[CKFetchNotificationChangesOperation alloc] initWithPreviousServerChangeToken:nil];
operation.notificationChangedBlock = ^(CKNotification *notification) {
[array addObject:notification.notificationID];
};
operation.completionBlock = ^{
CKMarkNotificationsReadOperation *op = [[CKMarkNotificationsReadOperation alloc] initWithNotificationIDsToMarkRead:array];
[op start];
};
[operation start];
Run Code Online (Sandbox Code Playgroud)
再一次没有运气......
任何建议将不胜感激!谢谢,克里斯
push-notification apple-push-notifications ios8 cloudkit cksubscription
编辑:今天在2015年8月27日重新测试,它再次运作,苹果已修复它.
我有一个处于开发模式的应用程序.该应用程序使用CKSubscription来获取服务器上的更改通知,为所有三个选项配置:创建,更新,删除.一切都运行正常但最近在回归测试期间我发现应用程序没有收到有关记录更新的通知,创建和删除通知仍然有效.正如我在仪表板上检查的那样,所有三个选项都正确设置了susbcription类型,并且应用程序已注册CKSubscription,因为它是在几天前工作时才像魅力一样.我没有收到CloudKit的任何错误.重置开发环境没有帮助.我已经重新测试了我确信它正在工作的版本,并得到了相同的结果.
知道可能导致这个问题的原因,我还应该检查/尝试什么?
附加信息: 我猜服务器端可能出现问题.我没有更改我订阅CloudKit事件和处理推送通知的代码中的任何内容 - 无论如何,它正在工作的版本不再获得更新通知.我正在处理的应用程序已发布,因此更改容器是不行的.不确定这是否会导致问题,只是想提一下:应用程序使用相同的容器将核心数据存储在云中 - 应用程序升级的目标是将数据迁移到CloudKit并将其用作云专门存储.令人困惑的是,一切都运行良好数周并突然停止工作,没有任何明确的原因,可能是因为密集测试的负载效应,添加记录类型......
使用从头开发的应用程序测试: 我编写了一个简单的测试应用程序来检查接收通知.我只能收到有关创建记录的通知.我的代码出了什么问题:
import UIKit
import CloudKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
let container = CKContainer.defaultContainer()
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let settings = UIUserNotificationSettings(forTypes: .Alert, categories: nil)
application.registerUserNotificationSettings(settings)
application.registerForRemoteNotifications()
return true
}
func application(application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: NSError) {
println("didFailToRegisterForRemoteNotificationsWithError: \(error)")
}
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
println("didRegisterForRemoteNotificationsWithDeviceToken: \(deviceToken)")
subscribe()
}
func subscribe() {
// let predicate = NSPredicate(format: …Run Code Online (Sandbox Code Playgroud) 我创建了一个创建和更新订阅.创作总是很完美,我从其他设备获得推送通知.更新发送到iCloud,您可以在那里看到它们,但推送通知不会传递给设备.
- (void)subscribeWithType:(NSString*)type completionHandler:(void(^)(CKSubscription *))completionHandler
{
if (self.enabled == NO || _available == NO || _reachability.currentReachabilityStatus != ReachableViaWiFi)
{
if (completionHandler)
{
dispatch_async(dispatch_get_main_queue(), ^{
completionHandler(nil);
});
}
return;
}
NSPredicate *truePredicate = [NSPredicate predicateWithValue:YES];
CKSubscriptionOptions options = CKSubscriptionOptionsFiresOnRecordCreation | CKSubscriptionOptionsFiresOnRecordUpdate;
CKSubscription *subscription = [[CKSubscription alloc] initWithRecordType:type
predicate:truePredicate
subscriptionID:[CTUtils GetUUID]
options:options];
CKNotificationInfo *notification = [[CKNotificationInfo alloc] init];
notification.shouldSendContentAvailable = YES;
notification.alertLocalizationKey = @"";
notification.shouldBadge = NO;
subscription.notificationInfo = notification;
CKModifySubscriptionsOperation *operation = [[CKModifySubscriptionsOperation alloc] initWithSubscriptionsToSave:@[subscription] subscriptionIDsToDelete:nil];
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
__block …Run Code Online (Sandbox Code Playgroud) push-notification apple-push-notifications ios cloudkit cksubscription
我不太了解有关订阅的信息.我有私人数据库.我创建了一个订阅表.如果我在一个iCloud帐户下订阅了两个设备,则会发生错误:订阅时出错:
CKError 0x165c6ac0:"服务器拒绝请求"(15/2032); server message ="订阅与'C6051A24-2DB5-47EA-98D2-7D8786AA6D3B'重复"; uuid = 48AC7472-006A-4FD7-84A9-DB342C83C199; container ID ="iCloud.com.*.*"
NSPredicate *truePredicate = [NSPredicate predicateWithValue:YES];
CKSubscription *itemSubscription = [[CKSubscription alloc] initWithRecordType:RecordType
predicate:truePredicate
options:CKSubscriptionOptionsFiresOnRecordCreation | CKSubscriptionOptionsFiresOnRecordUpdate];
CKNotificationInfo *notification = [[CKNotificationInfo alloc] init];
notification.shouldSendContentAvailable = YES;
notification.alertLocalizationKey = @"";
notification.shouldBadge = NO;
itemSubscription.notificationInfo = notification;
[self.privateDatabase saveSubscription:itemSubscription completionHandler
Run Code Online (Sandbox Code Playgroud)
也许我做错了什么?我需要对两台设备做什么才能收到订阅通知?
编辑:
也.我只创建一个订阅.如果我使用方法fetchAllSubscriptionsWithCompletionhandler,我会看到每个表的3-4个订阅.但这很奇怪,因为我只创造了一个.当我收到通知时,我会看到更多通知.