CK订阅不起作用
Posted
技术标签:
【中文标题】CK订阅不起作用【英文标题】:CKSubscription not working 【发布时间】:2015-06-18 21:26:27 【问题描述】:我正在我的 App Delegate 的 didFinishLaunchingWithOptions
方法中创建我的两个 CKSubscriptions
。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
// Override point for customization after application launch.
UIUserNotificationSettings *notificationSettings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:notificationSettings];
[[UIApplication sharedApplication] registerForRemoteNotifications];
_myContainer = [CKContainer containerWithIdentifier:@"iCloud.com.isaranjha.Copyfeed"];
_privateDatabase = [_myContainer privateCloudDatabase];
[_privateDatabase fetchSubscriptionWithID:@"subscription" completionHandler:^(CKSubscription *subscription, NSError *error)
if (subscription)
else
NSPredicate *predicate = [NSPredicate predicateWithValue:YES];
CKSubscription *subscription = [[CKSubscription alloc] initWithRecordType:@"Strings" predicate:predicate subscriptionID:@"subscription" options:CKSubscriptionOptionsFiresOnRecordCreation | CKSubscriptionOptionsFiresOnRecordDeletion | CKSubscriptionOptionsFiresOnRecordUpdate];
CKNotificationInfo *notificationInfo = [CKNotificationInfo new];
notificationInfo.alertBody = @"";
notificationInfo.shouldSendContentAvailable = YES;
subscription.notificationInfo = notificationInfo;
[_privateDatabase saveSubscription:subscription completionHandler:^(CKSubscription *subscription, NSError *error)
];
];
[_privateDatabase fetchSubscriptionWithID:@"subscription1" completionHandler:^(CKSubscription *subscription, NSError *error)
if (subscription)
else
NSPredicate *predicate1 = [NSPredicate predicateWithValue:YES];
CKSubscription *subscription1 = [[CKSubscription alloc] initWithRecordType:@"Images" predicate:predicate1 subscriptionID:@"subscription1" options:CKSubscriptionOptionsFiresOnRecordCreation | CKSubscriptionOptionsFiresOnRecordDeletion | CKSubscriptionOptionsFiresOnRecordUpdate];
CKNotificationInfo *notificationInfo1 = [CKNotificationInfo new];
notificationInfo1.shouldSendContentAvailable = YES;
notificationInfo1.alertBody = @"";
subscription1.notificationInfo = notificationInfo1;
[_privateDatabase saveSubscription:subscription1 completionHandler:^(CKSubscription *subscription, NSError *error)
];
];
ViewController *view = [[ViewController alloc] init];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:view];
self.window.rootViewController = navController;
return YES;
那些创建成功,当我注销NSError
时,它返回null,之后每次打开应用程序时,它都能正确获取它们。但是,当在一台设备(例如 iPhone)上创建或删除记录时,通知不会在另一台设备(例如 Mac)上触发(或未正确接收)。这就是我在 Mac 上收听通知的方式。
- (void)application:(NSApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
NSLog(@"CKSubscription received.");
CKQueryNotification *cloudKitNotification = [CKQueryNotification notificationFromRemoteNotificationDictionary:userInfo];
[[NSNotificationCenter defaultCenter] postNotificationName:@"CloudKitUpdated" object:nil userInfo:@@"ckNotification" : cloudKitNotification];
不幸的是,NSLog
永远不会触发。
【问题讨论】:
您可能需要查看您的开发人员配置文件配置。最常见的错误与使用错误配置文件的 sanbox 环境有关... 你到底是什么意思?我应该具体检查我的配置什么?你说的很有道理。 【参考方案1】:你有一个空的 alertbody
notificationInfo1.alertBody = @"";
这样,当您的应用处于非活动状态时,您将不会收到推送通知。当您手动激活您的应用程序时,您将能够使用 CKFetchNotificationChangesOperation 查询通知。这是我在EVCloudKitDao 中如何使用它的sn-p:
public func fetchChangeNotifications(skipRecordID: CKRecordID?, inserted:(recordID:String, item: EVCloudKitDataObject) -> Void, updated:(recordID: String, item: EVCloudKitDataObject) -> Void, deleted:(recordId: String) -> Void, completed:()-> Void)
var defaults = NSUserDefaults.standardUserDefaults()
var array: [NSObject] = [NSObject]()
var operation = CKFetchNotificationChangesOperation(previousServerChangeToken: self.previousChangeToken)
operation.notificationChangedBlock = notification in
if notification.notificationType == .Query
if var queryNotification = notification as? CKQueryNotification
array.append(notification.notificationID)
if skipRecordID != nil && skipRecordID?.recordName != queryNotification.recordID.recordName
if queryNotification.queryNotificationReason == .RecordDeleted
deleted(recordId: queryNotification.recordID.recordName)
else
EVCloudKitDao.publicDB.getItem(queryNotification.recordID.recordName, completionHandler: item in
EVLog("getItem: recordType = \(EVReflection.swiftStringFromClass(item)), with the keys and values:")
EVReflection.logObject(item)
if queryNotification.queryNotificationReason == .RecordCreated
inserted(recordID: queryNotification.recordID.recordName, item: item)
else if queryNotification.queryNotificationReason == .RecordUpdated
updated(recordID: queryNotification.recordID.recordName, item: item)
, errorHandler: error in
EVLog("ERROR: getItem for change notification.\n\(error.description)")
)
operation.fetchNotificationChangesCompletionBlock = changetoken, error in
var op = CKMarkNotificationsReadOperation(notificationIDsToMarkRead: array)
op.start()
EVLog("changetoken = \(changetoken)")
self.previousChangeToken = changetoken
if operation.moreComing
self.fetchChangeNotifications(skipRecordID, inserted: inserted, updated: updated, deleted: deleted, completed:completed)
else
completed()
operation.start()
当您的应用处于活动状态时,您应该会在应用 didReceiveRemoteNotification 中收到通知。
【讨论】:
好的,我认为我们在 CKFetchNotificationChangesOperation 上走在了正确的轨道上。您能否通过一个示例来更新您的答案,说明如何在选择我的菜单时将其与我的代码设置一起使用。以上是关于CK订阅不起作用的主要内容,如果未能解决你的问题,请参考以下文章