Question

J'ai un objet UILocalNotification que j'ai installé avec des intervalles réguliers jour, semaine et mois. J'ai aucun problème du tout accès à la date d'incendie de l'objet:

[cell.detailTextLabel setText:[notification1.fireDate description]];

Mais j'ai des problèmes à obtenir la prochaine date d'incendie. Si j'imprimer l'objet notification1 ci-dessus à la console, je reçois ceci:

<UIConcreteLocalNotification: 0x613e060>{fire date = 2010-11-29 03:53:52 GMT, time zone = America/Denver (MST) offset -25200, repeat interval = 16, next fire date = 2010-11-30 03:53:52 GMT}

Cet objet contient quelque part la valeur ou les données dont j'ai besoin pour afficher la prochaine date de feu ... mais je ne peux pas le trouver! Est-ce que quelqu'un sait où je peux l'obtenir par programmation?

Merci

Était-ce utile?

La solution

Je ne pense pas que la prochaine date d'incendie est disponible comme une propriété mais plutôt calculée à partir fireDate et repeatInterval. calcul de la date peut être difficile avec les différents fuseaux horaires et autres choses désagréables. Dans votre exemple, vous avez choisi une répétition quotidienne et de calculer la prochaine date de feu, vous pouvez faire quelque chose le long des lignes de:

NSCalendar *calendar = localNotif.repeatCalendar;
if (!calendar) {
  calendar = [NSCalendar currentCalendar];
}

NSDateComponents *components = [[[NSDateComponents alloc] init] autorelease];
components.day = 1;
NSDate *nextFireDate = [calendar dateByAddingComponents:components toDate:localnotif.fireDate options:0];

Si vous utilisez une autre répétition d'intervalle vous devez modifier le code en conséquence. Si vous deviez utiliser NSMonthCalendarUnit vous devez utiliser components.month = 1 à la place.

Autres conseils

Pour calculer le suivant Date de feu pour un UILocalNotification répéter, vous devez:

  1. Figure le montant de repeatInterval il y a eu entre la date d'incendie d'origine de la notification (à savoir sa propriété de fireDate) et maintenant.
  2. les Ajouter au fireDate de la notification.

Voici une approche:

NSCalendar *calendar = [NSCalendar autoupdatingCurrentCalendar];

NSDateComponents *difference = [calendar components:notif.repeatInterval
                                           fromDate:notif.fireDate
                                             toDate:[NSDate date]
                                            options:0];

NSDate *nextFireDate = [calendar dateByAddingComponents:difference
                                                 toDate:notif.fireDate
                                                options:0];

Cela fonctionne dans de nombreux scénarios, mais voici un scénario où il ne fonctionnera pas:

Supposons que:

  • `fireDate est de la notification 01/01 à 14h00
  • est repeatInterval (à savoir la répétition quotidienne) de NSDayCalendaryUnit de la notification
  • La date est maintenant à 08/01 15h00

Le code ci-dessus calcule la différence de 7 jours (01/01 + 7 jours = 08/01), les ajouter à fireDate, et donc ensemble nextFireDate 08/01 à 14 heures . Mais ce qui est du passé, nous voulons nextFireDate être 09/01 à 14 heures !

Donc si vous utilisez le code ci-dessus et votre repeatInterval est NSDayCalendaryUnit, puis ajoutez ces lignes:

if ([nextFireDate timeIntervalSinceDate:[NSDate date]] < 0) {
    //next fire date should be tomorrow!
    NSDateComponents *extraDay = [[NSDateComponents alloc] init];
    extraDay.day = 1;
    nextFireDate = [calendar dateByAddingComponents:extraDay toDate:nextFireDate options:0];
}

J'ont pensé que cet wiki de la communauté, ne hésitez pas à modifier si vous avez trouvé une meilleure façon de faire le calcul!

Je voudrais simplement ajouter repeatInterval jusqu'à ce que les mensonges de date dans l'avenir:

-(NSDate*)nextFireDateForNotification:(UILocalNotification*)notification {
        NSCalendar *calendar = notification.repeatCalendar;
        if (!calendar) {
            calendar = [NSCalendar currentCalendar];
        }

        NSDate* date = [notification.fireDate copy];
        while (date.timeIntervalSinceNow > 0) {
            date = [calendar dateByAddingUnit:notification.repeatInterval value:1 toDate:date options:0];
        }
        return date;
    }

est Swift 4 et en utilisant func nextDate du calendrier.

extension UILocalNotification {

    var nextFireDate: Date? {
        guard let fireDate = fireDate else { return nil }

        let today = Date()
        let cal = Calendar.current

        if fireDate.compare(today) == .orderedDescending {
            return fireDate
        }

        let s: Set<Calendar.Component>
        switch repeatInterval {
        case .year: s = [.month, .day, .hour, .minute, .second]
        case .month: s = [.day, .hour, .minute, .second]
        case .day: s = [.hour, .minute, .second]
        case .hour: s = [.minute, .second]
        case .minute: s = [.second]
        default: return nil // Not supporting other intervals
        }

        let components = cal.dateComponents(s, from: fireDate)
        return cal.nextDate(after: today, matching: components, matchingPolicy: .nextTimePreservingSmallerComponents)
    }

}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top