Push notification working properly in app from Java APNS,
But one notification in payload with
{
aps = {
"content-available" = 1;
};
key = value;
key = value;
key = value;
}
This is not working in any state of app in iPhone 7, working in other devices, also check with battery mode.
From sender we see log and check response it's sending, but not received in device.
What was the reason for particular device or state ??
i have searched over web but see almost same content which i m using,
i got data in func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: #escaping (UIBackgroundFetchResult) -> Void)
this function when device receive any kind of push notification.
Related
I have used Twilio Chat SDK for my iOS app. The notifications when new message is added to the channel is coming up fine. But it doesn't update the app's notification badge count. I have attached the screenshot for push notification configuration in Twilio Portal.
Also when I ask for user authorization for notification,
the options set are:
let options: UNAuthorizationOptions = [.badge, .sound, .alert]
Your notification payload should look like the following to update app badge count:
{
"aps" : {
"alert" : "You got notificaiton.",
"badge" : 5
}
}
When this payload is received the badge count updates to 5.
Update: As mentioned in the Twilio documentation:
To update badge count on an application icon, you should pass badge count from the Chat Client delegate to the application:
func chatClient(_ client: TwilioChatClient, notificationUpdatedBadgeCount badgeCount: UInt) {
UIApplication.shared.applicationIconBadgeNumber = Int(badgeCount)
}
Note: But, this only works when the App is active. To update the badge count when the App is inactive you need to configure notification payload to the above-mentioned format from via a custom Twilio server, default configuration doesn't allow this.
When the app is inactive you can use this method to append the badge count:
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: #escaping (UIBackgroundFetchResult) -> Void) {
if UIApplication.shared.applicationState != .active {
UIApplication.shared.applicationIconBadgeNumber += 1
}
}
Scenarios:
1) Silent or Normal payload when App's in Foreground:
Nothing happens
2) Silent payload when App's in Background:
Nothing happens
3) Normal payload when App's in Background:
If User click the notification to open the App.
triggers the application:didReceiveRemoteNotification:fetchCompletionHandler
If user open the App clicking the App icon:
Nothing happens
These are the payloads I'm using for the APNs:
Normal payload: .
{
"aps":{
"alert":"andre test",
"badge":0,
"sound":"default",
"content-available":1
},
"acme-syncalarm":"true"
}
Silent payload: .
{
"aps":{
"content-available":1
},
"acme-syncalarm":"true"
}
I've implemented the Remote Push Notification using this code:
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: #escaping (UIBackgroundFetchResult) -> Void) {
print("Receeeeeeeeived: \(userInfo)")
UIApplication.shared.applicationIconBadgeNumber = 11
completionHandler(.newData)
}
I also implemented this to check if the App is recovering from a kill state (as I've read in some Questions too), but the code never enters the print(rn)line.
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
if let rn = launchOptions?[UIApplicationLaunchOptionsKey.remoteNotification] {
print(rn)
}
}
EDIT 1 -
I have also enabled Remote Notifications in background mode for the App.
What do I have to do to cover the "Nothing Happens" Scenarios? 1 , 2 and 3.2 ?
Some notes:
"If user open the App clicking the App icon: Nothing happens" <-- That's expected, because you didn't interact with any notification directly. Imagine if you had 5 notifications arrived. How would you know which notification you should process...
normal payload won't have any key named content-available. So that again is a silent notification. Can you first see my answer here?
Some suggestions:
Make sure you've enabled Remote Notifications in background mode. Like this:
Additionally See here. iOS 11 initial releases were buggy for silent notifications. Make sure you have the latest version for your testing, otherwise it won't work. If you have an iOS 10 device, then first try testing with that...
Make sure you have Background App refresh and notifications available on your device. To see how to do it, refer to my linked answer.
Are you creating the payload yourself or you're using FireBase? If you're using Firebase then some of the keys change...and you must adjust accordingly.
make sure you've set some object as the delegate of UNUserNotificationCenterDelegate e.g.:
UNUserNotificationCenter.current().delegate = delegateObject
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: #escaping (UNNotificationPresentationOptions) -> Void) {
let content = notification.request.content
// Process notification content
completionHandler([.alert, .sound, .badge]) // Display notification as regular alert and play sound
}
Code copied from here.
If you don't do such then you won't be showing any notification when the app is in the foreground. This should resolve the issue of when app is in foreground and you've received a normal remote notification.
I'm trying to update the badge value remotely via a push notification.
Everything works fine but when the app is open I get an empty alert (containing my app name and a close button).
I read about silent notifications in apple's documentation but it seems that even with specifying content-available : 1 in the notification payload, the payload must not contain badge for the notification to be silent.
Is updating the badge without receiving an alert possible ?
If you are using a silent push notification, then you cannot include the badge key in the aps dictionary, so you can't update the badge directly with a silent push.
You can include your own keys and values in the aps dictionary and this dictionary is available in the didReceiveRemoteNotification:fetchCompletionHandler UIApplicationDelegate function.
In this function you can extract your own "badge" key from the aps dictionary and use this to update the badge number directly using the UIApplication property [applicationIconBadgeNumber][1]
UIApplication.shared.applicationIconBadgeNumber = someValue
Something like:
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: #escaping (UIBackgroundFetchResult) -> Void) {
if let badgeNumberStr = userInfo["myBadge"] as? String {
if let badgeNumber = Int(badgeNumberStr) {
application.applicationIconBadgeNumber = badgeNumber
}
}
}
I have integrated push notification through GCM everything is working fine. But I am not getting notification message and sound. And the function didReceiveNotification: called in app delegate. And also not getting in background state.
Before making any comment or downvote consider following things.
I assume you have configured App Identifier in Developer portal, if not visit Apple Developer center
You have generated required provisional Profile & Certificate from Apple Developer Portal. If not visit App Distribution Guide
Make sure you have configured your bundle identifier correctly as defined in Apple Developer portal.
Following answer guides to configure APNS using your custom backend to send Push Notifications not for FireBase/GCM. To configure it using Firebase or GCM(As Firebase Cloud Messaging (FCM) is the new version of GCM) follow Google documentation
If all the above things are configured correctly then follow below steps:
Step 1: Register for APNS with Appropriate settings in didFinishLaunchingWithOptions inside AppDelegate file
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
let notificationTypes: UIUserNotificationType = [UIUserNotificationType.Alert, UIUserNotificationType.Badge, UIUserNotificationType.Sound]
let pushNotificationSettings = UIUserNotificationSettings(forTypes: notificationTypes, categories: nil)
application.registerUserNotificationSettings(pushNotificationSettings)
application.registerForRemoteNotifications()
return true
}
Step 2: Add delegate methods to handle success or failure for APNS registration by adding following delegate methods
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
// Convert binary Device Token to a String (and remove the <,> and white space charaters).
var deviceTokenStr = deviceToken.description.stringByReplacingOccurrencesOfString(">", withString: "", options: nil, range: nil)
deviceTokenStr = deviceTokenStr.stringByReplacingOccurrencesOfString("<", withString: "", options: nil, range: nil)
deviceTokenStr = deviceTokenStr.stringByReplacingOccurrencesOfString(" ", withString: "", options: nil, range: nil)
print(deviceTokenStr);
// *** Store device token in your backend server to send Push Notification ***
}
func application(application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: NSError) {
print(error)
}
Step 3: Now you have configured your APNS on device end, You can fire Push Notification from your server/backend, When Push Notification is received following method will be called when your app is in Foreground. Implement it into AppDelegate.
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
print(userInfo)
}
To handle Push Notification while your application is in background (but not killed by removing from multitask) you need to take care of following things.
Make sure you have enabled Background Modes in Project Navigation->Targets->Capabilities->Turn on Background Modes and select Remote Notifications.
Now implement following method to handle Push Notification while in background. Make sure you handle UIBackgroundFetchResult properly.
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
}
Note: If func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) method is implemented func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) method will not be called.
Read more about APNS in Apple Documentation.
Usually, iOS apps can receive push notifications via APNS not GCM and could not get any data when app is in background state. If iOS app gets push notification via APNS and it is in background state, the push notifications just shown in notification center & top of the screen with app's icon. If you see the notification, there's no problem with the server.
And there's no data arrived when app is in the background state, you should make your server api for the notifications data when the app is back on foreground state.
I've got push notifications going to the application I'm working on, but I can't seem to manage them in the application. If I can't manage the notifications in the application, how else can I reduce the incrementing value of the badge icon for the application app-icon?
You can change badge count in push data, also if you need manage received push notification data, use this function:
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void)
It's a snap to change the badge count from anywhere in the app:
UIApplication.sharedApplication().applicationIconBadgeNumber = 4