iOS推送通知 - 如何在不显示警报的情况下更新应用图标徽章?

15
有没有一种方法可以在不显示警告或打开应用程序的情况下更新徽章中的数字?
我正在编写一个应用程序,它应该始终显示图标徽章中未读消息的当前数量,但我希望这样做而不向用户显示任何警报。
我正在开发iOS 5.0+应用程序。
编辑:为了更清楚,我是在询问一种在应用程序未运行时进行此操作的方法。我希望服务器推送一个新的徽章数字而不显示警报。这可能吗?

据我所知,这完全由操作系统处理。您有什么特定的原因不想显示警报吗? - Anupdas
这个应用程序是为非常高的消息频率构建的,我不想打扰用户。所以根据你的说法 - 只有当用户进入通知中心并禁用警报时,我才能实现这种行为? - Ran Dahan
@Pandu1251没有理解你上一句话的意思。你在谈论什么逻辑? - Ran Dahan
@Ran,如果您使用推送通知服务,则接收到推送将始终显示警报消息,并且这是iOS的默认属性。如果应用程序关闭,则也会显示警报消息。但是您不想显示警报消息,而是想显示徽章数字。因此,您不应使用Push Notification,因为它会自动显示警报消息。您可以定期向服务器发送请求以获取当前徽章号码,以显示为本地通知。并且此代码需要在后台运行。 - sumon
@sumon 我本来希望这个功能可以像 Windows Phone 的磁贴通知一样实现... 好吧,谢谢你的回答。 - Ran Dahan
4个回答

27
你可以做到这一点。 可以在没有警报的情况下发送推送通知。 甚至可以注册你的应用程序只用于徽章通知,在这种情况下,提供者服务器甚至无法发送警报或声音。
“通知有效载荷” 每个推送通知都携带有一个有效载荷。有效载荷指定了如何向用户发出警报以下载到客户端应用程序中等待的数据。通知有效载荷允许的最大大小为256个字节;苹果推送通知服务拒绝超过此限制的任何通知。请记住,通知的传递是“尽力而为”,不能保证。
对于每个通知,提供者必须组成一个严格遵守RFC 4627的JSON字典对象。该字典必须包含由键aps标识的另一个字典。aps字典包含一个或多个属性,指定以下操作:
向用户显示的警报消息 要徽章应用程序图标的数字 要播放的声音
请注意,它说“一个或多个属性”。警报属性是可选的。你甚至可以发送一个只包含自定义属性的空aps字典的通知。
示例5。以下示例显示一个空的aps字典;因为缺少徽章属性,所以应用程序图标上显示的任何当前徽章号码都将被移除。acme2自定义属性是两个整数的数组。
{

    "aps" : {

    },

    "acme2" : [ 5,  8 ]

}

用户唯一会看到的警报是询问他/她是否允许推送通知的警报。该警报仅在安装后首次启动应用程序时显示。

在此示例中,您注册了非警报通知(仅限徽章和声音):

Listing 2-3  Registering for remote notifications

- (void)applicationDidFinishLaunching:(UIApplication *)app {

   // other setup tasks here....

    [[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)];

}



// Delegation methods

- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)devToken {

    const void *devTokenBytes = [devToken bytes];

    self.registered = YES;

    [self sendProviderDeviceToken:devTokenBytes]; // custom method

}



- (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)err {

    NSLog(@"Error in registration. Error: %@", err);

}

所有引用均来自苹果本地和推送通知编程指南。

Eran,我有一个后续问题。如果我的应用程序在后台监控用户位置,那么应用程序能否在用户不知情或打开应用程序的情况下接收通知并执行一些代码?如果它接收到推送通知,我希望应用程序将其位置发送到服务器... - Trj
在负载中发送推送通知时,是否可以不包含应用图标上的数字?因为我不想使用应用图标上的数字概念。或者我可以将其设置为数字"0"吗? - siva
@siva 当然可以。徽章参数是可选的。 - Eran
更新: 在iOS 8及以上版本中,通知负载允许的最大大小为2千字节 - Raptor
1
@Raptor 如果使用二进制方法,则为 2K,如果使用 HTTP/2,则为 4K。 - makerofthings7
更新:对于常规远程通知,最大大小为4KB(4096字节)(二进制接口中的2KB),对于VoIP通知,最大大小为5KB(5120字节)。 - Lal Krishna

2

在本地处理应用程序徽章数字时,您应使用applicationIconBadgeNumber

[UIApplication sharedApplication].applicationIconBadgeNumber = number_of_notifications;

我认为如果从远程通知中添加徽章计数,那么没有警报是不可能的。你应该阅读关于APN服务的内容,在你的情况下,你可能需要注册UIRemoteNotificationTypeBadge,你应该阅读有关本地和推送通知编程指南的内容。


抱歉我表达不够清晰,我的意思是当应用程序关闭时。请查看我的编辑。 - Ran Dahan
在这种情况下,您将拥有方法didReceiveRemoteNotification,您可以在此方法中执行任何操作。 - nsgulliver
也许我漏掉了什么,但是 didReceiveRemoteNotification 不是在应用程序启动时执行吗?我不想启动应用程序,只想更新徽章而不运行任何应用程序代码。 - Ran Dahan
确切地说,didReceiveRemoteNotification是AppDelegate的委托方法,在应用程序运行时运行,你所谈论的东西由操作系统处理,并且你在itunesConnect上注册应用程序以接收通知。 - nsgulliver
是的,你应该仔细阅读如何注册远程通知,它被称为APN服务 - nsgulliver
显示剩余2条评论

1
你可以使用

标签


[UIApplication sharedApplication].applicationIconBadgeNumber = aNumber;

抱歉我表达不够清楚,我的意思是当应用程序关闭时。请看我的编辑。 - Ran Dahan

1
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo

{

    [[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];
}

使用这个方法....这会帮助你。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接