I'm looking into enabling background fetch in our iOS app to give time to PubNub to prevent a presence timeout.
EDIT - Some background: our app is communicating its geolocation to a service over a pubnub channel. We ask the user to authorize location when its in the background, and when that's granted, we're already getting occasional time from the os. We've been trying to use presence features so the service can know if our app has quit/dropped connectivity vs just stopped moving. However when the device stops moving when in the background, we don't get execution time from locations arriving, and so pubnub timeout occurs anyway.
After enabling that background state, it looks like I need to
setMinimumBackgroundFetchInterval
with an interval when we have a connection we don't want to timeout (and also with Never
when we don't).application:performFetchWithCompletionHandler:
However, some things are not obvious:
What fetch interval should I choose in relation to our pubnub timeout? It seems the fetch interval specified is not necessarily obeyed by the os. In general we've wanted to keep our timeouts short so when our app goes offline or is force quit, our other end detects that fairly soon. That seems at odds with the heartbeat and making sure we don't inadvertent timeouts. I'm considering just using the Minimum
interval.
I don't think I need do anything in my performFetchWithCompletionHandler
method to make sure the presence heartbeat is sent, rather just by the fact that the app is woken up will let PubNub's timers fire and take care of everything. However can I do anything do invoke the completion block only after the heartbeat transaction, or know when to return newData
vs. noData
vs. failed
. Also, I'm concerned that just calling the completion right away every time with noData
will be taken by the os as a clue to back off the fetch interval.
Or, if anyone can recommend an alternative to this approach for preventing timeouts, I'd appreciate that.
If you want to keep your background app presence on a channel (or channels), you can simply use a REST call to send a heartbeat every 4 minutes (faster than every 5 minutes which is the default timeout - 4 just seemed like a nice round number):
https://ps.pndsn.com/v2/presence/sub-key/{yourSubKey}/channel/{listOfchannels}/heartbeat?&uuid={clientuuid}
For example:
https://ps.pndsn.com/v2/presence/sub-key/sub-c-1234.../channel/channel1,channel2/heartbeat?&uuid=db9c5e39-7c95-40f5-8d71-125765b6f561
Just make sure the UUID you send is the same as the UUID you initialized the PubNub instance with in that user's app.
This heartbeat ping has the same effect as a long running subscribe
connection. It will keep the given UUID present on the channels you pass in.
See PubNub REST Docs for more details.