4
votes

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;
}
3
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
@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
please check my answer below. - Malek_Jundi

3 Answers

2
votes

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.

0
votes

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.

-1
votes

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.