As a slightly open question: Can/how does one send a network request every 5 minutes from a minimised iOS app?
In our case, we want to make sure that a certain message written when offline is sent as soon as the user regains internet access, even if the app is minimised.
Attempts at a solution
Most people are thinking down the 'app posting it' line, which hits the 3 min limit as mentioned.
Is there anything around the server pinging the app (perhaps with a notification) to trigger the app to respond with the required information?
Related
My app listens for 3 geofences while the app is closed. When entering a geofence, the identifier is sent to the back-end. Everything works wonderful but I would like to also handle the case when there is no network connection when entering the geofence. Like waiting with sending the request until there is a connection. This has to work when the the app is closed.
It only has to work on devices with iOS 11 or higher. Waitsforconnectivity does not work, I think because the time window from the geofence is to small. When i start the app that specific request is successfully sended so it does work but not if the app is closed. I have to manually start the app to let the pending request send when there is a connection. I also tried dataTask and uploadTask but these give the same behaviour as with waitsForConnectivity. I also think that is not possible to check if there is a network connection with scheduling a task with a timer in the future? Because the app is closed.
Is this even possible? I think the only way to do this is with a remote push notification but running code as a response to a push notification is only allowed with Voip.
I find it hard to believe that this isn't possible since this so easy with a BroadcastReceiver on Android.
Try BackgroundFetch
You can wake your app with certain periodic interval with this approach, without user interaction. Once your app wakes up, check if you have some pending data to be sent to the server. If yes, send it. If the internet connection is not there, no problem, program your app to wake up at let us say every 5 hours.
// Fetch data once an hour.
UIApplication.shared.setMinimumBackgroundFetchInterval(3600)
A simple call like above will wake your app up after 1 hour. Follow the steps in the link and you'll get the idea.
My main question is how to detect the application termination by the end user when it was in the background (Suspended) to be able to send logout request to the server ?
We already have a timeout interval in the server to kill the session, but assume that the interval is 5 minutes so this means that the session will be alive for 5 minutes after the user terminated the app and anyone can sniff on the data and reuse it.
Notes:
We use HTTPS connection and SSL Certificate Pining.
We also implemented a heartbeat web service to be called by client app every fixed interval to tell the server to keep the session alive for this interval, if this web service didn't call for specific session, the server will kill this session.
Once your app is suspended you don't get any further notice before you are terminated. There is no way to do what you want.
Plus, the user could suspend your app to do something else (like play a game) and then not go back to your app for DAYS.
If you want to log out when the user leaves your app, do it on the willBeSuspended message. Ask for more background time and send a logout right then and there.
Mohamed Amer,
Here is an approach used by Quickblox Server and I feel its pretty much solid though it involves a little overhead.
Once the client application (either iOS android) establishes the session with quickblox server, quickblox server expects the client application to send the presence information to server after a regular interval continuously.
Sending the presense information is pretty much simple. They have written a api which we keep hitting after a interval of 5 mins with session id that we have. They validate the session id and once found valid they will extend the expiration time for the user ascociated with that id for 5 mins more.
What they will do I believe is that,
Approach 1 : they maintain the last hit time and for all the subsequesnt request they check if the request time is within the the time frame of 5 min if yes simply process it. If the request comes after 5 min they will delete the session id for the user and respond saying you have timeout the session.
Approach 2 : Because they provide online and offline info as well they cant simply depend on the incoming request to delete the session id from server so they probably create a background thread which swipes over the db to find the entry with last hit time greater then 5 min and removes it from DB. and declares the user session expired.
Though this involves client apps continously hitting the server and increases the burden on the server for the app like chat application in which presense information is so vital this overhead is still fine i believe.
Hope I have provided you with some idea at least :)
It's generally a common question.
I wonder how do mail apps implement functionality of email-receiving?
I need to implement a simple sync between two devices(for example) using my web service.
Imagine a to do list app.
Is it possible to implement such a functionality: device1 makes an entry,then sends a message to webservice, webservice informs device2 that changes took place and device2 adjusts its data and displays that entry?
On iOS what you want could easily be implement with push notifications.
As soon as the server detects changes that device2 needs to be aware of the server will send a push notification to that device.
After the user views the notification the app should update it self, it would also be a good idea to let the app update it self when coming to the foreground.
The reason for doing it with Push Notification and not polling is that if your app is in the background you can only continue to run a process for 10 min max. You might get around this by adding the background mode to your app, like VOIP, Audio or location. But if you app does not fall in those categories apple might reject your app.
With Push notification the device will receive the notification even if your app isn't running or in background.
Basically there are 2 ways:
polling, each device asks the webserver for changes every N minutes: new todo, delete a todo, change a todo, ... and then each device will adjust. The frequency of the poll depends of the level of real time you are looking for. It can be 1 call every second or every 12 hours or much more.
implement a kind of BOSH protocol: the device opens a connection to the server. The server keeps it open until there something new to send to the device or the connection times out. In that case, the device reopens it.
Option 1 is better for your todo app because you don't need real-time accuracy. The option 2 is better for a chat application where you don't want to wait for the message.
I have an app that tracks wildlife where the user enters data based on their observations (eg. user enters they see 3 moose). The data is then uploaded to a server. However, because this app will be used out in the field where there is often no internet connection, I want to save data if there is no connection, and upload the data as soon as the network is available
I know about Reachability, but it looks like I can only check if the internet connection is available at that moment, and doesn't check in the background for internet connectivity
So to summarize:
If there is an internet connection when users submits data, then that's fine.
If there is no internet connection, when user submits data, I want to save this data. As soon as there is an internet connection, I want the data to be uploaded, without needing the user to open up the app again. I can't rely on the user to open the app again causing the data to be submitted, because they will likely only use this app out of the range of cell towers, and will likely NEVER run the app in a location with a network connection, so it would have to automatically submit this data for them.
Looking around, I can't find an answer so I'm beginning to wonder...is this even possible?
No, Apple don't allow applications to run indefinitely in the background for this purpose, and they don't allow applications to be triggered remotely or anything of that nature. At best you could have your application run in the background to get notifications about major location changes, but you'd have to have it as a proper feature rather than a hack to get around this limitation, otherwise your application won't get approved by Apple.
I know it's possible to utilize the network in the background but only for a limited time after the user closes the app. You could create a timer which checks for a network connection (using Reachability or by pinging Google) and set the timer to fire every minute after the app closes. It's not a very efficient solution but it may work. You should look into how long you can maintain a connection after the app close though, I think it is 5-10 minutes.
We are building an enterprise class Work Order application where the users will often be in areas with no network coverage. We want to be sure that when they come back into coverage, any work that they have done on locally stored work orders is sent back to the server ASAP. This is easy to do if the user keeps the app running, but in our situation it is very likely that they will switch between apps, and the Work Order app may not be running when they come back into coverage.
We have thought of having the app fire an email to a server side listener when it senses that it is out of coverage. When the device comes back into coverage, the email should get delivered, and the server can send a push notification to the user to open the app. This feels like a bit of a hack... is there a better way to handle this situation?
As you already noticed, push notifications is the way to go, but even with them its not guaranteed that the user will send the data or even open the app.
I would suggest that you make the data itself expire after a limited time and alert the users when they minimize or even close the application.
You can also use local notification to alert about expiration.
So long as this is an enterprise application that doesn't have to be distributed through the App Store, you can abuse the audio background processing mode to keep your application running at all times. All you have to do is play a silent audio file on a loop as if you were a media player. This will keep your application running in the background, where you can retry connections to the server as you'd like.