【问题标题】:Getting Device ID or Mac Address in iOS [duplicate]在iOS中获取设备ID或Mac地址[重复]
【发布时间】:2010-11-09 18:20:26
【问题描述】:

我有一个使用 rest 与服务器通信的应用程序,我想获取 iphone 的 mac 地址或设备 ID 以进行唯一性验证,该怎么做?

【问题讨论】:

标签: ios objective-c device mac-address


【解决方案1】:

[[UIDevice currentDevice] uniqueIdentifier] 保证对每个设备都是唯一的。

【讨论】:

  • 对于这个问题的新手,UDID API 在 iOS 5 中已被弃用。要获得唯一标识符,您需要改为使用 iPhone 的 MAC 地址。
  • @diwup,MAC 地址会根据用户是使用蜂窝连接还是 Wi-Fi 连接而变化,对吗?还是两种类型的网络接口都一样?
  • 什么是不被弃用的替代方案?
  • 在 iOS 6+ 中使用 identifierForVendor,返回 NSUUID 对象
  • 这是一篇很棒的文章,有替代品:doubleencore.com/2013/04/unique-identifiers
【解决方案2】:

uniqueIdentifier(在 iOS 5.0 中已弃用。相反,创建一个特定于您的应用的唯一标识符。)

文档建议使用CFUUIDCreate 而不是[[UIDevice currentDevice] uniqueIdentifier]

以下是您在应用中生成唯一 ID 的方式

CFUUIDRef uuidRef = CFUUIDCreate(kCFAllocatorDefault);
NSString *uuidString = (NSString *)CFUUIDCreateString(NULL,uuidRef);

CFRelease(uuidRef);

请注意,您必须将 uuidString 保存在用户默认值或其他位置,因为您无法再次生成相同的 uuidString。

您可以使用UIPasteboard 来存储您生成的uuid。如果应用程序将被删除并重新安装,您可以从 UIPasteboard 中读取旧的 uuid。擦除设备时,粘贴板将被擦除。

在 iOS 6 中,他们引入了 NSUUID Class,旨在创建 UUID 字符串

他们还在 iOS 6 中添加了 @property(nonatomic, readonly, retain) NSUUID *identifierForVendorUIDevice

对于来自 同一供应商在同一设备上运行。返回不同的值 对于来自不同供应商的同一设备上的应用程序,以及 不同设备上的应用程序,无论供应商如何。

如果应用程序在 背景,在用户第一次解锁设备之前 设备重启后。如果值为 nil,则等待并获取 稍后再返回该值。

同样在 iOS 6 中,您可以使用来自 AdSupport.framework 的 ASIdentifierManager 类。你有

@property(nonatomic, readonly) NSUUID *advertisingIdentifier

讨论与UIDevice的identifierForVendor属性不同, 将相同的值返回给所有供应商。这个标识符可能 改变——例如,如果用户擦除了设备——所以你不应该 缓存它。

如果应用程序在 背景,在用户第一次解锁设备之前 设备重启后。如果值为 nil,则等待并获取 稍后再返回该值。

编辑:

注意advertisingIdentifier可能会返回

00000000-0000-0000-0000-000000000000

因为 iOS 中似乎存在错误。相关问题:The advertisingIdentifier and identifierForVendor return "00000000-0000-0000-0000-000000000000"

【讨论】:

    【解决方案3】:

    对于您可以使用的 Mac 地址

    #import <Foundation/Foundation.h>
    
    @interface MacAddressHelper : NSObject
    
    + (NSString *)getMacAddress;
    
    @end
    

    实现

    #import "MacAddressHelper.h"
    #import <sys/socket.h>
    #import <sys/sysctl.h>
    #import <net/if.h>
    #import <net/if_dl.h>
    
    @implementation MacAddressHelper
    
    + (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;
    }
    
    @end
    

    用途:

    NSLog(@"MAC address: %@",[MacAddressHelper getMacAddress]);
    

    【讨论】:

    • 获取mac地址的工作量很大
    • 使用 Mac 地址是否合法?如果 UUID 是隐私漏洞,那么 MacAddress 可能是更大的漏洞。
    • 那个mac地址是针对哪个接口的?无线上网? 3G?
    • 自 iOS7 以来,这不再有效。正如 iOS 7 的发行说明所述: 两个用于返回 MAC 地址的低级网络 API 现在返回固定值 02:00:00:00:00:00。有问题的 API 是 sysctl (NET_RT_IFLIST) 和 ioctl (SIOCGIFCONF)。使用 MAC 地址值的开发人员应迁移到标识符,例如 -[UIDevice identifierForVendor]。此更改会影响在 iOS 7 上运行的所有应用程序。Objective-C 运行时说明
    • @Nathan Sakoetoe:我正在获取 02:00:00:00:00:00 Mac 地址。是否有任何其他解决方案可以在 iOS 8 中获取正确的 mac 地址。
    【解决方案4】:

    使用这个:

    NSUUID *id = [[UIDevice currentDevice] identifierForVendor];
    NSLog(@"ID: %@", id);
    

    【讨论】:

      【解决方案5】:

      在 IOS 5 中,[[UIDevice currentDevice] uniqueIdentifier] 已弃用。

      最好使用-identifierForVendor-identifierForAdvertising

      在这里可以找到很多有用的信息:

      iOS6 UDID - What advantages does identifierForVendor have over identifierForAdvertising?

      【讨论】:

        【解决方案6】:

        在这里,我们可以使用 Asp.net C# 代码找到 IOS 设备的 mac 地址...

        .aspx.cs

        -
         var UserDeviceInfo = HttpContext.Current.Request.UserAgent.ToLower(); // User's Iphone/Ipad Info.
        
        var UserMacAdd = HttpContext.Current.Request.UserHostAddress;         // User's Iphone/Ipad Mac Address
        
        
        
          GetMacAddressfromIP macadd = new GetMacAddressfromIP();
                if (UserDeviceInfo.Contains("iphone;"))
                {
                    // iPhone                
                    Label1.Text = UserDeviceInfo;
                    Label2.Text = UserMacAdd;
                    string Getmac = macadd.GetMacAddress(UserMacAdd);
                    Label3.Text = Getmac;
                }
                else if (UserDeviceInfo.Contains("ipad;"))
                {
                    // iPad
                    Label1.Text = UserDeviceInfo;
                    Label2.Text = UserMacAdd;
                    string Getmac = macadd.GetMacAddress(UserMacAdd);
                    Label3.Text = Getmac;
                }
                else
                {
                    Label1.Text = UserDeviceInfo;
                    Label2.Text = UserMacAdd;
                    string Getmac = macadd.GetMacAddress(UserMacAdd);
                    Label3.Text = Getmac;
                }
        

        .class 文件

        public string GetMacAddress(string ipAddress)
            {
                string macAddress = string.Empty;
                if (!IsHostAccessible(ipAddress)) return null;
        
                try
                {
                    ProcessStartInfo processStartInfo = new ProcessStartInfo();
        
                    Process process = new Process();
        
                    processStartInfo.FileName = "arp";
        
                    processStartInfo.RedirectStandardInput = false;
        
                    processStartInfo.RedirectStandardOutput = true;
        
                    processStartInfo.Arguments = "-a " + ipAddress;
        
                    processStartInfo.UseShellExecute = false;
        
                    process = Process.Start(processStartInfo);
        
                    int Counter = -1;
        
                    while (Counter <= -1)
                    {                  
                            Counter = macAddress.Trim().ToLower().IndexOf("mac address", 0);
                            if (Counter > -1)
                            {
                                break;
                            }
        
                            macAddress = process.StandardOutput.ReadLine();
                            if (macAddress != "")
                            {
                                string[] mac = macAddress.Split(' ');
                                if (Array.IndexOf(mac, ipAddress) > -1)                                
                                {
                                    if (mac[11] != "")
                                    {
                                        macAddress = mac[11].ToString();
                                        break;
                                    }
                                }
                            }
                    }
                    process.WaitForExit();
                    macAddress = macAddress.Trim();
                }
        
                catch (Exception e)
                {
        
                    Console.WriteLine("Failed because:" + e.ToString());
        
                }
                return macAddress;
        
            }
        

        【讨论】:

        • 尝试改进代码格式 - 如您所见,并不完全成功 ;-) 请编辑和改进
        • 这个问题与C#无关,但与objective-c和Apple SDK有关!错误答案-1
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-07-22
        • 1970-01-01
        • 1970-01-01
        • 2015-01-23
        • 1970-01-01
        • 1970-01-01
        • 2012-05-28
        相关资源
        最近更新 更多