He buscado sobre este tema, pero encontré muy pocos detalles que fueron útiles. Con estos detalles, he intentado cocinar un código de la siguiente manera.
Nota: compare los detalles compartidos en esta publicación con otras publicaciones antes de marcar esto como DUPLICADO, y no solo por el tema.
- (NSArray *)getDataCountersForType:(int)type {
BOOL success;
struct ifaddrs *addrs = nil;
const struct ifaddrs *cursor = nil;
const struct sockaddr_dl *dlAddr = nil;
const struct if_data *networkStatisc = nil;
int dataSent = 0;
int dataReceived = 0;
success = getifaddrs(&addrs) == 0;
if (success) {
cursor = addrs;
while (cursor != NULL) {
if (cursor->ifa_addr->sa_family == AF_LINK) {
dlAddr = (const struct sockaddr_dl *) cursor->ifa_addr;
networkStatisc = (const struct if_data *) cursor->ifa_data;
if (type == WiFi) {
dataSent += networkStatisc->ifi_opackets;
dataReceived += networkStatisc->ifi_ipackets;
}
else if (type == WWAN) {
dataSent += networkStatisc->ifi_obytes;
dataReceived += networkStatisc->ifi_ibytes;
}
}
cursor = cursor->ifa_next;
}
freeifaddrs(addrs);
}
return [NSArray arrayWithObjects:[NSNumber numberWithInt:dataSent], [NSNumber numberWithInt:dataReceived], nil];
}
Este código recopila información sobre el uso de Internet de un dispositivo iPhone (y no solo mi aplicación).
Ahora, si uso internet a través de WiFi o 3G, obtengo los datos (bytes) solo en ifi_obytes
(enviado) y ifi_ibytes
(recibido) pero creo que debería obtener el uso de WiFi en ifi_opackets
y ifi_ipackets
.
También quería agregar que si estoy conectado a una red WiFi, pero no estoy usando Internet, todavía obtengo valor agregado ifi_obytes
y ifi_ibytes
.
Puede ser que me equivoque en la implementación o comprensión. Necesito a alguien que me ayude.
Editar: en lugar de AF_LINK
lo intenté AF_INET
(en sockaddr_in
lugar de sockaddr_dl
). Esto bloquea la aplicación.
Es importante comprender que estos contadores se proporcionan desde el último inicio del dispositivo.
Por lo tanto, para hacer un uso efectivo de ellos, debe acompañar cada muestra con el tiempo de actividad del dispositivo (puede usarlo
mach_absolute_time()
; consulte esto para obtener más información)Una vez que tenga muestras de contadores + tiempo de actividad, puede tener mejores heurísticas en cuanto al uso de datos ...
fuente
Para agregar a la respuesta aceptada, es importante darse cuenta de que la cantidad de datos que muestra la interfaz se desborda y se reinicia
0
después de cada4 GB
, especialmente si está utilizando este código para calcular la diferencia entre dos lecturas. Esto es porqueifi_obytes
yifi_ibytes
areuint_32
y su valor máximo es4294967295
.Además, recomiendo usar
unsigned int
s para las variables que contienen los datos enviados y recibidos. Losint
s regulares tienen la mitad del valor máximo de un entero sin signo, por lo que al agregarlosifi_obytes
, puede causar un desbordamiento.fuente
Versión rápida de la respuesta aceptada. También divido el código en unidades más pequeñas.
fuente
Arreglé el código fuente anterior a la versión Swift3
fuente
Una nueva versión basada en versiones anteriores, pero adaptada para Swift4 y Xcode 9
fuente
Perdón por la misma respuesta de nuevo.
pero descubrí que UInt32 no es suficiente, por lo que se bloquea cuando se vuelve demasiado grande.
Acabo de cambiar UInt32 a UInt64 y funciona bien.
fuente