ios networking cellular-network

¿Cómo puedo saber si el acceso celular para mi aplicación iOS está deshabilitado?



networking cellular-network (6)

Tengo una aplicación para iOS que realiza algunas pequeñas solicitudes de red al iniciar la aplicación (actualizaciones de recursos, etc.). Si el usuario desactiva el acceso celular para la aplicación en la Configuración de iOS, recibirá un aviso de iOS sobre el uso de la red cada vez que se inicie. ¿Hay alguna forma de saber mediante programación que los datos celulares de esta aplicación se hayan deshabilitado, de modo que pueda deshabilitar las solicitudes al inicio?


A partir de iOS9, la capacidad de verificar la configuración para habilitar / deshabilitar el uso de datos celulares para su aplicación (Configuración / Celular / Nombre de aplicación) está disponible usando la clase CTCellularData de Apple. El siguiente código establecerá cellularDataRestrictedState cuando se ejecute inicialmente y luego lo configurará y registrará cuando cambie:

import CoreTelephony var cellularDataRestrictedState = CTCellularDataRestrictedState.restrictedStateUnknown let cellState = CTCellularData.init() cellState.cellularDataRestrictionDidUpdateNotifier = { (dataRestrictedState) in if cellularDataRestrictedState != .restrictedStateUnknown { // State has changed - log to console print("cellularDataRestrictedState: " + "/(dataRestrictedState == .restrictedStateUnknown ? "unknown" : dataRestrictedState == .restricted ? "restricted" : "not restricted")") } cellularDataRestrictedState = dataRestrictedState }

Desafortunadamente (a partir de iOS11), esto parece comprobar solo el estado del interruptor de la aplicación; si el interruptor de su aplicación está configurado para habilitarse y el usuario cambia el interruptor maestro de datos celulares a deshabilitado, esta API devolverá el estado de la aplicación como "no restringido" ".



Así que encontré esto en los foros de Apple Dev de un ingeniero de Apple ( https://devforums.apple.com/message/1059332#1059332 ).

Otro desarrollador escribió a DTS y, por lo tanto, tuve la oportunidad de investigar esto en profundidad. Lamentablemente, las noticias son como las esperaba: no hay una forma compatible de detectar que su aplicación se encuentra en este estado. Tampoco hay una manera de hacer una conexión de red "sin interacción del usuario", es decir, solicitar que la conexión falle en lugar de presentar la IU de esta manera. Si estas limitaciones están causando problemas para su aplicación, lo invito a presentar un error que describa sus requisitos específicos.
https://developer.apple.com/bug-reporting/

Por lo tanto, parece que no es posible detectar si los datos celulares de tu aplicación se han desactivado.

Editar

Archivé un radar para este pedido que se agregue. Acabo de recibir esta notificación en mi radar

Creemos que este problema se ha abordado en la última versión beta de iOS 9.

Miré a través de las diferencias de API, pero hasta ahora no puedo encontrar la nueva API.


Hay muchos marcos que le darán el estado de su conectividad de red y, por supuesto, puede rodar el suyo propio. He encontrado AFNetworking para ser uno de los mejores. Tiene una clase de singleton llamada AFNetworkReachabilityManager que AFNetworkReachabilityManager algunas de las complejidades para usted. Específicamente, querrá ver las dos propiedades booleanas:

reachableViaWWAN reachableViaWiFi

También hay un bloque de estado cambiado de accesibilidad que puede establecer:

– setReachabilityStatusChangeBlock:

AFNetworking Github

AFNetworkReachabilityManager


He encontrado que la clase CTCellularData necesita algo de tiempo para llegar al valor correcto. En mi implementación, llamé al didUpdateNotifier muy pronto después de appDidFinishLaunching . Cuando mi llamada de red está regresando con errores, definitivamente tengo un valor correcto para el estado restringido.

class CellularRestriction: NSObject { private static var cellularData = CTCellularData() private static var currentState = CTCellularDataRestrictedState.restrictedStateUnknown static var isRestricted: Bool { currentState = cellularData.restrictedState return currentState == .restricted } static func prepare() { if currentState == .restrictedStateUnknown { cellularData.cellularDataRestrictionDidUpdateNotifier = { state in currentState = cellularData.restrictedState // This value may be inconsistent, however the next read of isRestricted should be correct. } } } }


Solo quería agregar una versión de Objective C del código Swift anterior para futuros viajeros.

- (void)monitorCanUseCellularData { if (GCIsiOS9) { CTCellularData *cellularData = [[CTCellularData alloc] init]; NSLog(@"%ld", cellularData.restrictedState); // 0, kCTCellularDataRestrictedStateUnknown [cellularData setCellularDataRestrictionDidUpdateNotifier:^(CTCellularDataRestrictedState state) { NSLog(@"%ld", state); self.canUseCellularData = cellularData.restrictedState ==2?true:false; }]; } }