Contents
  1. 1. 获取设备的信息
  2. 2. 获取设备的唯一标示符
    1. 2.1. UDID (Unique Device Identifier)
    2. 2.2. UUID(Universally Unique Identifier)
    3. 2.3. IDFA(identifierForIdentifier)
    4. 2.4. IDFV(identifierForVendor)
  3. 3. 获取当前屏幕分辨率的信息
  4. 4. 获取运营商的信息
  5. 5. 获取电池的相关信息
  6. 6. 获取设备型号
  7. 7. 获取设备IP
  8. 8. 获取应用的PList信息
  9. 9. 获取UA信息

有些时候我们需要动态获取移动设备的一些信息,大多数情况官方都有对应的方法直接获取,但是也有一些是官方没有直接提供获取方法的,如设备型号、设备IP等。但是我们可以可以调用私有方法实现。

获取设备的信息

1
2
3
4
5
NSString *name = [[UIDevice currentDevice] name];
NSString *model = [[UIDevice currentDevice] model];
NSString *localizedModel = [[UIDevice currentDevice] localizedModel];
NSString *systemName = [[UIDevice currentDevice] systemName];
NSString *systemVersion = [[UIDevice currentDevice] systemVersion];

获取设备的唯一标示符

UDID (Unique Device Identifier)

UDID的全称是Unique Device Identifier,顾名思义,它就是苹果IOS设备的唯一识别码。

它由40个字符的字母和数字组成,在很多需要限制一台设备一个账号的应用中经常会用到。在iOS5之前可以获取到设备的UDID,后来被苹果禁止了。

UUID(Universally Unique Identifier)

UUID是Universally Unique Identifier的缩写,中文意思是通用唯一识别码。

它是让分布式系统中的所有元素,都能有唯一的辨识资讯,而不需要透过中央控制端来做辨识资讯的指定。这样,每个人都可以建立不与其它人冲突的UUID。在此情况下,就不需考虑数据库建立时的名称重复问题。苹果公司建议使用UUID为应用生成唯一标识字符串。

开发者可以在应用第一次启动时调用一次,然后将该串存储起来,替代UDID来使用。但是,如果用户删除该应用再次安装时,又会生成新的字符串,所以不能保证唯一识别该设备。使用UUID,就要考虑应用被删除后再重新安装时的处理。一个解决的办法是:UUID一般只生成一次,保存在iOS系统里面,如果应用删除了,重装应用之后它的UUID还是一样的,除非系统重置 。但是不能保证在以后的系统升级后还能用(如果系统保存了该信息就能用)。

1
NSString *uuid = [[NSUUID UUID] UUIDString]

IDFA(identifierForIdentifier)

广告标示符,适用于对外,例如广告推广,换量等跨应用的用户追踪等。

是iOS 6中另外一个新的方法,提供了一个方法advertisingIdentifier,通过调用该方法会返回一个NSUUID实例,最后可以获得一个UUID,由系统存储着的。不过即使这是由系统存储的,但是有几种情况下,会重新生成广告标示符。

重置:设置 -> 通用 -> 还原 -> 还原位置与隐私
重置:设置 -> 隐私 -> 广告 -> 还原广告标示符
关闭:设置 -> 隐私 -> 广告 -> 限制广告追踪

在同一个设备上的所有App都会取到相同的值,是苹果专门给各广告提供商用来追踪用户而设的,用户可以重置或限制此idfa的使用,故此idfa有可能会取不到值。但好在Apple默认是允许追踪的,而且一般用户都不知道有这么个设置,所以基本上用来监测推广效果,是戳戳有余了。

1
NSString *idfa = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];

IDFV(identifierForVendor)

Vindor标示符,适用于对内:例如分析用户在应用内的行为等。

是给Vendor标识用户用的,每个设备在所属同一个Vender的应用里,都有相同的值。其中的Vender是指应用提供商,但准确点说,是通过BundleID的DNS反转的前两部分进行匹配,如果相同就是同一个Vender,例如对于com.somecompany.appone,com.somecompany.apptwo这两个BundleID来说,就属于同一个Vender,共享同一个idfv的值。和idfa不同的是,idfv的值是一定能取到的,所以非常适合于作为内部用户行为分析的主id,来标识用户,替代OpenUDID。

注意:如果用户将属于此Vender的所有App卸载,则idfv的值会被重置,即再重装此Vender的App,idfv的值和之前不同。

1
NSString *idfv = [[[UIDevice currentDevice] identifierForVendor] UUIDString];

获取当前屏幕分辨率的信息

1
2
3
4
CGRect rect = [[UIScreen mainScreen] bounds];
CGFloat scale = [[UIScreen mainScreen].scale];
CGFloat width = rect.size.width * scale;
CGFloat height = rect.size.height * scale;

获取运营商的信息

需要先导入头文件

1
2
#import <CoreTelephony/CTCarrier.h>
#import <CoreTelephony/CTTelephonyNetworkInfo.h>

创建对象(iOS7+)

1
CCTelephonyNetworkInfo *info = [[CTTelephonyNetworkInfo alloc] init];

获取运行商的名称

1
2
CTCarrier *carrier = [info subscriberCellularProvider];
NSString *mCarrier = [NSString stringWithFormat:@"%@",[carrier carrierName]];

获取当前网络的类型

1
NSString *mConnectType = [[NSString alloc] initWithFormat:@"%@",info.currentRadioAccessTechnology];

类型有以下:

1
2
3
4
5
6
7
8
9
10
11
CTRadioAccessTechnologyGPRS //2G
CTRadioAccessTechnologyEdge //2G
CTRadioAccessTechnologyWCDMA
CTRadioAccessTechnologyHSDPA
CTRadioAccessTechnologyHSUPA
CTRadioAccessTechnologyCDMA1x //2G
CTRadioAccessTechnologyCDMAEVDORev0
CTRadioAccessTechnologyCDMAEVDORevA
CTRadioAccessTechnologyCDMAEVDORevB
CTRadioAccessTechnologyeHRPD
CTRadioAccessTechnologyLTE //4G

ios7之前的话apple给我们提供了Reachability来获取。
首先要导入SystemConfiguration.framework,把下载下来的Reachability.hReachability.m加进项目中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Reachability *reach = [Reachability reachabilityWithHostName:@"www.apple.com"];
switch([reach currentReachabilityStatus])
{
case NotReachable: //没有连接上
//do something
break;
case ReachableViaWiFi: //通过wifi连接
//do something
break;
case ReachableViaWWAN: //通过GPRS连接
//do something
break;
default: <span style="white-space:pre"> </span>//未知情况
//do something
break;
}

注意:通常CoreTelephonyReachability结合使用,使用嵌套switch来判断2G3G4GWifi

获取电池的相关信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
//获取电池当前的状态,共有4种状态
-(NSString*) getBatteryState {
UIDevice *device = [UIDevice currentDevice];
if (device.batteryState == UIDeviceBatteryStateUnknown) {
return @"UnKnow";
}else if (device.batteryState == UIDeviceBatteryStateUnplugged){
return @"Unplugged";
}else if (device.batteryState == UIDeviceBatteryStateCharging){
return @"Charging";
}else if (device.batteryState == UIDeviceBatteryStateFull){
return @"Full";
}
return nil;
}
//获取电量的等级,0.00~1.00
-(float) getBatteryLevel {
return [UIDevice currentDevice].batteryLevel;
}
-(void) getBatteryInfo
{
NSString \*state = getBatteryState();
float level = getBatteryLevel()*100.0;
//yourControlFunc(state, level); //写自己要实现的获取电量信息后怎么处理
}
//打开对电量和电池状态的监控,类似定时器的功能
-(void) didLoad
{
[[UIDevice currentDevice] setBatteryMonitoringEnable:YES];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(getBatteryInfo:) name:UIDeviceBatteryStateDidChangeNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(getBatteryInfo:) name:UIDeviceBatteryLevelDidChangeNotification object:nil];
[NSTimer scheduledTimerWithTimeInterval:0.5f target:self selector:@selector(getBatteryInfo:) userInfo:nil repeats:YES];
}

获取设备型号

因Apple官方没有直接获取设备型号的API,故只能使用以下私有方法获取。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
- (NSString*)deviceString
{
// 需要#import "sys/utsname.h"
struct utsname systemInfo;
uname(&systemInfo);
NSString *deviceString = [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];
//iPhone
if ([deviceString isEqualToString:@"iPhone1,1"]) return @"iPhone 2G (A1203)";
if ([deviceString isEqualToString:@"iPhone1,2"]) return @"iPhone 3G (A1241/A1324)";
if ([deviceString isEqualToString:@"iPhone2,1"]) return @"iPhone 3GS (A1303/A1325)";
if ([deviceString isEqualToString:@"iPhone3,1"]) return @"iPhone 4 (A1332)";
if ([deviceString isEqualToString:@"iPhone3,2"]) return @"iPhone 4 (A1332)";
if ([deviceString isEqualToString:@"iPhone3,3"]) return @"iPhone 4 (A1349)";
if ([deviceString isEqualToString:@"iPhone4,1"]) return @"iPhone 4S (A1387/A1431)";
if ([deviceString isEqualToString:@"iPhone5,1"]) return @"iPhone 5 (A1428)";
if ([deviceString isEqualToString:@"iPhone5,2"]) return @"iPhone 5 (A1429/A1442)";
if ([deviceString isEqualToString:@"iPhone5,3"]) return @"iPhone 5c (A1456/A1532)";
if ([deviceString isEqualToString:@"iPhone5,4"]) return @"iPhone 5c (A1507/A1516/A1526/A1529)";
if ([deviceString isEqualToString:@"iPhone6,1"]) return @"iPhone 5s (A1453/A1533)";
if ([deviceString isEqualToString:@"iPhone6,2"]) return @"iPhone 5s (A1457/A1518/A1528/A1530)";
if ([deviceString isEqualToString:@"iPhone7,1"]) return @"iPhone 6 Plus (A1522/A1524)";
if ([deviceString isEqualToString:@"iPhone7,2"]) return @"iPhone 6 (A1549/A1586)";
if ([deviceString isEqualToString:@"iPhone8,1"]) return @"iPhone 6S";
if ([deviceString isEqualToString:@"iPhone8,2"]) return @"iPhone 6S Plus";
if ([deviceString isEqualToString:@"iPhone8,4"]) return @"iPhone SE";
if ([deviceString isEqualToString:@"iPhone9,1"]) return @"iPhone 7";
if ([deviceString isEqualToString:@"iPhone9,2"]) return @"iPhone 7 Plus";
//iPod
if ([deviceString isEqualToString:@"iPod1,1"]) return @"iPod Touch 1G (A1213)";
if ([deviceString isEqualToString:@"iPod2,1"]) return @"iPod Touch 2G (A1288)";
if ([deviceString isEqualToString:@"iPod3,1"]) return @"iPod Touch 3G (A1318)";
if ([deviceString isEqualToString:@"iPod4,1"]) return @"iPod Touch 4G (A1367)";
if ([deviceString isEqualToString:@"iPod5,1"]) return @"iPod Touch 5G (A1421/A1509)";
if ([deviceString isEqualToString:@"iPod7,1"]) return @"iPod Touch 6G";
//iPad
if ([deviceString isEqualToString:@"iPad1,1"]) return @"iPad 1G (A1219/A1337)";
if ([deviceString isEqualToString:@"iPad2,1"]) return @"iPad 2 (A1395)";
if ([deviceString isEqualToString:@"iPad2,2"]) return @"iPad 2 (A1396)";
if ([deviceString isEqualToString:@"iPad2,3"]) return @"iPad 2 (A1397)";
if ([deviceString isEqualToString:@"iPad2,4"]) return @"iPad 2 (A1395+New Chip)";
if ([deviceString isEqualToString:@"iPad2,5"]) return @"iPad Mini 1G (A1432)";
if ([deviceString isEqualToString:@"iPad2,6"]) return @"iPad Mini 1G (A1454)";
if ([deviceString isEqualToString:@"iPad2,7"]) return @"iPad Mini 1G (A1455)";
if ([deviceString isEqualToString:@"iPad3,1"]) return @"iPad 3 (A1416)";
if ([deviceString isEqualToString:@"iPad3,2"]) return @"iPad 3 (A1403)";
if ([deviceString isEqualToString:@"iPad3,3"]) return @"iPad 3 (A1430)";
if ([deviceString isEqualToString:@"iPad3,4"]) return @"iPad 4 (A1458)";
if ([deviceString isEqualToString:@"iPad3,5"]) return @"iPad 4 (A1459)";
if ([deviceString isEqualToString:@"iPad3,6"]) return @"iPad 4 (A1460)";
if ([deviceString isEqualToString:@"iPad4,1"]) return @"iPad Air (A1474)";
if ([deviceString isEqualToString:@"iPad4,2"]) return @"iPad Air (A1475)";
if ([deviceString isEqualToString:@"iPad4,3"]) return @"iPad Air (A1476)";
if ([deviceString isEqualToString:@"iPad4,4"]) return @"iPad Mini 2G (A1489)";
if ([deviceString isEqualToString:@"iPad4,5"]) return @"iPad Mini 2G (A1490)";
if ([deviceString isEqualToString:@"iPad4,6"]) return @"iPad Mini 2G (A1491)";
if ([deviceString isEqualToString:@"iPad4,7"]) return @"iPad Mini 3G";
if ([deviceString isEqualToString:@"iPad4,8"]) return @"iPad Mini 3G";
if ([deviceString isEqualToString:@"iPad4,9"]) return @"iPad Mini 3G";
if ([deviceString isEqualToString:@"iPad5,1"]) return @"iPad Mini 4G";
if ([deviceString isEqualToString:@"iPad5,2"]) return @"iPad Mini 4G";
if ([deviceString isEqualToString:@"iPad6,3"]) return @"iPad Pro";
if ([deviceString isEqualToString:@"iPad6,4"]) return @"iPad Pro";
if ([deviceString isEqualToString:@"iPad6,7"]) return @"iPad Pro";
if ([deviceString isEqualToString:@"iPad6,8"]) return @"iPad Pro";
//Simulator
if ([deviceString isEqualToString:@"i386"]) return @"iPhone Simulator";
if ([deviceString isEqualToString:@"x86_64"]) return @"iPhone Simulator";
return deviceString;
}

获取设备IP

获取外网IP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
+(NSString *)deviceWANIPAdress{
NSError *error;
NSURL *ipURL = [NSURL URLWithString:@"http://pv.sohu.com/cityjson?ie=utf-8"];
NSMutableString *ip = [NSMutableString stringWithContentsOfURL:ipURL encoding:NSUTF8StringEncoding error:&error];
if ([ip hasPrefix:@"var returnCitySN = "]) {
NSRange range = NSMakeRange(0, 19);
[ip deleteCharactersInRange:range];
NSString * nowIp =[ip substringToIndex:ip.length-1];
NSData * data = [nowIp dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary * dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
return dict[@"cip"];
}
return nil;
}

上述获取外网IP的方法较复杂,简洁方法实现

1
2
3
4
5
+(NSString *)deviceWANIPAdress{
NSError *error;
NSURL *ipURL = [NSURL URLWithString:@"http://ifconfig.me/ip"];
return [NSMutableString stringWithContentsOfURL:ipURL encoding:NSUTF8StringEncoding error:&error];
}

获取内网IP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
//导入头文件
#import <sys/socket.h>
#import <sys/sockio.h>
#import <sys/ioctl.h>
#import <net/if.h>
#import <arpa/inet.h>
//私有方法
- (NSString *)getDeviceIPAddress {
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0) return nil;
NSMutableArray *ips = [NSMutableArray array];
int BUFFERSIZE = 4096;
struct ifconf ifc;
char buffer[BUFFERSIZE], *ptr, lastname[IFNAMSIZ], *cptr;
struct ifreq *ifr, ifrcopy;
ifc.ifc_len = BUFFERSIZE;
ifc.ifc_buf = buffer;
if (ioctl(sockfd, SIOCGIFCONF, &ifc) >= 0){
for (ptr = buffer; ptr < buffer + ifc.ifc_len; ){
ifr = (struct ifreq *)ptr;
int len = sizeof(struct sockaddr);
if (ifr->ifr_addr.sa_len > len) {
len = ifr->ifr_addr.sa_len;
}
ptr += sizeof(ifr->ifr_name) + len;
if (ifr->ifr_addr.sa_family != AF_INET) continue;
if ((cptr = (char *)strchr(ifr->ifr_name, ':')) != NULL) *cptr = 0;
if (strncmp(lastname, ifr->ifr_name, IFNAMSIZ) == 0) continue;
memcpy(lastname, ifr->ifr_name, IFNAMSIZ);
ifrcopy = *ifr;
ioctl(sockfd, SIOCGIFFLAGS, &ifrcopy);
if ((ifrcopy.ifr_flags & IFF_UP) == 0) continue;
NSString *ip = [NSString stringWithFormat:@"%s",inet_ntoa(((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr)];
[ips addObject:ip];
}
}
close(sockfd);
NSString *deviceIP = @"";
for (int i=0; i < ips.count; i++) {
if (ips.count > 0) {
deviceIP = [NSString stringWithFormat:@"%@",ips.lastObject];
}
}
return deviceIP;
}

获取应用的PList信息

1
2
NSString *bundleId = [[NSBundle mainBundle] bundleIdentifier]
NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary]

可以根据infoDictionary的key值使用下面方法获取对应的信息

1
- (nullable id)objectForInfoDictionaryKey:(NSString *)key;

获取UA信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
- (NSString *)createHttpRequest {
self.webView = [[UIWebView alloc] init];
self.webView.delegate = self;
[self.webView loadRequest:[NSURLRequest requestWithURL: [NSURL URLWithString:@"http://www.eoe.cn"]]];
return [self userAgentString];
}
-(NSString *)userAgentString {
while (self.userAgent == nil) {
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}
return self.userAgent;
}
-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
if (webView == self.webView) {
self.userAgent = [request valueForHTTPHeaderField:@"User-Agent"];
return NO;
}
return YES;
}
Contents
  1. 1. 获取设备的信息
  2. 2. 获取设备的唯一标示符
    1. 2.1. UDID (Unique Device Identifier)
    2. 2.2. UUID(Universally Unique Identifier)
    3. 2.3. IDFA(identifierForIdentifier)
    4. 2.4. IDFV(identifierForVendor)
  3. 3. 获取当前屏幕分辨率的信息
  4. 4. 获取运营商的信息
  5. 5. 获取电池的相关信息
  6. 6. 获取设备型号
  7. 7. 获取设备IP
  8. 8. 获取应用的PList信息
  9. 9. 获取UA信息