UIDevice

  • iOS 的 APP 应用开发的过程中,有时为了 bug 跟踪或者获取用反馈的需要自动收集用户设备、系统信息、应用信息等等,这些信息方便开发者诊断问题,当然这些信息是用户的非隐私信息,是通过开发 api 可以获取到的。那么通过那些 api 可以获取这些信息呢,iOS 的 SDK 中提供了 UIDevice,NSBundle,NSLocale。
  • UIDevice 提供了多种属性、类函数及状态通知,帮助我们全方位了解设备状况。从检测电池电量到定位设备与临近感应,UIDevice 所做的工作就是为应用程序提供用户及设备的一些信息。UIDevice 类还能够收集关于设备的各种具体细节,例如机型及 iOS 版本等。其中大部分属性都对开发工作具有积极的辅助作用。
  • bundle 是一个目录,其中包含了程序会使用到的资源。这些资源包含了如图像、声音、编译好的代码、nib 文件(用户也会把 bundle 称为 plug-in),对应 bundle,cocoa 提供了类 NSBundle。一个应用程序看上去和其他文件没有什么区别. 但是实际上它是一个包含了 nib 文件,编译代码,以及其他资源的目录。我们把这个目录叫做程序的 main bundle。通过这个路径可以获取到应用的信息,例如应用名、版本号等。
  • NSLocale 可以获取用户的本地化信息设置,例如货币类型,国家,语言,数字,日期格式的格式化,提供正确的地理位置显示等等。下面的代码获取机器当前语言和国家代码。

1、设备相关信息的获取

  • 1.1 设备基本信息

// 获取当前设备
UIDevice *device = [UIDevice currentDevice];

// 获取设备名称
/*
e.g. "My iPhone"
*/
NSString *name = device.name;

// 获取设备类型
/*
e.g. @"iPhone", @"iPod touch"
*/
NSString *model = device.model;

// 获取本地化设备类型
/*
localized version of model
*/
NSString *localizedModel = device.localizedModel;

// 获取设备系统名称
/*
e.g. @"iOS"
*/
NSString *systemName = device.systemName;

// 获取设备系统版本
/*
e.g. @"4.0"
*/
NSString *systemVersion = device.systemVersion;

// 获取设备 UUID
/*
可用于唯一标识该设备,同一供应商不同应用具有相同的 UUID
*/
NSUUID *identifierForVendor = device.identifierForVendor;
NSString *UUID = identifierForVendor.UUIDString;
  • 1.2 设备方向

// 判断设备是否生成设备转向通知
BOOL generatesDeviceOrientationNotifications = device.isGeneratingDeviceOrientationNotifications;

// 开启设备转向通知
/*
通过调用该方法通知设备:如果用户改变了设备的朝向,我们想获悉这一点
在注册设备方向通知时,需要先调用该方法
*/
[device beginGeneratingDeviceOrientationNotifications];

// 停止设备转向通知
/*
在移除设备方向通知后,需要调用该方法
*/
[device endGeneratingDeviceOrientationNotifications];

// 注册屏幕方向变化通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deviceOrientationDidChange)
         name:@"UIDeviceOrientationDidChangeNotification"
       object:nil];

// 获取设备方向
/*
UIDeviceOrientationUnknown,
UIDeviceOrientationPortrait,            // home button on the bottom    竖向,头向上
UIDeviceOrientationPortraitUpsideDown,  // home button on the top       竖向,头向下
UIDeviceOrientationLandscapeLeft,       // home button on the right     横向,头向左
UIDeviceOrientationLandscapeRight,      // home button on the left      横向,头向右
UIDeviceOrientationFaceUp,              // face up                      平放,屏幕朝上
UIDeviceOrientationFaceDown             // face down                    平放,屏幕朝下

除非正在生成设备方向的通知,否则返回 UIDeviceOrientationUnknown
*/
UIDeviceOrientation orientation = [UIDevice currentDevice].orientation;
  • 1.3 设备电池监控

// 判断设备是否开启电池监控
/*
default is NO
*/
BOOL batteryMonitoringEnabled = device.isBatteryMonitoringEnabled;

// 开启电池监控
/*
default is NO
*/
device.batteryMonitoringEnabled = YES;

// 获取设备电池状态
/*
UIDeviceBatteryStateUnknown,
UIDeviceBatteryStateUnplugged,   // on battery, discharging      未充电
UIDeviceBatteryStateCharging,    // plugged in, less than 100%   正在充电
UIDeviceBatteryStateFull,        // plugged in, at 100%          满电

如果禁用电池监控,则电池状态为 UIDeviceBatteryStateUnknown
*/
UIDeviceBatteryState batteryState = device.batteryState;

// 注册电池状态变化通知
[[NSNotificationCenter defaultCenter] addObserver:self
     selector:@selector(deviceBatteryStateDidChange)
         name:@"UIDeviceBatteryStateDidChangeNotification"
       object:nil];

// 获取电池电量
/*
0 .. 1.0. 如果电池状态为 UIDeviceBatteryStateUnknown,百分比为 -1.0
*/
float batteryLevel = device.batteryLevel;

// 注册电池电量变化通知
[[NSNotificationCenter defaultCenter] addObserver:self
     selector:@selector(deviceBatteryLevelDidChange)
         name:@"UIDeviceBatteryLevelDidChangeNotification"
       object:nil];
  • 1.4 设备接近状态监控

// 判断设备是否开启接近状态监控
/*
default is NO
*/
BOOL proximityMonitoringEnabled = device.isProximityMonitoringEnabled;

// 开启接近状态监控
/*
default is NO
*/
device.proximityMonitoringEnabled = YES;

// 获取接近状态
/*
如果设备不具备接近感应器,则总是返回 NO
*/
BOOL proximityState = device.proximityState;

// 注册接近状态变化通知

[[NSNotificationCenter defaultCenter] addObserver:self
     selector:@selector(deviceProximityStateDidChange)
         name:@"UIDeviceProximityStateDidChangeNotification"
       object:nil];
  • 1.5 设备性能

// 判断设备是否支持多任务
BOOL multitaskingSupported = device.multitaskingSupported;
  • 1.6 设备操作

// 获取用户界面模式
/*
UIUserInterfaceIdiomUnspecified = -1,
UIUserInterfaceIdiomPhone   // iPhone and iPod touch style UI    iPhone 和 iPod touch 风格
UIUserInterfaceIdiomPad     // iPad style UI                     iPad 风格
UIUserInterfaceIdiomTV      // Apple TV style UI                 Apple TV 风格
UIUserInterfaceIdiomCarPlay // CarPlay style UI                  CarPlay 风格
*/
UIUserInterfaceIdiom userInterfaceIdiom = device.userInterfaceIdiom;

// 播放一个输入的声音
[device playInputClick];

// UIInputViewAudioFeedback 协议方法
/*
实现该方法,返回 YES 则自定义的视图能够播放输入的声音
*/
- (BOOL)enableInputClicksWhenVisible {

    return YES;
}

2、App 应用相关信息的获取

NSDictionary *dicInfo = [[NSBundle mainBundle] infoDictionary];
CFShow((__bridge CFTypeRef)(dicInfo));

// App 应用名称
NSString *appName = [dicInfo objectForKey:@"CFBundleName"];

// App 应用版本
NSString *appVersion = [dicInfo objectForKey:@"CFBundleShortVersionString"];

// App 应用 Build 版本
NSString *appBuild = [dicInfo objectForKey:@"CFBundleVersion"];

3、用户的本地化信息的获取

  • NSLocale

// 语言 en
NSString *language = [[NSLocale preferredLanguages] objectAtIndex:0];

// 国家 en_US
NSString *country = [[NSLocale currentLocale] localeIdentifier];

4、获取设备唯一标识

  • iOS系统中,获取设备唯一标识的方法有很多:

    • 1、UDID:UDID 的全称是 Unique Device Identifier Description,顾名思义,它就是苹果 iOS 设备的唯一识别码。

      • UDID 是由子母和数字组成的 40 个字符串的序号,用来区别每一个唯一的 iOS 设备,包括 iPhones, iPads, 以及 iPod touches,这些编码看起来是随机的,实际上是跟硬件设备特点相联系的。
      • UDID 可以关联其它各种数据到相关设备上。例如,连接到开发者账号,可以允许在发布前让设备安装或测试应用;也可以让开发者获得 iOS 测试版进行体验。苹果用 UDID 连接到苹果的 ID,这些设备可以自动下载和安装从 App Store 购买的应用、保存从 iTunes 购买的音乐、帮助苹果发送推送通知、即时消息。 在 iOS 应用早期,UDID 被第三方应用开发者和网络广告商用来收集用户数据,可以用来关联地址、记录应用使用习惯,以便推送精准广告。
    • 2、OPEN UDID
      • iOS 2.0 版本以后 UIDevice 提供一个获取设备唯一标识符的方法 uniqueIdentifier,通过该方法我们可以获取设备的序列号,这个也是目前为止唯一可以确认唯一的标示符。许多开发者把 UDID 跟用户的真实姓名、密码、住址、其它数据关联起来;网络窥探者会从多个应用收集这些数据,然后顺藤摸瓜得到这个人的许多隐私数据。同时大部分应用确实在频繁传输 UDID 和私人信息。 为了避免集体诉讼,苹果最终决定在 iOS 5 的时候,将这一惯例废除,开发者被引导生成一个唯一的标识符,只能检测应用程序,其他的信息不提供。现在应用试图获取 UDID 已被禁止且不允许上架。所以这个方法作废。
    • 3、UUID:UUID 是 Universally Unique Identifier 的缩写,中文意思是通用唯一识别码.
      • 我们可以获取到 UUID,然后把 UUID 保存到 KeyChain 里面。这样以后即使 App 删了再装回来,也可以从 KeyChain 中读取回来。使用 group 还可以可以保证同一个开发商的所有程序针对同一台设备能够获取到相同的不变的 UDID。但是刷机或重装系统后 UDID 还是会改变。
    • 4、MAC Address
      • 使用 WiFi 的 mac 地址来取代已经废弃了的 uniqueIdentifier 方法。
      • 然而在 iOS 7 中苹果再一次无情的封杀 mac 地址,使用之前的方法获取到的 mac 地址全部都变成了 02:00:00:00:00:00。
    • 5、IDFA:广告标示符(IDFA-identifierForIdentifier),iOS6.0 及以后
      • 全名 advertisingIdentifier。直译就是广告 id, 在同一个设备上的所有 App 都会取到相同的值,是苹果专门给各广告提供商用来追踪用户而设的,用户可以在 设置|隐私|广告追踪 里重置此id的值,或限制此 id 的使用,故此 id 有可能会取不到值,但好在 Apple 默认是允许追踪的,而且一般用户都不知道有这么个设置,所以基本上用来监测推广效果,是戳戳有余了。由于 IDFA 会出现取不到的情况,故绝不可以作为业务分析的主 id,来识别用户。
      • 获取代码:
      #import <AdSupport/AdSupport.h>
      NSString *adId = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
    • 从 17 年 2 月初开始,Apple 开始拒绝采集 IDFA(identifier for advertising)而未集成任何广告服务的应用进入 AppStore。
    • 6、IDFV:应用提供商标示符(IDFV-identifierForVendor),iOS6.0 及以后
      • 全名 identifierForVendor。顾名思义,是给 Vendor 标识用户用的,每个设备在所属同一个 Vender 的应用里,都有相同的值。其中的 Vender 是指应用提供商,但准确点说,是通过 BundleID 的反转的前两部分进行匹配,如果相同就是同一个 Vender,例如对于 com.taobao.app1, com.taobao.app2 这两个 BundleID 来说,就属于同一个 Vender,共享同一个 idfv 的值。和 IDFA 不同的是,IDFV 的值是一定能取到的,所以非常适合于作为内部用户行为分析的主 id,来标识用户,替代 OpenUDID。如果用户将属于此 Vender 的所有 App 卸载,则 IDFV 的值会被重置,即再重装此 Vender 的 App,IDFV 的值和之前不同。
      • 获取代码:
      NSString *idfv = [[[UIDevice currentDevice] identifierForVendor] UUIDString]; 
      • 上面所有这些表示设备唯一的标识,在 iOS 7 中要么被禁止使用,要么重新安装程序后两次获取的标识符不一样。由于 iOS 系统存储的数据都是在 sandBox 里面,一旦删除 App,sandBox 也不复存在。
    • iOS 中获取设备唯一标示符的方法一直随版本的更新而变化。iOS 2.0 版本以后 UIDevice 提供一个获取设备唯一标识符的方法 uniqueIdentifier,通过该方法我们可以获取设备的序列号,这个也是目前为止唯一可以确认唯一的标示符。好景不长,因为该唯一标识符与手机一一对应,苹果觉得可能会泄露用户隐私,所以在 iOS 5.0 之后该方法就被废弃掉了;iOS 6.0 系统新增了两个用于替换 uniqueIdentifier 的接口,分别是:identifierForVendor,advertisingIdentifier,但这两个接口会在应用重新安装时改变数值,并不是唯一的标示符,所以开发者改为使用 WiFi 的 mac 地址来取代;iOS 7 中苹果又封杀 mac 地址,所以开发者再次改变思路使用 KeyChain 来保存获取到的 UDID,这样以后即使 App 删了再装回来,也可以从 KeyChain 中读取回来。
    • 首先保存设备的 UUID,可以使用类方法 + (id)UUID 是一个类方法,调用该方法可以获得一个 UUID。通过下面的代码可以获得一个 UUID 字符串:
    NSString *uuid = [[NSUUID UUID] UUIDString];
    • 也可以保存在 iOS 6 中新增的 Vindor 标示符 (IDFV-identifierForVendor),获取这个 IDFV 的新方法被添加在已有的 UIDevice 类中。跟 advertisingIdentifier 一样,该方法返回的是一个 NSUUID 对象。
    NSString *idfv = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
    • 如果用户卸载了同一个 vendor 对应的所有程序,然后在重新安装同一个 vendor 提供的程序,此时 identifierForVendor 会被重置,所以这里要用到 KeyChain 来保存。KeyChain(钥匙串)是使用苹果设备经常使用的,通常要调试的话,都得安装证书之类的,这些证书就是保存在 KeyChain 中,还有我们平时浏览网页记录的账号密码也都是记录在 KeyChain 中。iOS 中的 KeyChain 相比 OS X 比较简单,整个系统只有一个 KeyChain,每个程序都可以往 KeyChain 中记录数据,而且只能读取到自己程序记录在 KeyChain 中的数据。iOS 中 Security.framework 框架提供了四个主要的方法来操作 KeyChain:
    // 查询 OSStatus
    SecItemCopyMatching(CFDictionaryRef query, CFTypeRef *result);
    
    // 添加 OSStatus
    SecItemAdd(CFDictionaryRef attributes, CFTypeRef *result); 
    
    // 更新 KeyChain 中的 ItemOSStatus
    SecItemUpdate(CFDictionaryRef query, CFDictionaryRef attributesToUpdate);
    
    // 删除 KeyChain 中的 ItemOSStatus
    SecItemDelete(CFDictionaryRef query)
    • 这四个方法参数比较复杂,一旦传错就会导致操作 KeyChain 失败,文档中介绍的比较详细,大家可以查查官方文档。而苹果提供的 KeyChain 使用起来略麻烦,所以这里推荐一个第三方库 SSKeychain/SAMKeychain 对苹果安全框架 API 进行了简单封装,支持对存储在钥匙串中密码、账户进行访问,包括读取、删除和设置。SSKeyChains 使用简单,通过实例代码便可掌握。
    // 保存一个 UUID 字符串到钥匙串:
    CFUUIDRef uuid = CFUUIDCreate(NULL);
    assert(uuid != NULL);
    CFStringRef uuidStr = CFUUIDCreateString(NULL, uuid);
    
    [SSKeychain setPassword:[NSString stringWithFormat:@"%@", uuidStr] forService:@"com.yourapp.yourcompany"account:@"user"];
    
    // 从钥匙串读取 UUID:
    NSString *retrieveuuid = [SSKeychainpasswordForService:@"com.yourapp.yourcompany"account:@"user"];
    
    // 注意: setPassword 和 passwordForSevice 方法中的 services 和 accounts 参数应该是一致的。
    • 基本的实现思路便是这样,下面是具体的一种具体实现代码,仅供参考。
    + (NSString *)getDeviceId {
    
    NSString *currentDeviceUUIDStr = [SSKeychain passwordForService:[NSBundle mainBundle].bundleIdentifier account:@"uuid"];
    
    if (currentDeviceUUIDStr == nil || [currentDeviceUUIDStr isEqualToString:@""]) {
    
    NSUUID *currentDeviceUUID  = [UIDevice currentDevice].identifierForVendor;
    currentDeviceUUIDStr = currentDeviceUUID.UUIDString;
    currentDeviceUUIDStr = [currentDeviceUUIDStr stringByReplacingOccurrencesOfString:@"-" withString:@""];
    currentDeviceUUIDStr = [currentDeviceUUIDStr lowercaseString];
    [SSKeychain setPassword: currentDeviceUUIDStr forService:[NSBundle mainBundle].bundleIdentifier account:@"uuid"];
    }
    return currentDeviceUUIDStr;
    }
    

原文地址:https://www.cnblogs.com/CH520/p/9413504.html

时间: 2024-10-09 18:39:41

UIDevice的相关文章

Android无线测试之—UiAutomator UiDevice API介绍五

屏幕旋转 一.屏幕旋转相关知识: 1)旋转方向:0度,90度(向左转),180度,270度(向右转) 2)重力感应器:重力感应器是旋转所依靠的 3)固定位置:指将屏幕方向固定在0度,90度或者180度等 4)物理旋转:物理旋转与重力感应器关联在一块,关闭物理旋转就是关闭了重力感应器,反之亦然) 二.旋转屏幕相关API: 返回值 方法名 描述 void setOrientationLeft() 通过禁用传感器,然后模拟设备向左转,并且固定位置 void setOrientationNatural(

Apple开发者文档中关于UIApplication/UIScreen/UIDevice的简述

UIApplication/UIScreen/UIDevice平常用的很少:但毕竟是属于UIKit的重要组成部分,有必要了解一下. UIDevice 通过UIDevice可以获取一个描述当前设备的单例.你可以获取以下设备相关的信息:设备名,设备型号,操作系统名称和版本. 我们还可以通过UIDevice实例检测设备的变化,比方横屏还是竖屏.Orientation属性代表了设备的方位,也可以通过注册UIDeviceOrientationDidChangeNotification通知消息来实时获取方位

iOS学习笔记(十三)——获取手机信息(UIDevice、NSBundle、NSLocale)

iOS的APP的应用开发的过程中,有时为了bug跟踪或者获取用反馈的需要自动收集用户设备.系统信息.应用信息等等,这些信息方便开发者诊断问题,当然这些信息是用户的非隐私信息,是通过开发api可以获取到的.那么通过那些api可以获取这些信息呢,iOS的SDK中提供了UIDevice,NSBundle,NSLocale. UIDevice UIDevice提供了多种属性.类函数及状态通知,帮助我们全方位了解设备状况.从检测电池电量到定位设备与临近感应,UIDevice所做的工作就是为应用程序提供用户

Android无线测试之—UiAutomator UiDevice API介绍七

截图与等待空闲 一.截图和等待空闲相关知识: 1)图片缩放比例:例如图片从100像素缩小到50像素 2)图片质量:是指图片大小,质量越高图片越大,质量越低图片越小 3)File类:指的是一个文件或者一个文件夹 4)图片格式:图片截图都采用的PNG格式 5)空闲状态:窗口没有更新就是没有动作,界面处于不动状态 6)窗口更新事件:窗口打开的过程就是一个更新事件,打开后不动了就是空闲状态 二.截图相关API: 返回值 方法名 描述 boolean takeScreenShot(File storePa

Android无线测试之—UiAutomator UiDevice API介绍八

获取包名.开启通知栏.快速设置.获取布局文件的方法 一.包名.通知栏.快速设置.布局文件等相关知识: 1)包名:标示应用的符号,每个应用的名字 2)通知栏:从主界面的顶端向下拉,就可以打开通知栏 3)快速设置:打开通知栏,右上角有个设置,快速设置可以进行设置.无线网络等等 4)布局文件:界面布局的文件,显示界面各个控件元素信息的文件 二.相关API: 返回值 包名 描述 void getCurrentPackageName() 获取当前界面的包名 void dumpWindowHierarchy

Android无线测试之—UiAutomator UiDevice API介绍六

一.灭屏和唤醒屏幕相关知识: 1)灭屏:按电源键将屏幕熄灭 2)唤醒屏幕:在灭屏状态下按电源键唤醒屏幕 二.灭屏与唤屏相关的API: 返回值 方法名 描述 void wakeUp() 模拟按电源键,如果屏幕是唤醒的没有任何作用 void sleep() 模拟按电源键,如果屏幕是关闭的则没有任何作用 boolean isScreenOn() 检查屏幕是否亮屏 三.API应用举例: package com.uiautomatortest; import android.graphics.Point;

IOS UIDevice距离传感器(打开 关闭)

●  什么是传感器 ●  传感器是一种感应\检测装置, 目前已经广泛应用于智能手机上 ●  iPhone5中内置的传感器有 ●  运动传感器\加速度传感器\加速计(Motion/Accelerometer Sensor) ●  环境光传感器(Ambient Light Sensor) ●  距离传感器(Proximity Sensor) ●  磁力计传感器(Magnetometer Sensor) ●  内部温度传感器(Internal Temperature Sensor) ●  湿度传感器(

UIDevice之获取设备信息

UIDevice这个类提供了一个代表当前设备的一个实例.从这个实例中可以获得有关设备如指定名称,信息设备模型,和操作系统名称和版本.UIDevice直接继承自NSObject. UIDevice类可以提供了多种属性.类函数及状态通知,帮助我们全方位了解设备状况.从检测电池电量到定位设备与临近感应,UIDevice所做的工作就是为应用程序提供用户及设备的一些信息. UIDevice类还能够收集关于设备的各种具体细节,例如机型及iOS版本等.其中大部分属性都对开发工作具有积极的辅助作用. 我们可以获

1.UiDevice API 详细介绍

1.UiDevice按键与keycode使用 返回值 方法名 说明 boolean pressBack() 模拟短按返回back键 boolean pressDPadCenter() 模拟按轨迹球中点按键 boolean pressSPadDown() 模拟轨迹球向下按键 boolean pressDPadLeft() 模拟轨迹球向左按键 boolean pressDPadRight() 模拟轨迹球向右按键 boolean pressDPadUp() 模拟轨迹球向上按键 boolean pres

获取iOS系统版本 --- UIDevice的使用

UIDevice类是一个单例,其唯一的实例( [UIDevice currentDevice] ) 代表了当前使用的设备. 通过这个实例,可以获得设备的相关信息(包括系统名称,版本号,设备模式等等). 也可以使用使用该实例来监测设备的特征(比如物理方向). NSString *strName = [[UIDevice currentDevice] name]; // Name of the phone as named by user 系统工具名称 NSString *strId = [[UID