und danke für Ihren Rat!Wie Abrufen des CKRecord von der CKSubscriptionID, die von FetchAllSubscriptionsWithCompletionHandler kam?
Ich benutze fetchAllSubscriptionsWithCompletionHandler, und ich sehe die SubscrictionID von jedem CKSubscription, nachdem die Push-Benachrichtigung gesendet wird. Wie kann ich den CKRecord von der SubscriptionID abrufen?
Ich sehe die Remote Push Notification nicht von einer CKReference, die erstellt wurde. Ich kann den CKRecord und den zugehörigen Datensatz über CloudKit DashBoard anzeigen. Ich erhalte eine Push-Benachrichtigung, wenn der übergeordnete Datensatz erstellt wird, aber nicht, wenn die CKReference für den untergeordneten Datensatz erstellt wird.
-(void)SubscribeForReference:(CKRecord *)record
{
NSUserDefaults *trackSubscription = [NSUserDefaults standardUserDefaults];
BOOL hasSubscribed = [[NSUserDefaults standardUserDefaults] objectForKey:@"alreadySubscribedForReference"] != nil;
//BOOL hasSubscribed = [trackSubscription objectForKey:@"alreadySubscribedForReference"];
if (hasSubscribed == false) {
//creates a subscription based on a CKReference between two ckrecords
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"sentences == %@", record.recordID];
// 1) subscribe to record creations
CKSubscription *subscriptionRelation =
[[CKSubscription alloc] initWithRecordType:@"RecordTypeName"
predicate:predicate
options:CKSubscriptionOptionsFiresOnRecordCreation | CKSubscriptionOptionsFiresOnRecordUpdate | CKSubscriptionOptionsFiresOnRecordDeletion | CKSubscriptionOptionsFiresOnRecordUpdate];
//http://stackoverflow.com/questions/27371588/cloudkit-notifications
CKNotificationInfo *notificationInfo = [[CKNotificationInfo alloc] init];
// I added this because of apple's documentation
notificationInfo.desiredKeys = @[@"word",@"identifier"];
notificationInfo.alertLocalizationArgs = @[@"word"];
notificationInfo.alertLocalizationKey = @"%[email protected]";
notificationInfo.shouldBadge = YES;
subscriptionRelation.notificationInfo = notificationInfo;
[self.privateDatabase saveSubscription:subscriptionRelation completionHandler:^(CKSubscription * _Nullable subscription, NSError * _Nullable error) {
if (error == nil) {
[trackSubscription setObject:subscription.subscriptionID forKey:@"alreadySubscribedForReference"];
[trackSubscription synchronize];
}else
NSLog(@"something went wrong with saving the CKSubcription with error...\n%@\n",[error localizedDescription]);
}];
}
else{
NSLog(@"\nSubscribeForReference: ALREADY has subscription: %@ set for key 'alreadySubscribedForReference' \n\n ", [trackSubscription objectForKey:@"alreadySubscribedForReference"]);
}
}
Der Code unten lief, wenn die App gestartet wird, sofern eine Internetverbindung:
-(void)runWhenAppStarts
{
CKFetchSubscriptionsOperation *fetchSubscriptionsOperation = [CKFetchSubscriptionsOperation fetchAllSubscriptionsOperation];
fetchSubscriptionsOperation.fetchSubscriptionCompletionBlock = ^(NSDictionary *subscriptionsBySubscriptionID, NSError *operationError) {
if (operationError != nil)
{
// error in fetching our subscription
CloudKitErrorLog(__LINE__, NSStringFromSelector(_cmd), operationError);
if (operationError.code == CKErrorNotAuthenticated)
{
// try again after 3 seconds if we don't have a retry hint
//
NSNumber *retryAfter = operationError.userInfo[CKErrorRetryAfterKey] ? : @3;
NSLog(@"Error: %@. Recoverable, retry after %@ seconds", [operationError description], retryAfter);
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(retryAfter.intValue * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self subscribe];
});
}
}
else
{
if (self.subscribed == NO)
{
// our user defaults says we haven't subscribed yet
//
if (subscriptionsBySubscriptionID != nil && subscriptionsBySubscriptionID.count > 0)
{
// we already have our one CKSubscription registered with the server that we didn't know about
// (not kept track in our NSUserDefaults) from a past app install perhaps,
//
NSLog(@"\nsubscriptionsBySubscriptionID (dictionary) = %@\n",subscriptionsBySubscriptionID);
NSArray *allSubscriptionIDKeys = [subscriptionsBySubscriptionID allKeys];
NSLog(@"\nallSubscriptionIDKeys (array) = %@\n",allSubscriptionIDKeys);
if (allSubscriptionIDKeys != nil)
{
[self updateUserDefaults:allSubscriptionIDKeys[0]];
for (NSString *subscriptions in allSubscriptionIDKeys) {
NSLog(@"subscriptionID: %@\n",subscriptions);
}
}
}
else
{
// no subscriptions found on the server, so subscribe
NSLog(@"...starting subscriptions on server...\n");
[self startSubscriptions];
}
}
else
{
// our user defaults says we have already subscribed, so check if the subscription ID matches ours
//
NSLog(@"...our user defaults says we have already subscribed, with subscriptionsBySubscriptionID = %@\nso check if the subscription ID matches the one already stored in NSUserDefaults...\n",subscriptionsBySubscriptionID);
if (subscriptionsBySubscriptionID != nil && subscriptionsBySubscriptionID.count > 0)
{
// we already have our one CKSubscription registered with the server that
// we didn't know about (not kept track in our NSUserDefaults) from a past app install perhaps,
//
//NSDictionary *subscriptionsBySubscriptionID has a structure of @{key: value} == @{NSString: CKSubscription}
NSArray *allSubscriptionIDKeys = [subscriptionsBySubscriptionID allKeys];//contains the NSString representation of the subscriptionID.
NSArray *allSubscriptionIDVALUES = [subscriptionsBySubscriptionID allValues];// the values are the corresponding CKSubscription objects
for (CKSubscription *values in allSubscriptionIDVALUES) {
NSLog(@"\nCKSubscriptionValue = %@\n",values);
}
NSLog(@"\n...we already have our one CKSubscription registered with the server that..so lets look at allSubscriptionIDKeys =%@.\n\nvalues ...\nallSubscriptionIDVALUES = %@\n\n",allSubscriptionIDKeys,allSubscriptionIDVALUES);
if (allSubscriptionIDKeys != nil)
{
NSString *ourSubscriptionID = [[NSUserDefaults standardUserDefaults] objectForKey:kSubscriptionIDKey];
if (![allSubscriptionIDKeys[0] isEqualToString:ourSubscriptionID])
{
// our subscription ID doesn't match what is on the server, to update our to match
NSLog(@"...our subscription ID doesn't match what is on the server, going to update our NSUserDefaults...\n");
[self updateUserDefaults:allSubscriptionIDKeys[0]];
}
else
{
// they match, no more work here
NSLog(@"...iCloud server already has this subscriptionID, so do nothing.i.e. don't subscribe again..\n");
}
}
}
}
}
};
[self.privateDatabase addOperation:fetchSubscriptionsOperation];
}
Vielen Dank für Ihre Antwort! Die CKFetchSubscriptionsOperation * fetchAbonnementsOperation stammt aus Apples CloudPhoto-Beispielcode. Er ruft die ungelesenen cksubsription-IDs ab, die in iCloud gespeichert sind. Mein Problem ist jetzt, dass ich diese subscriptionIDs habe, wie bekomme ich das CKRecord, das die Push-Benachrichtigung verursachte? Ich habe beispielsweise 5 Datensätze zu iCloud hinzugefügt, aber nur 1-Push-Benachrichtigungen angezeigt. Wie erhalte ich den CKRecord von den anderen 4-CKRecords, die die Push-Benachrichtigung verursacht haben? –
Unten ist, was ich nach dem Abrufen der Abonnements, die auf iCloud sind, sehen kann ...... wir haben bereits unsere eine CKSubscription registriert mit dem Server, dass..alsallSubscriptionIDKeys = ( "AB3A1141-B86C-445E-8B4C -06142F2717C9" "98D91BCB-4D01-429F-90FB-D26C91993348" "54FF397E-373D-4289-B6C0-D553BF104CD1" "A07AC98F-AFCF-48D6-8DA1-A4F986B6E246" „3E283535-8BAA-4BD2 -8C8C-5E83F5274632" "F35ADFBE-FEEA-4531-9BF3-D76F70F4E87A" "CFD160D3-EB99-4933-965A-2EF5C1C68798" "F1C7DA0C-7DBA-4D4C-BB0A-34AD180FD410" ). –
Fetched CKSubscription Wörterbuch Werte ... allSubscriptionIDVALUES = ( „, subscriptionOptions = 7, subscriptionID = AB3A1141-B86C-445E-8B4C-06142F2717C9, zoneID = (null)> " –