en2
接口。
添加:
[[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@"en2"]
在 iPhone/iPad/OSX: How to get my IP address programmatically? 中的第一种解决方案,可以通过有线连接获取设备的IP地址。
更新:扩展@Raptor上面链接的解决方案;如果无线和有线IP地址都存在,则会返回两者IP地址。然后只需检查返回字典值的长度即可确定使用哪个IP地址。
#import <ifaddrs.h>
#import <arpa/inet.h>
+ (NSDictionary *)getBothIPAddresses {
const NSString *WIFI_IF = @"en0";
NSArray *KNOWN_WIRED_IFS = @[@"en1",@"en2",@"en3",@"en4"];
NSArray *KNOWN_CELL_IFS = @[@"pdp_ip0",@"pdp_ip1",@"pdp_ip2",@"pdp_ip3"];
const NSString *UNKNOWN_IP_ADDRESS = @"";
NSMutableDictionary *addresses = [NSMutableDictionary dictionaryWithDictionary:@{@"wireless":UNKNOWN_IP_ADDRESS,
@"wired":UNKNOWN_IP_ADDRESS,
@"cell":UNKNOWN_IP_ADDRESS}];
struct ifaddrs *interfaces = NULL;
struct ifaddrs *temp_addr = NULL;
int success = 0;
success = getifaddrs(&interfaces);
if (success == 0) {
temp_addr = interfaces;
while(temp_addr != NULL) {
if (temp_addr->ifa_addr == NULL) {
temp_addr = temp_addr->ifa_next;
continue;
}
if(temp_addr->ifa_addr->sa_family == AF_INET) {
if([[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:WIFI_IF]) {
[addresses setObject:[NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)] forKey:@"wireless"];
}
if([KNOWN_WIRED_IFS containsObject:[NSString stringWithUTF8String:temp_addr->ifa_name]]) {
[addresses setObject:[NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)] forKey:@"wired"];
}
if([KNOWN_CELL_IFS containsObject:[NSString stringWithUTF8String:temp_addr->ifa_name]]) {
[addresses setObject:[NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)] forKey:@"cell"];
}
}
temp_addr = temp_addr->ifa_next;
}
}
freeifaddrs(interfaces);
return addresses;
}
更新:
en3
接口,另一种可能性;似乎取决于适配器类型。这让我想到可能还有其他接口我还没有发现,基于使用的硬件,请在评论中指出。
更新:
也是 en4
;不像我最初认为的那样取决于适配器,因为某个时刻拥有完全相同硬件的 Mini 决定从一个接口切换到这个新接口。此外,我开始认为只需将 ifa_name 与任何格式为 en[2..n]
的字符串进行比较,只要它位于 AF_INET
家族(例如,en1
不是,并且不返回我们正在寻找的地址);如果没有更多证据,实现类似于 Prod 的东西可能为时过早,因此现在我使用“已知”有线接口列表来管理。
更新:
还考虑了移动 AF_INET
接口,在iOS 网络接口名称的确切含义是什么?什么是 pdp_ip?什么是 ap? 中提到。
更新:
以太网 IP 地址最近开始出现在某些新 iPad 上的 en1
接口上,因此在它是 AF_INET
家族成员时也应该考虑。没有可区分的韵律或原因,它会发生在不同的 iPad 型号和 iOS 版本中。