如何以编程方式获取iOS设备的MAC地址

17

我如何在我的应用程序中以编程方式获取iOS设备的MAC码?


1
请检查此链接https://dev59.com/SHRB5IYBdhLWcg3wQVSV - Exploring
1
还有这个链接http://developer.apple.com/library/mac/#samplecode/GetPrimaryMACAddress/Introduction/Intro.html - Exploring
6个回答

19

现在 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);

10

您可以使用以下函数获取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属性。)

链接: https://developer.apple.com/library/prerelease/ios/releasenotes/General/WhatsNewIniOS/Articles/iOS7.html#//apple_ref/doc/uid/TP40013162-SW1

关于MAC地址的对话:

如何以编程方式获取iPhone的MAC地址?


2

看起来在iOS 7及以后,获取MAC地址将无法使用。请查看苹果公司的iOS文档中的“已弃用的API”部分。


1

0

2
请避免使用链接,即使在SO中也是如此。请将链接更改为简短的摘要,以便理解答案。可以将链接作为附加信息添加,但这不是理解答案的简单方法。 - shapiro yaacov

0

实际上,在 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
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接