Достижимость возвращает значение False для сотовой сети, когда включены Wi-Fi и сотовая связь - PullRequest
4 голосов
/ 29 марта 2012

Я использую Код доступности Apple , чтобы определить, есть ли подключение к Интернету или нет.

Теперь я обнаружил, что, когда я включаю Cellular и WIFI, мой чек на Cellular показывает FALSE, а мой WIFI - TRUE.

Я попытался изменить возвращаемое значение NetworkStatus для этого .. Но безуспешно.

Может ли кто-нибудь помочь мне с этим вопросом ???

То, что я хочу, это когда обе сети включены, моя Reachability должна показывать TRUE для обоих.

Может ли кто-нибудь помочь мне понять следующие пункты:

  1. Что будет SCNetworkReachabilityGetFlags(reachabilityRef, &flags) делать точно ??

  2. Как проверить только для networkStatusForFlags в коде ниже ??

    - (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;
    }
    

Также как изменить код ниже, чтобы получить только 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;
}

РЕДАКТИРОВАТЬ:

Я использую имя хоста как www.apple.com и также пытался http://www.apple.com. Но в WIFI я получаю TRUE и только в сотовой сети я получаю 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 ]

2 голосов
/ 20 августа 2014

Строка:

**BOOL** retVal = NotReachable;

недействительна.Это должно быть:

**NetworkStatus** retVal = NotReachable;

В нашем случае это помогло установить правильное значение в retVal (т.е. ReachableViaWWAN).

В противном случае, даже если вы введете в последнем «если», вы получите ReachableViaWiFiпотому что он брошен в BOOL.

0 голосов
/ 29 марта 2012

1. SCNetworkReachabilityGetFlags(reachabilityRef, &flags) определяет, достижима ли данная цель с использованием текущей конфигурации сети.

2.пожалуйста, проверьте мой код, который через него я проверяю доступность к сети

+ (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;

        }
    }
}

обратите внимание, что "reachabilityDelegate" - это делегат, который я определяю, чтобы получить сетевые классы в других классах .. а "internetReach" - это переменная экземпляра из класса Reachability.

Надеюсь, это будет полезно.

0 голосов
/ 29 марта 2012

WIFI указывает только на локальное подключение к Wi-Fi (в пределах диапазона IP-адресов), но не на подключение к Wi-Fi на устройстве.

Единственная информация, которую вы получаете, - это если ваше приложение может или не может подключиться к вашему удаленному серверу. Вы не получаете никакой информации о том, какое соединение оно использует.

...