BGProcessingTask not fired when device not connected to external power - ios

I'm able to schedule and run a BGProcessingTask and it works fine, but only if the device is connected to the external power. I've tried to set requiresExternalPower = false but nothing changes. To be sure my task send an email when it starts so I can monitor it. When I disconnect the power cable the task is not lunched anymore. Is there any solution?

Related

How to get notified when a previously connected peripheral re-connects later (a connection originating from peripheral)?

So I am building an IoT device and now I am working on battery optimizations. I am able to tell the device to connect to a central it has bonded to. This works(ish). You can observe the device connecting in bluetooth settings, but about 5 seconds later it disconnects. I would assume that since there is nothing happening and nothing asking for it, it drops the connection. I also assume that this is allowed for ANCS. What I want to know is can it be used for anything else? I would like to be able to shut off the device, not have to scan constantly in app, and have the system notify my central manager that the device has connected later (when a user wakes it up.
I know I can call
[_manager retrievePeripheralsWithIdentifiers:identifiers];
to get devices I have connected to before, but I am not seeing a way to attach unconnected ones to the manager so that when they do connect in the background, the app knows about it. Anyone have a solution for this?

Notify app when connection state changes in background

When app goes in background seems there is no way to use Reachability module to make possible app to be notified about:
Device is disconnected from current network then connects back.
Device is disconnected from current network and connects to a new network.
Device receives a new IP.
These events are important, app must update it's location otherwise user will miss calls, etc.
Update:
App is using setKeepAliveTimeout to trigger each 10 minutes a registration process which will update location, but this is too long.

Why don't downloads switch back to wifi after been on a cellular network?

I have encountered a rather strange behavior when trying to implement download functionality on iOS. The download implementation works fine in that it finishes successfully, can run in the background, and file is stored on device. However during a download, I can turn of wifi to let the task switch to and continue on cellular network (or just start the download using cellular). This behaves as aspected. But when I enable wifi again, the download never seem to switch back to using wifi. The device is connected, and the wifi-connection-bars displays at the statusbar. Using rechability functions to check what connection that is available will even return Wifi, but the download seems to be stuck at using cellular.
The way I am detecting this is looking at the Usage stats in the system settings. The cellular data usage will rise in sync with the pending download, and continue to rise until the download is finished (even if wifi is turned on again).
I have tested with both Alamofire and by using NSURLSession and NSURLSessionDownloadTask directly, and they both behaves similarly. I have also seen this behavior in two completely seperate projects, on multiple devices, in iOS 8.4 and 9.1, when the apps are in the foreground or the background, and even AppStore behaves like this when downloading apps!
Has somebody else experienced this?
And if so, did you find any way to gracefully switch tasks back to wifi?
Thanks in advance.
This is normal behavior. Adding a new network interface (e.g. turning Wi-Fi on) doesn't stop existing TCP connections. They will continue until the original network interface goes away.
If you want to pause the request and reconnect when Wi-Fi becomes available, you'll need to call cancelByProducingResumeData: on the task, then create a new request with that resume data to restart the request from where it left off. That new request will go over the currently active network interface, which would typically be the Wi-Fi interface if Wi-Fi is up and running.
Before you stop the existing request, though, I would suggest trying a probe request for something like Google's generate 204 or one of Apple's captive portal detection URLs, to ensure that Wi-Fi really is working.

How to reliably keep a voip app alive in ios?

I have a voip app for ios, based on webrtc. I also have a signaling server made with nodejs. I can connect to the server and make calls without a problem. But tracking presence (online/offline) accurately is a problem.
Just for the record, here is a list of everything I did to ensure a stable connection:
Set the background mode "Voice over IP"
Flag the inputstream as a voip stream with "[inputStream setProperty:NSStreamNetworkServiceTypeVoIP
forKey:NSStreamNetworkServiceType];"
Turned on persistent wifi by setting "UIRequiresPersistentWiFi" to YES in the plist file
I implemented "setKeepAliveTimeout:handler:" and I use it to send a ping to the server (unnecessary, but you never know...)
I created a small test app that does nothing more than connect to the server and respond to "ping" with the message "pong". This app sends "ping" to the server when the keep alive timeout handler fires and the server replies with "pong". I also created a simple test server that does nothing more than let clients connect, send "ping" to a client when I send "send_ping" to it via telnet and responds to "ping" with the message "pong".
Here is my client code
What I expect is the following:
Starting the app and signing in should create a persistent connection to the server (works)
Telnetting into the server and typing send_ping makes the server send "ping" to the client and the client should send "pong" back (works)
Putting the device in standby should have no effect on the above ping-pong mechanism (doesn't work)
Putting the device in standby and unlocking it after a few hours, then sending a ping to it should make the client send a pong back (works)
Turning off wifi on the client (without cellular enabled) should be detected on the server-side and kill the socket (doesn't work)
I log all messages from the server in a textview on the client with a timestamp, and sometimes when I put the device in standby the pings I send from the server just don't arrive at all. Sometimes it takes over a minute for the app to receive the ping message, sometimes it responds immediately. I don't understand why it is so random. Sometimes this undesired behaviour starts after mere minutes in standby mode, sometimes it goes alright for a while but breaks after 20+ minutes, sometimes all messages from the server arrive at once as soon as I unlock the device.
Push notifications and voip push notifications could be a solution, but they are also slightly unreliable. There should be a way to make this work 100% of the time.

How to prevent Web Socket from disconnecting while iPhone/iPad goes in lock state?

We have implemented HTML5 Web socket in my iPhone and iPad app. Web Socket works fine when app goes background (iPad/iPhone is not in lock state). But it gets disconnect when iPhone or iPad gets lock.
Is there any way to keep web socket running even when iPhone/iPad is lock?
Thanks.
According to my own experiments. When you lock the device, the device seems to shut down WiFi and close network sockets, most likely in order to save power. The mobile broadband connections remains active though, and sockets seem to survive. At least for some time.
Have you tried to wrap the some parts of the socket code inside a beginBackgroundTaskWithExpirationHandler()? This should at least allow you to gracefully close the socket, or keep the socket alive for some time. The OS will, however, kill your task it after a global timer expires.

Resources