0

I am new to iOS programming and don't have an object-oriented programming background.

I have an application that is essentially a user interface for several web APIs.

I have a Reachability class that allows me to check whether there is a valid internet connection. This works well when a user is on the login page and there are no other actions.

However, say I have a view with 5 buttons on that all require internet connection to work. Would I just have every button call this Reachability.isConnected() -> Bool method prior to actually making the API call?

I am concerned that this is not the right logic to follow. Should I have a background process to regularly check for a connection?

It's this breaking down functionality into discrete classes that I am having problems with because of my lack of OOP experience.

Any advice on the best way to handle this connectivity check would be great.

Larme
  • 24,190
  • 6
  • 51
  • 81
Brian Marsh
  • 577
  • 2
  • 6
  • 19
  • Well, it depends on why you want to check the connection before the calls. If there's no connection, your request will fail with error and you can notify user about that anyway. – J.Wang Mar 09 '16 at 11:13
  • Depends on requirement whether you want to check the connection continuously or on some event – Bhagyalaxmi Poojary Mar 09 '16 at 11:14
  • Check this http://stackoverflow.com/questions/25928826/using-apples-reachability-class-in-swift – kb920 Mar 09 '16 at 12:45

3 Answers3

5

To check connection network you have to create a class, put it in a "Service" folder for example, and copy past this code:

import Foundation
import SystemConfiguration

public class Reachability {

    class func isConnectedToNetwork() -> Bool {

        var zeroAddress = sockaddr_in(sin_len: 0, sin_family: 0, sin_port: 0, sin_addr: in_addr(s_addr: 0), sin_zero: (0, 0, 0, 0, 0, 0, 0, 0))
        zeroAddress.sin_len = UInt8(sizeofValue(zeroAddress))
        zeroAddress.sin_family = sa_family_t(AF_INET)

        let defaultRouteReachability = withUnsafePointer(&zeroAddress) {
            SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, UnsafePointer($0))
        }

        var flags: SCNetworkReachabilityFlags = SCNetworkReachabilityFlags(rawValue: 0)
        if SCNetworkReachabilityGetFlags(defaultRouteReachability!, &flags) == false {
            return false
        }

        let isReachable = flags == .Reachable
        let needsConnection = flags == .ConnectionRequired

        return isReachable && !needsConnection

    }
}

Then, use it like this wherever you want:

if Reachability.isConnectedToNetwork() {

     // Do stuff if you're connected to the internet

}
else {

    // Do stuff if you're not connected to the internet
}

hope it can help you ;)

Thomas
  • 1,289
  • 1
  • 17
  • 29
0

Include Reachability

and then have method like this.

For Objective C :-

+ (BOOL)internetAvailable
{
// check if we've got network connectivity
    Reachability *myNetwork = [Reachability reachabilityWithHostname:@"google.com"];
    NetworkStatus myStatus = [myNetwork currentReachabilityStatus];

    switch (myStatus) 
    {
        case NotReachable:
        return NO;
        break;

    case ReachableViaWWAN:
        return YES;
        break;

    case ReachableViaWiFi:
        return YES;
        break;

    default:
        return YES;
        break;
    }
}

Edit:-

For swift :-

import Foundation
import SystemConfiguration

public class Reachability {

class func isConnectedToNetwork() -> Bool {

    var zeroAddress = sockaddr_in(sin_len: 0, sin_family: 0, sin_port: 0, sin_addr: in_addr(s_addr: 0), sin_zero: (0, 0, 0, 0, 0, 0, 0, 0))
    zeroAddress.sin_len = UInt8(sizeofValue(zeroAddress))
    zeroAddress.sin_family = sa_family_t(AF_INET)

    let defaultRouteReachability = withUnsafePointer(&zeroAddress) {
        SCNetworkReachabilityCreateWithAddress(nil, UnsafePointer($0)).takeRetainedValue()
    }

    var flags: SCNetworkReachabilityFlags = 0
    if SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags) == 0 {
        return false
    }

    let isReachable = (flags & UInt32(kSCNetworkFlagsReachable)) != 0
    let needsConnection = (flags & UInt32(kSCNetworkFlagsConnectionRequired)) != 0

    return isReachable && !needsConnection
}

}

just call these methods wherever required.

Awesome.Apple
  • 1,316
  • 1
  • 11
  • 24
0

There are two ways to check network connectivity, either you can set an observer for network connection changes so that you will get notified whenever the network connection status changes(either connected or disconnected).

(You can check network connectivity using iOS Reachability class or you can use AFNetworking library for same)

If you want to continuously monitor network changes you should set observer as follows:

Add this code to your didFinishLaunchingWithOptions in AppDelegate

NSNotificationCenter.defaultCenter().addObserver(self, selector:"checkNetworkStatus", name: ReachabilityChangedNotification, object: nil);

do{self.reachability = try Reachability.reachabilityForInternetConnection()}catch{}

  do{try self.reachability.startNotifier()}catch{

  }

self.performSelector("checkNetworkStatus", withObject: nil, afterDelay: 0.6)

Add below code to your AppDelegate

var networkStatus : Reachability.NetworkStatus!
var objNetworkStatusView : NetworkStatusView! = nil

func checkNetworkStatus()
{
    networkStatus = reachability.currentReachabilityStatus

    if (networkStatus == Reachability.NetworkStatus.NotReachable)
    {
        print("Not Reachable")
        objNetworkStatusView = NetworkStatusView(frame:CGRectMake(0, 0, self.window!.frame.size.width, self.window!.frame.size.height))
        UIApplication.sharedApplication().keyWindow?.addSubview(objNetworkStatusView)
        UIApplication.sharedApplication().keyWindow?.bringSubviewToFront(objNetworkStatusView)
    }
    else
    {
        print("Reachable")
        if((objNetworkStatusView) != nil)
        {
        objNetworkStatusView.removeFromSuperview()
        }
    }
}

And if you just want to check network connectivity before making request to your service you should check network connection manually as follows:

Create instance of delegate in the class where you have to call web service or you have to check network connectivity,

let delegate = UIApplication.sharedApplication().delegate as! AppDelegate

And check network connectivity as

if (delegate.networkStatus==Reachability.NetworkStatus.NotReachable) {
   delegate.checkNetworkStatus()
} else {
  //You can call web service here
}
Bharat Modi
  • 4,158
  • 2
  • 16
  • 27
  • Thank you Bharat, this is going to be extremely useful. This code checks for internet connection every 0.6 seconds right? Then will bring the view objNetworkStatusView into view until connected again? So you could have a message saying "No internet connection detected"? You could do this with other things like checking that the cookie has not expired right? – Brian Marsh Mar 09 '16 at 11:30
  • checkNetworkStatus is called after 0.6 of delay because if you call checkNetworkStatus method just when the app is loaded then it would not return the correct result, so you need to call this function after some time delay, if network is not available the user would be shown with a view indicating there is no network connection, and it has nothing to do with cookie. It will just check network connectivity. – Bharat Modi Mar 09 '16 at 11:38
  • Network state is continuously observed, and NetworkStatusView would be shown as soon as the network is disconnected not after 0.6 sec's. – Bharat Modi Mar 09 '16 at 11:41