iPhone 数据使用跟踪/监控 [英] iPhone Data Usage Tracking/Monitoring
问题描述
我搜索了这个主题,但发现有用的细节很少.根据这些细节,我尝试编写如下代码.
注意:在将此帖子标记为重复之前,请将此帖子中共享的详细信息与其他帖子进行比较,而不仅仅是按主题.
- (NSArray *)getDataCountersForType:(int)type {布尔成功;结构 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;成功 = getifaddrs(&addrs) == 0;如果(成功){游标 = 地址;而(光标!= NULL){如果(光标->ifa_addr->sa_family == AF_LINK){dlAddr = (const struct sockaddr_dl *) cursor->ifa_addr;networkStatisc = (const struct if_data *) cursor->ifa_data;如果(类型== WiFi){dataSent += networkStatisc->ifi_opackets;dataReceived += networkStatisc->ifi_ipackets;}否则如果(类型== WWAN){dataSent += networkStatisc->ifi_obytes;dataReceived += networkStatisc->ifi_ibytes;}}cursor = cursor->ifa_next;}freeifaddrs(地址);}返回 [NSArray arrayWithObjects:[NSNumber numberWithInt:dataSent], [NSNumber numberWithInt:dataReceived], nil];}
此代码收集 iPhone 设备(而不是我的应用程序)的互联网使用信息.
现在,如果我通过 WiFi 或 3G 使用互联网,我只能在 ifi_obytes
(发送)和 ifi_ibytes
(接收)中获取数据(字节),但我认为我应该在 ifi_opackets
和 ifi_ipackets
中使用 WiFi.
还想补充一点,如果我已连接到 WiFi 网络,但不使用互联网,我仍然可以为 ifi_obytes
和 ifi_ibytes
添加价值.>
可能是我在实施或理解上有误.需要有人帮助我.
<小时>我尝试了 AF_INET
(sockaddr_in
而不是 sockaddr_dl
)而不是 AF_LINK
.这会导致应用程序崩溃.
pdp_ip0
是接口之一,所有pdpXXX
都是WWAN
代码>专用于不同功能的接口、语音邮件、通用网络接口.
我在苹果论坛上读到:操作系统不会逐个进程地保留网络统计信息.因此,这个问题没有确切的解决方案.但是,您可以获取每个网络接口的网络统计信息.
一般来说,en0
是您的 Wi-Fi
接口,pdp_ip0
是您的 WWAN
接口.
没有什么好方法可以获取信息 wifi/蜂窝网络数据,因为特定的日期时间!
数据统计信息(ifa_data->ifi_obytes
和 ifa_data->ifi_ibytes
)是从之前的设备重启中存储的.
我不知道为什么,但是 ifi_opackets
和 ifi_ipackets
仅针对 lo0
显示(我认为是它的主界面).>
是的.然后设备通过 WiFi
连接并且不使用互联网 if_iobytes
值仍然存在,因为此方法提供网络字节交换而不仅仅是互联网.
#include #include 静态 NSString *const DataCounterKeyWWANSent = @"WWANSent";静态 NSString *const DataCounterKeyWWANReceived = @"WWANReceived";static NSString *const DataCounterKeyWiFiSent = @"WiFiSent";static NSString *const DataCounterKeyWiFiReceived = @"WiFiReceived";NSDictionary *DataCounters(){结构 ifaddrs *addrs;const struct ifaddrs *cursor;u_int32_t WiFiSent = 0;u_int32_t WiFiReceived = 0;u_int32_t WWANSent = 0;u_int32_t WWANReceived = 0;如果 (getifaddrs(&addrs) == 0){游标 = 地址;而(光标!= NULL){如果(光标->ifa_addr->sa_family == AF_LINK){#ifdef 调试const struct if_data *ifa_data = (struct if_data *)cursor->ifa_data;如果(ifa_data != NULL){NSLog(@"接口名称 %s: sent %tu received %tu",cursor->ifa_name,ifa_data->ifi_obytes,ifa_data->ifi_ibytes);}#万一//接口名称://en0 是 WiFi//pdp_ip0 是 WWANNSString *name = @(cursor->ifa_name);if ([name hasPrefix:@"en"]){const struct if_data *ifa_data = (struct if_data *)cursor->ifa_data;如果(ifa_data != NULL){WiFiSent += ifa_data->ifi_obytes;WiFiReceived += ifa_data->ifi_ibytes;}}if ([name hasPrefix:@"pdp_ip"]){const struct if_data *ifa_data = (struct if_data *)cursor->ifa_data;如果(ifa_data != NULL){WWANSent += ifa_data->ifi_obytes;WWANReceived += ifa_data->ifi_ibytes;}}}cursor = cursor->ifa_next;}freeifaddrs(地址);}返回@{DataCounterKeyWiFiSent : @(WiFiSent),DataCounterKeyWiFiReceived : @(WiFiReceived),DataCounterKeyWWANSent : @(WWANSent),DataCounterKeyWWANReceived : @(WWANReceived)};}
改进了复制/粘贴支持!
I've searched over this topic but found very few details which were helpful. With these details I've tried to cook some code as follows.
Note: Please compare the details shared in this post with other posts before marking this as DUPLICATE, and not just by the subject.
- (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];
}
This code collects information of internet usage of an iPhone device (and not my application alone).
Now, if I use internet through WiFi or through 3G, I get the the data (bytes) only in ifi_obytes
(sent) and ifi_ibytes
(received) but I think I should get WiFi usage in ifi_opackets
and ifi_ipackets
.
Also wanted to add that if I'm connected to a WiFi network, but am not using internet, I still get value added to ifi_obytes
and ifi_ibytes
.
May be I'm wrong in the implementation or understanding. Need someone to help me out.
Edit: Instead of AF_LINK
I tried AF_INET
(sockaddr_in
instead of sockaddr_dl
). This crashes the application.
The thing is that pdp_ip0
is one of interfaces, all pdpXXX
are WWAN
interfaces dedicated to different functions, voicemail, general networking interface.
I read in Apple forum that : The OS does not keep network statistics on a process-by-process basis. As such, there's no exact solution to this problem. You can, however, get network statistics for each network interface.
In general en0
is your Wi-Fi
interface and pdp_ip0
is your WWAN
interface.
There is no good way to get information wifi/cellular network data since, particular date-time!
Data statistic (ifa_data->ifi_obytes
and ifa_data->ifi_ibytes
) are stored from previous device reboot.
I don't know why, but ifi_opackets
and ifi_ipackets
are shown just for lo0
(I think its main interface ).
Yes. Then device is connected via WiFi
and doesn't use internet if_iobytes
values still come because this method provides network bytes exchanges and not just internet.
#include <net/if.h>
#include <ifaddrs.h>
static NSString *const DataCounterKeyWWANSent = @"WWANSent";
static NSString *const DataCounterKeyWWANReceived = @"WWANReceived";
static NSString *const DataCounterKeyWiFiSent = @"WiFiSent";
static NSString *const DataCounterKeyWiFiReceived = @"WiFiReceived";
NSDictionary *DataCounters()
{
struct ifaddrs *addrs;
const struct ifaddrs *cursor;
u_int32_t WiFiSent = 0;
u_int32_t WiFiReceived = 0;
u_int32_t WWANSent = 0;
u_int32_t WWANReceived = 0;
if (getifaddrs(&addrs) == 0)
{
cursor = addrs;
while (cursor != NULL)
{
if (cursor->ifa_addr->sa_family == AF_LINK)
{
#ifdef DEBUG
const struct if_data *ifa_data = (struct if_data *)cursor->ifa_data;
if (ifa_data != NULL)
{
NSLog(@"Interface name %s: sent %tu received %tu",cursor->ifa_name,ifa_data->ifi_obytes,ifa_data->ifi_ibytes);
}
#endif
// name of interfaces:
// en0 is WiFi
// pdp_ip0 is WWAN
NSString *name = @(cursor->ifa_name);
if ([name hasPrefix:@"en"])
{
const struct if_data *ifa_data = (struct if_data *)cursor->ifa_data;
if (ifa_data != NULL)
{
WiFiSent += ifa_data->ifi_obytes;
WiFiReceived += ifa_data->ifi_ibytes;
}
}
if ([name hasPrefix:@"pdp_ip"])
{
const struct if_data *ifa_data = (struct if_data *)cursor->ifa_data;
if (ifa_data != NULL)
{
WWANSent += ifa_data->ifi_obytes;
WWANReceived += ifa_data->ifi_ibytes;
}
}
}
cursor = cursor->ifa_next;
}
freeifaddrs(addrs);
}
return @{DataCounterKeyWiFiSent : @(WiFiSent),
DataCounterKeyWiFiReceived : @(WiFiReceived),
DataCounterKeyWWANSent : @(WWANSent),
DataCounterKeyWWANReceived : @(WWANReceived)};
}
Improved copy/paste support !
这篇关于iPhone 数据使用跟踪/监控的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!