0

When a user is trying to change the state of a UISwitch in a custom UITableViewCell I want to notify the user that it is not allowed if there is no active internet connection. My problem is to decide where to put the internet connection check logic. It's easiest to put it in the custom cell class but that's a view class and adhering to the MVC design pattern this might not be the best approach.

I tried to search for an answer to my question but could not find any that could assist me in my decision.

Thank you in advance for any helpful suggestions.

Robert
  • 5,278
  • 43
  • 65
  • 115
Sanxion
  • 95
  • 1
  • 6

3 Answers3

2

First you have download the Reachability class from below link.

Reachability Class

Then import the Reachability class in AppDelegate.h file.

#import Reachability.h

Please write the below code in AppDelegate.h file.

@property(nonatomic)Reachability *internetReachability;
@property(nonatomic)BOOL isInternet;

Note that APP_DELEGATE is an instance of AppDelegate and IS_INTERNET is an instance of isInternet variable which declared in AppDelegate.h file.

#define APP_DELEGATE ((AppDelegate *)[[UIApplication sharedApplication] delegate])
#define IS_INTERNET APP_DELEGATE.isInternet

After that just copy and paste the below code in your AppDelegate.m file and call the setupTheInternetConnection method in didFinishLaunchingWithOptions method.

-(void)setupTheInternetConnection {    

    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];

    //Setup Internet Connection
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reachabilityChanged:) name:kReachabilityChangedNotification object:nil];

    self.internetReachability = [Reachability reachabilityForInternetConnection];
    [self.internetReachability startNotifier];
    [self updateInterfaceWithReachability:self.internetReachability];
}

- (void) reachabilityChanged:(NSNotification *)note {

    Reachability* curReach = [note object];
    NSParameterAssert([curReach isKindOfClass:[Reachability class]]);
    [self updateInterfaceWithReachability:curReach];
}

- (void) updateInterfaceWithReachability: (Reachability*) curReach {

    if(curReach == self.internetReachability) {

        NetworkStatus netStatus = [curReach currentReachabilityStatus];

        switch (netStatus) {

            case NotReachable: {

                IS_INTERNET = FALSE;
                break;
            }

            case ReachableViaWWAN: {

                IS_INTERNET = TRUE;
                break;
            }

            case ReachableViaWiFi: {

                IS_INTERNET = TRUE;
                break;
            }
        }
    }
}

Now you can check the internet connection in any of your controller by using the value of IS_INTERNET.

Hope it will work for you.

Ramkrishna Sharma
  • 6,961
  • 3
  • 42
  • 51
  • Thank you for a very detailed answer / solution. I do use Reachability and thought about putting the code in a singleton but I like your solution and will try it. The ViewController holding a reference to the tableView is set to be the delegate of each cell and is called when the user toggles the UISwitch. If there is no internet connection the cell is reloaded and the state of the UISwitch will be set to whatever is was before the user interacted with it. Another route could be to disable the UISwitch as soon as there's no internet connection but for now I go with the first route. – Sanxion Dec 16 '15 at 20:03
  • You should not put this logic in the AppDelegate. App design should be modular and this approach leads to messy and unserviceable code. For simple detection of an internet connection you can write helper methods in a designated class that doesn't need to be a singleton. For constant monitoring of an internet connection, this could be done again by a designated class that is instantiated by or injected into the view controller. Architecture and design of an app is very important in these situations. – Rob Sanders Dec 16 '15 at 21:26
  • @RamkrishnaSharma down votes are not supposed to be used in revenge. They are used to help other users find the best solution to a problem. – Rob Sanders Dec 18 '15 at 10:14
  • @RASS : I am not believe in revenge in any more. Instead of down vote you can give the suggestion so that I can improve my answer in future and I am also motivated that someone like you good developer can review my answer and give the suggestion. – Ramkrishna Sharma Dec 18 '15 at 18:24
1

I usually have a NetworkManager that has all that logic.

#import "NetworkManager.h"
#import <Reachability.h>
@implementation NetworkManager

+ (void)performActionIfConnection:(void(^)())action andError:(void(^)())error{
    if ([NetworkManager test]) {
        if (action) {
            action();
        }
    }else{
        if (error) {
            error();
        }
    }
}

+ (BOOL) test
{
    Reachability *reach = [Reachability reachabilityForInternetConnection];
    NetworkStatus remoteHostStatus = [reach currentReachabilityStatus];
    return !(remoteHostStatus == NotReachable);
}

@end
rob180
  • 901
  • 1
  • 9
  • 29
-1

Your cell should not be aware of the process AT ALL.

A potential architecture would be to have the view controller constantly knowledgeable of the internet connection. This could be achieved with a networker class that updates the VC about network changes. This way the VC could fire the appropriate warnings e.t.c. when the user taps a switch.

Rob Sanders
  • 5,197
  • 3
  • 31
  • 58
  • I agree, one possible route I could take - based on your answer - would be to disable the UISwitch as soon as there's no internet connection. So instead of warning the user if they hit the switch while there is no internet connection, I would disable the switch until the internet connection became active again. – Sanxion Dec 16 '15 at 20:09
  • Exactly. Also I wouldn't put this logic in the `AppDelegate` Ramkrishna Sharma's answer is not good practice, and his code is VERY brittle. – Rob Sanders Dec 16 '15 at 21:21
  • @RASS : If you can provide with some good examples then it would be great rather than just explaining what we need to do to handle the internet connection in the VC. – Ramkrishna Sharma Dec 18 '15 at 08:56
  • @RamkrishnaSharma the question was ***where to put the logic***. Not ***what is the logic***. My answer addresses the architecture not the logic. Thanks for the down vote anyway. For a nice example see @rob180 answer. His `NetworkManager` is the kind of thing that you would inject into the VC. See [dependency injection](http://stackoverflow.com/questions/130794/what-is-dependency-injection) for further details. – Rob Sanders Dec 18 '15 at 09:07
  • @RASS : Thanks for sharing the link of the dependency injection, it is really a nice tutorials. I have provided a solution based on that for constantly monitor the internet connection in one central accessible place. – Ramkrishna Sharma Dec 18 '15 at 10:04