I made a test program that log the download speed of a big file.
I start downloading the file using WiFi with an average speed of 180KB/s.
Then I start the app again downloading the file using 3G with an average speed of 20KB/s. After a few minutes of download, I enable WiFi. In the status bar the WiFi icon appear but the download speed don't change.
I was expecting that iOS switch between connections from 3G to WiFi. But it looks that although WiFi is enable, 3G is also enable. Is that correct?
In case that 3G speed is faster than WiFi, iOS switch to the better connection automatically?
In case both connections are enable it is posible to decide which one of the connection use?
If it posible to test 3G and WiFi download speed at same time?
My best guess is that once a networking connection is established, the established connected stays alive until it finishes. For example, if you start a download over a cellular data connection, the download will complete on that same connection. If that is, in fact, the case then enabling WiFi in the middle of a download won't affect the download speed for that current download, but if you start a new download after establishing the WiFi connection, the new download should transfer at WiFi speeds.
Related
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.
Apologizing in advance, I am no 802.11 expert and this is a long winded question...
I am working on an iOS voip client, we use the Cocoaasyncsocket library for our TCP/UDP connections. The app/iDevice is allowed to roam in/out of wifi coverage (for the purposes of this discussion we will assume the app is using wifi only... no cellular connection). We have the appropriate plist settings for backgroundmode (voip, audio) as well as requiring persistent wifi.
We are having a problem that seems particular to Cisco AP's. With the client app in the foreground and roaming out and in of wifi range, we noticed that eventually the iOS device will eventually not automatically rejoin the network. After a great deal of debug the failure to rejoin was noted to have nothing to do with the app. The failure to re-join can ultimately be reproduced by forcing the AP (via config) to deauthenticate the iDevice three times. After the 1st and 2nd deauthentications, the iDevice readily automatically re-joins. But after the 3rd time, iOS does not automatically rejoin the network.
The network will be rejoined if, for example, the iOS email app is put in the foreground.
We were curious if any other VOIP type apps suffered this problem, and ran an experiment with running FaceTime and Skype on the iOS device.
Skype behaved much like our voip app, after the 3rd deauth the connection was lost. Trying to initiate another call resulted in a message to the effect of "must have an internet connection to make a call".
FaceTime did disconnect on the 3rd deauth and failed to automatically rejoin... however, we were able to re-initiate another FaceTime call which caused iOS to rejoin the network and make the call.
We would like to emulate the FaceTime behavior, but so far do not understand what we should be doing differently. To the best of our knowledge, we are properly closing the open sockets when we get disconnected. Is anyone familiar with this issue and have some insight to offer?
Suppose that:
You are connected to Internet over 3G
You are constantly connected to a server over tcp (like http) and you are retrieving continuous data (like audio or video).
You enter into a WIFI enabled area which you have auto-connection enabled (remembered network); so iPhone automatically connects to WIFI in the background.
In this case, "as I have inspected" connection that was active through 3G is NOT interrupted. I can handle this situation by manually cutting connection and reconnecting again. (which will use WIFI this time)
However, this is only what I currently inspected and I am not sure if this happens on all OS versions and iOS devices.
Do you know if Apple has a procedure for this scenario? Scenario: Strict rules defined for what iOS does to active connections when connection type is changed from 3G to WIFI or from WIFI to 3G?
iOS 7 introduced a new user configuration to disable cellular data for specific apps. It can be configured in "Settings"->"Cellular" and then scrolling down.
You'll find a switch for each installed app and can see how much cellular data it has consumed.
How can I programmatically test if the switch is turned on for my app? Is there an API for that? Can I determine how much data my app has used over cellular?
I'm not asking to get the values for all apps. I'm only interested in my apps usage.
There is no API to detect your download consumption or whether cellular is active for your app.
If your app tries to connect to a website, but cellular is turned off, then iOS may ask the user to turn cellular back on. I'm not exactly sure how that works, but it is probably similar to the iOS 6 "no network connection" alert that would pop up if there is no connection but an app tries to access the internet.
You can check if the current internet connection is over WiFi or Cellular, but if Cellular is disabled you will just be told that there is no network connection.
More details here: iOS Detect 3G or WiFi
You can't check if the cellular data switch is turned on.
The closest thing is that you can check if a specific host is reachable over cellular connection using the SCNetworkReachability kSCNetworkReachabilityFlagsIsWWAN flag.
Additionally, you can enable/disable cellular data for specific connections using the NSURLRequest allowsCellularAccess property.
Reference: https://developer.apple.com/library/ios/documentation/NetworkingInternetWeb/Conceptual/NetworkingOverview/Platform-SpecificNetworkingTechnologies/Platform-SpecificNetworkingTechnologies.html
This answer suggests how data usage can be measured system-wide: iPhone Data Usage Tracking/Monitoring
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.