2016-02-25 20 views
5

Sto utilizzando Reachability class da Apple per rilevare eventi di rete che hanno un impatto sulla funzionalità della mia app. Si tratta di un'app VoIP che utilizza setKeepAliveTimeout, quindi ogni ~ 10 minuti si riattiva legge lo stato della rete e decide se la connessione deve essere aggiornata.iOS Raggiungibilità segnala WiFi, quando il WiFi è attivo

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

Così ogni 10 minuti viene chiamato isWifiConnect e l'app legge nuovamente lo stato della rete.

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

Sebbene abbia WiFi nel dispositivo la chiamata restituisce falso, cioè nessuna WiFi, ed inoltre NotReachable per lo stato di rete.

Tuttavia dopo un intervallo di tempo molto breve viene richiamata la richiamata di raggiungibilità e il wifi sembra collegato. Tuttavia, ho già attivato un evento a causa del valore dell'errore e l'app chiude la connessione con il server ritenendo che non vi sia alcun collegamento wi-fi.

Facendo qualche ricerca che ho trovato questo nel file Readme del file Reachability.m (fornito da Apple)

Per impostazione predefinita, l'applicazione utilizza www.apple.com per il suo host remoto. È possibile modificare l'host che utilizza in APLViewController.m modificando il valore della variabile remoteHostName in -viewDidLoad.

IMPORTANTE: raggiungibilità deve utilizzare DNS per risolvere il nome host prima è in grado di determinare la raggiungibilità di che ospitano, e questo può richiedere tempo su alcune connessioni di rete. Per questo motivo, l'API restituirà NotReachable fino al completamento della risoluzione dei nomi. Questo ritardo può essere visibile nell'interfaccia su alcune reti

.

Potrebbe essere questo il problema? Il ritardo nella ricerca DNS? O devo migliorare anche il mio codice?

Quando ho inizializzare l'app Io chiamo questo

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

Se uso un indirizzo IP come questo è corretto?

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

È sicuro utilizzare un IP pubblico? es. "17.178.96.59" è il risultato di un nslookup per apple.com

C'è un metodo nella classe Reachability che sembra essere utilizzato dalla demo di Apple.

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

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

    return NO; 
} 

Perché è necessaria la connessione? Può essere utilizzato per risolvere il problema?

+0

perché si chiamano i metodi dopo ogni 10 minuti, piuttosto che è possibile utilizzare https://github.com/ashleymills/Reachability.swift –

+0

Ho bisogno di attivare un evento di registro sorso ogni 10 minuti circa – cateof

risposta

0

La raggiungibilità deve essere creata con un nome host, non un indirizzo esplicito. L'intero punto del sistema DNS è che gli indirizzi cambiano a volte per gli host. Il collegamento diretto a un server dei nomi dovrebbe fornire una certa sicurezza in questo senso, ma non è così che dovrebbe funzionare.

Raggiungibilità è spesso una supposizione migliore, non un duro e veloce. L'unico modo per essere sicuri è provare effettivamente. La connessione richiesta è correlata a questo, perché è il dispositivo che dice "tutto sembra a posto, non ho appena provato a connetterlo per davvero".

Quindi, probabilmente, è necessario attivare il keep alive senza controllare lo stato di raggiungibilità e utilizzare il risultato della richiesta per decidere se c'è un errore o meno. Se è necessario essere sicuri, inviare una richiesta effettiva e rivedere il risultato effettivo.

+0

Esempio di codice ovunque? – cateof

+0

codice di esempio per cosa esattamente? Intendo licenziare il tuo 'refresh' e controllare la risposta – Wain

1

Per preservare la carica della batteria, iOS chiuderà l'hardware di rete quando non viene utilizzato attivamente. Questo significa spegnere il WiFi e le radio cellulari. In questa situazione, Reachability non sarà in grado di riportare un risultato completo, perché non può controllare la situazione senza dover riaccendere tutto. Questo è ciò che è kSCNetworkReachabilityFlagsConnectionRequired - per dirti che è necessario stabilire una connessione per riattivare il backup dell'hardware.

Quello che stai vedendo è probabilmente qualcosa che si sta svegliando quando il telefono è sbloccato (la tua app o un'altra app con permessi di background) e quindi tutto si sveglia, si vede subito un errore, ma poi WiFi si connette e si è connessi di nuovo .

È necessario gestire Raggiungibilità come se fosse in grado di dirti "decisamente raggiungibile" o "decisamente non raggiungibile" ma anche "situazione sconosciuta". Devi decidere cosa farai nella situazione sconosciuta. Se si effettua una connessione di rete immediatamente, si scaricherà la batteria più rapidamente del normale. Un'alternativa potrebbe essere solo aspettare che la rete si riattivi per qualche altro motivo. Dipende solo da te.