xcode iOS 徽章编号实时更新

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8734078/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 22:54:14  来源:igfitidea点击:

iOS badge number live update

iphoneiosxcodeipadsdk

提问by Mc.Lover

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 !

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

    int a = [DateComponents showDay];
    [UIApplication sharedApplication].applicationIconBadgeNumber = a ;

回答by Rob B

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

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

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. 您可以创建和安排一个“静默”通知来更新应用程序徽章,而不用提醒用户或播放这样的警报声音:

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 dayTomorrowis an int of tomorrow's day of the month. and secondsis 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 couldmake this notification repeat every day using the repeatIntervalproperty, but the problem here though is that the next day you need to change dayTomorrowto be a different value, and again the day after that. But a repeated alert will always have the same value in applicationIconBadgeNumber.

哪里dayTomorrow是一个月中明天的整数。并且seconds是一些时间间隔 - 这可能类似于午夜的间隔。发送此通知后,用户将不会收到警报或声音,但应用程序徽章应更新为新值。您可以使用该repeatInterval属性每天重复此通知,但这里的问题是您需要在第二天更改dayTomorrow为不同的值,并在之后的第二天再次更改。但是重复的警报在 中将始终具有相同的值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 repeatIntervalto 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... unlessyou 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:

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

[[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 applicationIconBadgeNumberproperty. 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:

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

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:

其他几点需要注意:

  • 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.
  • 我不确定本地通知的可靠性。不能保证推送通知,但我希望并期望本地通知能保证送达。例如,如果手机在午夜关闭并且只在早上 7 点打开,我希望安排在午夜的本地通知将立即发送。但我从来没有测试过这个。
  • 如果您的应用程序在发送预定通知时当前处于打开状态,application:didReceiveLocalNotification:则会调用 ,但不会更新徽章图标。因此,为了迎合这种情况,我建议每次启动应用程序时(或从后台返回到前台)将徽章图标更新为当天。
  • 不确定 Apple 会如何使用徽章图标。在您的应用程序时,他们可能会觉得这让用户感到困惑,因为它通常用于指示应用程序中新/更改数据的项目数。因此,您的应用可能会因此被拒绝。
  • 理想情况下,Apple 会为开发人员提供一个 API 来向用户提供这种“一目了然”的信息,无论是通过以某种方式更改应用程序图标/徽章还是通过小部件等来实现的。我上面描述的应该工作,但显然有点难以绕过 iOS 的当前限制。内置日历应用程序每天都会更改其图标以显示月份中的哪一天,我可以看到很多应用程序都可以从这种行为中受益 - 例如,天气应用程序可以显示当前位置的天气状况图标。

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:

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

[[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:

这里发生的事情是:

  • 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 midnightTodayand 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 NSDateComponentsto 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 applicationIconBadgeNumberto be components.day
  • Each of the 64 notifications is scheduled with UIApplication, to be delivered 1 to 64 days in the future.
  • 我们用 取今天的日期[NSDate date],然后将它分解成我们想要保留的组件(年、月、日),然后将时间组件(小时、分钟、秒)设置为午夜。这给了我们midnightToday.
  • 我们循环了 64 次,每次创建一个新的日期,该日期是未来 1 到 64 天,通过midnightToday每天的秒数乘以我们希望该日期在未来的天数相加。我们使用此日期来安排本地通知。
  • 我们还需要计算出徽章编号的月份日期。因此,我们再次使用NSDateComponents将未来日期分解为我们感兴趣的部分——在这种情况下,这只是我们指定的那一天NSDayCalendarUnit。然后我们可以设置applicationIconBadgeNumbercomponents.day
  • 64 个通知中的每一个都与 UIApplication 一起安排,将在未来 1 到 64 天内交付。

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.

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

回答by oskob

You should be able to do it with UILocalNotification

你应该可以用 UILocalNotification 做到这一点

I'm not sure if you can set it to auto repeat once a day but you might be able to spam noticifations to emulate that.

我不确定您是否可以将其设置为每天自动重复一次,但您可以通过垃圾邮件通知来模拟这一点。

http://developer.apple.com/library/IOs/#documentation/iPhone/Reference/UILocalNotification_Class/Reference/Reference.html

http://developer.apple.com/library/IOs/#documentation/iPhone/Reference/UILocalNotification_Class/Reference/Reference.html

回答by Hubert Kunnemeyer

How and where are you calling this method? If you set a timer to run this code every x seconds it will update on the next timer fire.

您如何以及在哪里调用此方法?如果您设置一个计时器每 x 秒运行一次此代码,它将在下一次计时器触发时更新。