iOS学习——获取iOS设备的各种信息
不管是在Android开发还是iOS开发过程中,有时候我们需要经常根据设备的一些状态或信息进行不同的设置和性能配置,例如横竖屏切换时,电池电量低时,内存不够时,网络切换时等等,我们在这时候需要进行一些友好的提示和保护设备的一些设置。在Android开发中我们可以通过DeviceUtil这个工具类来获取设备网络状态、电池电量等各种状态信息,那么在iOS开发中,我们是否也能获取到设备的各种状态信息呢?答案是肯定的,本文就主要来学习一下在iOS开发过程中如何获取到设备的各种状态信息。
在iOS中要获取设备的状态信息,主要涉及到三个类:UIDevice、NSbundle和NSlocale。这三个类分别对应不同的信息:
- UIDevice是设计到设备的状态信息最多最常用的一个类,主要用于获取类函数及状态通知,可以检测手机电量、定位、感应、机型、当前系统版本等等。
- NSbundle是一个目录,其中包含了程序会使用到的资源,这些资源包含了图像、声音、编译好的代码,通过这些亦可获取一些应用信息。
- NsLocale可以获取用户的本地化信息,如货币、语言、国家、数字、日期格式、地理位置显示等等。
一 UIDevice
通过UIDevice可以获取到的信息非常多,UIDevice类展示了一些关键的特定于设备的属性,包括使用的iPhone ,Ipad或iPod Touch型号、设备名称、以及OS名称和版本。他是一种一站式解决方案,用于提取出某些系统详细信息。每个方法都是一个实例方法,他们是使用UIDevice单例通过[UIDevice currentDevice]调用的。
- UIDevice官网介绍
- UiDevice API 详细介绍
1.1 通过UIDevice获取设备基本状态
对于通过UIDevice获取到的设备状态信息如下图所示,具体获取方法参见:史上最全的iOS各种设备信息获取总结(iPhone8/iPhone X 已更新)
1.2 UIDevice中对状态信息的监控
UIDevice中对设备的方向、电池状态、电量以及距离传感器等信息都能进行获取,有时候我们需要对相应的状态进行监控,以便在状态发生改变时我们采取相应的措施。要对一些状态进行监控,显然最好的办法就是通过通知的方法进行操作,在状态变化时发出通知,然后我们采取对应的方法。下面是UIDevice中提供的通知类型。
//设备方向改变时发送的通知 UIKIT_EXTERN NSString *const UIDeviceOrientationDidChangeNotification; //电池状态改变时发送的通知 UIKIT_EXTERN NSString *const UIDeviceBatteryStateDidChangeNotification NS_AVAILABLE_IOS(3_0); //电量改变时发送的通知 UIKIT_EXTERN NSString *const UIDeviceBatteryLevelDidChangeNotification NS_AVAILABLE_IOS(3_0); //距离传感器状态改变时发送的通知 UIKIT_EXTERN NSString *const UIDeviceProximityStateDidChangeNotification NS_AVAILABLE_IOS(3_0);
其中,设备方向的枚举选项有以下几种:
typedef NS_ENUM(NSInteger, UIDeviceOrientation) {UIDeviceOrientationUnknown,UIDeviceOrientationPortrait, // home键在下UIDeviceOrientationPortraitUpsideDown, // home键在上UIDeviceOrientationLandscapeLeft, // home键在右UIDeviceOrientationLandscapeRight, // home键在左UIDeviceOrientationFaceUp, // 屏幕朝上UIDeviceOrientationFaceDown // 屏幕朝下 };
电池状态的枚举选项有一下几种:
typedef NS_ENUM(NSInteger, UIDeviceBatteryState) {UIDeviceBatteryStateUnknown,UIDeviceBatteryStateUnplugged, // 放电状态UIDeviceBatteryStateCharging, // 充电未充满状态UIDeviceBatteryStateFull, // 充电已充满 };
电池电量是一个float类型的值,从0.0 ~ 1.0表示电池电量的百分比:
@property(nonatomic, readonly) float batteryLevel; //电池电量
距离传感器的状态是用一个BOOL类型的值来表示手机是离用户近还是远:
//A Boolean value indicating whether the proximity sensor is close to the user (YES) or not (NO) @property(nonatomic, readonly) BOOL proximityState;
当我们需要对某一个信息进行监控时,我们需要进行三步:添加状态通知--> 开启监控开关 --> 完成监控动作(调用方法)。
- 添加状态通知:即将某种状态的监控信息添加到通知中心。
//添加设备方向的监控通知 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(change) name:UIDeviceOrientationDidChangeNotification object:nil];//添加距离状态的监控通知 [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(notice) name:UIDeviceProximityStateDidChangeNotification object:nil];
- 开启监控开关:iOS开发中,UIDevice的每一个状态通知都对应有一个开关来控制是否开启对应的监控和通知,我们需要打开对应状态的开关。
//打开设备方向监测,这是用方法控制 [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];//不需要时可以关闭设备方向监控 [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];//打开电池状态和电池电量监测开关,不需要时可以关闭 [UIDevice currentDevice].batteryMonitoringEnabled=YES;//打开手机距离传感器监测开关,不需要时可以关闭 [UIDevice currentDevice].proximityMonitoringEnabled=YES;
此外,对于设备方向监控, UIDevice还提供了一个BOOL类型的只读属性来获取当前监控状态:
//A Boolean value that indicates whether the receiver generates orientation notifications (YES) or not (NO) @property(nonatomic, readonly, getter=isGeneratingDeviceOrientationNotifications) BOOL generatesDeviceOrientationNotifications;
- 完成监控动作:就是所监控的状态发生变化时采取的动作,也就是在第一步添加通知时的 selector:@selector(change) 中方法的完成,这样当监控的状态发生变化是就会自动调用对用的方法执行。
//设备方向改变时调用该方法 -(void)change{NSLog(@"change"); }//设备离用户的距离状态发生变化时调用该方法 -(void)notice{if ([UIDevice currentDevice].proximityState) {NSLog(@"近距离");}else{NSLog(@"远距离");} }
二 设备上安装的App信息
在开发过程中,有时候我们需要了解设备上安装了那些App,以及是否安装了一些特定的App以方便我们进行开发,最近我们公司的OA项目中就需要将特定类型的OA信息可以转发到微信、QQ上,这时候我们就需要判断设备上是否安装了对应的App,然后进行相关的操作。因此,在这种情况下,获取设备上是否安装了特定的App以及设备上安装了那些App则显得比较重要了。
那么如何判断我们的iOS设备上是否安装了特定的App呢?有两种方案:
- 直接判断是否安装了特定的App
- 先获取到iOS设备上安装的所有App的清单,然后判断是否有特定的App
2.1 直接判断iOS设备是否安装了特定的app
这个方法其实是比较简单的,但是你需要知道该软件的URL Schemes,知道软件的URL Schemes可以使用openUrl来获取ios是否安装了某款软件,比如这样 [[UIApplication sharedApplication] canOpenURL:@"damon://"] ,会返回一个bool值,为true则安装了,否则没有安装。扩展iOS软件之间的调用:IOS的软件之间的调用(URL Schemes)
方法很简单,但是问题了,我们要如何获取到特定App的URL Schemes呢?下面两个步骤带大家一起学会如何获取:
- 获取app的url schemes 的方法 :把相应的 app 的 ipa 安装文件下载下来,把文件 .ipa 的后缀改成 .zip,然后解压,打开 Payload/xxx.app/Info.plist 这个文件,找到 URL types 下的 URL Schemes 下的数组对应的值就是这个 app 的 URL Scheme 了
- 简单验证一个 URL Scheme 是否正确的方法:在真机设备(此设备要安装了待验证的 app)里面打开 Safari,然后在地址栏中键入该应用的 URL Scheme,后加 ://,比如 Weico 的,在地址栏中键入 weico:// ,然后点击确定,如果能正常调用出 Weico,即代表这个 URL Scheme 正确可用
- 部分URL schemes名单:https://www.zhihu.com/question/19907735,仅做参考,这个不保证正确性
我们判断某个特定的App是否被安装一般都是用来进行跳转或打开的,如果安装了,我们该如何实现跳转呢?首先,我们需要将检测的UrlScheme添加到白名单即可,添加方法:info.plist 增加LSApplicationQueriesSchemes (array类型),把要检测的app的UrlScheme加进去。
最后,我们在代码中调用Application 的canopenUrl 的方法判断设备时候有对应的应用 程序,返回YES表示已安装了该app ,代码如下:
if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"IOSDevApp://"]]) { //说明此设备有安装app }else{ //说明此设备没有安装app }
2.2 获取iOS设备上安装的所有App清单
要获取iOS设备上安装所有App清单以及一些必要信息,实际上这一个是不允许的,因为涉及到个人隐私问题。但是我们可以通过反射的方法开进行获取。一般的方法是:
-(void)getAllApp {Class LSApplicationWorkspace_class = objc_getClass("LSApplicationWorkspace");NSObject* workspace = [LSApplicationWorkspace_class performSelector:@selector(defaultWorkspace)];NSArray *allApplications = [workspace performSelector:@selector(allApplications)];//这样就能获取到手机中安装的所有AppNSLog(@"设备上安装的所有app:%@",allApplications); }
打印出来的结果类似如下形式:
设备上安装的所有app:("<LSApplicationProxy: 0x12e563310> com.apple.Passbook <file:///Applications/Passbook.app>","<LSApplicationProxy: 0x12e563bb0> com.apple.GameController <file:///Applications/GameController.app>", )
从打印结果看出,我们上一步所获取到的allApplications数组中的元素是一个LSApplicationProxy类型的,我们要把这个转换成字符串, 这个字符串中不只包含了App的bundle ID,还包含了安装的路径,因为这个路径不唯一不确定,所以我们判断是否安装了某个App只需判断这个字符串中的bundle ID,所有我们还要对字符串做处理。前提是要知道你要判断的这个app的Bundle ID 是什么。
//解析数据,获取每一个app信息总的 Class LSApplicationProxy_class = object_getClass(@"LSApplicationProxy");for (LSApplicationProxy_class in appList){//这里可以查看一些信息NSString *bundleID = [LSApplicationProxy_class performSelector:@selector(applicationIdentifier)];NSString *version = [LSApplicationProxy_class performSelector:@selector(bundleVersion)];NSString *shortVersionString = [LSApplicationProxy_class performSelector:@selector(shortVersionString)];NSLog(@"bundleID:%@\n version: %@\n ,shortVersionString:%@\n", bundleID,version,shortVersionString);}
从所有安装App信息中判断是否安装了特定App的方法:
-(void)isInstallLDApp:(NSArray *)allAPP { NSInteger zlConnt = 0;for (NSString *appStr in allAPP) {NSString *app = [NSString stringWithFormat:@"%@",appStr];//转换成字符串NSRange range = [app rangeOfString:@"LdWBrowserIPhone"];//是否包含这个bundle IDif (range.length > 1){zlConnt ++;}}if (zlConnt >= 1) {NSLog(@"已安装");}else{NSLog(@"没有安装");} }
2.3 总结
- 方法一的优点:效率高,代码量小 ,但前提是要先知道要判断的app 的UrlSchemes
- 方法二的优点:完美解决iOS9的canopenurl 白名单的限制;
缺点: 遍历的过程中可能会消耗性能, App Store审核可能会被拒,前提是要知道你要判断的这个app的Bundle ID 是什么
三 NSbundle和NSlocale
参考自:ios开发之UIDevice使用总结
bundle是一个目录,其中包含了程序会使用到的资源. 这些资源包含了如图像,声音,编译好的代码,nib文件(用户也会把bundle称为plug-in). 对应bundle,cocoa提供了类NSBundle.一个应用程序看上去和其他文件没有什么区别. 但是实际上它是一个包含了nib文件,编译代码,以及其他资源的目录. 我们把这个目录叫做程序的main bundle。通过这个路径可以获取到应用的信息,例如应用名、版本号等。通过NSBundle可以获得这几个信息:
//app应用相关信息的获取 NSDictionary *dicInfo = [[NSBundle mainBundle] infoDictionary]; // CFShow(dicInfo); NSString *strAppName = [dicInfo objectForKey:@"CFBundleDisplayName"]; NSLog(@"App应用名称:%@", strAppName); NSString *strAppVersion = [dicInfo objectForKey:@"CFBundleShortVersionString"]; NSLog(@"App应用版本:%@", strAppVersion); NSString *strAppBuild = [dicInfo objectForKey:@"CFBundleVersion"]; NSLog(@"App应用Build版本:%@", strAppBuild);
NSLocale可以获取用户的本地化信息设置,例如货币类型,国家,语言,数字,日期格式的格式化,提供正确的地理位置显示等等。下面的代码获取机器当前语言和国家代码。通过NSLocale可以这样使用:
NSArray *languageArray = [NSLocale preferredLanguages]; NSString *language = [languageArray objectAtIndex:0]; NSLog(@"语言:%@", language);//en NSLocale *locale = [NSLocale currentLocale]; NSString *country = [locale localeIdentifier]; NSLog(@"国家:%@", country); //en_US
转载于:https://www.cnblogs.com/mukekeheart/p/8252495.html
iOS学习——获取iOS设备的各种信息相关推荐
- 服务器能识别手机型号,iOS获取当前设备型号等信息(全)包含iPhone7和iPhone7P
获取设备信息总结 1.获取设备的信息 2.获取设备的唯一标示符 3.为系统创建一个随机的标示符 4.获取当前屏幕分辨率的信息 5.获取运营商的信息 需要先导入头文件 创建对象 获取运行商的名称 获取当 ...
- iOS学习之iOS沙盒(sandbox)机制和文件操作(二)
接上篇 iOS学习之iOS沙盒(sandbox)机制和文件操作(一) 我们看看如何获取应用程序沙盒目录.包括真机的沙盒的目录. 1.获取程序的Home目录 [cpp] view plaincopy N ...
- iOS获取当前设备型号等信息总结 包含iPhone7和iPhone7P
#include <sys/types.h> #include <sys/sysctl.h> //获得设备型号 + (NSString *)getCurrentDeviceMo ...
- swift获取openuuid_iOS获取当前设备型号等信息(全)包含iPhone7和iPhone7P
#include #include //获得设备型号 + (NSString *)getCurrentDeviceModel { int mib[2]; size_t len; charchar *m ...
- IOS学习之苹果设备分辨率一览表
IOS 设备分辨率一览表 设备 屏幕尺寸 分辨率 (pt) Render 分辨率 (px) PPI iPhone4(S)/iPod Touch4G 3.5 320x480 @2x 640x960 33 ...
- iOS开发——获取本设备IP
不说废话,直接上代码. #import <ifaddrs.h> #import <arpa/inet.h> - (NSString *)getIPAddress { NSStr ...
- iOS学习之iOS沙盒(sandbox)机制和文件操作复习
1.iOS沙盒机制 iOS应用程序只能在为该改程序创建的文件系统中读取文件,不可以去其它地方访问,此区域被成为沙盒,所以所有的非代码文件都要保存在此,例如图像,图标,声音,映像,属性列表,文本文件等. ...
- iOS学习之iOS沙盒(sandbox)机制和文件操作(一)
1.iOS沙盒机制 iOS应用程序只能在为该改程序创建的文件系统中读取文件,不可以去其它地方访问,此区域被成为沙盒,所以所有的非代码文件都要保存在此,例如图像,图标,声音,映像,属性列表,文本文件等. ...
- java获取usb设备的相关信息
我从上上个礼拜开始接触,公司需要,所以开始在网上搜索相关资料,但是都没有找到合适的范例,但万幸终于测试出合适的代码. import java.io.UnsupportedEncodingExcepti ...
最新文章
- Github 年度最受欢迎的 TOP30 Python 项目,超值
- 利用Bash给Linux服务器增添色彩
- 用bash命令得到Windows一个目录下的所有文件并且把结果输入到一个文件
- ASP.NET操作Word文档(转)
- python server.py_python manage.py runserver报错
- JVM调优总结(六)-分代垃圾回收详述2
- Kotlin之?和!!最简单的理解
- Java NIO学习笔记之图解ByteBuffer
- matlab imfill孔洞填充
- JVM运行参数_JVM内存模型_常用内存分析工具
- 使用Matlab(R2018b)画复杂函数的图形(网格图meshgrid)及等高线contour
- 面试题,你觉得什么样的产品适合做成saas?
- Qt Ctreator搭配VS2013调试——整合QML/C++调试需要的从属调试引擎无法被创建
- airpods pro是按压还是触摸_AirPods Pro体验:真好用,但我还是想退货啊
- select 实现类似多线程_redis中的网络IO有了解过吗,它是单线程的还是多线程的,为什么要用单线程?...
- jspsmartupload上传文件 servlet得不到jsp参数
- Mysql优化(出自官方文档) - 第九篇(优化数据库结构篇)
- Atitit OOCSS vs bem
- pr如何跳到关键帧_全套pr视频剪辑教程[叫兽七叔讲解]
- (LeetCode)数数关系——Non-decreasing Array(非递减数组)
热门文章
- 安装wireshark显示npcap失败的解决办法
- VBA 单元格基本操作 - 复制 粘贴 区域选择
- 物联网ARM开发-4协议-单总线应用温湿度传感器
- 对比损失Contrastive Loss
- 在windows里用flashfxp连接虚拟机ubuntu中ftp服务器vsftpd,连接被拒的问题
- 【已解决】Using insecure protocols with repositories, without explicit opt-in, is unsupported. Switch Mav
- parallel desktop 17 安装win7 科来抓包 无网络适配器可用
- “对DllRegisterServer的调用失败,错误代码为0×80070005 ”
- SAS中保留t值、F值和Z值的三位小数
- USB端口的打印机映射成LPT并口