简体   繁体   中英

NSNotifications For A Date In The Past

I am coding an app that has a lot of dates that are based in the past. For instance, an anniversary date. Let's say this date is December 25th, 2000.

The user picks this date from a date picker and then the date is saved to the user's device. (so imagine the date saved is December 25th, 2000)

While thinking of how I was going to code the NSNotifications, I realized my biggest task (now seeming impossible) is how will I be able to send the user a reminder of a date that is in the future but based on a date in the past.

Example :
Anniversary date is December 25th, 2000

Remind User Every Year of December 25th.

I imagine that there must be a way, but my searches have come up empty handed.

Not sure what language you are using, but basic logic here is once user selected a date, setup a local notification for the closes date, then set the repeat to kCFCalendarUnitYear

Example code in objective-C

-(void)setAlert:(NSDate *)date{
    //Note date here is the closest anniversary date in future you need to determine first
    UILocalNotification *localNotif = [[UILocalNotification alloc]init];
    localNotif.fireDate = date;
    localNotif.alertBody = @"Some text here...";
    localNotif.timeZone = [NSTimeZone defaultTimeZone]; 
    localNotif.repeatInterval = kCFCalendarUnitYear; //repeat yearly
    //other customization for the notification, for example attach some info using 
    //localNotif.userInfo = @{@"id":@"some Identifier to look for more detail, etc."};
   [[UIApplication sharedApplication]scheduleLocalNotification:localNotif];
}

Once you setup the alert and the alert fired, you can handle the notification in the AppDelegate.m file by implementing

- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification completionHandler:(void(^)())completionHandler{
    //handling notification code here.
}

Edit:

For how to get the closest date, you can implemented a method to do that

-(NSDate *) closestNextAnniversary:(NSDate *)selectedDate {
    // selectedDate is the old date you just selected, the idea is extract the month and day component of that date, append it to the current year, if that date is after today, then that's the date you want, otherwise, add the year component by 1 to get the date in next year
    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSInteger month = [calendar component:NSCalendarUnitMonth fromDate:selectedDate];
    NSInteger day = [calendar component:NSCalendarUnitDay fromDate:selectedDate];
    NSInteger year = [calendar component:NSCalendarUnitYear fromDate:[NSDate date]];
    NSDateComponents *components = [[NSDateComponents alloc] init];
    [components setYear:year];
    [components setMonth:month];
    [components setDay:day];
    NSDate *targetDate = [calendar dateFromComponents:components];
    // now if the target date is after today, then return it, else add one year 
    // special case for Feb 29th, see comments below 
    // your code to handle Feb 29th case.
    if ([targetDate timeIntervalSinceDate:[NSDate date]]>0) return targetDate;
    [components setYear:++year];
    return [calendar dateFromComponents:components];
}

One thing you need to think is how to treat the February 29th, do you want to alarm every year at Feb. 28th (non leap year), or do you want alarm every four years? Then you need to implement your own logic.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM