Pregunta

tengo un objeto UILocalNotification que he fijado con intervalos de repetición días, semanas y meses. Estoy teniendo ningún problema en absoluto el acceso a la fecha de fuego del objeto:

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

Pero estoy teniendo problema para conseguir la próxima fecha de fuego. Si imprimo el objeto notification1 anterior a la consola, me sale esto:

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

Este objeto contiene algún lugar del valor o datos que necesito para mostrar la siguiente fecha de fuego ... pero no puedo encontrar! ¿Alguien sabe donde puedo conseguirlo mediante programación?

Gracias

¿Fue útil?

Solución

No creo que la próxima fecha de fuego está disponible como una propiedad sino más bien calculada a partir de fireDate y repeatInterval. Fecha de cálculo puede ser complicado con diferentes zonas horarias y otras cosas desagradables. En su ejemplo se ha elegido una repetición diaria y para calcular la próxima fecha de fuego que puede hacer algo en la línea 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 utilizar algún otro intervalo de repetición que tendría que cambiar el código en consecuencia. Si se va a utilizar NSMonthCalendarUnit tendría que utilizar components.month = 1 lugar.

Otros consejos

Para calcular la Siguiente fecha de fuego durante un UILocalNotification repetir, usted tiene que:

  1. Averiguar la cantidad de repeatInterval que ha habido entre la fecha de fuego original de la notificación (es decir, su propiedad fireDate) y ahora.
  2. Añadir a fireDate de la notificación.

Aquí está uno de los enfoques:

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

Esto funciona de muchos escenarios, pero aquí hay un escenario en el que no va a funcionar:

Supongamos que:

  • de la notificación `fireDate es 01/01 a las 2:00 pm
  • repeatInterval de la notificación es NSDayCalendaryUnit (es decir, la repetición diaria)
  • La fecha actual es 08/01 a las 3:00 pm

El código anterior calcular la diferencia a 7 días (01/01 + 7 días = 08/01), añadirlos a fireDate, y por lo tanto conjunto nextFireDate a 08/01 a 14:00 . Pero eso está en el pasado, queremos nextFireDate sea 09/01 a las 14:00 !

Así que si se utiliza el código anterior y su repeatInterval es NSDayCalendaryUnit, a continuación, añadir estas líneas:

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

Esta respuesta ha resultado wiki de la comunidad, no dude en editar si usted ha encontrado una mejor manera de hacer el cálculo!

i simplemente añadiría la repeatInterval hasta que la fecha está en el futuro:

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

Este es en Swift 4 y el uso de nextDate func de calendario.

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

}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top