Is it possible to query for push authorisations by sending a silent push and have that reported back to my server?
I'm assuming silent push does not require push permissions.
Kind of, yes. If you send a silent push notification and your app has not been forced killed, then it could send back an update back to some of your servers saying that it got the notification.
Nevertheless, if the user manually quits the app, then those notifications are thrown away by the operating system, so you are not able to tell.
Also, you could simply call isRegisteredForRemoteNotifications on your application to check if the device is registered or not.
Update
To be more clearly: It doesn't matter if anything is turned on or off, you can never ever rely on the delivery of a message. The operating system may just delay the delivery, or skip it at all, and you'll never know. At least, not on the server side. Your app truely can check (once it is running again)
what kind of notifications it received (it just has to do some bookkeeping), and then ask the server if everything it has is also everything the server send sometime - but this logic has to be implemented by you.
Silent push notifications don't require push notifications permissions, but they can still be disabled by turning off "background app refresh":
Is Silent Remote Notifications possible if user has disabled push for the app?
Doing background networking requests of any kind while another app is running is a battery intensive thing to do. Many sites tell users to disable background app refresh for apps that use a lot of power. Using this feature unnecessarily could draw attention to your app and have your users disable this permission:
https://www.businessinsider.com/how-to-make-iphone-last-longer-battery-life-tip-2019-7?r=US&IR=T#:~:text=Turn%20off%20Background%20App%20Refresh.&text=That%20way%20the%20next%20time,%22%20and%20select%20%22Off.%22
You could simply check for push notification permissions on the launch of your app and record it there instead. Using silent push notifications to track the users settings is quite an odd thing to do. With everyone interested in what apps are tracking these days, and apple going out of their way to inform users of whats being tracked, doing this might get your app some bad press if it's discovered. I wouldn't install an app doing something like this, as I would be thinking "what else are they going to track while my app is off"
Related
I need to extend my app functionality with push notifications. The desired outcome would be to send silent notifications which will trigger the creation of local notifications.
I read about this silent notifications and they seem to be very unreliable.
First of all according to this:
"If something force quits or kills the app, the system discards the held notification.".
https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/pushing_background_updates_to_your_app the silent notification can be discarded. From my understanding force quit means that you double tap on home screen button and swipe up the app, right?
Secondly, according to this https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/pushing_background_updates_to_your_app apple doesn't recommend to send more than 3-4 silent notifications per hour. Do you have any experience with this behaviour? if you send 15 notification on an hour how many did you get?
If what I wrote above is true, then what alternative I have to silent notifications?
I believe remote notifications (of type alert, for example) are not affected by my two points above, right? Even if you force kill the app you will still get them.
I know there are so some stack overflow questions that covers parts of this topics but they are pretty old.
I understand that Silent Notifications and Remote Notifications are different things. The silent is just a regular Push Notification that doesn't generate any kind of alert to the user, it goes directly to the Notification Center, but there's still a hidden notification somewhere. Notice that the docs doesn't mention silent anywhere.
Now Remote Notifications are the real deal for your needs. This kind of notification doesn't produce any kind of alert to the end user, its just a payload that is passed into your AppDelegate methods, that way you can generate asynchronous calls to your app to inform that some external event happened, and take some action about it, like updating your local database.
The thing is, Remote Notifications rely on the same APNS infrastructure, and Apple doesn't guarantee the delivery of notifications. Although the failure rate tends to be very low nowadays, you should be aware that you can't rely on notifications for serious business logic. Background updates is a more a means of having your local state in sync and immediately available when the user opens the app, but it doesn't save you from having to manually trigger synchronization logic when your app is opened.
So about the specific bullets:
The thing is, iOS manages received notifications and optimizes the delivery to your app. Notifications can be received while your app is in background or stopped state. If you've sent a notification to the user and iOS kept it cached while your app was in background, and then the user forcibly killed your app, this notification will be lost. This should be probably be a very rare scenario, but could happen.
I personally don't have experience with this notification throughput stuff. I believe this is probably related to the fact that when a notification is sent and your app is in background, iOS will run it in background to deliver the notification and give you a chance to process it. Depending on the volume of notifications the operating system may impose restrictions on the background processing to preserve battery or other system resources.
So, I don't know your feature requirements, but I wouldn't consider the Remote Notification infrastructure much reliable for more than small updates to the local state.
shortly after this post I managed to convince our team to use push notifications instead of polling! We will use AWS Pinpoint, which uses APNs for IOS. So far everything is amazing, but we are missing a crucial functionality:
We need to make sure that push notification is delivered if the app is in foreground even if user has disabled notification and has disabled background app refresh for our app.
I understand that push notifications would if app is in background and user has disabled background app refresh, but why it affects foreground? Otherwise, polling is still essential, because it does work if user is in foreground...
Perhaps I am mistaken (I hope so), but I have tested various cases and could not solve this particular case.
If the user has disabled notifications, you will not get notifications.
Also, just a caution, push notifications are not a guaranteed quick delivery. If your connections are odd, they can come slowly. Also, if you move from cell to wifi or vice-versa it can make weird things happen with the notifications.
One thing you can try-- don't let your app run if they have disabled notifications. If it is required for your app to function properly, check for enabled notifications in your app delegate at applicationDidBecomeActive
My problem is: I just can't make silent notifications work when a user has force-quit(swiped away) the app!
I guess the following is a fact: A silent push (with content-available:1) will NOT trigger application(_:didReceiveRemoteNotification:fetchCompletionHandler:) nor any other method (it will NOT launch the app) if the application was force-quit (swiped away) by the user! Can anyone prove this wrong?
I have made sure I've enabled Background Mode: Remote Notifications.
But what if non-silent notifications don't work for me? I need silent ones, I need to be able to run some checks before I show it! What If I want to check if the right user is logged on to my application after I receive a notification from remote server? (since I can't guarantee that when he logged out he successfully let the server know about it, so I assume the server doesn't know for sure)
What would be the right approach to take in my situation?
There are many questions about similar things, but not many people involved, I wonder why? I don't believe that I have such a rare case. Maybe my basic approach to solving this kind of problem is wrong? It doesn't seem to be a problem on Android platform at all!
I am using FCM as central point of sending out notifications, so if you say that PushKit can solve my problems, too bad that FCM doesn't support VoIP certificates. But, I wonder, can PushKit really solve this? Or Apple just designed it this way that when a user force-quit an app, it means that this app must shut up altogether with its ability to push remote notifications?!
I don't consider this a duplicate of Firebase silent notification does not start up a closed iOS app because what I am asking here is what would be the solution if you want to check if the user to whom the notification is addressed for corresponds to the user logged in to the application? It can be considered duplicate if it turns out that there is absolutely no solution for this on iOS platform.
You ask:
Or [has] Apple just designed it this way that when a user force-quit an app, it means that this app must shut up altogether with its ability to push remote notifications?
Yes, this is how it is designed. App Programming Guide for iOS: Understanding When Your App Gets Launched into the Background says:
In most cases, the system does not relaunch apps after they are force quit by the user. One exception is location apps, which in iOS 8 and later are relaunched after being force quit by the user. In other cases, though, the user must launch the app explicitly or reboot the device before the app can be launched automatically into the background by the system. When password protection is enabled on the device, the system does not launch an app in the background before the user first unlocks the device.
Is not possible. when the app is in background or suspended modes, you will have 30 sec to do some stuff. But if user kill app manually func didReceiveRemoteNotification will never called.
Upd:
When an iOS device receives a silent notification, the system wakes your app in the background and calls the application(_:didReceiveRemoteNotification:fetchCompletionHandler:) method of its app delegate. Your app has 30 seconds of wall-clock time to perform any tasks and call the provided completion handler. For more information, see Handling Notifications and Notification-Related Actions.
Since push notifications may not be delivered sometimes (you can lose a few of them), you can not run code after the iPhone is turned on to check if there is new information available from the server, and you can not run code if your iOS App is closed... What can you do if you want to be as more accurate as possible in for example a Chat App in iOS?
I mean, inform the user as faster as possible that he has new info available. Comparisons: WhatsApp is updated without any delay.
You can do background fetch if your App is in background. But if the App is closed and you miss a push, it's not going to be up to date until the next push arrives or user opens the App. The same with silent notifications. If the app is terminated by the user, you are not going to receive it. Is there any way to solve it? It must be because other Apps do it... If there is any "private and secret" API that they are using (I read about this answer when no one know how to do that)... Is there any way to apply to use it?
UPDATE:
I'm using push notifications. The goal is to fix when a push doesn't arrive. Example: User A send chat message to user B. User B doesn't have the App open. The system lose the push. User B is not going to receive the message until he open the App.
Push notifications seems to be your only way even if you do loose a few of them, which I don't know how you would since they are pushed to apples secure server... but what do I know. As long as the user turns on the push notifications you should be fine. They may be delayed due to apples way of handling them. Honestly push seems to be the future, having your app constantly every minute or two check for new messages is a huge battery water in conjunction with normal texting apps. Your app should provide the best live data but since apple restricts to push notifications when the app is off or not running just stick to push notifications and only push major events to the user. I believe you can set up a job scheduler using quartz or schedulator to setup your server to push notifications to your app.
In my settings tabbar:
I have a feature specific switch which can be turned OFF or ON based on API response.
From website only admin is authorized to turn ON/OFF.
I can make /user API call everytime on settings tap to check the current settings for the user but there are couple of disadvantage like if user is already on setting then it will not update the UI and calling api everytime on settings tap doesn't sounds a perfect solution.
I think better solution is to send a silent push notification which i can use to make the API call to update the settings UI whenever needed.
But if user has disabled the push notification will I still receive silent push ? What is the recommended approach to handle such situations ?
Short answer, yes
The exciting new opportunity for app developers in iOS 8 is that Apple will now deliver “silent” pushes even if the user has opted out of notifications. Also, “silent push” is no longer just for Newsstand apps. Every app can take advantage of this ability to refresh content in the background, creating the most up-to-date, responsive experience possible, the moment the user opens the app.
Although...
Users still have the ability to switch off your app’s ability to process a “silent push” by means of the “Background App Refresh” control. Even though Apple Push Notification service (APNs) will deliver a push marked “content-available” to your phone, the OS will not wake up your app to receive it, effectively dropping it on the floor. However, opting out of “Background App Refresh” is a lesser-known capability not directly associated with Notifications. You don’t access this preference in your Notifications Settings--it’s located under General > Background App Refresh screen.
Keep this in mind when building your application.
Source:
https://www.urbanairship.com/blog/watch-list-ios-8-opt-in-changes
This matrix might help. At left hand side, it shows if "didReceiveRemoteNotification: " method will get called or not. Other two columns is related to setting app. Settings -> YourApp. If yourApp supports Notifications and background app refresh. Look into matrix to check when you app will receive silent push.
Other answers are good. But they are not official answers.
The official answer is in What's New in Notifications WWDC 2015 video:
Silent notifications are enabled by default. The user does not need to
approve your -- does not give permission to your app to use them, and
you can just start using them without asking the user for permission.
But silent notifications are the mechanism behind background app
refresh. At any point you know that the user can go in settings and
disable them. So you can't depend on them always being available. You
don't know if the user the turn them off, and you are not getting a
notification anymore. This also means that silent notifications are
delivered with the best effort. That means that when the notification
arrives on the user's device, the system is going to make some
choices.
For more see this image and this answer