I created a custom calendar for iOS , and I am trying using badge number to show number of the Day , but numbers did not change after one day passed , I mean they should update lively here is my code : I need something like weather live application , this application does not send any push notification !
int a = [DateComponents showDay];
[UIApplication sharedApplication].applicationIconBadgeNumber = a ;
Go to Settings and open Notifications. Scroll down and tap on Messages. To disable notifications altogether, toggle off Allow Notifications. To remove badges, turn off the toggle next to Badges.
The iOS badge count displays the number of unread notifications within your application, taking the form of a red circle in the upper-right hand corner of the app icon. In recent years, badging has come to be an effective means for re-engaging app users.
Check Settings app On your iPhone or iPad, leave Things and go to the Settings app. Tap Notifications. Scroll down to find Things and tap it. Enable the toggle for Badges (if it's already on, toggle it off and back on).
It's not easy to do this currently in iOS. You can get close, but not update the badge reliably every day unless the user opens the app occasionally.
You'll need to use UILocalNotification
. You can create and schedule a "silent" notification that updates the app badge without alerting the user or playing an alert sound like this:
UILocalNotification* notification = [[UILocalNotification alloc] init];
notification.fireDate = [NSDate dateWithTimeIntervalSinceNow:seconds];
notification.timeZone = [NSTimeZone systemTimeZone];
notification.alertBody = nil;
notification.soundName = nil;
notification.applicationIconBadgeNumber = dayTomorrow;
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
[notification release];
where dayTomorrow
is an int of tomorrow's day of the month. and seconds
is some time interval - this could be something like the interval to midnight. When this notification is delivered, there will be no alert or sound for the user, but the app badge should be updated to the new value. You could make this notification repeat every day using the repeatInterval
property, but the problem here though is that the next day you need to change dayTomorrow
to be a different value, and again the day after that. But a repeated alert will always have the same value in applicationIconBadgeNumber
.
So I think the only way to achieve anything close to what you want is to schedule multiple of those local notifications - you can schedule up to 64 in advance - each one a day apart, and each one with that day's value set as the applicationIconBadgeNumber
. These need to be non-repeating, so make sure you set repeatInterval
to nil (or don't set it, as nil is the default value). Assuming all of these notifications are delivered reliably by iOS, you would be able to update the badge number silently and without bothering the user for up to 64 days. After that, the badge would stop updating... unless you manage to schedule more notifications in the meantime - i.e. when the user opens up the app. What you could try doing is cancelling all existing scheduled notifications at app launch:
[[UIApplication sharedApplication] cancelAllLocalNotifications];
and then loop through 64 days in advance, scheduling a notification for midnight each day with the correct day of the month for the applicationIconBadgeNumber
property. As long as the user opened up your app at least once every 64 days, you would keep the badge icon up to date. If you envisage your app users opening the app frequently (e.g. multiple times per day), then an optimisation might be to check the number of existing notifications scheduled before cancelling them and creating 64 new ones, like this:
if ([[[UIApplication sharedApplication] scheduledLocalNotifications] count] < 10)
{
//there are 10 or fewer days' worth of notifications scheduled, so create and
//schedule more here, up to 64 in total.
}
A couple of other points to note:
application:didReceiveLocalNotification:
is called but the badge icon will not be updated. So in order to cater for this case, I would suggest updating the badge icon to the current day every time the app is launched (or returns to the foreground from the background).EDIT:
Here's a code snippet to cancel any existing local notifications and schedule 64 in the future for midnight and with the correct day of the month specified as the badge number:
[[UIApplication sharedApplication] cancelAllLocalNotifications];
NSCalendar* calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents* components = [calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:[NSDate date]];
[components setHour:0];
[components setMinute:0];
[components setSecond:0];
NSDate* midnightToday = [calendar dateFromComponents:components];
const int SECONDS_PER_DAY = 60 * 60 * 24;
for (int i = 1; i <= 64; i++)
{
NSDate* futureDate = [midnightToday dateByAddingTimeInterval:i * SECONDS_PER_DAY];
NSDateComponents* components = [calendar components:NSDayCalendarUnit fromDate:futureDate];
UILocalNotification* notification = [[UILocalNotification alloc] init];
notification.fireDate = futureDate;
notification.timeZone = [NSTimeZone systemTimeZone];
notification.alertBody = nil;
notification.soundName = nil;
notification.applicationIconBadgeNumber = components.day;
//NSLog(@"futureDate: %@", [NSDateFormatter localizedStringFromDate:futureDate dateStyle:NSDateFormatterMediumStyle timeStyle:NSDateFormatterMediumStyle]);
//NSLog(@"notification: %@", notification);
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
[notification release];
}
[calendar release];
What's going on here is:
[NSDate date]
, and then break it into the components we want to keep (year, month, day), and then set the time components (hour, minute, second) to be midnight. This gives us midnightToday
. midnightToday
and adding on the number of seconds per day multiplied by how many days in the future we want the date to be. We use this date to schedule the local notification.NSDateComponents
to break the future date into the components we are interested in - which in this case is only the day so we specify NSDayCalendarUnit
. We can then set the applicationIconBadgeNumber
to be components.day
Note that this will probably only work for users that use the Gregorian (western style) calendar - depending on your market you might need to consider the other calendar types in use around the world and support those too.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With