我如何在我的应用程序中以编程方式获取iOS设备的MAC码?
我如何在我的应用程序中以编程方式获取iOS设备的MAC码?
现在 iOS 7 设备总是会返回 MAC 地址为 02:00:00:00:00:00。
因此最好使用 [UIDevice identifierForVendor]
。
所以最好调用这个方法来获取应用程序特定的唯一键。
类别将更适合。
#import "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);
您可以使用以下函数获取MAC地址:
+(NSString *)getMacAddress
{
int mgmtInfoBase[6];
char *msgBuffer = NULL;
NSString *errorFlag = NULL;
size_t length;
// 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";
// Get the size of the data available (store in len)
else if (sysctl(mgmtInfoBase, 6, NULL, &length, NULL, 0) < 0)
errorFlag = @"sysctl mgmtInfoBase failure";
// Alloc memory based on above call
else if ((msgBuffer = malloc(length)) == NULL)
errorFlag = @"buffer allocation failure";
// Get system information, store in buffer
else if (sysctl(mgmtInfoBase, 6, msgBuffer, &length, NULL, 0) < 0)
{
free(msgBuffer);
errorFlag = @"sysctl msgBuffer failure";
}
else
{
// Map msgbuffer to interface message structure
struct if_msghdr *interfaceMsgStruct = (struct if_msghdr *) msgBuffer;
// Map to link-level socket structure
struct sockaddr_dl *socketStruct = (struct sockaddr_dl *) (interfaceMsgStruct + 1);
// Copy link layer address data in socket structure to an array
unsigned char macAddress[6];
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]];
if(IsDEBUG) NSLog(@"Mac Address: %@", macAddressString);
// Release the buffer memory
free(msgBuffer);
return macAddressString;
}
// Error...
if(IsDEBUG) NSLog(@"Error: %@", errorFlag);
return errorFlag;
}
但正如他所说#Randomclik,从iOS 7开始mac地址无法使用。
来自苹果的信息:
在iOS 7及之后的版本中,如果您请求iOS设备的MAC地址,系统会返回值02:00:00:00:00:00。如果您需要识别设备,请使用UIDevice的identifierForVendor属性。(需要一个标识符用于自身广告目的的应用程序可以考虑使用ASIdentifierManager的advertisingIdentifier属性。)
关于MAC地址的对话:
看起来在iOS 7及以后,获取MAC地址将无法使用。请查看苹果公司的iOS文档中的“已弃用的API”部分。
建议所有人都使用官方的iOS 7方法并使用[UIDevice identifierForVendor]。
同时考虑一些旧的假设迁移。
我猜你可以通过结合以下两个答案来获得它。
首先,使用以下方法找到设备的IP地址:
https://dev59.com/9V0a5IYBdhLWcg3wD1Hb#30754194
其次,通过使用以下方法找到该地址的MAC地址:
https://dev59.com/jIzda4cB1Zd3GeqPpazL#31246085
我现在会尝试它,并告诉你它的表现如何。
实际上,在 iOS >= 7 上获取 mac 地址似乎是可能的,这个信息来自于这个 博客,解决方案基于 ipV6。 我已经在运行 15.5 的 iPhone12 上进行了测试,它可以正常工作。 以下是有趣的代码:
func GetMACAddress(){
let address = getAddress()
macAddressLabel = GetMACAddressFromIPv6(ip: address ?? "")
print(macAddressLabel)
}
func GetMACAddressFromIPv6(ip: String) -> String{
let IPStruct = IPv6Address(ip)
if(IPStruct == nil){
return ""
}
let extractedMAC = [
(IPStruct?.rawValue[8])! ^ 0b00000010,
IPStruct?.rawValue[9],
IPStruct?.rawValue[10],
IPStruct?.rawValue[13],
IPStruct?.rawValue[14],
IPStruct?.rawValue[15]
]
let str = String(format: "%02x:%02x:%02x:%02x:%02x:%02x", extractedMAC[0] ?? 00,
extractedMAC[1] ?? 00,
extractedMAC[2] ?? 00,
extractedMAC[3] ?? 00,
extractedMAC[4] ?? 00,
extractedMAC[5] ?? 00)
return str
}
// this function was taken from
// https://dev59.com/9V0a5IYBdhLWcg3wD1Hb#30754194
//and is slightly modified:
func getAddress() -> String? {
var address: String?
// Get list of all interfaces on the local machine:
var ifaddr: UnsafeMutablePointer<ifaddrs>?
guard getifaddrs(&ifaddr) == 0 else { return nil }
guard let firstAddr = ifaddr else { return nil }
// For each interface ...
for ifptr in sequence(first: firstAddr, next: { $0.pointee.ifa_next }) {
let interface = ifptr.pointee
// Check IPv6 interface:
let addrFamily = interface.ifa_addr.pointee.sa_family
if addrFamily == UInt8(AF_INET6) {
// Check interface name:
let name = String(cString: interface.ifa_name)
if name.contains("ipsec") {
// Convert interface address to a human readable string:
var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST))
getnameinfo(interface.ifa_addr, socklen_t(interface.ifa_addr.pointee.sa_len),
&hostname, socklen_t(hostname.count),
nil, socklen_t(0), NI_NUMERICHOST)
address = String(cString: hostname)
let ipv6addr = IPv6Address(address ?? "::")
if(ipv6addr?.isLinkLocal ?? false){
return address
}
}
}
}
freeifaddrs(ifaddr)
return address
}