简体   繁体   English

如何在 iOS 推送通知上增加徽章

[英]How to do badge increment on iOS push notification

I'm currently getting badge from payload.我目前正在从有效载荷中获取徽章。 But how can i update that value.但是我怎样才能更新那个值。

{"aps":
    {"alert":"Notification Hub test notification2",
     "badge":1,
     "sound":"Default"}
}

when i send this it is always shows 1 in the badge number but when i go inside app and exit it's getting updated.It is because of this,当我发送它时,它总是在徽章编号中显示 1,但是当我进入应用程序并退出时,它正在更新。正因为如此,

func applicationDidBecomeActive(application: UIApplication) {
        UIApplication.sharedApplication().applicationIconBadgeNumber = UIApplication.sharedApplication().applicationIconBadgeNumber + 1
    }

But when i send a new push notification it's again shows 1 as badge number in the icon.但是当我发送新的推送通知时,它再次在图标中显示 1 作为徽章编号。 How should i do this, to my understand i should send updated badge when i send the payload.我应该怎么做,据我了解,我应该在发送有效负载时发送更新的徽章。 For that i have to deal with backend.为此,我必须处理后端。

Is there any suggestion other than this to handle inside app?除此以外还有什么建议可以在应用程序内部处理吗?

If your project has a notification extension, you can do a badge setting inside it.如果您的项目有通知扩展,您可以在其中进行标记设置。

First of all, enable App Groups and save your badge count from the app notification service extension in UserDefaults .首先,启用 App Groups 并从UserDefaults中的应用通知服务扩展中保存您的徽章计数。 We are using app groups because we need to clear the badge count from AppDelegate when opening the app.我们正在使用应用程序组,因为我们需要在打开应用程序时从AppDelegate清除徽章计数。 Also you can set value of badge as bestAttemptContent.badge from notification service extension您还可以从通知服务扩展中将徽章的值设置为bestAttemptContent.badge

In notification service extension:在通知服务扩展中:

if let userDefaults = UserDefaults(suiteName: "group.com.bundle.appname") {
    
    let badgeCount = userDefaults.integer(forKey: "badgeCount")
    if badgeCount > 0 {
        userDefaults.set(badgeCount + 1, forKey: "badgeCount")
        bestAttemptContent.badge = badgeCount + 1 as NSNumber
    } else {
        
        userDefaults.set(1, forKey: "badgeCount")
        bestAttemptContent.badge = 1
    }
}

In AppDelegate you can clear badge...and set value for the badge as zero on userdefaults在 AppDelegate 中,您可以清除徽章...并在 userdefaults 上将徽章的值设置为零

if let userDefaults = UserDefaults(suiteName: "group.com.bundle.appname") {
    userDefaults.set(0, forKey:"badgeCount") // "change "badgecount" to be "badgeCount"
}
UIApplication.shared.applicationIconBadgeNumber = 0

I will give my way to you :我会给你我的方式:

My plan is to use KVO to listen the [UIApplication sharedApplication].applicationIconBadgeNumber我的计划是使用 KVO 来监听[UIApplication sharedApplication].applicationIconBadgeNumber

- (void)setupBadgeOperation {
    [[UIApplication sharedApplication] addObserver:self forKeyPath:@"applicationIconBadgeNumber" options:NSKeyValueObservingOptionNew context:nil];
}

And once value changed, I use [[NSNotificationCenter defaultCenter] postNotificationName:STATUS_BADGENUMBER_CHANGED object:nil] to inform the UI where needs to be modified for the change of badge.一旦值更改,我使用[[NSNotificationCenter defaultCenter] postNotificationName:STATUS_BADGENUMBER_CHANGED object:nil]通知 UI 需要修改哪些位置以更改徽章。

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *, id> *)change context:(void *)context {
    if ([keyPath isEqualToString:@"applicationIconBadgeNumber"]) {
        [[NSNotificationCenter defaultCenter] postNotificationName:STATUS_BADGENUMBER_CHANGED object:nil];
    }
}

There is three case of receiving a remote notification to change the [UIApplication sharedApplication].applicationIconBadgeNumber .接收远程通知以更改[UIApplication sharedApplication].applicationIconBadgeNumber的三种情况。

a.一个。 app is foreground应用程序是前台
b.湾。 app is background应用程序是背景
c. C。 app is not launch应用程序未启动

in a and b case, this method will be called:在 a 和 b 情况下,将调用此方法:

- (void)application:(UIApplication *)application
    didReceiveRemoteNotification:(NSDictionary *)userInfo
          fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
    void(^tapBlock)(void(^completeHandler)()) = ^(void(^completeHandler)()) { 
    // here I remove some code not related with the question
    NSNumber *badgeNumber = userInfo[@"aps"][@"badge"];
    [UIApplication sharedApplication].applicationIconBadgeNumber = badgeNumber.integerValue;
} 

in c case, there is no way to get the callback, so I will do it manually.在c的情况下,没有办法获取回调,所以我将手动进行。

- (void)applicationDidBecomeActive:(UIApplication *)application {
    [[NSNotificationCenter defaultCenter] postNotificationName:STATUS_BADGENUMBER_CHANGED object:nil];
}

That's all, and works well for me.就是这样,对我来说效果很好。

Here my way Swift:这是我的方式斯威夫特:

1) You need to set badge ( a variable you can call it whatever you want) to zero into Firebase Realtime database once you launch the app. 1) 启动应用程序后,您需要在 Firebase Realtime 数据库中设置徽章(您可以随意调用它的变量)为零。 Plus set application.applicationIconBadgeNumber = 0. Here is how I do it in AppDelegate:加上设置 application.applicationIconBadgeNumber = 0。这是我在 AppDelegate 中的操作方式:

func applicationDidBecomeActive(_ application: UIApplication) {
    // 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.
    application.applicationIconBadgeNumber = 0

    // Reset badge number to zero
    let userID = Auth.auth().currentUser?.uid

    let dbRef = Database.database().reference()
    dbRef.child("Users Info").child(userID!).updateChildValues(["badge":"0"], withCompletionBlock: { (err, ref) in
        if err != nil {
            print(err!)
            return
        }
    })

}

2) Go to index.js where a function is triggered. 2) 转到触发函数的 index.js。

...
return admin.database().ref('/Users Info/' + owner).once('value', snapshot => {

    var ownerValue = snapshot.val();

    var badgeNumber = parseInt(ownerValue.badge) + 1;

    // Notification details.
    const payload = {
      notification: {
        title: 'You have a new request!',
        body: `A new request from ${downedBy.name}.`,
        badge:`${badgeNumber}`,
        sound: 'default',
      }
    };
    ...
    ...
    // Upload the new value of badge into Firebase to keep track of the number
    return admin.database().ref('/Users Info/' + owner).update({badge:badgeNumber});
    ...
    })

First of all, leave it to your server guys to send you updated badge counter.首先,让您的服务器人员向您发送更新的徽章计数器。 Your job is only to display it, not to maintain it on your end.你的工作只是展示它,而不是最终维护它。

You need to perform the update operations in applicationDidReceiveRemoteNotifications Delegate method like this:您需要在applicationDidReceiveRemoteNotifications Delegate 方法中执行更新操作,如下所示:

func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]){
       let notification = userInfo["aps"] as? NSDictionary
       let badge = (notification["badge"] as String).toInt() 
       UIApplication.sharedApplication().applicationIconBadgeNumber = UIApplication.sharedApplication().applicationIconBadgeNumber + badge;

}

And in your DidBecomeActive method:在您的DidBecomeActive方法中:

func applicationDidBecomeActive(application: UIApplication) {
       if(UIApplication.sharedApplication().applicationIconBadgeNumber!=0){
    UIApplication.sharedApplication().applicationIconBadgeNumber = 0
    }

This is with the assumption that your server sends you updated push badge counter.这是假设您的服务器向您发送更新的推送徽章计数器。 In , I'd do something like this to convey to the Server that push counter must be set to zero now:中,我会做这样的事情来向服务器传达推送计数器现在必须设置为零:

var currentInstallation = PFInstallation.currentInstallation()
      if currentInstallation.badge != 0 {
        currentInstallation.badge = 0
        currentInstallation.save
       }

If I don't do this, Server will assume that Push has never been read yet and will increment the badge counter on their end on the next push and so on.如果我不这样做,服务器将假定 Push 尚未被读取,并会在下一次推送时在其末端增加标记计数器,依此类推。

Keep your badge count in NSUserDefault for maximum availability.将您的徽章计数保留在 NSUserDefault 中以获得最大可用性。 even if you restart your device, then also you would be able to get badge count from NSUserDefault.即使您重新启动设备,您也可以从 NSUserDefault 获取徽章计数。

When you get another payload then you could keep incrementing badge count in NSUserDefault.当您获得另一个有效负载时,您可以在 NSUserDefault 中继续增加徽章计数。

Server must increment much count in @"badge" key.服务器必须在@"badge"键中增加很多计数。 When you open app, you need send request to server - Reset Push Counter (badge).当您打开应用程序时,您需要向服务器发送请求 - 重置推送计数器(徽章)。 In applicationDidBecomeActive method.applicationDidBecomeActive方法中。

{"aps":
    {"alert":"Notification Hub test notification2",
     "badge":20,
     "sound":"Default"}
}

Whenver we use the push notification.每当我们使用推送通知时。 we have to update its badge count.我们必须更新它的徽章数量。 Otherwise each and every time badge will be same.否则每次徽章都是一样的。 eg If you got a notification its count is 1 and you read it it will still shows badge 1. so for this you have to clear the badge.例如,如果您收到通知,其计数为 1,并且您阅读了它,它仍会显示徽章 1。因此,您必须清除徽章。 by using code like this,通过使用这样的代码,

  func applicationDidBecomeActive(application: UIApplication) {
        application.applicationIconBadgeNumber = 0
    }

For handling the badge best solution is use the notification extension you can create a.处理徽章的最佳解决方案是使用您可以创建的通知扩展。 notification extension and also use KVO to update the badge in app.通知扩展,还使用 ​​KVO 更新应用程序中的徽章。 and app group for saving the number of badge and managing in app.和应用程序组,用于保存徽章数量并在应用程序中管理。 when you get notification you can read how many notification you have and add the badge of notification to that and update your notification that its当您收到通知时,您可以阅读您有多少通知并将通知徽章添加到该通知并更新您的通知

guard let content = (request.content.mutableCopy() as? UNMutableNotificationContent) else {
        contentHandler(request.content)
        return
    }

    if let badge = bestAttemptContent?.badge as? Int {
        let newBadge = badge + NotificationManangerBridge.shared.getTotalBadge()
        content.badge = NSNumber(value: newBadge)
        NotificationManangerBridge.shared.updateTotalBadge(badgeCount: newBadge)

    } else {
        content.badge = 0
    }
    guard let notification = bestAttemptContent?.copy() as? UNNotificationContent else { return }
    contentHandler(notification)

You are going in a correct direction.你正朝着正确的方向前进。 You will have to update badge number from your payload and that's the standard way in push notifications.您必须从有效负载中更新徽章编号,这是推送通知的标准方式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM