CK订阅不工作
CKSubscription not working
我正在我的 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
时,它 returns 为空,此后每次我打开应用程序时,它都能正确获取它们。但是,当在一台设备上创建或删除记录时,比如 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
从未触发。
你有一个空的 alertbody
notificationInfo1.alertBody = @"";
有了它,当您的应用程序处于非活动状态时,您将不会收到推送通知。当您手动激活您的应用程序时,您将能够使用 CKFetchNotificationChangesOperation 查询通知。这是我在 EVCloudKitDao:
中如何使用它的片段
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 中收到通知。
我正在我的 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
时,它 returns 为空,此后每次我打开应用程序时,它都能正确获取它们。但是,当在一台设备上创建或删除记录时,比如 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
从未触发。
你有一个空的 alertbody
notificationInfo1.alertBody = @"";
有了它,当您的应用程序处于非活动状态时,您将不会收到推送通知。当您手动激活您的应用程序时,您将能够使用 CKFetchNotificationChangesOperation 查询通知。这是我在 EVCloudKitDao:
中如何使用它的片段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 中收到通知。