Hariharan
Hariharan

Reputation: 1

IOS CancelNotificaion on particular date when the app is in Background

I am working on a application that reminds about the expiry date. I have implemented the same using UILocalNotification with repeat Interval (NSMonthCalendarUnit, NSDayCalendarUnit,NSDayCalendarUnit). For example I have the fire date on 01-01-2012 and the repeat interval is NSDayCalendarUnit and the end date is 12-12-2012, is it possbile to cancelLocalNotification: on expiry.

here is the code:-

- (void) scheduleNotificationOn:(NSDate*) fireDate
                       text:(NSString*) alertText
                     action:(NSString*) alertAction
                      sound:(NSString*) soundfileName
                launchImage:(NSString*) launchImage 
                    andInfo:(NSDictionary*) userInfo


{



userInfo = [NSDictionary dictionaryWithObjectsAndKeys:
            txtExpiryDate.text, @"ExpiryDate",
            txtRegNo.text , @"RegNo",
            nil];



UILocalNotification *localNotification = [[UILocalNotification alloc] init];

localNotification.fireDate = fireDate;
localNotification.timeZone = [NSTimeZone systemTimeZone];   
localNotification.userInfo = userInfo;
localNotification.alertBody = alertText;
localNotification.alertAction = alertAction;    


NSLog(@"Repeat Type:%@",txtRepeat.text);

if([txtRepeat.text isEqualToString:@"Every Week"])
{

    NSLog(@"Every Week");
    localNotification.repeatInterval = 256;
}

else if([txtRepeat.text isEqualToString:@"Every Month"])
{
    NSLog(@"Every Month");
    localNotification.repeatInterval = NSMonthCalendarUnit;   
}

else if([txtRepeat.text isEqualToString:@"Every Day"])

{
    NSLog(@"Every Day");
    localNotification.repeatInterval = NSDayCalendarUnit;

}


if(soundfileName == nil)
{
    localNotification.soundName = UILocalNotificationDefaultSoundName;
}
else 
{
    localNotification.soundName = soundfileName;
}

NSLog(@"appDelegate.BadgeNumber:%d",appDelegate.BadgeNumber);

localNotification.alertLaunchImage = launchImage;
appDelegate.BadgeNumber = appDelegate.BadgeNumber + 1;
localNotification.applicationIconBadgeNumber = appDelegate.BadgeNumber;    

[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];

[localNotification release];
}

I have worked by comparing current date to expiry date. But this work only if the app is in foreground and i cannot cancelnotification not background for a particular date. Please find the below code for the same:-

- (void)applicationDidBecomeActive:(UIApplication *)application
{
/*
 Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
 */
    BadgeNumber = 0;   
application.applicationIconBadgeNumber = BadgeNumber;



NSArray *localNotifications = [[UIApplication sharedApplication] scheduledLocalNotifications];
[[UIApplication sharedApplication] cancelAllLocalNotifications];

NSDateFormatter *formatter =[[[NSDateFormatter alloc]init] autorelease];
[formatter setDateFormat:@"dd/MM/yyyy"];

NSLog(@"localNotifications Count %d",localNotifications.count);


for (UILocalNotification *notify in localNotifications)
{
    //notify.applicationIconBadgeNumber = 0;

    NSString *ExpiryDateString = [notify.userInfo objectForKey:@"ExpiryDate"];
    NSDate *ExpiryDate = [formatter dateFromString:ExpiryDateString];
    NSDate * NextFireDate = nil;
    NSLog(@"Expiry Date:%@",ExpiryDateString);

    if(notify.repeatInterval == NSDayCalendarUnit)
    {
        NSLog(@"Repeat Every Day");
        NextFireDate =  [[NSDate date] dateByAddingDays:1];
        NSLog(@"Next FireDate: %@",[formatter stringFromDate:NextFireDate]); 

    }
    if(notify.repeatInterval == NSWeekCalendarUnit)
    {
        NSLog(@"Repeat Every Day");
        NextFireDate =  [[NSDate date] addTimeInterval:D_WEEK];
        NSLog(@"Next FireDate: %@",[formatter stringFromDate:NextFireDate]); 

    }
    if(notify.repeatInterval == NSMonthCalendarUnit)
    {
        NSLog(@"Repeat Every Day");
        //NextFireDate =  [[NSDate date] addTimeInterval:D_Month];
        NextFireDate = [self CalculateExipiryDateForMonth];
        NSLog(@"Next FireDate: %@",[formatter stringFromDate:NextFireDate]); 

    }


    NSComparisonResult result = [NextFireDate compare:ExpiryDate];
    NSLog(@"NSComparisonResult:%d",result);

    if(result == NSOrderedDescending)
    {

        NSLog(@"Cancell......... Notification");
        NSLog(@"notify :::%@",notify);

    }
    else 
    {
        NSLog(@"Re-Schedule Notification");
        BadgeNumber =  BadgeNumber + 1;

        notify.applicationIconBadgeNumber = BadgeNumber;

        NSLog(@"BadgeNumber:%d",BadgeNumber);

        [[UIApplication sharedApplication] scheduleLocalNotification:notify];
    }
}


}



-(NSDate*) CalculateExipiryDateForMonth
{

NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];

NSDateComponents *components = [[NSDateComponents alloc] init];
components.month = 1;
NSDate *nextMonth = [gregorian dateByAddingComponents:components toDate:[NSDate date] options:0];
[components release];

NSDateComponents *nextMonthComponents = [gregorian components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit fromDate:nextMonth];
NSDate *expiryDay = [gregorian dateFromComponents:nextMonthComponents];


NSDateComponents *dayComponent = [[NSDateComponents alloc] init];
dayComponent.day = -1;

NSDate *NewExpiry = [gregorian dateByAddingComponents:dayComponent toDate:expiryDay options:0];  



[gregorian release]; 
[dayComponent release];

NSDateFormatter *formatter = [[[NSDateFormatter alloc] init] autorelease];
[formatter setDateFormat:@"dd/MM/yyyy"];
NSLog(@"Next Exipiry Date -----:%@",[formatter stringFromDate:NewExpiry]);


return NewExpiry;
}

Upvotes: 0

Views: 567

Answers (2)

Hariharan
Hariharan

Reputation: 1

                 **Apple RESPONSE:-**

I'm responding to your question about UILocalNotification.

At this time UILocalNotification does not have a way to specify an expiry date or number of repetitions before the notification is automatically canceled.

The closest you can get today is to schedule up to 64 individual notifications instead of using the repeat interval.

But you're correct; if the user doesn't ever bring your app to the foreground, it won't have the opportunity to cancel or reschedule local notifications.

I highly recommend that you file an enhancement request at < https://developer.apple.com/bugreporter> asking for this functionality in a future release of iOS.

You also asked about what happens to local notifications when the user removes your app from the device. iOS stores the local notifications so that they are still scheduled if the user deletes and then reinstalls the app.

When your app runs, it can check the scheduledLocalNotifications property of UIApplication and remove any notifications that are no longer relevant.

Best regards, --gc


Garth Cummings Apple Developer Technical Support

Upvotes: 0

Darren
Darren

Reputation: 10129

In short, no, you cannot cancel a UILocalNotification while your app is running in the background.

Upvotes: 1

Related Questions