Observe WiFi / 3G changes - ios

Is it possible to observe when the user switch between WiFi and cellular data (3G/4G)?
Maybe something in Reachability, but I don't know what.

The easiest way I think is import CoreTelephony and observe CTRadioAccessTechnologyDidChangeNotification and then switch over that like this:
let networkInfo = CTTelephonyNetworkInfo()
let radio = networkInfo.currentRadioAccessTechnology
guard let currentRadio = radio else {
print("No radio info available")
return
}
switch currentRadio {
case CTRadioAccessTechnologyLTE,
CTRadioAccessTechnologyHSDPA: //3.5G "T-Mobile 4G"
print("This is 4G / LTE")
case CTRadioAccessTechnologyeHRPD, //3.5G "Verizon 3G"
CTRadioAccessTechnologyHSUPA,
CTRadioAccessTechnologyWCDMA,
CTRadioAccessTechnologyCDMAEVDORev0,
CTRadioAccessTechnologyCDMAEVDORevA,
CTRadioAccessTechnologyCDMAEVDORevB:
print("This is 3G")
case CTRadioAccessTechnologyGPRS,
CTRadioAccessTechnologyCDMA1x
CTRadioAccessTechnologyEdge:
print("This is 2G")
default:
print("Unknown cellular network type")
}
If you listen for that notification while also using standard Reachability, you can use this switch to get cell network type. You will need currentReachabilityStatus to independently check for a WiFi connection. As far as I am aware, in Swift you need to set up a bridging header to use Apple's Reachability class but there are Swift implementations available as well on github.

Yes Reachability provide you with type of network connected. It gives 3 different status - Not Connected to internet, Connected to Wifi, Connected to Mobile Data.
NetworkStatus status = [reachability currentReachabilityStatus];
if(status == NotReachable)
{
//No Connectivity to Internet
}
else if (status == ReachableViaWiFi)
{
//Connected via WiFi
}
else if (status == ReachableViaWWAN)
{
//Connected via Mobile Data
}

Related

Unable to send files between 2 device using Network Framework

I'm having trouble using network framework to transfer a collection of 1 minute video files between a recording device and a repository master device. All devices are on the same wifi. But the problem is that the distance between devices somehow is player a role in the transfer. When I have strong wifi signal on both devices, but if the devices are further than 100 feet apart, the transfer won't happen. Conversely, if both devices have very weak wifi signal (e.g. 1 bar), but are next to each other, the transfer happens without a hitch. It's as if the devices are doing something more akin to wifi direct than transfer for a LAN, which is what I really want. I'm assuming someone familiar with the framework can advise how to entirely avoid using any peer to peer wifi direct type of transfer, and force the system to transfer over the WLAN. That way all I need to do is make sure all devices have a decent wifi signal (e.g. are on the network with a decent connection), and regardless of how far they are physically from each other, the files will transfer without a hitch. Hope someone can clear this up for me.
Thanks.
Sending files between 2 devices at close range
disabled Bluetooth
Made sure both devices are on the same local network.
#Paulw11 - Thank you for the response, I have provided more details that I should have provided initially, I do apologize for that. Thanks again for the help.
We are using the mDNS approach.
func startBrowsing() {
guard browser == nil else { return }
let params = NWParameters()
params.includePeerToPeer = true
params.requiredInterfaceType = .wifi
let browser = NWBrowser(for: .bonjour(type: bonjourService, domain: nil), using: params)
self.browser = browser
browser.browseResultsChangedHandler = {
[weak self] results, changes in
guard let self = self else { return }
self.delegate?.peerBrowser(self, didUpdateResults: Array(results))
}
browser.stateUpdateHandler = { [weak self] newState in
guard let self = self else { return }
os_log("[browser] %#", newState.debugDescription)
switch newState {
case .cancelled:
break
case .failed:
os_log("[browser] restarting")
self.browser?.cancel()
self.startBrowsing()
case .ready:
break
case .setup:
break
#unknown default:
break
}
}
browser.start(queue: .main)
}
There are no such errors. I can see the standard communication is still working and because of that the sender(iPhone) will continue to send the files to iPad (receiver) with out fail but the receiver couldn’t able to receive it.
3.No
The code used to send data from one peer to another.
func sendMessage(type: UInt32, content: Data) {
guard connection?.state == .ready else {
return
}
let framerMessage = NWProtocolFramer.Message(messageType: type)
let context = NWConnection.ContentContext(identifier: "Message", metadata: [framerMessage])
connection?.send(content: content, contentContext: context, isComplete: true, completion: .idempotent)
}

How do I detect change in internet connection on iOS, delegate style?

I need a function to run only when the system detects there is no internet connection, then another function to run when the system detects an internet connection.
I'm thinking of something like this:
func onInternetConnection() {
//Enable actions
}
func onInternetDisconnection() {
//Disable actions, alert user
}
I will also need a way to detect when the system is reconnecting, so I can let the user know it's reconnecting, like in Facebook's Messenger.
How can I do this?
I'm using Moya/Alamofire for my network layer.
This works in case of Alamofire
import Alamofire
// In your view did load or in app delegate do like this
let reachabilityManager = NetworkReachabilityManager()
reachabilityManager.listener = { status in
switch status {
case .notReachable:
print("The network is not reachable")
self.onInternetDisconnection()
case .unknown :
print("It is unknown whether the network is reachable")
self.onInternetDisconnection() // not sure what to do for this case
case .reachable(.ethernetOrWiFi):
print("The network is reachable over the WiFi connection")
self.onInternetConnection()
case .reachable(.wwan):
print("The network is reachable over the WWAN connection")
self.onInternetConnection()
}
}
Alamofire and Rechability are library and that have some features to check internet connection. You can use one from that.

How to detect internet connection when connected to wifi but no intenernet: iOS

I just want to know how to detect internet connectivity in iOS when device is connected to wifi but no intenet connection in modem.
I have used apple's and AFNetworking's reachability but they only check for connectivity and returns connected flag even there is no working internet in modem.
I found the solution by hitting host via Reachability:-
Might be helpful for someone.
-(BOOL)isCheckConnection {
Reachability *rc = [Reachability reachabilityWithHostName:#"www.google.com"];
NetworkStatus internetStatus = [rc currentReachabilityStatus];
if(internetStatus==0)
{
//#"NoAccess";
return NO;
}
else if(internetStatus==1)
{
//#"ReachableViaWiFi";
return YES;
} else if(internetStatus==2)
{
//#"ReachableViaWWAN";
return YES;
}
else
{
//#"Reachable";
return YES;
}
}
In order to be sure that your device is really connected to internet, at least you have to try a ping to a up&running at anytime server (like stackoverflow.com o google.com).
Of course, as suggested by #jonrsharpe in question's comments, if this check is necessary in order to understand if app can reach the web server, then a ping or something like that to your web server is also necessary.
But a ping to a surely working web server (like google) will give you the answer it your device is connected to internet (so your modem can reach internet), that way if your web server is not responding you can accordingly show a warning alert in your app to inform user that currently your server is unreachable.
Going to code, you can try to check connection status with Reachability library like below
Reachability *reachability = [Reachability reachabilityWithHostName:#"stackoverflow.com"];
NetworkStatus networkStatus = [reachability currentReachabilityStatus];
and then check networkStatus variable: if 0 you don't have access to internet, otherwise YES, so
if(networkStatus==0) {
// no access to internet
} else {
// you have access to internet
}

Check if device is connected to the internet in Swift2

I'm trying to find a way to check to see if my application has a connection to the internet for my application. I've tried using the various Reachability libraries you can find on GitHub which cause compiling errors for my project. (Makes other libraries not available, for some reason) and I've also tried the JustHTTP library for making a GET request to http://www.google.com but it fails every time.
I'm not exactly sure what the issue is here, but I'd like to know how some of you go about validating a connection to the internet before allowing users to use the application.
This question was marked as a duplicated and linked to a question which used the Reachability library provided by AshleyMills. Which I had stated I've attempted using these libraries already, but could not do to confliction errors in my project. The GET request code provided on this question is also out of date, and does not work on SWIFT2. This linked question also assumes that I do not need to support anything under iOS 9 which seems like a bad practice. My minimum support is iOS8
Swift 2.x (requires Reachability)
do {
let reachable = try Reachability.init(hostname: "https:\\www.google.com")
if(reachable.currentReachabilityStatus == Reachability.NetworkStatus.ReachableViaWWAN){
//Device is connected thru 3G/4G/LTE
}else if(reachable.currentReachabilityStatus == Reachability.NetworkStatus.ReachableViaWiFi){
//Device is connected thru WiFi
}else{
//Device is not connected to the internet
}
}catch{
//Device is not connected to the internet
}
You can get Reachability here
Add Reachability.swift to your project.
And try below code.
do
{
let connected: Bool = try Reachability.reachabilityForInternetConnection().isReachable()
if connected == true
{
print("Internet connection OK")
}
else
{
print("Internet connection FAILED")
let alert = UIAlertView(title: "No Internet Connection", message: "Make sure your device is connected to the internet.", delegate: nil, cancelButtonTitle: "OK")
alert.show()
}
}
catch
{
print("Handle Exception")
}
This code might help. You need the Reachability lib, this snippet can give you an example to check if your device reaches Internet via WiFi or via 4G/3G/LTE
func checkNetworkStatus() -> Bool {
let reachability: Reachability = Reachability.reachabilityForInternetConnection()
let networkStatus = reachability.currentReachabilityStatus().rawValue;
var isAvailable = false;
switch networkStatus {
case (NotReachable.rawValue):
isAvailable = false;
break;
case (ReachableViaWiFi.rawValue):
isAvailable = true;
break;
case (ReachableViaWWAN.rawValue):
isAvailable = true;
break;
default:
isAvailable = false;
break;
}
return isAvailable;
}
If your request fail all the time maybe it's because you are not doing them over https but over http. It has to do with ATS on iOS 9 - this blog explains very well how to disable (if you want - not recommended) ATS http://ste.vn/2015/06/10/configuring-app-transport-security-ios-9-osx-10-11/

iOS isActiveNetworkMetered api

I'm developing an iOS app which needs to know whether the cellular network is metered to save the cost, do we have an api in iOS to get the information?
In android the api is http://developer.android.com/reference/android/net/ConnectivityManager.html#isActiveNetworkMetered().
Returns if the currently active data network is metered. A network is classified as metered when the user is sensitive to heavy data usage on that connection due to monetary costs, data limitations or battery/performance issues. You should check this before doing large data transfers, and warn the user or delay the operation until another network is available.
Thanks,
James
There is no check exactly to check like network is metered or not but you can check whether the network connection is via cellular or wifi.
You can use the Reachability class provide by apple here
Then implement the following to find whether you have connected on cellular
- (BOOL)networkCheckForCellular
{
Reachability *wifiReach = [Reachability reachabilityForInternetConnection];
NetworkStatus netStatus = [wifiReach currentReachabilityStatus];
switch (netStatus)
{
case NotReachable:
{
NSLog(#"%#",#"NETWORKCHECK: Not Connected");
return false;
break;
}
case ReachableViaWiFi:
{
NSLog(#"%#",#"NETWORKCHECK: Connected Via WiFi");
return false;
break;
}
case ReachableViaWWAN:
{
NSLog(#"%#",#"NETWORKCHECK: Connected Via WWAN");
return true;
break;
}
}
return false;
}

Resources