Comparer 2 évenements

Jean75Jean75 Membre
décembre 2014 modifié dans API UIKit #1

Bonjour à  tous,


 


Encore moi, je viens vous voir sur un problème sur lequel je bloque depuis presque 1 semaine, en essayant tout testé, sans aucun résultat.


 


J'arrive à  ajouter un événement au calendrier iOS sans difficultés.


 


 


J'aimerais pouvoir comparer si l'évenement que j'ajoute, se trouve déjà  dans le calendrier (s'il y a une occurence) et si c'est le cas l'ajouter (et autrement ne pas le faire), mais visiblement je m'y prends mal au vu du NSLog.


 


 


Voila ce que j'ai fait:



EKEventStore *store = [[EKEventStore alloc] init];

[store requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) {
        dispatch_async(dispatch_get_main_queue(), ^{
            if (!granted) {
                UIAlertView *alert=[[UIAlertView alloc] initWithTitle:@Accès aux calendrier message:@L'accès au calendrier est nécessaire pour utiliser cette fonctionnalité delegate:nil cancelButtonTitle:@OK otherButtonTitles: nil];
                [alert show];
            }
            
            
            for(int index=0; index<listeRdv.count;index++)
            {
                
                
                
                EKEvent *event = [EKEvent eventWithEventStore:store];
                
                Variables *objStatutCompte = [Variables getStatutCompte];
                
                NSString* titreEvent;
                
                if([objStatutCompte.statutCompte isEqualToString:@clt])
                {
                    titreEvent = [NSString stringWithFormat:@Intervention avec %@", listeRdv[index][@pSalarieNom]];
                    event.title=titreEvent;
                    
                }
                else if([objStatutCompte.statutCompte isEqualToString:@slr])
                {
                    titreEvent = [NSString stringWithFormat:@Intervention chez %@", listeRdv[index][@ClientNom]];
                    event.title=titreEvent;
                }
                
                NSString* adresseClient = [NSString stringWithFormat:@%@ %@", listeRdv[index][@AdresseRueNumero], listeRdv[index][@AdresseRue]];
                
                NSString* lieuEvent = [NSString stringWithFormat:@%@, %@", adresseClient, listeRdv[index][@AdresseVille]];
                
                
                event.location=lieuEvent;
                
                NSString* currentDay = [[listeRdv[index] objectForKey: @pDate] substringWithRange:NSMakeRange(0,2)];
                NSInteger jourCourant = [currentDay integerValue];
                
                NSString* currentMonth = [[listeRdv[index] objectForKey: @pDate] substringWithRange:NSMakeRange(3,2)];
                NSInteger mCourant = [currentMonth integerValue];
                
                NSString* currentYear = [[listeRdv[index] objectForKey: @pDate] substringWithRange:NSMakeRange(6,4)];
                NSInteger anCourante = [currentYear integerValue];
                
                NSString* dateDebut = [NSString stringWithFormat:@%ld-%ld-%02ld %@:00", (long)anCourante, (long)mCourant, (long)jourCourant, listeRdv[index][@pHeureDeb]];
                NSString* dateFin = [NSString stringWithFormat:@%ld-%ld-%02ld %@:00", (long)anneeCourante, (long)moisCourant, (long)jourCourant, listeRdv[index][@pHeureFin]];
                
                NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
                [dateFormatter setDateFormat:@yyyy-MM-dd HH:mm:ss];
                [dateFormatter setTimeZone:nil];
                NSDate* dateD = [dateFormatter dateFromString:dateDebut];
                
                NSDate* dateF = [dateFormatter dateFromString:dateFin];
                
                event.startDate=dateD;
                event.endDate=dateF;
                
                NSMutableArray *myAlarmsArray = [[NSMutableArray alloc] init];
                EKAlarm *alarm1 = [EKAlarm alarmWithRelativeOffset:-3600]; // 1 Hour
                [myAlarmsArray addObject:alarm1];
                
                event.alarms=myAlarmsArray;
                
                for(int i=0; i < eventList.count; i++){
                    
                    
                    if(![[[eventList objectAtIndex:i] title] isEqualToString:titreEvent]&& ![[[eventList objectAtIndex:i] startDate] isEqual:dateD])
                    {
                        NSLog(@Différent %@ %@ // %@ %@ ", titreEvent, dateD, [[eventList objectAtIndex:i] title], [[eventList objectAtIndex:i] startDate]);
                    
                        
                        [event setCalendar:[store defaultCalendarForNewEvents]];
                        NSError *err = nil;
                        [store saveEvent:event span:EKSpanThisEvent commit:YES error:&err];
                        
                        /*UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@à‰vénement ajouté
                         message:@L'événement a bien été ajouté
                         delegate:self
                         cancelButtonTitle:@Ok
                         otherButtonTitles:nil, nil];
                         [alert show];*/
                    }
                    else
                    {
                        NSLog(@Idem %@ %@ // %@ %@", titreEvent, dateD, [[eventList objectAtIndex:i] title], [[eventList objectAtIndex:i] startDate]);
                        /*UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@à‰vénement existant
                         message:@L'événement existe déjà 
                         delegate:self
                         cancelButtonTitle:@Ok
                         otherButtonTitles:nil, nil];
                         [alert show];*/
                        
                    }
                    
                }
                
            }
            
            
            
        });
    }];

J'aimerais vraiment comprendre mon erreur, et la règler d'ici lundi, car nous devons rendre l'application bientôt et c'est la dernière fonctionnalité restante.


 


 


Merci d'avance ;)


Réponses

  • Hello,


     


    Jamais travaillé avec ça mais tu as des identifiants des événements, il faut les utiliser pour la comparaison. 




     




    Declaration

    OBJECTIVE-C


    @property(nonatomic, readonly) NSString *eventIdentifier






    Discussion

    You can use this identifier to look up an event with the EKEventStore method eventWithIdentifier:.


    If the calendar of an event changes, its identifier most likely changes as well.




    https://developer.apple.com/library/mac/documentation/EventKit/Reference/EKEventClassRef/index.html#//apple_ref/occ/instp/EKEvent/eventIdentifier

  • Bon a priori mon problème est réglé merci samir.


     


    Il faut juste que je récupère le mois actuel pour le remplacer par la date/heure actuelle ici



    NSPredicate *fetchCalendarEvents = [store predicateForEventsWithStartDate:[NSDate date] endDate:endDate calendars:calendarArray];

    Une idée de comment faire s'il vous plait ?


  • Je rencontre toujours ce problème.


     


    Faut il utiliser le NSDateComponents ? Le NSDateFormatter ?


  • NSDateComponents normalement. Mais je n'ai pas trop compris ce que tu voulais faire.


  • Salut,


     


    J'ai pas bien saisie ta question. Tu veux récupérer tous les événements du mois actuel ? 


  • C'est bien cela oui Samir.


     


    Et pour cela je pense qu'il faut remplacer le [NSDate date], par 01/mois courant/année courante 00:00:00.


     


    Larme comment ça s'utilise du coup ? J'ai essayé de faire un NSDateComponents.month et il m'a rejeté en disant que c'est un int et qu'il veut une date


  • Le problème vient du fait que tu confond date et date. La date dans le langage courant est donnée par le jour/mois/année, alors que la date Cocoa est un instant absolu dans le temps qui ensuite peut se représenter différemment en fonction du calendrier utilisé et du temps local.


     


    Pour résoudre ton problème, il faut jongler avec NSDate qui représente un instant absolu dans le temps, NSCalendar qui représente un calendrier particulier et NSDateComponents qui facilite l'accès aux différentes composantes d'une date exprimée dans un calendrier particulier.


     


    Pour comprendre comment tout cela fonctionne il faut se référer au Date and Time Programming Guide.


  • Bonjour jpimbert,


     


    Merci pour cette explication.


     


    J'ai déjà  consulté le guide, mais ça m'a pas franchement aidé à  résoudre mon souci


  • Si j'ai compris ton exemple (et pas ton explication pas claire), tu cherches à  avoir la date du début du mois, c'est ça ?

    Maintes fois posée sur le net, et répondu sur StackOverFlow. Il faut bien utiliser NSDateComponents pour avoir au final une NSDate du début du mois.
  • Tu as bien compris.


     


    J'ai pourtant cherché et pas trouvé


  • C'est bon, c'est réglé merci à  tous ;)



    NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
        NSDateComponents *comp = [gregorian components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay) fromDate:[NSDate date]];
        [comp setDay:1];
        NSDate *firstDayOfMonthDate = [gregorian dateFromComponents:comp];
        
        
        NSPredicate *fetchCalendarEvents = [store predicateForEventsWithStartDate:firstDayOfMonthDate endDate:endDate calendars:calendarArray];
  • Joanna CarterJoanna Carter Membre, Modérateur

    Je viens de faire quelques commentaires sur ton code avant les messages les plus récents:



    EKEventStore *store = [[EKEventStore alloc] init];

    [store requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error)
    {
    dispatch_async(dispatch_get_main_queue(), ^
    {
    if (!granted)
    {
    UIAlertView *alert=[[UIAlertView alloc] initWithTitle:@Accès aux calendrier message:@L'accès au calendrier est nécessaire pour utiliser cette fonctionnalité delegate:nil cancelButtonTitle:@OK otherButtonTitles: nil];

    [alert show];

    return; // sinon, l'exécution continuera après les accolades
    }


    for(int index=0; index < listeRdv.count; index++)
    {
    EKEvent *event = [EKEvent eventWithEventStore:store];

    Variables *objStatutCompte = [Variables getStatutCompte];

    // pas nécessaire
    // NSString* titreEvent;

    if([objStatutCompte.statutCompte isEqualToString:@clt])
    {
    event.title = [NSString stringWithFormat:@Intervention avec %@", listeRdv[index][@pSalarieNom]];
    }
    else if([objStatutCompte.statutCompte isEqualToString:@slr])
    {
    event.title = [NSString stringWithFormat:@Intervention chez %@", listeRdv[index][@ClientNom]];
    }

    NSString* adresseClient = [NSString stringWithFormat:@%@ %@", listeRdv[index][@AdresseRueNumero], listeRdv[index][@AdresseRue]];

    // pas nécessaire
    // NSString* lieuEvent;

    event.location = [NSString stringWithFormat:@%@, %@", adresseClient, listeRdv[index][@AdresseVille]];

    // pourquoi les dates sont elles stockées comme NSString dans la listeRdv ?

    NSString* currentDay = [[listeRdv[index] objectForKey: @pDate] substringWithRange:NSMakeRange(0,2)];

    NSInteger jourCourant = currentDay.integerValue;

    NSString* currentMonth = [[listeRdv[index] objectForKey: @pDate] substringWithRange:NSMakeRange(3,2)];

    NSInteger mCourant = currentMonth.integerValue;

    NSString* currentYear = [[listeRdv[index] objectForKey: @pDate] substringWithRange:NSMakeRange(6,4)];

    NSInteger anCourante = currentYear.integerValue;


    NSCalendar *calendar = [NSCalendar calendarWithIdentifier:NSCalendarIdentifierGregorian];

    NSDateComponents *dateComponents = [[NSDateComponents alloc] init];


    dateComponents.day = jourCourant;

    dateComponents.month = mCourant;

    dateComponents.year = anCourante;

    NSString *heureDebutStr = [[listeRdv[index] objectForKey: @pHeureDeb] substringWithRange:NSMakeRange(0,2)];

    dateComponents.hour = heureDebutStr.integerValue;

    NSString *minuteDebutStr = [[listeRdv[index] objectForKey: @pHeureDeb] substringWithRange:NSMakeRange(3,2)];

    dateComponents.minute = minuteDebutStr.integerValue;

    event.startDate = [calendar dateFromComponents:dateComponents];


    dateComponents.month = moisCourant;

    dateComponents.year = anneeCourante;

    NSString *heureFinStr = [[listeRdv[index] objectForKey: @pHeureFin] substringWithRange:NSMakeRange(0,2)];

    dateComponents.hour = heureFinStr.integerValue;

    NSString *minuteFinStr = [[listeRdv[index] objectForKey: @pHeureFin] substringWithRange:NSMakeRange(3,2)];

    dateComponents.minute = minuteFinStr.integerValue;

    event.endDate = [calendar dateFromComponents:dateComponents];

    // inutile
    // NSString* dateDebut = [NSString stringWithFormat:@%ld-%ld-%02ld %@:00", (long)anCourante, (long)mCourant, (long)jourCourant, listeRdv[index][@pHeureDeb]];
    // NSString* dateFin = [NSString stringWithFormat:@%ld-%ld-%02ld %@:00", (long)anneeCourante, (long)moisCourant, (long)jourCourant, listeRdv[index][@pHeureFin]];
    //
    // NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    // [dateFormatter setDateFormat:@yyyy-MM-dd HH:mm:ss];
    // [dateFormatter setTimeZone:nil];
    // NSDate* dateD = [dateFormatter dateFromString:dateDebut];
    //
    // NSDate* dateF = [dateFormatter dateFromString:dateFin];
    //
    // event.startDate=dateD;
    // event.endDate=dateF;
  • Merci Joanna


  • Joanna CarterJoanna Carter Membre, Modérateur
    décembre 2014 modifié #15

    J'ai oublié quelque chose. Dans ce code :



    if([objStatutCompte.statutCompte isEqualToString:@clt])
    {
    event.title = [NSString stringWithFormat:@Intervention avec %@", listeRdv[index][@pSalarieNom]];
    }
    else if([objStatutCompte.statutCompte isEqualToString:@slr])
    {
    event.title = [NSString stringWithFormat:@Intervention chez %@", listeRdv[index][@ClientNom]];
    }

    Qu'est-ce qui se serait passé si objeStatutCompte.statutCompte ne contenait ni "clt" ni "slr" ?


     


    Tu profiterais d'avoir un cas défaut qui lance une exception :



    if([objStatutCompte.statutCompte isEqualToString:@clt])
    {
    event.title = [NSString stringWithFormat:@Intervention avec %@", listeRdv[index][@pSalarieNom]];
    }
    else
    {
    if([objStatutCompte.statutCompte isEqualToString:@slr])
    {
    event.title = [NSString stringWithFormat:@Intervention chez %@", listeRdv[index][@ClientNom]];
    }
    else
    {
    NSException *exception = [NSException exceptionWithName:NSInvalidArgumentException reason:@Rdv clé inconnu userInfo:nil];

    @throw exception;
    }
    }

    En plus, tu as échangé les deux cas  ::)


  • Joanna CarterJoanna Carter Membre, Modérateur

    Mieux encore, c'est à  remplacer les "magic strings" par un enum :



    typedef NS_ENUM(NSUInteger, StatutCompte)
    {
    StatutCompteInconnu,
    StatutCompteClient,
    StatutCompteSalarie
    };


    @interface Variables : NSObject

    @property (nonatomic) StatutCompte statutCompte;

    ...

    @end

    Du coup, tu pourrais utiliser un switch, qui est moins susceptible aux erreurs d'orthographe pour les noms



    NSString *nom = nil;

    switch (objStatutCompte.statutCompte)
    {
    case StatutCompteClient:
    {
    nom = listeRdv[index][@ClientNom];
    }
    break;

    case StatutCompteSalarie:
    {
    nom = listeRdv[index][@pSalarieNom];
    }
    break;

    default:
    {
    NSException *exception = [NSException exceptionWithName:NSInvalidArgumentException reason:@Rdv clé inconnu userInfo:nil];

    @throw exception;
    }
    }

    event.title = [NSString stringWithFormat:@Intervention chez %@", nom];
Connectez-vous ou Inscrivez-vous pour répondre.