Forum Xamarin.Forms
We are excited to announce that the Xamarin Forums are moving to the new Microsoft Q&A experience. Q&A is the home for technical questions and answers at across all products at Microsoft now including Xamarin!

We encourage you to head over to Microsoft Q&A for .NET for posting new questions and get involved today.

Badge count in Xamarin IOS when app is killed

I am trying to set the Badge count in Xamarin Forms application for IOS. I am using Azure notification Hub. Everything is working fine except the badge is not getting set when app is killed. I am sending the badge value from backend service.

Please let me know what i need to do to make it work even when the app is killed. I received the notification even the app is killed but badge count is not changing.

Here is my code

PushNotificationService.cs
public class PushNotificationService: IPushNotificationService
{
public DeviceInstallation GetDeviceRegistration(params string[] tags)
{
if (AppDelegate.DeviceToken == null)
{
return null;
}

        var registrationId= AppDelegate.DeviceToken;

        var installation = new DeviceInstallation
        {
            InstallationId = UIDevice.CurrentDevice.IdentifierForVendor.ToString(),
            Platform = "apns",
            PushChannel = registrationId
        };
        System.Diagnostics.Debug.WriteLine($"[service]: {installation.InstallationId}");
        // Set up tags to request
        installation.Tags.AddRange(tags);
        // Set up templates to request
       PushTemplate genericTemplate = new PushTemplate
        {

            Body = "{\"aps\":{\"alert\":{\"title\":\"$(messageTitleParam)\",\"body\":\"$(messageBodyParam)\"},\"content-available\":1,\"badge\" : \"$(badge)\",\"sound\":\"$(messageSound)\"},\"custom\":{\"orderid\":\"$(orderid)\",\"page\":\"$(page)\",\"dataBaseId\":\"$(notificationId)\"}}"
        };
        installation.Templates.Add("genericTemplate", genericTemplate); 
        return installation;
    }

    public string GetDeviceId()
    {

        return UIDevice.CurrentDevice.IdentifierForVendor.ToString();
    }


}

AppDelegate.cs

public override void DidReceiveRemoteNotification(
UIApplication application,
NSDictionary userInfo,
Action completionHandler)
{
NSDictionary aps = userInfo.ObjectForKey(new NSString("aps")) as NSDictionary;

        var badgecount= new NSString("badge");
        if (aps.ContainsKey(badgecount))
        {
           string count = (aps[badgecount] as NSString).ToString();
            BadgeImplementation badge = new BadgeImplementation();
            badge.SetBadge(Convert.ToInt16(count));
        } 

}

Best Answer

Answers

  • Y3z1Y3z1 Member ✭✭

    Make sure that you had allowed your app receive notification :System Setting **-> **Notification -> your App -> open the option Badges .

  • Virender_dangiVirender_dangi Member ✭✭

    @Y3z1 - Yes Badges option is already enabled. I am able to set the badge value when application is in background as well but the issue is only when application is killed.
    If i send the json directly from Azure notification Hub then also badge is getting set. So i am not sure how i can make it work when application is killed.

  • LandLuLandLu Member, Xamarin Team Xamurai
    edited July 2

    Did this template register successfully?
    When the application is at the foreground, DidReceiveRemoteNotification will be called. And you changed the badge there.
    But if your application is closed, the badge is set by the notification payload. Try to have a test on the Azure portal using this payload:

    {
        "aps" : {
            "alert" : "Notification comes",
            "badge" : 9
        }
    }
    

    Will this badge be displayed on the icon?

  • Virender_dangiVirender_dangi Member ✭✭

    @LandLu - How i can verify if template registration is successful ? I haven't got any exception or error in template registration.

    Yes when app is at foreground i am setting the badge in DidReceiveRemoteNotification and its working.
    But its not working when application is closed.

    From azure portal if i send this payload badge is getting set properly.

  • LandLuLandLu Member, Xamarin Team Xamurai

    This appears that it's the issue of the registration or the format of the notification.
    Try to add a breakpoint in this method GetDeviceRegistration to see whether it is called to register the template.
    Could you please show the payload you sent from the background service?

  • Virender_dangiVirender_dangi Member ✭✭

    @LandLu - Yes template is getting registered. I am able to fetch the details from azure after registration.

    {
    "installationId": "F9386130-A31C-488C-9F0F-0226306E2CE5",
    "pushChannel": "C59B3BE83549AEBAB748601A1E9BBCF77B4FF00E1A80170F2F14416AC7AAD541",
    "pushChannelExpired": false,
    "platform": 2,
    "expirationTime": "9999-12-31T23:59:59.9999999Z",
    "tags": [
    "uid:TestUser"
    ],
    "pushVariables": null,
    "templates": {
    "genericTemplate": {
    "body": "{\"aps\":{\"alert\":{\"title\":\"$(messageTitleParam)\",\"body\":\"$(messageBodyParam)\"},\"content-available\":1,\"badge\" : \"$(badge)\",\"sound\":\"$(messageSound)\"},\"custom\":{\"orderid\":\"$(orderid)\",\"page\":\"$(page)\",\"dataBaseId\":\"$(notificationId)\"}}",
    "headers": null,
    "expiry": null,
    "tags": [
    "genericTemplate"
    ]
    }
    },
    "secondaryTiles": null
    }

    Here is my dto from background service

    public class MyNotificationDto
    {
    public DeviceInstallation deviceInstallation { get; set; }
    public string Appname { get; set; }

        public PushRequest pushRequest { get; set; }
    
        public string InstallationId{get; set; }
    
    }
    

    public class PushRequest
    {
    ///


    /// Body of the push message.
    ///

    [JsonProperty("body")]
    public string Body { get; set; }

        /// <summary>
        /// Icon to be displayed for notification.
        /// </summary>
        [JsonProperty("icon")]
        public string Icon { get; set; }
    
        /// <summary>
        /// The title text for the notification.
        /// </summary>
        [JsonProperty("title")]
        public string Title { get; set; }
    
        /// <summary>
        /// A custom sound path to use for the notification or 'default' to use the default notification sound.
        /// *Note: Sounds on individual notifications were deprecated in Android O(API 26). You now have to set them on a channel.
        /// </summary>
        [JsonProperty("sound")]
        public string Sound { get; set; }
    
        /// <summary>
        /// True if notification needs to be silent, without sound.
        /// </summary>
        [JsonProperty("silent")]
        public string Silent { get; set; }
    
        /// <summary>
        /// The path to a packaged image asset or a url to a public image.
        /// </summary>
        [JsonProperty("largeIcon")]
        public string LargeIcon { get; set; }
    
        /// <summary>
        /// This should be one of the priority values from -2 (low) to 2 (max). The default is 0.
        /// </summary>
        [JsonProperty("priority")]
        public string Priority { get; set; }
    
        /// <summary>
        /// If the device supports custom badge count icons this value will be used to set the badge count.
        /// </summary>
        [JsonProperty("badge")]
        public string Badge { get; set; }
    
        /// <summary>
        /// The colour to apply to the notification (generally affects icon and title text colour). Should be of the form #RRGGBB.
        /// </summary>
        [JsonProperty("color")]
        public string Color { get; set; }
    
        /// <summary>
        /// From Android 8.0 you need to specify a channel for a notification. This is the channel id. If you omit this field the notification will be assigned to your first notification channel.
        /// </summary>
        [JsonProperty("channel")]
        public string Channel { get; set; }
    
        /// <summary>
        /// Either a path to a local asset packaged with your application or a url to a public image.
        /// </summary>
        [JsonProperty("backgroundImage")]
        public string BackgroundImage { get; set; }
    
        /// <summary>
        ///  Use to specify the text colour when a background image is specified. Colour supported formats are:
        /// "#RRGGBB"
        /// "#AARRGGBB"
        /// </summary>
        [JsonProperty("BackgroundImageTextColor")]
        public string BackgroundImageTextColor { get; set; }
    
        /// <summary>
        /// A resource name to use as the icon for the group.
        /// </summary>
        [JsonProperty("groupIcon")]
        public string GroupIcon { get; set; }
    
        /// <summary>
        ///  Notifications with the same group key are grouped together.
        /// </summary>
        [JsonProperty("groupKey")]
        public string GroupKey { get; set; }
    
        /// <summary>
        /// The title for the group notification.
        /// </summary>
        [JsonProperty("groupTitle")]
        public string Grouptitle { get; set; }
    
        /// <summary>
        /// Summary text for the group notification.
        /// </summary>
        [JsonProperty("groupSummary")]
        public string GroupSummary { get; set; }
    
        /// <summary>
        /// The action category, indicates the actions to display along with this notification.
        /// </summary>
        [JsonProperty("actionCatagory")]
        public string ActionCatagory { get; set; }
    
        /// <summary>
        /// Any custom key value pairs
        /// </summary>
        [JsonProperty("custom")]
        public Dictionary<string, string> Custom { get; set; }
    
        /// <summary>
        /// send notification having specific tag.
        /// </summary>
        [JsonProperty("tags")]
        public string[] Tags { get; set; }
    }
    

    Here is my service code which calls notification Hub client.

    Dictionary<string, string> templateParams = new Dictionary<string, string>();
    templateParams["messageBodyParam"] = myNotificationDto.pushRequest.Body;
    templateParams["messageTitleParam"] = myNotificationDto.pushRequest.Title;
    templateParams["messageSound"] = myNotificationDto.pushRequest.Sound;
    templateParams["messageSilentParam"] = myNotificationDto.pushRequest.Silent;
    templateParams["messageIcon"] = myNotificationDto.pushRequest.Icon;
    templateParams["messageLargeIcon"] = myNotificationDto.pushRequest.LargeIcon;
    templateParams["channel"] = myNotificationDto.pushRequest.Channel;
    templateParams["priority"] = myNotificationDto.pushRequest.Priority;
    templateParams["backgroundImage"] = myNotificationDto.pushRequest.BackgroundImage;
    templateParams["backgroundImageTextColor"] = myNotificationDto.pushRequest.BackgroundImageTextColor;
    templateParams["badge"] = myNotificationDto.pushRequest.Badge;
    templateParams["color"] = myNotificationDto.pushRequest.Color;
    templateParams["groupIcon"] = myNotificationDto.pushRequest.GroupIcon;
    templateParams["groupKey"] = myNotificationDto.pushRequest.GroupKey;
    templateParams["groupSummary"] = myNotificationDto.pushRequest.GroupSummary;
    templateParams["groupTitle"] = myNotificationDto.pushRequest.Grouptitle;
    templateParams["actionCatagory"] = myNotificationDto.pushRequest.ActionCatagory;
    templateParams["notificationId"] = NotificationId;
    for(int x=0; x< myNotificationDto.pushRequest.Custom.Count; x++)
    {
    var key = myNotificationDto.pushRequest.Custom.Keys.ElementAt(x);
    templateParams[$"{key}"] = myNotificationDto.pushRequest.Custom[myNotificationDto.pushRequest.Custom.Keys.ElementAt(x)];
    }

    var result = await client.SendTemplateNotificationAsync(templateParams, string.Join(" || ", myNotificationDto.pushRequest.Tags));

  • LandLuLandLu Member, Xamarin Team Xamurai

    Could you confirm this by debugging the DidReceiveRemoteNotification?
    When the application is on the foreground, this event will be called.
    Try to print the userInfo there to see whether the badge has been successfully sent.

  • Virender_dangiVirender_dangi Member ✭✭

    @LandLu - Yes DidReceiveRemoteNotification is being called when application is foreground or Background and we get the badge value also and its getting set as well.

    Only issue is when application is closed/Killed. That's the time badge is not getting set and we can't debug also after killing the application.

  • Virender_dangiVirender_dangi Member ✭✭

    Thanks @LandLu . I will check with Azure support.

    Just to be clear we need to write code only For background and Foreground. And that time DidReceiveRemoteNotification method will be triggered and we set the badge count in that method. For closed app payload coming from Azure notification hub should be good to set the badge count.

  • LandLuLandLu Member, Xamarin Team Xamurai

    For closed app payload coming from Azure notification hub should be good to set the badge count.

    Yes.
    None code will be triggered since your application hasn't been run. The badge is set by the system.

  • Virender_dangiVirender_dangi Member ✭✭

    Thanks @LandLu - I found the problem. In my NotifcationDTO i was sending Badge property as string . I changed it to Int and it started working.

    Thanks alot for your help.

  • LandLuLandLu Member, Xamarin Team Xamurai

    Glad you make it.

Sign In or Register to comment.