et merci pour vos conseils! J'utilise fetchAllSubscriptionsWithCompletionHandler et je vois l'identificateur subscritionID de chaque CKSubscription après l'envoi de la notification push. Comment puis-je récupérer le CKRecord à partir de l'abonnementID?Comment récupérer le CKRecord à partir du CKSubscriptionID provenant de fetchAllSubscriptionsWithCompletionHandler?
Je ne vois pas la notification Push à distance à partir d'un CKReference créé. Je peux voir le CKRecord et son enregistrement lié via CloudKit DashBoard. Je reçois une notification Push à partir de la création de son enregistrement parent, mais pas lors de la création de CKReference sur l'enregistrement enfant.
-(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"]);
}
}
Le code ci-dessous est couru lorsque l'application est lancée, à la condition est une connexion Internet:
-(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];
}
Merci pour votre réponse! CKFetchSubscriptionsOperation * fetchSubscriptionsOperation provient de l'exemple de code CloudPhoto d'Apple. Il récupère les ID cksubscription non lus qui sont stockés sur iCloud. Mon problème est maintenant que j'ai ces subscriptionID, comment puis-je obtenir le CKRecord qui a causé la notification push? Par exemple, j'ai ajouté 5 enregistrements à iCloud, mais j'ai seulement vu une notification 1-push. Comment récupérer le CKRecord des autres 4-CKRecords qui ont provoqué la notification push? –
Ci-dessous ce que je peux voir après avoir récupéré les abonnements qui sont sur iCloud ...... nous avons déjà notre un CKSubscription enregistré avec le serveur que ... permet de regarder allSubscriptionIDKeys = ( "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" ). –
dictionnaire valeurs tirées par les cheveux de CKSubscription ... allSubscriptionIDVALUES = ( «, subscriptionOptions = 7, subscriptionID = AB3A1141-B86C-445E-8B4C-06142F2717C9, zoneID = (nul)> " –