iOS 徽章编号实时更新 [英] iOS badge number live update

查看:20
本文介绍了iOS 徽章编号实时更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我为 iOS 创建了一个自定义日历,我正在尝试使用徽章编号来显示当天的编号,但一天过去后编号没有改变,我的意思是他们应该及时更新,这是我的代码:我需要像天气直播这样的应用程序,这个应用程序不发送任何推送通知!

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 ;

推荐答案

目前在 iOS 中做到这一点并不容易.您可以接近,但不能每天可靠地更新徽章除非用户偶尔打开应用.

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.

您需要使用 UILocalNotification.您可以创建和安排静默"通知来更新应用徽章,而无需提醒用户或播放如下提示音:

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

其中 dayTomorrow 是一个月中明天的整数.seconds 是一些时间间隔 - 这可能类似于午夜的间隔.发送此通知后,用户将不会收到警报或声音,但应用程序徽章应更新为新值.您可以使用 repeatInterval 属性每天重复此通知,但这里的问题是第二天您需要将 dayTomorrow 更改为是一个不同的值,然后在第二天再次.但是重复的警报在 applicationIconBadgeNumber 中总是具有相同的值.

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.

所以我认为实现任何接近你想要的东西的唯一方法是安排多个本地通知——你最多可以提前安排 64 个——每一个间隔一天,每一个都设置为当天的值applicationIconBadgeNumber.这些必须是非重复的,因此请确保将 repeatInterval 设置为 nil(或不要设置它,因为 nil 是默认值).假设所有这些通知都由 iOS 可靠地传递,您将能够在长达 64 天的时间内静默更新徽章编号,而不会打扰用户.在那之后,徽章将停止更新......除非您设法在此期间安排更多通知 - 即当用户打开应用程序时.您可以尝试做的是在应用启动时取消所有现有的预定通知:

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

然后提前 64 天循环,为 applicationIconBadgeNumber 属性安排每天午夜的通知,并使用正确的月份日期.只要用户至少每 64 天打开一次您的应用程序,您就会使徽章图标保持最新状态.如果您设想您的应用用户频繁打开应用(例如每天多次),那么优化可能是在取消之前检查现有通知的数量并创建 64 个新通知,如下所示:

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

另外几点需要注意:

  • 我不确定本地通知的可靠性.不能保证推送通知,但我希望并期望本地通知能保证送达.例如如果手机在午夜关闭并且只在早上 7 点打开,我希望安排在午夜的本地通知将立即发送.但我从来没有测试过这个.
  • 如果您的应用程序在发送预定通知时当前处于打开状态,则会调用 application:didReceiveLocalNotification: 但不会更新徽章图标.因此,为了适应这种情况,我建议每次启动应用程序时(或从后台返回前台)将徽章图标更新为当天.
  • 不确定 Apple 会如何使用徽章图标.在审查您的应用程序时,他们可能会觉得这让用户感到困惑,因为它通常用于指示应用程序中新/更改数据的项目数.因此,您的应用可能会因此被拒绝.
  • 理想情况下,Apple 会为开发人员提供一个 API,以便向用户提供这种一目了然"的信息,无论是通过以某种方式更改应用程序图标/徽章,还是通过小部件等实现的.我所做的上面描述的应该可行,但显然有点难以绕过 iOS 的当前限制.内置日历应用程序每天都会更改其图标以显示月份中的哪一天,我可以看到很多应用程序都可以从这种行为中受益 - 例如天气应用可以显示当前位置的天气状况图标.
  • I'm not sure on how reliable the local notifications are. Push notifications are not guaranteed, but I would hope and expect that local notifications are guaranteed to be delivered. e.g. if the phone is turned off at midnight and only turned on at say 7 AM, I would hope that the local notification scheduled for midnight would be immediately delivered. But I've never tested this.
  • If your app is currently open when a scheduled notification is delivered, the 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).
  • Not sure what Apple would make of this use of the badge icon. On reviewing your app, they might feel that it is confusing to the user since it is normally used to indicate the number of items of new/changed data in an app. So your app could get rejected for this.
  • Ideally Apple would provide an API for developers to provide this kind of "at a glance" info to the user, whether that's achieved by changing the application icon/badge in some way, or by a widget etc. What I've described above should work but is clearly a bit of a kludge to get around the current limitations of iOS. The built in calendar app changes its icon every day to show the day of the month and I can see a lot of apps could benefit from this behaviour - e.g. the weather app could show an icon of the weather conditions at the current location.

这是一个代码片段,用于取消任何现有的本地通知,并在未来将 64 安排在午夜,并将正确的月份日期指定为徽章编号:

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

这里发生了什么:

  • 我们用[NSDate date]取今天的日期,然后把它分解成我们想要保留的组件(年、月、日),然后设置时间组件(小时、分钟、第二)是午夜.这给了我们 midnightToday.
  • 我们循环了 64 次,每次创建一个新的日期,即未来 1 到 64 天的日期,方法是取 midnightToday 并将每天的秒数乘以在未来的天数我们希望日期成为的未来.我们使用此日期来安排本地通知.
  • 我们还需要计算出徽章编号的月份日期.因此,我们再次使用 NSDateComponents 将未来日期分解为我们感兴趣的组件 - 在这种情况下只是日期,因此我们指定 NSDayCalendarUnit.然后我们可以将 applicationIconBadgeNumber 设置为 components.day
  • 这 64 条通知中的每一条都与 UIApplication 一起安排,在未来 1 到 64 天内交付.
  • We take today's date with [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.
  • We loop through 64 times, each time creating a new date that is from 1 to 64 days in the future by taking 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.
  • We also need to work out the day of the month for the badge number. So again we use 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
  • Each of the 64 notifications is scheduled with UIApplication, to be delivered 1 to 64 days in the future.

请注意,这可能仅适用于使用公历(西方风格)日历的用户 - 根据您的市场,您可能需要考虑世界各地使用的其他日历类型并也支持这些日历类型.

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.

这篇关于iOS 徽章编号实时更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆