Domanda

Ho un oggetto UILocalNotification che ho installato con intervalli di ripetizione giorno, settimana e mese. Sto avendo alcun problemi a tutti l'accesso alla data di fuoco dell'oggetto:

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

Ma io sto avendo problemi ricevendo la prossima data di fuoco. Se stampo l'oggetto notification1 sopra alla console, ottengo questo:

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

Questo oggetto contiene da qualche parte il valore o dati che ho bisogno per visualizzare la successiva data di fuoco ... ma non riesco a trovarlo! Qualcuno sa dove posso ottenere a livello di codice?

Grazie

È stato utile?

Soluzione

Non credo che la prossima data di fuoco è disponibile come proprietà, ma piuttosto calcolata da fireDate e repeatInterval. Data di calcolo può essere difficile con diversi fusi orari e altre cose brutte. Nel tuo esempio si è scelto una ripetizione quotidiana e per calcolare la prossima data del fuoco si può fare qualcosa sulla falsariga di:

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

Se si utilizza un altro intervallo di ripetizione si dovrebbe modificare il codice di conseguenza. Se si sceglie di usare NSMonthCalendarUnit si dovrebbe usare components.month = 1 invece.

Altri suggerimenti

Per calcolare il Avanti data fuoco per un UILocalNotification ripetere, è necessario:

  1. Capire la quantità di repeatInterval c'è stato tra la data di fuoco originale della notifica (vale a dire la sua proprietà fireDate) e ora.
  2. li Aggiungi a fireDate della notifica.

Ecco un approccio:

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

Questo funziona in molti scenari, ma ecco uno scenario in cui non funzionerà:

Si supponga che:

  • della comunicazione `fireDate è 01/01 alle 2:00 pm
  • repeatInterval della notifica NSDayCalendaryUnit (cioè ripetizione giornaliera)
  • La data di oggi è 08/01 alle 3:00 pm

Il codice qui sopra calcolare la differenza a 7 giorni (01/01 + 7 giorni = 08/01), aggiungerli al fireDate, e quindi insieme nextFireDate a 08/01 alle 14:00 . Ma questo è nel passato, vogliamo nextFireDate essere 09/01 alle 14:00 !

Quindi, se si utilizza il codice di cui sopra e la vostra repeatInterval è NSDayCalendaryUnit, quindi aggiungere queste righe:

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

Ho segnato questa risposta come wiki comunità, sentitevi liberi di modificarlo Se si è trovato un modo migliore per fare il calcolo!

Vorrei solo aggiungere il repeatInterval fino a quando le bugie data futura:

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

Questo è in Swift 4 e l'utilizzo del calendario nextDate Funz.

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

}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top