¿Cómo puedo obtener programáticamente la dirección MAC de un iphone?

¿Alguien sabe cómo obtener programáticamente la dirección MAC y la dirección IP de un iPhone?


NOTA A partir de iOS7, ya no puede recuperar las direcciones MAC del dispositivo. Se devolverá un valor fijo en lugar del MAC actual


Algo con lo que tropecé hace un tiempo. Originalmente desde aquí lo modifiqué un poco y lo limpié todo.

IPAddress.h
IPAddress.c

Y para usarlo

 InitAddresses(); GetIPAddresses(); GetHWAddresses(); int i; NSString *deviceIP = nil; for (i=0; i 

Los nombres de los adaptadores varían según el simulador / dispositivo, así como wifi o celular en el dispositivo.

Actualización: esto no funcionará en iOS 7. Debe usar ASIdentifierManager .


Más solución limpia en el sitio web de MobileDeveloperTips:

 #include  #include  #include  #include  ... - (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; } 

Quería algo para devolver la dirección independientemente de si wifi estaba habilitado, por lo que la solución elegida no funcionó para mí. Utilicé otra llamada que encontré en algún foro después de algunos ajustes. Terminé con lo siguiente (disculpe mi oxidado C):

 #include  #include  #include  #include  #include  #include  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; } 

Y luego lo llamaría pidiendo en0 , de la siguiente manera:

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

A partir de iOS 7, el sistema siempre devuelve el valor 02:00:00:00:00:00 cuando solicita la dirección MAC en cualquier dispositivo.

En iOS 7 y posteriores, si solicita la dirección MAC de un dispositivo iOS, el sistema devuelve el valor 02: 00: 00: 00: 00: 00. Si necesita identificar el dispositivo, use en su lugar la propiedad identifierForVendor de UIDevice. (Las aplicaciones que necesitan un identificador para sus propios fines publicitarios deberían considerar el uso de la propiedad advertisingIdentifier de ASIdentifierManager).

Referencia: releasenotes

Hay varias soluciones sobre esto, pero no pude encontrar una cosa completa. Así que hice mi propia solución para:

nicinfo

Cómo utilizar :

 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!"); } 

Esto parece una solución bastante limpia: 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; } 

Ahora los dispositivos iOS 7 siempre devuelven una dirección MAC de 02: 00: 00: 00: 00: 00.

Así que es mejor usar [UIDevice identifierForVendor].

así que es mejor llamar a este método para obtener una clave única específica de la aplicación

La categoría será más adecuada

importar “UIDevice + Identifier.h”

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

Ahora llame al método anterior para obtener una dirección única

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

@Grantland Esta “solución bastante limpia” se parece a mi propia mejora con respecto a la solución de iPhoneDeveloperTips.

Puedes ver mi paso aquí: https://gist.github.com/1409855/

 /* Original source code courtesy John from iOSDeveloperTips.com */ #include  #include  #include  #include  + (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]]; NSLog(@"Mac Address: %@", macAddressString); // Release the buffer memory free(msgBuffer); return macAddressString; } // Error... NSLog(@"Error: %@", errorFlag); return nil; } 
 #import  #import  #import  #import  #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; } 

Para crear un UniqueString basado en el identificador único del dispositivo en iOS 6:

 #import  NSString *uniqueString = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString]; NSLog(@"uniqueString: %@", uniqueString); 

Muchas de estas preguntas solo abordan la dirección de Mac. Si también necesita la dirección IP, acabo de escribir esto, puede necesitar algún trabajo pero parece funcionar bien en mi máquina …

 - (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 @"?.?.?.?"; } 

Ya no es posible en dispositivos con iOS 7.0 o posterior, por lo que no está disponible para obtener la dirección MAC en Swift.

Como Apple dijo:

En iOS 7 y posteriores, si solicita la dirección MAC de un dispositivo iOS, el sistema devuelve el valor 02: 00: 00: 00: 00: 00. Si necesita identificar el dispositivo, use en su lugar la propiedad identifierForVendor de UIDevice. (Las aplicaciones que necesitan un identificador para sus propios fines publicitarios deberían considerar el uso de la propiedad advertisingIdentifier de ASIdentifierManager).