I have developed a small iBeacon based application, when the application detects one of our iBeacons makes a call to a web service to obtain a data set and send a local notification to the user. All this is working correctly.
I have now raised the idea that these local notifications could vary over short time intervals, with new content. The problem is that if the user does not leave the region of the iBeacon and reenters, the application will not "wake up" and the user will not receive the new updated notification.
After asking for advice on how to tackle the problem, someone suggested using remote notifications. Reading about it I found the silent remote notifications, but I'm not sure if I can use them as I'm thinking.
My idea is this, when a notification is modified or created and is associated to a iBeacon on the server, sending a silent push notification to the application so that it "wakes" if not in foreground. Thus, when the application "wakes up", you can do ranging few seconds, and if any iBeacon near detect and send the new notification.
Is this possible and permissible? I can send all silent push notifications that I want or is there some limit?Thanks
This is possible and permissible. You can read more about this in the Using Push Notifications to Initiate a Download section here:
https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html
However, there are a few drawbacks:
Remote notifications can be slow to arrive, and are actually not even guaranteed by Apple to arrive at all.
They are a bit of a headache to set up given that you need to build server ifrastructure to send them.
A less timely alternative is to just do periodic refreshes, but the OS typically lets your app do this only once a day. See Fetching Small Amounts of Content Opportunistically here:
https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html
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.
While working with APNS, I was able to have push notifications work flawlessly while device is online.
For any APNS push I send while device is offline, only the last one is received once the device is back online. This seems to be coherent with Apple's Store-and-Forward design.
However - I did notice, that when sending WhatsApp messages to an offline device, once this device goes online it receives all push notifications (one for each message). This is not something based on collapse identifier, but rather independent push notification for each message.
So how did WhatsApp do it?
Tried using Notification Extension and attempt to post multiple local notifications, but this also fails as extensions are not allowed to do that.
Instead of a normal push notification, use a Background Notification, which will not show anything visible, but wake up your app in background. Use this event, to make api call, get relevant data and generate multiple local notifications.
Note the following from the documentation when you implement application(_:didReceiveRemoteNotification:fetchCompletionHandler:) :
system calls this method when your app is running in the foreground or background
system does not automatically launch your app if the user has force-quit it
you must call the block in the handler parameter (fetchCompletionHandler) or your app will be terminated. Your app
has up to 30 seconds of wall-clock time to process the notification
and call the specified completion handler block
Apps that use significant amounts of power when processing remote notifications may not always be woken up early to process future
notifications
Please read relevant documentation completely before making ANY assumptions about how you think this should work.
I have an application which has communication with a remote server. The server should push data into it using remote notification silently, and I need to get and store these data into a CoreData database. The user won't be aware of the whole process.
I can successfully get notified when the app receives a remote notification, while it is either in the foreground or background mode. However, I need to get data while the app is terminated as well.
I searched for the possible solutions. For example, this SO question was good if I don't tend to use silent notification. I also saw the PushKit capability, but I am not sure about the Apple Review result.
What is the possible solution?
If I want to use VoIP and PushKit to get notified when the app is terminated, would Apple reject my application?
If you’re not creating a VoIP app and you want your app to be in the App Store then the correct answer is: it is not possible. The only thing that can be done is adjusting your requirements in some way.
For instance you can send some notifications that will be visible for user in the Notification Center and wait until the user taps the notification or starts the app the usual way. Then the app will be able to do all the operations you need.
The delivery of push notifications is not guaranteed, so you should not rely on them to synchronise data.
For example, if multiple push notifications are sent while the device is offline, only the last notification is delivered when the device comes back online; the earlier notifications are lost.
When your app launches one of the first things it should do is check with your server for new data.
As stated clearly in Apple docs, beacon ranging can be done in background for a short period of time only, say up to 10 seconds by default or up to 3 minutes with the help of background task expiration handler. As per my app's use case, app needs to do beacon ranging for every 15 mins until user exits the region. I am thinking of using background push notification(silent push notification) for this purpose(assuming data connection is available on the device always). So the flow goes like this, upon user entering the region, app calls the server with device token, server sends silent push notification for every 15 minutes. Once app received push notification, it does beacon ranging within allowed period of time if needed. Question I have here is whether using push notification in background mode to do ranging is legal, will I face any issues during app store submission.
Note: Also I need to enable BLE background mode for the app, to read some characteristics from some BLE devices.
Technically you can do it, but Apple mostly rejects such app. One important thing you have to consider is that, if the app is manually killed by the user and not running in the background, then the app won't wake up with silent push notification. There is a workaround if you have VoIP push notifications it will wake the app even from the terminated state. But you might need strong reason while pushing it to AppStore.
If you misuse one of the background modes, the app will probably be rejected, saying that, I don't think silent push notifications were meant for: keep an iOS app in "Background" state by sending it a silent push notification every few minutes.
another thing is that silent push notifications are rate limited as described http://asciiwwdc.com/search?q=push+notification, so I'm not sure if they will be sent every few minutes.
Apple says that;
Silent notifications are not meant as a way to keep your app awake in
the background, nor are they meant for high priority updates. APNs
treats silent notifications as low priority and may throttle their
delivery altogether if the total number becomes excessive. The actual
limits are dynamic and can change based on conditions, but try not to
send more than a few notifications per hour.
You might want to see this article. The user talks about apps that use silent notification for triggering location tracking. But eventually it's a hack that Apple may reject some time in the future, so it's best to have a contingency plan. FWIW so far I haven't heard anyone reporting rejection.
So the official answer is don't do it, as for the why you can refer to Ashish's answer. The unofficial answer is if you can't change your business logic then do it at your own risk.
The iOS application I'm working on does the exact same thing with the exception that I'm using recording instead of a Beacon. Recording by iOS standards gives more issues in pushing the app to the app store.
But Apple did not reject this app. Although we still are facing some issues but they don't relate to your problem.
You can follow such a tutorial for further help apart from the answer you were looking for : iOS Push Notification Demysitfied
Also, I've done firing of local notifications, while the application is in the background. BLE even works if the app is killed by the system, when the OS receives some communication from your peripheral or central, iOS wakes your app up and executes the desired function, before putting your app back to sleep.
I am using FCM to send iOS push notifications for an app that is used worldwide. Different users are in different time zones.
Is there a way to specify ,that when delivered at worktime local time Mon-Fri (8:00 - 17:00) it will have sound, but any other it will be without sound. I do not want to disturb the user at night.
This question is mostly about the worst situation when my app isn't running/backgrounded/suspended (for example after reboot) and/or offline
.My app uses background fetch, but that doesn't guarantee that it will be running at the delivery time of the push notification.
The problem is i do not know in advance when the push notification will be delivered. If i knew i would specify the sound key in the JSON.
The user could be offline when the push notification is sent.
For example, i send the push notification at night without sound, but the user enables internet connection at day and receives the notification without sound (because it was sent in the night)
Scheduling the sending time at the server won't solve this, because we cannot control the delivery time.
If it is possible using directly APNS without Firebase then that would also solve my problem.
Thank you very much.
Clarification:
When my app is running i have enough control to decide according to local time if the sound should be played. The question is aimed at the other case when my app isn't running/backgrounded/suspended.
I am using silent data notifications (JSON key data with content-available=1) to deliver all neccessary info, but when my app is not running there is only one way to send a notification that will be shown - that is a Display notification (JSON key notification)