J'ai cherché sur ce sujet, mais j'ai trouvé très peu de détails utiles. Avec ces détails, j'ai essayé de préparer du code comme suit.
Remarque: veuillez comparer les détails partagés dans cet article avec d'autres articles avant de le marquer comme DUPLICATE, et pas seulement en fonction du sujet.
- (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];
}
Ce code recueille des informations sur l'utilisation d'Internet d'un appareil iPhone (et pas uniquement de mon application).
Maintenant, si j'utilise Internet via WiFi ou via 3G, je reçois les données (octets) uniquement dans ifi_obytes
(envoyé) et ifi_ibytes
(reçu) mais je pense que je devrais utiliser le WiFi dans ifi_opackets
et ifi_ipackets
.
Je voulais également ajouter que si je suis connecté à un réseau WiFi, mais que je n'utilise pas Internet, j'obtiens toujours une valeur ajoutée à ifi_obytes
et ifi_ibytes
.
Peut-être que je me trompe dans la mise en œuvre ou la compréhension. Besoin de quelqu'un pour m'aider.
Edit: Au lieu de AF_LINK
j'ai essayé AF_INET
( sockaddr_in
au lieu de sockaddr_dl
). Cela plante l'application.
Il est important de comprendre que ces compteurs sont fournis depuis le dernier démarrage de l'appareil.
Donc, pour les utiliser efficacement, vous devez accompagner chaque échantillon de la disponibilité de l'appareil (vous pouvez utiliser
mach_absolute_time()
- voir ceci pour plus d'informations)Une fois que vous avez des échantillons de compteurs + temps de disponibilité, vous pouvez avoir de meilleures heuristiques quant à l'utilisation des données ...
la source
Pour ajouter à la réponse acceptée, il est important de se rendre compte que la quantité de données affichées par l'interface déborde et redémarre
0
après chaque4 GB
, surtout si vous utilisez ce code pour calculer la différence entre deux lectures. C'est parce queifi_obytes
etifi_ibytes
sontuint_32
et leur valeur maximale est4294967295
.De plus, je recommande d'utiliser
unsigned int
s pour les variables contenant les données envoyées et reçues. Lesint
s normaux ont la moitié de la valeur maximale d'un entier non signé, donc lors de l'ajoutifi_obytes
, cela peut provoquer un débordement.la source
Version rapide de la réponse acceptée. Je décompose également le code en unités plus petites.
la source
J'ai corrigé le code source ci-dessus à la version Swift3
la source
Une nouvelle version basée sur les versions précédentes, mais adaptée pour Swift4 et Xcode 9
la source
Désolé pour la même réponse à nouveau.
mais j'ai trouvé que UInt32 n'est pas suffisant, donc il plante quand il est devenu trop gros.
Je viens de changer UInt32 en UInt64 et cela fonctionne très bien.
la source