Reputation: 593
How do I get an iOS device's MAC code programmatically in my app?
Upvotes: 17
Views: 70690
Reputation: 519
Actually it seems possible to get macaddr even on iOS >= 7 the information comes from this blog and the solution is based on ipV6. I have tested on iPhone12 running under 15.5 and it works fine. Here is the interesting code:
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://stackoverflow.com/a/30754194/3508517
//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
}
Upvotes: 0
Reputation: 9
You can get it by combining the following two answers i guess.
First, find ip of the device by using the following:
https://stackoverflow.com/a/30754194/1089206
Second, find the MAC of that address, by using the following:
https://stackoverflow.com/a/31246085/1089206
I'll be trying it out now and will let you know how it goes.
Upvotes: 0
Reputation: 923
Now iOS 7 devices – are always returning a MAC address of 02:00:00:00:00:00.
So better use [UIDevice identifierForVendor]
so better to call this method to get app specific unique key
Category will more suitable
#import "UIDevice+Identifier.h"
- (NSString *) identifierForVendor1
{
if ([[UIDevice currentDevice] respondsToSelector:@selector(identifierForVendor)]) {
return [[[UIDevice currentDevice] identifierForVendor] UUIDString];
}
return @"";
}
Now call above method to get unique address
NSString *like_UDID=[NSString stringWithFormat:@"%@",
[[UIDevice currentDevice] identifierForVendor1]];
NSLog(@"%@",like_UDID);
Upvotes: 19
Reputation: 1939
everybody is good advised to use the offical ios 7 way and use [UIDevice identifierForVendor]
And also think about the migration from some older assumptions.
Upvotes: 1
Reputation: 4520
You can get the MAC Adress using the following function:
+(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;
}
But as he said #Randomclik, mac address is unavailable from ios 7 and up.
form apple:
In iOS 7 and later, if you ask for the MAC address of an iOS device, the system returns the value 02:00:00:00:00:00. If you need to identify the device, use the identifierForVendor property of UIDevice instead. (Apps that need an identifier for their own advertising purposes should consider using the advertisingIdentifier property of ASIdentifierManager instead.)
Conversation about MAC Address:
How can I programmatically get the MAC address of an iphone
Upvotes: 10
Reputation: 29
It seems that in iOS 7 and later get MAC addres will not work. Look at What's new on iOS document from Apple. (Deprecated APIs section.)
Upvotes: 2