我怎样才能以编程方式获取iPhone的MAC地址

有谁知道如何以编程方式获得iPhone的MAC地址和IP地址?


注意从iOS7起,您不能再检索设备MAC地址。 将返回一个固定值,而不是实际的MAC


我刚才偶然发现了一些东西。 原来从这里我修改了一下,清理了一些东西。

IPAddress.h
IPAddress.c

并使用它

 InitAddresses(); GetIPAddresses(); GetHWAddresses(); int i; NSString *deviceIP = nil; for (i=0; i<MAXADDRS; ++i) { static unsigned long localHost = 0x7F000001; // 127.0.0.1 unsigned long theAddr; theAddr = ip_addrs[i]; if (theAddr == 0) break; if (theAddr == localHost) continue; NSLog(@"Name: %s MAC: %s IP: %s\n", if_names[i], hw_addrs[i], ip_names[i]); //decided what adapter you want details for if (strncmp(if_names[i], "en", 2) == 0) { NSLog(@"Adapter en has a IP of %s", ip_names[i]); } } 

适配器名称取决于模拟器/设备以及设备上的wifi或单元。

更新:这将无法在iOS 7上运行。您应该使用ASIdentifierManager 。


MobileDeveloperTips网站上更干净的解决scheme :

 #include <sys/socket.h> #include <sys/sysctl.h> #include <net/if.h> #include <net/if_dl.h> ... - (NSString *)getMacAddress { int mgmtInfoBase[6]; char *msgBuffer = NULL; size_t length; unsigned char macAddress[6]; struct if_msghdr *interfaceMsgStruct; struct sockaddr_dl *socketStruct; NSString *errorFlag = NULL; // Setup the management Information Base (mib) mgmtInfoBase[0] = CTL_NET; // Request network subsystem mgmtInfoBase[1] = AF_ROUTE; // Routing table info mgmtInfoBase[2] = 0; mgmtInfoBase[3] = AF_LINK; // Request link layer information mgmtInfoBase[4] = NET_RT_IFLIST; // Request all configured interfaces // With all configured interfaces requested, get handle index if ((mgmtInfoBase[5] = if_nametoindex("en0")) == 0) errorFlag = @"if_nametoindex failure"; else { // Get the size of the data available (store in len) if (sysctl(mgmtInfoBase, 6, NULL, &length, NULL, 0) < 0) errorFlag = @"sysctl mgmtInfoBase failure"; else { // Alloc memory based on above call if ((msgBuffer = malloc(length)) == NULL) errorFlag = @"buffer allocation failure"; else { // Get system information, store in buffer if (sysctl(mgmtInfoBase, 6, msgBuffer, &length, NULL, 0) < 0) errorFlag = @"sysctl msgBuffer failure"; } } } // Befor going any further... if (errorFlag != NULL) { NSLog(@"Error: %@", errorFlag); return errorFlag; } // Map msgbuffer to interface message structure interfaceMsgStruct = (struct if_msghdr *) msgBuffer; // Map to link-level socket structure socketStruct = (struct sockaddr_dl *) (interfaceMsgStruct + 1); // Copy link layer address data in socket structure to an array memcpy(&macAddress, socketStruct->sdl_data + socketStruct->sdl_nlen, 6); // Read from char array into a string object, into traditional Mac address format NSString *macAddressString = [NSString stringWithFormat:@"%02X:%02X:%02X:%02X:%02X:%02X", macAddress[0], macAddress[1], macAddress[2], macAddress[3], macAddress[4], macAddress[5]]; NSLog(@"Mac Address: %@", macAddressString); // Release the buffer memory free(msgBuffer); return macAddressString; } 

无论是否启用了wifi,我都想要返回地址,所以select的解决scheme不适合我。 我经过一些调整后在另一个论坛上使用了另一个电话。 我结束了以下(原谅我生锈的C):

 #include <sys/types.h> #include <stdio.h> #include <string.h> #include <sys/socket.h> #include <net/if_dl.h> #include <ifaddrs.h> char* getMacAddress(char* macAddress, char* ifName) { int success; struct ifaddrs * addrs; struct ifaddrs * cursor; const struct sockaddr_dl * dlAddr; const unsigned char* base; int i; success = getifaddrs(&addrs) == 0; if (success) { cursor = addrs; while (cursor != 0) { if ( (cursor->ifa_addr->sa_family == AF_LINK) && (((const struct sockaddr_dl *) cursor->ifa_addr)->sdl_type == IFT_ETHER) && strcmp(ifName, cursor->ifa_name)==0 ) { dlAddr = (const struct sockaddr_dl *) cursor->ifa_addr; base = (const unsigned char*) &dlAddr->sdl_data[dlAddr->sdl_nlen]; strcpy(macAddress, ""); for (i = 0; i < dlAddr->sdl_alen; i++) { if (i != 0) { strcat(macAddress, ":"); } char partialAddr[3]; sprintf(partialAddr, "%02X", base[i]); strcat(macAddress, partialAddr); } } cursor = cursor->ifa_next; } freeifaddrs(addrs); } return macAddress; } 

然后我会打电话给en0 ,如下所示:

 char* macAddressString= (char*)malloc(18); NSString* macAddress= [[NSString alloc] initWithCString:getMacAddress(macAddressString, "en0") encoding:NSMacOSRomanStringEncoding]; free(macAddressString); 

从iOS 7开始,当您在任何设备上询问MAC地址时,系统始终会返回值02:00:00:00:00:00

在iOS 7及更高版本中,如果您要求提供iOS设备的MAC地址,系统将返回值02:00:00:00:00:00。 如果您需要识别设备,请改用UIDevice的identifierForVendor属性。 (需要为自己的广告目的标识符的应用程序应该考虑使用ASIdentifierManager的advertisingIdentifier属性代替。)“

参考: releasenotes

有不同的解决scheme,但我找不到一个完整的东西。 所以我做了我自己的解决scheme:

nicinfo

如何使用 :

 NICInfoSummary* summary = [[[NICInfoSummary alloc] init] autorelease]; // en0 is for WiFi NICInfo* wifi_info = [summary findNICInfo:@"en0"]; // you can get mac address in 'XX-XX-XX-XX-XX-XX' form NSString* mac_address = [wifi_info getMacAddressWithSeparator:@"-"]; // ip can be multiple if(wifi_info.nicIPInfos.count > 0) { NICIPInfo* ip_info = [wifi_info.nicIPInfos objectAtIndex:0]; NSString* ip = ip_info.ip; NSString* netmask = ip_info.netmask; NSString* broadcast_ip = ip_info.broadcastIP; } else { NSLog(@"WiFi not connected!"); } 

这看起来像一个很干净的解决scheme: UIDevice BIdentifier

 // Return the local MAC addy // Courtesy of FreeBSD hackers email list // Accidentally munged during previous update. Fixed thanks to erica sadun & mlamb. - (NSString *) macaddress{ int mib[6]; size_t len; char *buf; unsigned char *ptr; struct if_msghdr *ifm; struct sockaddr_dl *sdl; mib[0] = CTL_NET; mib[1] = AF_ROUTE; mib[2] = 0; mib[3] = AF_LINK; mib[4] = NET_RT_IFLIST; if ((mib[5] = if_nametoindex("en0")) == 0) { printf("Error: if_nametoindex error\n"); return NULL; } if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) { printf("Error: sysctl, take 1\n"); return NULL; } if ((buf = malloc(len)) == NULL) { printf("Could not allocate memory. error!\n"); return NULL; } if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) { printf("Error: sysctl, take 2"); free(buf); return NULL; } ifm = (struct if_msghdr *)buf; sdl = (struct sockaddr_dl *)(ifm + 1); ptr = (unsigned char *)LLADDR(sdl); NSString *outstring = [NSString stringWithFormat:@"%02X:%02X:%02X:%02X:%02X:%02X", *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4), *(ptr+5)]; free(buf); return outstring; } 

现在iOS 7设备 – 总是返回一个MAC地址为02:00:00:00:00:00。

所以最好使用[UIDevice identifierForVendor]。

所以更好地调用这个方法来获得应用程序特定的唯一键

类别会更合适

导入“UIDevice + Identifier.h”

 - (NSString *) identifierForVendor1 { if ([[UIDevice currentDevice] respondsToSelector:@selector(identifierForVendor)]) { return [[[UIDevice currentDevice] identifierForVendor] UUIDString]; } return @""; } 

现在调用上面的方法来获得唯一的地址

 NSString *like_UDID=[NSString stringWithFormat:@"%@", [[UIDevice currentDevice] identifierForVendor1]]; NSLog(@"%@",like_UDID); 

@Grantland这个“非常干净的解决scheme”看起来类似于我对iPhoneDeveloperTips解决scheme的改进。

你可以在这里看到我的步骤: https : //gist.github.com/1409855/

 #import <sys/socket.h> #import <net/if_dl.h> #import <ifaddrs.h> #import <sys/xattr.h> #define IFT_ETHER 0x6 

 - (NSString*)macAddress { NSString* result = nil; char* macAddressString = (char*)malloc(18); if (macAddressString != NULL) { strcpy(macAddressString, ""); struct ifaddrs* addrs = NULL; struct ifaddrs* cursor; if (getifaddrs(&addrs) == 0) { cursor = addrs; while (cursor != NULL) { if ((cursor->ifa_addr->sa_family == AF_LINK) && (((const struct sockaddr_dl*)cursor->ifa_addr)->sdl_type == IFT_ETHER) && strcmp("en0", cursor->ifa_name) == 0) { const struct sockaddr_dl* dlAddr = (const struct sockaddr_dl*) cursor->ifa_addr; const unsigned char* base = (const unsigned char*)&dlAddr->sdl_data[dlAddr->sdl_nlen]; for (NSInteger index = 0; index < dlAddr->sdl_alen; index++) { char partialAddr[3]; sprintf(partialAddr, "%02X", base[index]); strcat(macAddressString, partialAddr); } } cursor = cursor->ifa_next; } } result = [[[NSString alloc] initWithUTF8String:macAddressString] autorelease]; free(macAddressString); } return result; } 

要在iOS 6中根据设备的唯一标识符创builduniqueString:

 #import <AdSupport/ASIdentifierManager.h> NSString *uniqueString = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString]; NSLog(@"uniqueString: %@", uniqueString); 

很多这些问题只解决Mac地址。 如果您还需要IP地址,我只是写了这个,可能需要一些工作,但似乎在我的机器上运行良好…

 - (NSString *)getLocalIPAddress { NSArray *ipAddresses = [[NSHost currentHost] addresses]; NSArray *sortedIPAddresses = [ipAddresses sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)]; NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init]; numberFormatter.allowsFloats = NO; for (NSString *potentialIPAddress in sortedIPAddresses) { if ([potentialIPAddress isEqualToString:@"127.0.0.1"]) { continue; } NSArray *ipParts = [potentialIPAddress componentsSeparatedByString:@"."]; BOOL isMatch = YES; for (NSString *ipPart in ipParts) { if (![numberFormatter numberFromString:ipPart]) { isMatch = NO; break; } } if (isMatch) { return potentialIPAddress; } } // No IP found return @"?.?.?.?"; } 

在运行iOS 7.0或更高版本的设备上不可能 ,因此无法在Swift中获取MAC地址。

正如苹果所言:

在iOS 7及更高版本中,如果您要求提供iOS设备的MAC地址,系统将返回值02:00:00:00:00:00。 如果您需要识别设备,请改用UIDevice的identifierForVendor属性。 (需要为自己的广告目的标识符的应用程序应考虑使用ASIdentifierManager的advertisingIdentifier属性。)