Frage

ich ein UILocalNotification bezweckt, dass ich Setup mit Wiederholungsintervallen Tag, Woche und Monat. Ich habe keine Probleme überhaupt das Feuer Datum des Objekts zugreifen:

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

Aber ich habe Probleme das nächste Feuer Datum bekommen. Wenn ich das oben notification1 Objekt auf die Konsole ausdrucken, ich diese:

<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}

Dieses Objekt enthält irgendwo den Wert oder die Daten Ich brauche das nächste Feuer Datum anzuzeigen ... aber ich kann es nicht finden! Weiß jemand, wo ich kann es programmatisch bekommen?

Danke

War es hilfreich?

Lösung

Ich glaube nicht, das nächste Feuer Datum als Objekt vorhanden ist, sondern von fireDate und repeatInterval berechnet. Datum Berechnung kann mit verschiedenen Zeitzonen und anderen unangenehmen Dingen schwierig sein. In Ihrem Beispiel haben Sie eine tägliche Wiederholung ausgewählt und das nächste Feuer Datum berechnen Sie etwas entlang der Linien von tun können:

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];

Wenn Sie eine andere Wiederholung verwenden Intervall Sie den Code entsprechend ändern müssten. Wenn Sie NSMonthCalendarUnit verwenden wären, würden Sie components.month = 1 stattdessen verwenden.

Andere Tipps

Um das Weiter Feuer Datum für eine Wiederholung UILocalNotification zu berechnen, müssen Sie:

  1. Herauszufinden, die Menge an repeatInterval Es gab zwischen der ursprünglichen Feuer Datum der Mitteilung (das heißt seine fireDate Eigenschaft) und jetzt.
  2. Fügen sie die Mitteilung des fireDate.

Hier ist ein Ansatz:

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];

Dies funktioniert in vielen Szenarien, aber hier ist ein Szenario, in dem es wird nicht funktionieren:

Nehmen wir an, dass:

  • die Mitteilung der `fireDate ist 01/01 um 14.00 Uhr
  • die Mitteilung des repeatInterval ist NSDayCalendaryUnit (d wiederholen täglich)
  • Das Datum ist jetzt 01.08 um 15.00 Uhr

Der obige Code wird den Unterschied zu 7 Tagen (01/01 + 7 Tage = 08/01), fügen Sie sich fireDate und damit Satz nextFireDate auf 01.08 auf 14.00 Uhr berechnen. Aber das ist in der Vergangenheit, wir wollen nextFireDate sein 01.09 auf 14.00 Uhr !

Also, wenn Sie den obigen Code verwenden und Ihre repeatInterval ist NSDayCalendaryUnit, dann fügen Sie die folgenden Zeilen:

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];
}

Ich markierte diese Antwort als Community Wiki, es fühlen Sie sich frei zu bearbeiten, wenn Sie einen besseren Weg gefunden haben, um die Berechnung zu tun!

ich würde nur die repeatInterval bis das Datum liegt in der Zukunft hinzuzufügen:

-(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;
    }

Dies ist in Swift 4 und mit Kalender des nextDate func.

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)
    }

}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top