How to increase badge number when sending a parse push notification - ios

I am having troubles increasing the badge number using the Parse iOS Framework.
When I call this code, the other user gets the Push notification, but his badge number is not increasing on the icon.
let push = PFPush()
let data = ["badge": "Increment"]
push.setData(data)
push.setChannel("channel_\(userId)")
push.setMessage(message)
var err: NSError?
do {
try push.sendPush()
} catch var error as NSError {
err = error
} catch {
fatalError()
}
Thanks!

Try with this in swift for increase
let currentCountStr = UIApplication.sharedApplication().applicationIconBadgeNumber.description
let currentCount = Int(currentCountStr)
if(currentCount > 0) {
UIApplication.sharedApplication().applicationIconBadgeNumber = currentCount! + 1
} else {
UIApplication.sharedApplication().applicationIconBadgeNumber = 1
}

You should check your database and/or code if you successfully updated 'Installation' table. The way it works is, that they store badge number in that table (perhaps refresh after each application is awaken) so later server can send incremented number inside notification payload.
Parse had a blog entry on this : http://blog.parse.com/announcements/badge-management-for-ios/
Just to add note how it works in more generic environment :
You should send actual new badge number from the server, it is not just incremented for you.
There is good deal of information on another question :
Increment the Push notification Badge iPhone

Related

ios 13 push-notification gets cleared as soon as we get when device is locked

when I'm receiving push notification on iOS 13, and device is locked. I' getting pushnotifcation, but it gets cleared immediately without any user interaction.
I'm using .net and following is payload code which I'm using
{to = notification.DeviceToken,
priority = "high",
content_available = true,
notification = new
{
body = notification.Message, //This will be a subtitle..
title = notification.Name, //This will be a title..
},
data = new
{
notificationId = notification.NotificationId,
userId = notification.UserId,
encryptedNotification = Crypto.Encrypt("id", notification.NotificationId.ToString())
}
};
string postbody = JsonConvert.SerializeObject(payload).ToString();
Byte[] byteArray = Encoding.UTF8.GetBytes(postbody);
tRequest.ContentLength = byteArray.Length;
**tRequest.Headers.Add("apns-push-type", "alert");**
**tRequest.Headers.Add("apns-priority", "5");**
}```
Please guide me what wrong in code.
have referred following azure code to implement, but not able to find the cause.
https://learn.microsoft.com/en-us/azure/notification-hubs/push-notification-updates-ios-13
This can happen if you have a code that decreases the app icon's notification badge number. If you do that, make sure you do it only if the application is active. If it is inactive and you decrease the badge number, it might cause the notification to appear and immediately disappear.

How to send push notification when content on a website changes

The core of the app I am building is that it sends a push notification to the user twice a week with a number from a website, at a specific time twice a week (example of the Swift code I'm using for this below).
I did some research about background execution, but I think I will not be able to use it because it's so limited (only for location, limited time, etc.).
Using a server is another option. I do not intend to make money with this app so it has to be a free option. That's why I was looking into Firebase.
I'm learning Swift now, it's the first programming language I'm learning.
Does anyone have an opinion on how to go about doing this?
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let url = URL(string: "https://store.nike.com/be/nl_nl/pd/air-vapormax-flyknit-hardloopschoen-heren/pid-11384993/pgid-12169774")!
let request = NSMutableURLRequest(url: url)
let task = URLSession.shared.dataTask(with: request as URLRequest) {
data, response, error in
var message = ""
if error != nil {
print(error)
} else {
if let unwrappedData = data {
let dataString = NSString(data: unwrappedData, encoding: String.Encoding.utf8.rawValue)
var stringSeperator = "exp-pdp-local-price js-pdpLocalPrice"
if let contentArray = dataString?.components(separatedBy: stringSeperator) {
if contentArray.count > 0 {
stringSeperator = "€"
let newContentArray = contentArray[1].components(separatedBy: stringSeperator)
if newContentArray.count > 0 {
message = newContentArray[0]
print(message)
}
}
}
}
}
if message == "" {
message = "The jackpot couldn't be found. Please try again."
}
DispatchQueue.main.sync(execute: {
//De text in het label van de weer app = message
//Gebruik 'self.' om naar de viewcontroller te verwijzen, want hier zit je in een closure en niet in de viewcontroller zelf.
})
}
task.resume()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Push notifications are not complicated.
Basically you have to register your device to APNS ( Apple push notification system ), once registered device, APNS will return you a token (each token is device unique). When u get the token from APNS you have to send the token to the server which will provide your devices with push notifications. Once the server app receives a token from device, you can save it in database.
For example :
username1 mobile_token1, mobile_token2.
Now, you can get tokens from database for specific username and send push notifications from the server to the devices.
When you send push notifications from server to devices, you have to send the token and data content to APNS, APNS then will send notification to specific device.
So the answer for your question is, if you want to send push notifications you have to send them from backend to devices, the moment you will send push notifications is when the web content changes, you get the tokens from the database, and send notifications to APNS.
The logic is same when you use firebase instead APNS.
Here is a nice tutorial for client side
https://www.raywenderlich.com/156966/push-notifications-tutorial-getting-started
It seems you don't need a push notification (also called remote notification) but a local one (see apple documentation).
You can configure when during week you want this local notification to be fired.
Edit: I did not catch that content of notifications depends on your previous piece of code.
So you can still use a local notification. It will be triggered by what is called a background fetch.
See this tutorial for example (search 'Background fetch' on the page).

How can I know when UNUserNotificationCenter's removeAllPendingNotificationRequests() has completed?

The iOS docs say that UNUserNotificationCenter's removeAllPendingNotificationRequests() is asynchronous.
What I want to do is this:
Call removeAllPendingNotificationRequests() to get rid of all my scheduled notifications
Schedule a bunch of new notifications, some of which may or may not have the same IDs as what was there previously
But since the documentation says that the method is asynchronously running on another thread (and there is no completion callback parameter) I'm worried that sometimes, depending on the vagaries of threads and timing and whatnot, that step #1 will still be going as I am creating things in step 2 and therefore it will also kill some of the new notifications I'm making.
This kind of stuff is a little tricky to test manually, since it depends on timing. So I'm curious is anyone knows if this is something I should be worried about or not...
In documentation for add notification I found this:
Calling -addNotificationRequest: will replace an existing notification
request with the same identifier.
Maybe the solution would be something like this:
Create new notification requests
Get all pending and filter out only the ones that will not be replaced
Delete not replaced
Add all new notifications
let center = UNUserNotificationCenter.current()
// Create new requests
let newRequests: [UNNotificationRequest] = [...]
let identifiersForNew: [String] = newRequests.map { $0.identifier }
center.getPendingNotificationRequests { pendingRequests in
// Get all pending notification requests and filter only the ones that will not be replaced
let toDelete = pendingRequests.filter { !identifiersForNew.contains($0.identifier) }
let identifiersToDelete = toDelete.map { $0.identifier }
// Delete notifications that will not be replaced
center.removePendingNotificationRequests(withIdentifiers: identifiersToDelete)
// Add all new requests
for request in newRequests {
center.add(request, withCompletionHandler: nil)
}
}
I have the same case as you and up to know I don't have a problem with this code:
center.getPendingNotificationRequests(completionHandler: { notifications in
var notificationIds:[String] = []
for notification in notifications {
if notification.identifier != "something_taht_I_dont_dismiss"{
notificationIds.append(notification.identifier)
}
}
self.center.removePendingNotificationRequests(withIdentifiers: notificationIds)
createAllNewNotifications()
})
If you want to double check all if the pending notifications are removed you can create simple recursion method for checking.
func removeAllNotificationsSafe() {
center.removeAllPendingNotificationRequests()
checkNotificationsAreRemoved()
}
func checkNotificationsAreRemoved() {
center.getPendingNotificationRequests(completionHandler: { notifications in
if notifications.count > 0 {
self.checkNotificationsAreRemoved()
} else {
self.doWhathverYouWant()
}
}
}
I don't believe this is needed, because all the actions of UNUserNotificationCenter will be synchronized between each other.

How to reset the Badge app icon number?

I integrated the Push Notification to the CloudKit so that every change in the iCloud will pop up a notification on my iPhone and the badge app icon number will add one correspondingly. However, when I used the code:
application.applicationIconBadgeNumber = 0
to reset that number in the applicationDidBecomeActive(_ application: UIApplication), I noticed that the badge app icon number truly disappeared but if another new notification came again, the number won't start from one again as supposed but just add one to the original total number before the reset. Therefore the number is getting bigger and bigger. I wonder how to solve this problem?
The problem is your apns payload, it contains badge count more than 1, you need to reset the payload as well.
When you set application.applicationIconBadgeNumber = 0 it just resets the badge count locally, not in the server.
Solution would be reset the badge count for the user in the server too.
Update: Apns Payload
{
"aps" : {
"alert" : {
"title" : "Push",
"body" : "Hello User"
},
"badge" : 5
}
}
The app shows the badge count same as in the apns payload above, you need to reset the badge value in the payload above from server.
Hope it helps.
Cheers.
I find that I should not only set the application side like:
UIApplication.sharedApplication().applicationIconBadgeNumber = 0
but I should also set the iCloud side in CKContainer. Therefore, the complete code is like below:
let operation = CKModifyBadgeOperation(badgeValue: 0)
operation.modifyBadgeCompletionBlock = {(error) in
if let error = error{
print("\(error)")
return
}
application.applicationIconBadgeNumber = 0
}
CKContainer.default().add(operation)

Update data model on Apple Watch when phone app is in background

I have written an iOS app that refreshes its data model when a push notification is received whilst the app is in the foreground, once the data is retrieved from the server I send that information to the watch kit app using:
// This code resides in ErrorsViewController.swift
func updateWatchContext() {
do {
let messages = convertParseObjectsToJSON(tasks)
try session?.updateApplicationContext(["messages" : messages])
} catch let error as NSError {
NSLog("Updating the context failed: " + error.localizedDescription)
}
}
func convertParseObjectsToJSON(data:[PFObject])->[[String : AnyObject]]
{
var data = [[String:AnyObject]]()
for var i = 0; i < tasks.count; i++
{
let object = tasks[i]
data.append([
"createDate" : object["createDate"],
"errorMessage" : object["errorCode"]
])
}
return data
}
This works fine when the application is in the foreground, the data model gets updated on the watch as expected. However in the scenario that the phone is running in the background, how can I make a background fetch, parse the data and send it to the watchkit app without waking the iPhone, using watch connectivity?
I was thinking about trying to add the code in AppDelegate, but I don't believe that will work. I'd like to note that I do not want to make any network requests directly from the watch itself due to the limited CPU power; it would be un-necessary to handle the data parsing there.

Resources