在iOS开发中,有很多时候我们需要知道设备的信息,根据不同设备、系统版本进行相应的适配工作。DeviceKit就是一款非常不错的第三方库。DeviceKit源码只有一个文件,这里并不会对其做过多的介绍。主要对其中用到的一些知识点做点小结。
1.utsname
utsname是linux系统中描述当前系统和硬件信息的一个struct
#define _SYS_NAMELEN 256
struct utsname {
char sysname[_SYS_NAMELEN]; // 系统名称
char nodename[_SYS_NAMELEN]; //系统的网络名称
char release[_SYS_NAMELEN]; //发布级别
char version[_SYS_NAMELEN]; //系统版本信息
char machine[_SYS_NAMELEN]; //硬件信息
};
int uname(struct utsname *);//提供一个获取结构体信息的方法
// 用例
var systemInfo = utsname()
uname(&systemInfo)
/*1. 可以看出这是由几个字符数组组成的结构体
2. 这里通过machine字符串获取硬件信息
*/
// 附带提下ProcessInfo类,用于获取进程的相关信息以及该进程所在系统的操作系统信息等
let identifier = ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"] ?? "iOS"
2.Mirror
由于Swift中并不提倡使用Runtime,而是像其他语言一样使用反射(Reflect),其本身是个结构体。
struct Mirror {
public let subjectType: Any.Type //对象的类型
public let children: Mirror.Children //对象的子节点
public let displayStyle: Mirror.DisplayStyle? //对象的展示风格(class,struct,enum,collection等等)
public var superclassMirror: Mirror? { get } //对象父类的mirror
}
// 通过遍历子节点,可以获取所需要的信息
let mirror = Mirror(reflecting: systemInfo.machine)
// 拼接字符串
let identifier = mirror.children.reduce("") { (identifier, element) in
guard let value = element.value as? Int8, value != 0 else {
return identifier
}
return identifier + String(UnicodeScalar(UInt8(value)))
}
3. indirect 关键字
indirect enum属于一个语法方面的知识点,在学习Swift时有过了解,但在实际应用中并没有碰到过,其主要对enum中的case添加了一个中间件,实现了递归的效果,当然也可以直接修饰 enum。
enum Device {
case iPadPro12Inch
...
case unknown(String)
indirect case simulator(Device) //修饰某个case
}
indirect enum Test {
...
}
// 通过这个关键字,可以很方便用递归实现一些类似的功能
4.Equtable,CustomStringConvertible协议
Equtable协议主要给类型添加是否相等的判断方法,而实现CustomStringConvertible则可对某个对象进行描述
extension Device: CustomStringConvertible {
var description: String {
switch self {
case .iPhone4: return "iPhone 4"
case .iPhone4s: return "iPhone 4s"
...
}
}
extension Device: Equatable {
public static func ==(lhs: Device, rhs: Device) -> Bool {
return lhs.description == rhs.description
}
}
// 更进一步还有Comparable: Equatable协议