I'm trying to use Apple push notifications. Everyting works fine except when app is in background.
The callback method DidRecieveRemoteNotification is sometimes not called immediately after notification is received. Sometimes it takes more then 5 minutes to be invoked. Is this standard behavior?
When the app is running in foreground callback method is called right after receiving notification. I would like the same behavior even when app is in background.
Silent notifications will invoke their callback immediately when in the background as their purpose is to wake the app up for a short period of time.
In order to save battery, regular push notifications won't invoke the callback while in the background (unless your app is executing something else in the background). The callback will be called the next time the app is opened, whether from tapping the notification or otherwise.
This is not something you can fix, this is how the eco-system works. If you need your app to do something immediately, you will have to use silent notifications
Related
Here a very tricky situation: I'm writing an alarm app in swift. At the moment the alarm is fired the application will most likely be in background or killed or even worse the iPhone is locked. As soon as the alarm is fired the app should set another notification automatically while in background. I'm able to do this in AppDelegate only if the app is in foreground, but in background, I'm only able to set a notification with a nice attachment and sound, but no code is executed. I'm not able to call a method after a local notification was received in background with a locked device.
Help would be very appreciated. I'm not sure there is a solution. Thank you very much.
Reading didReceiveRemoteNotification it says that this method is called if your app is running in the foreground or background.
What you may find useful is
In addition, if you enabled the remote notifications background mode,
the system launches your app (or wakes it from the suspended state)
and puts it in the background state when a remote notification
arrives. However, the system does not automatically launch your app if
the user has force-quit it. In that situation, the user must relaunch
your app or restart the device before the system attempts to launch
your app automatically again.
So, I don't the think you can work around the killed scenario. But with background mode enabled you can at least wake the app from at most the suspended mode.
Read Apple's Background Execution article, especially the section Understanding When Your App Gets Launched into the Background. Where it says a background execution is when
A push notification arrives for an app and the payload of the notification contains the content-available key with a value of 1.
You may be able to do some or most of what you want in here.
I am developing a messenger app like whatsapp, it has to notify the server that the message is received, I am sending the status to server when didReceiveRemoteNotification is called. But when the app is not in foreground, it is calling only when the user taps on the notification. How to make server calls even when the app is in background or not running?
To receive a remote notification when your app is in background or suspended mode first your server should send special parameter in notification payload called content-available = 1. to learn more about that look the documentation: https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/PayloadKeyReference.html#//apple_ref/doc/uid/TP40008194-CH17-SW5
Also turn on this switch in the project settings:
With this parameters when your app will receive a push notification it will be waken up for some small time to background mode and call didReceiveRemoteNotification. Don't forget to call completionHandler(<some enum parameter>) in the end of your task, or your process can be killed by iOS unexpectedly, for example when you're trying to perform async server requset. So when your async method completes call completionHandler closure argument of didReceiveRemoteNotification.
Actually there is no managed code can be run when your app is completely thrown away from the app switcher. As far as I know to perform that you should use VOIP push messages - but that kind of messages is only for apps with voice calls, like Skype or WhatsApp. This kind of apps has some code to perform even if they are completely turned off. iOS gives this ability to them to prepare to voice call. That's why all these messengers use Voice calls - to make instant delivery status for example. If you want that kind of interaction you should google more about VOIP. But your app should really have some voice calls function or it will be rejected by the app store.
I am building an app that needs to speak data while the app is in the background (or screen is off). The speaking part is done via AVSpeechSynthesizer.
My Android app launches a service that listens for the data and whenever it needs to say something, I say it and its done. Now iOS doesn't allow these kind background tasks from what I read. The closet thing is called 'Executing Finite-Length Tasks' which looks like has a time limit of 10 mins max. So this will not work for me. Instead it looks like I need to use Push Notifications.
Looking at the documentation for Push Notifications, if I understand it correctly, if my app is in the Foreground, then my app receives the Push Notification instantly. While if my app is in the Background, a notification is set (notification center), and once the user hits the notification, my app launches with the payload.
The question here is, is there anyway to make a push notification wake my app immediately so I can speak some info?
Or what are some of the other alternative approaches that should be used in this case?
My other idea would be to implement some sort of mp3 stream per user, that would stream audio which I could play in the background. But this seems excessive for what I am trying to accomplish?
I'm not sure if you'll be able to invoke speech synthesis from the background, but you can have you app notified when the push arrives. The trick is to implement the
- (void) application: (RMApp *) application didReceiveRemoteNotification: (NSDictionary *) userInfo fetchCompletionHandler: (void (^)(UIBackgroundFetchResult result)) completionHandler
UIApplicationDelegate method (note the completionHandler parameter).
You must also set the Remote Notifications Background Mode capability.
And you must set content-available in your push notification payload.
A decent writeup on these steps found here:
http://samwize.com/2015/08/07/how-to-handle-remote-notification-with-background-mode-enabled/
It looks like no matter I return UIBackgroundFetchResultNewData or UIBackgroundFetchResultNoData from performFetchWithCompletionHandler, it clears all previous notifications (local or push) for my app. This is not acceptable for me.
Anyone knows how do I do fetch and not make previous notifications cleared (disappear)?
My guess here is that you had a background fetch that was setting your badge number to 0, if that ever happens all your notifications are cleared.
Source: Apple's AppDelegate API Reference
application(_:didReceiveRemoteNotification:fetchCompletionHandler:)
Tells the app that a remote notification arrived that indicates there is data to be fetched. Use this method to process incoming remote notifications for your app. Unlike the
application(_:didReceiveRemoteNotification:)
method, which is called only when your app is running in the foreground, the system calls this method when your app is running in the foreground or background. In addition, if you enabled the remote notifications background mode, the system launches your app (or wakes it from the suspended state) and puts it in the background state when a remote notification arrives. However, the system does not automatically launch your app if the user has force-quit it. In that situation, the user must relaunch your app or restart the device before the system attempts to launch your app automatically again.
If the user opens your app from the system-displayed alert, the system may call this method again when your app is about to enter the foreground so that you can update your user interface and display information pertaining to the notification.
Note: You need to make sure that the app is checking for the state before settings the application's badge number to 0. Test the below cases:
Application running, receives a notification
Application terminated, receives a notification
Launch app directly from app icon
Launch app from notification received
Knowing the difference between the 3 approached below is essential in your use case.
Checking the notification object received in application(_:didReceiveRemoteNotification:)
Checking the notification object received in application(_:didReceiveRemoteNotification:fetchCompletionHandler:)
Checking the didFinishLaunchingWithOptions for UIApplicationLaunchOptionsRemoteNotificationKey
I've built a small ios app which perform periodic updates.
I'm registering my app for background fetches with a callback handler.
When app goes background I'm continue to receive callbacks over the time (every 20-30 minutes, event days later).
Once my app is terminated - the callback handler will be not executed any more.
Is it excepted behavior? I failed to find any mentions about activation from terminated state in Apple documentation on this.
ps: activation from the terminated state is crucial for my app. The approach of the activation could be any, except of user interaction.
It seems that if an app is terminated it will be awaken neither by background fetch nor push notification. No official documentation on this though.
Also keep in mind that if you kill your app from the app switcher
(i.e. swiping up to kill the app) then the OS will never relaunch the
app regardless of push notification or background fetch. In this case
the user has to manually relaunch the app once and then from that
point forward the background activities will be invoked.
Source here