2016-02-25 9 views
5

Korzystam z usługi Reachability class firmy Apple w celu wykrywania zdarzeń sieciowych, które mają wpływ na funkcjonalność mojej aplikacji. Jest to aplikacja VoIP, która używa setKeepAliveTimeout, więc co ~ 10 minut budzi się czyta stan sieci i decyduje, czy połączenie powinno zostać odświeżone.Zasięg iOS nie informuje o Wi-Fi, gdy jest aktywne WiFi

BOOL res = [app setKeepAliveTimeout:600 handler:^{   
     [[WIFI instance] isWifiConnected]; 
     [[AClass an_instance] refresh]; 
    } 
}]; 

Więc co 10 minutach isWifiConnected nazywa i aplikacja ponownie odczytuje stan sieci.

- (BOOL) isWifiConnected { 

    self.wifiReach = [Reachability reachabilityForLocalWiFi]; 
    NetworkStatus wifiStatus = [self.wifiReach currentReachabilityStatus]; 

    switch (wifiStatus) { 
     case NotReachable: { 
      m_wifiConnected = NO; 
      LOG(@"NetStatus:NotReachable"); 
      break; 
     } 
     case ReachableViaWiFi: { 
      m_wifiConnected = YES; 
      m_wwanConnected = NO; 
      LOG(@"NetStatus:ReachableViaWiFi"); 
      break; 
     } 
    } 
    return m_wifiConnected; 
} 

Chociaż mam WiFi w urządzeniu wywołanie zwraca fałsz, czyli nie ma WiFi, a ponadto NotReachable o status netto.

Jednak po bardzo krótkim odstępie czasu wywołanie zwrotne osiągów jest ponownie wywoływane, a połączenie Wi-Fi wydaje się być połączone. Jednak już wystrzeliłem ze względu na wartość błędu i aplikacja zamyka połączenie z serwerem, wierząc, że nie ma Wi-Fi.

Robi rozeznanie to znalazłem to w pliku Readme pliku Reachability.m (dostarczonych przez Apple)

Domyślnie aplikacja używa www.apple.com za zdalnego hosta. Możesz zmienić host, którego używa w APLViewController.m, modyfikując wartość zmiennej remoteHostName w -viewDidLoad.

WAŻNE: osiągalności musi używać DNS, aby rozwiązać nazwę hosta przed może określić osiągalność tego hosta, a to może potrwać na niektórych połączeniach sieciowych. Z tego powodu API zwróci NotReachable do momentu zakończenia rozwiązywania nazw. Opóźnienie to może być widoczne w interfejsie w niektórych sieciach

.

Czy to może być problem? Opóźnienie w wyszukiwaniu dns? Czy muszę też ulepszyć mój kod?

Kiedy zainicjować aplikację Ja nazywam to

self.hostReach = [Reachability reachabilityWithHostName: @"www.apple.com"]; 

Gdybym użyć adresu IP, jak to jest prawidłowe?

self.hostReach = [Reachability reachabilityWithHostName: @"1.2.3.4"]; 

Czy korzystanie z publicznego adresu IP jest bezpieczne? np. "17.178.96.59" jest wynikiem nslookup dla apple.com

Istnieje metoda w klasie osiągalnej, która wydaje się być używana w demo Apple.

- (BOOL)connectionRequired 
{ 
    NSAssert(_reachabilityRef != NULL, @"connectionRequired called with NULL reachabilityRef"); 
    SCNetworkReachabilityFlags flags; 

    if (SCNetworkReachabilityGetFlags(_reachabilityRef, &flags)) 
    { 
     return (flags & kSCNetworkReachabilityFlagsConnectionRequired); 
    } 

    return NO; 
} 

Dlaczego wymagane jest connectionRequired? Może być użyty do rozwiązania problemu?

+0

dlaczego wywołujesz metody po każdych 10 minutach, zamiast tego możesz użyć https://github.com/ashleymills/Reachability.swift –

+0

Potrzebuję wywołać zdarzenie rejestru sip co 10 minut około – cateof

Odpowiedz

0

Zasięg powinien być utworzony z nazwą hosta, a nie z jawnego adresu. Cały punkt systemu DNS polega na tym, że czasem adresy zmieniają się na hosty. Bezpośrednie połączenie z serwerem nazw powinno zapewniać pewne bezpieczeństwo w tym zakresie, ale nie jest tak, jak powinno działać.

Osiągalność jest często najlepszym odgadnięciem, a nie twardą i szybką. Jedyny sposób, by się upewnić, to faktycznie spróbować. Wymagane jest połączenie z tym, ponieważ to urządzenie mówi "wszystko wygląda dobrze, po prostu nie próbowałem się połączyć naprawdę".

Tak więc, prawdopodobnie powinieneś zwolnić przy życiu bez sprawdzania statusu osiągalności i użyć wyniku żądania, aby zdecydować, czy wystąpił błąd, czy nie. Jeśli musisz mieć pewność, wyślij aktualne zapytanie i sprawdź rzeczywisty wynik.

+0

Przykładowy kod w dowolnym miejscu? – cateof

+0

przykładowy kod, co dokładnie? Mam na myśli ogień "odśwież" i sprawdź odpowiedź – Wain

1

Aby oszczędzać baterię, system iOS zamknie sprzęt sieciowy, gdy nie jest aktywnie używany. Oznacza to wyłączenie WiFi i radia komórkowego. W tej sytuacji Osiągalność nie będzie w stanie podać pełnego wyniku, ponieważ nie może sprawdzić sytuacji bez ponownego włączenia wszystkiego. Właśnie do tego służy kSCNetworkReachabilityFlagsConnectionRequired - aby powiedzieć, że musisz nawiązać połączenie, aby obudzić sprzęt.

To, co widzisz, to prawdopodobnie coś, co budzi się po odblokowaniu telefonu (aplikacja lub inna aplikacja z uprawnieniami w tle), więc wszystko się budzi, natychmiast pojawia się błąd, ale połączenie Wi-Fi i znów jesteś podłączony .

Musisz radzić sobie z Osiągalnością, jak gdyby to znaczyło, że jesteś "zdecydowanie osiągalny" lub "zdecydowanie nieosiągalny", ale także "sytuacja nieznana". Musisz zdecydować, co zamierzasz zrobić w nieznanej sytuacji. W przypadku natychmiastowego nawiązania połączenia sieciowego bateria zostanie rozładowana szybciej niż normalnie. Alternatywą może być po prostu czekanie, aż sieć zostanie obudzona z innego powodu. To naprawdę zależy od ciebie.