4

I am using Apple's Reachability code, to determine whether Internet connectivity is there or not.

Now I found that when I keep Both Cellular and WIFI ON then my check for Cellular shows FALSE and my WIFI check shows TRUE.

I have tried modifying NetworkStatus return value for that.. But no success.

Can any one help me with this issue???

What I want is when Both network is ON, my Reachability should show TRUE for both.

Can anyone help me understanding below points :

  1. What will SCNetworkReachabilityGetFlags(reachabilityRef, &flags) will do exactly??

  2. How to check only for networkStatusForFlags in below code??

    - (NetworkStatus) currentReachabilityStatus
    {
    NSAssert(reachabilityRef != NULL, @"currentNetworkStatus called with NULL reachabilityRef");
    NetworkStatus retVal = NotReachable;
    SCNetworkReachabilityFlags flags;
    if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags))
    {
        if(localWiFiRef)
        {
            retVal = [self localWiFiStatusForFlags: flags];
        }
        else
        {
            retVal = [self networkStatusForFlags: flags];
        }
    }
    return retVal;
    }
    

Also how to change below code to get only NetworkStatusForFlags

- (NetworkStatus) networkStatusForFlags: (SCNetworkReachabilityFlags) flags
{
    if ((flags & kSCNetworkReachabilityFlagsReachable) == 0)
    {
        // if target host is not reachable
        return NotReachable;
    }

    BOOL retVal = NotReachable;

    if ((flags & kSCNetworkReachabilityFlagsConnectionRequired) == 0)
    {
        // if target host is reachable and no connection is required
        //  then we'll assume (for now) that your on Wi-Fi
        retVal = ReachableViaWiFi;
    }


    if ((((flags & kSCNetworkReachabilityFlagsConnectionOnDemand ) != 0) ||
         (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) != 0))
    {
        // ... and the connection is on-demand (or on-traffic) if the
        //     calling application is using the CFSocketStream or higher APIs

        if ((flags & kSCNetworkReachabilityFlagsInterventionRequired) == 0)
        {
            // ... and no [user] intervention is needed
            retVal = ReachableViaWiFi;
        }
    }

    if ((flags & kSCNetworkReachabilityFlagsIsWWAN) == kSCNetworkReachabilityFlagsIsWWAN)
    {
        // ... but WWAN connections are OK if the calling application
        //     is using the CFNetwork (CFSocketStream?) APIs.
        retVal = ReachableViaWWAN;
    }
    return retVal;
}

EDIT :

I am using hostname as www.apple.com and also tried http://www.apple.com. But in WIFI i am getting TRUE and only in Cellular network i am getting FALSE.

+ (MTPReachability*) reachabilityWithHostName: (NSString*) hostName;
{
    MTPReachability* retVal = NULL;
    SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithName(NULL, [hostName UTF8String]);
    if(reachability!= NULL)
    {
        retVal= [[[self alloc] init] autorelease];
        if(retVal!= NULL)
        {
            retVal->reachabilityRef = reachability;
            retVal->localWiFiRef = NO;
        }
    }
    return retVal;
}
DShah
  • 9,768
  • 11
  • 71
  • 127
  • i think this is a global problem.. because when i use "whatsapp" and having the wifi and cellular data both on the application suddenly stop sending messages like there is no network ! – Malek_Jundi Mar 29 '12 at 11:45
  • @Malek_Jundi : So by this you mean that there is no solution to this??? or Is there any alternate way?? Kindly look at my edited question... – DShah Mar 29 '12 at 11:59

3 Answers3

2

The line:

**BOOL** retVal = NotReachable;

is invalid. This should be :

**NetworkStatus** retVal = NotReachable;

In our case it helped set the right value in retVal (ie. ReachableViaWWAN).

Otherwise even if you enter in the last "if" you get ReachableViaWiFi because it's cast into a BOOL.

Jb Rieu
  • 31
  • 6
0

WIFI only indicates if you are on a local wifi connection (within the private range of IP addresses), not that you are using a wifi connection on the device.

The only information you get is if your app can or cannot connect to your remote server. You don't get any information as to which connection it is using.

Nick Bull
  • 4,276
  • 1
  • 18
  • 25
  • That is correct but on the basis of NetworkStatus flag i can know whether it is WIFI or WWAN. So I want that only... – DShah Mar 29 '12 at 11:18
  • Yes, WIFI is LOCAL WIFI (ie the local network on the private range of IP addresses). WWAN is WIDE AREA NETWORK - "The internet". Your cellular network won't be able to access your local network as it is connecting through the mobile operator's network. – Nick Bull Mar 29 '12 at 11:41
  • Thanks Nick for your reply, but can you please clear what you want to conclude?? Also i have edited my question so please have a look... – DShah Mar 29 '12 at 11:57
  • What I'm saying is that the only information you can get is whether you are connected to a local network (WIFI means local wifi network) or the internet (WWAN means wireless wide area network). You do NOT get to know which transmission service the device is using to connect to the internet, you just get told you are connected to the internet. You could be using cellular or wireless, but your app won't know (and shouldn't care). – Nick Bull Mar 29 '12 at 12:25
  • you are correct about transmission service. But I just want that When I check for availability of Cellular network then It should return TRUE, doesn't concern where it is used for transmission or not... – DShah Mar 29 '12 at 14:31
  • What are you using for your `reachabilityWithHostName` when you create your Reachability object? Post your setup code and where you are handling `reachabilityChanged` – Nick Bull Mar 29 '12 at 14:57
  • I have added the code for reachabilityWithHostName. Kindly please have a look. Can you just tell me why this problem is?? – DShah Mar 30 '12 at 11:14
  • Also Sorry i havnt downvoted. But I will vote once i will get my Answer. – DShah Mar 30 '12 at 11:15
-1

1.SCNetworkReachabilityGetFlags(reachabilityRef, &flags) will determines if the given target is reachable using the current network configuration.

2.please check my code which through it I check the reachability to the network

+ (BOOL) connectedToNetwork
{
    // Create zero addy
    struct sockaddr_in zeroAddress;
    bzero(&zeroAddress, sizeof(zeroAddress));
    zeroAddress.sin_len = sizeof(zeroAddress);
    zeroAddress.sin_family = AF_INET;

    // Recover reachability flags
    SCNetworkReachabilityRef defaultRouteReachability = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&zeroAddress);
    SCNetworkReachabilityFlags flags;

    BOOL didRetrieveFlags = SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags);
    CFRelease(defaultRouteReachability);

    if (!didRetrieveFlags)
    {
        return NO;
    }

    BOOL isReachable = flags & kSCNetworkFlagsReachable;
    BOOL needsConnection = flags & kSCNetworkFlagsConnectionRequired;
    return (isReachable && !needsConnection) ? YES : NO;
}

- (void) checkNetworkStatus:(NSNotification *)notice
{
    // called after network status changes

    NetworkStatus netStatus = [internetReach currentReachabilityStatus];
    switch (netStatus)
    {
        case NotReachable:
        {
            if([reachabilityDelegate respondsToSelector:@selector(internetConnectionLost)])
                [reachabilityDelegate internetConnectionLost];
            break;

        }
        case ReachableViaWiFi:
        case ReachableViaWWAN:
        {
            if([reachabilityDelegate respondsToSelector:@selector(internetConnectionRestored)] && [GlobalObjects connectedToNetwork])
                [reachabilityDelegate internetConnectionRestored];
            break;

        }
    }
}

notice that the "reachabilityDelegate" is a delegate i define it to get the network classes in other class's .. and "internetReach" is a instance variable from Reachability Class.

Hope this will be helpful.

Malek_Jundi
  • 6,140
  • 2
  • 27
  • 36
  • I think you have interpreted wrongly for 2nd question. What i want is when my app starts I check for both reachability WIFI and CELLULAR. And though I have both ON, i am getting FALSE in case of CELLULAR. Can you please tell me how above code will help me for my case??? – DShah Mar 29 '12 at 14:49
  • Sorry i didn't understand your need .. I just share my code with you because i think its may help you. But i dont feel that i deserve vote down !! Your comment is fair enough .. Sorry again for the wrong answer. – Malek_Jundi Mar 29 '12 at 16:50
  • i havnt done down vote sorry. Also i cant give you up vote as still i havnt found correct answer. – DShah Mar 30 '12 at 11:05
  • 1
    Also my question is fairly simple that when ever i check for Reachability with Cellular and Wifi ON, then I should get TRUE value in both case... – DShah Mar 30 '12 at 11:07