Advertisement
Guest User

Untitled

a guest
Mar 22nd, 2017
132
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 16.58 KB | None | 0 0
  1. import UIKit
  2. import SystemConfiguration.CaptiveNetwork
  3. import CoreTelephony.CTCarrier
  4. import CoreTelephony.CTTelephonyNetworkInfo
  5.  
  6.  
  7. public enum DeviceModel {
  8. case iPodTouch5
  9. case iPodTouch6
  10. case iPhone4
  11. case iPhone4s
  12. case iPhone5
  13. case iPhone5c
  14. case iPhone5s
  15. case iPhone6
  16. case iPhone6Plus
  17. case iPhone6s
  18. case iPhone6sPlus
  19. case iPhone7
  20. case iPhone7Plus
  21. case iPhoneSE
  22. case iPad2
  23. case iPad3
  24. case iPad4
  25. case iPadAir
  26. case iPadAir2
  27. case iPadMini
  28. case iPadMini2
  29. case iPadMini3
  30. case iPadMini4
  31. case iPadProSmall
  32. case iPadProLarge
  33. case appleTV
  34. case simulator
  35. case unknown
  36. }
  37.  
  38. public struct Device {
  39. /// Gets the Device identifier String.
  40. public static var identifier: String {
  41. var systemInfo = utsname()
  42. uname(&systemInfo)
  43.  
  44. let machineMirror = Mirror(reflecting: systemInfo.machine)
  45. let identifier = machineMirror.children.reduce("") { (identifier, element) in
  46. guard let value = element.value as? Int8, value != 0 else {
  47. return identifier
  48. }
  49. return identifier + String(UnicodeScalar(UInt8(value)))
  50. }
  51. return identifier
  52. }
  53.  
  54. /// Gets the model name for the device.
  55. public static var model: DeviceModel {
  56. switch identifier {
  57. case "iPod5,1": return .iPodTouch5
  58. case "iPod7,1": return .iPodTouch6
  59. case "iPhone3,1", "iPhone3,2", "iPhone3,3": return .iPhone4
  60. case "iPhone4,1": return .iPhone4s
  61. case "iPhone5,1", "iPhone5,2": return .iPhone5
  62. case "iPhone5,3", "iPhone5,4": return .iPhone5c
  63. case "iPhone6,1", "iPhone6,2": return .iPhone5s
  64. case "iPhone7,2": return .iPhone6
  65. case "iPhone7,1": return .iPhone6Plus
  66. case "iPhone8,1": return .iPhone6s
  67. case "iPhone8,2": return .iPhone6sPlus
  68. case "iPhone8,4": return .iPhoneSE
  69. case "iPhone9,1", "iPhone9,3": return .iPhone7
  70. case "iPhone9,2", "iPhone9,4": return .iPhone7Plus
  71. case "iPad2,1", "iPad2,2", "iPad2,3", "iPad2,4": return .iPad2
  72. case "iPad3,1", "iPad3,2", "iPad3,3": return .iPad3
  73. case "iPad3,4", "iPad3,5", "iPad3,6": return .iPad4
  74. case "iPad4,1", "iPad4,2", "iPad4,3": return .iPadAir
  75. case "iPad5,3", "iPad5,4": return .iPadAir2
  76. case "iPad2,5", "iPad2,6", "iPad2,7": return .iPadMini
  77. case "iPad4,4", "iPad4,5", "iPad4,6": return .iPadMini2
  78. case "iPad4,7", "iPad4,8", "iPad4,9": return .iPadMini3
  79. case "iPad5,1", "iPad5,2": return .iPadMini4
  80. case "iPad6,3", "iPad6,4": return .iPadProSmall
  81. case "iPad6,7", "iPad6,8": return .iPadProLarge
  82. case "AppleTV5,3": return .appleTV
  83. case "i386", "x86_64": return .simulator
  84. default: return .unknown
  85. }
  86. }
  87.  
  88.  
  89. /// hardware
  90. public struct CPU {
  91.  
  92. /// physical core
  93. public static var core: Int {
  94. var size = 0
  95. sysctlbyname("hw.physicalcpu", nil, &size, nil, 0)
  96. var count:Int8 = 0
  97. sysctlbyname("hw.physicalcpu", &count, &size, nil, 0)
  98. return Int(count)
  99. }
  100.  
  101. /// 线程 (4核8线程)
  102. public static var process: Int {
  103. return ProcessInfo.processInfo.activeProcessorCount
  104. }
  105.  
  106. public struct Cache {
  107.  
  108. /* 从 CPU 到 CPU 周期 大约需要的时间
  109. +----------+----------+--------------+
  110. | traget | cycle | time |
  111. +----------+-------------------------+
  112. | Memory | - | 60 - 80ns |
  113. +----------+-------------------------+
  114. | QPI | - | 20ns | /// QPI 总线传输(between sockets,not drawn)
  115. +----------+-------------------------+
  116. | L3 cache | 40-45 | 15ns |
  117. +----------+-------------------------+
  118. | L2 cache | 10 | 3ns |
  119. +----------+-------------------------+
  120. | L1 cache | 3-4 | 1ns |
  121. +----------+-------------------------+
  122. | 寄存器 | 1 | ---- |
  123. +----------+-------------------------+
  124. */
  125.  
  126. /// bytes
  127. /// cpu 一级缓存
  128. public static var l1size: Int64 {
  129. var size = MemoryLayout.size(ofValue: Int.self)
  130. var count:Int64 = 0
  131. sysctlbyname("hw.l1icachesize", &count, &size, nil, 0)
  132. return count
  133. }
  134.  
  135. /// bytes
  136. /// cpu 二级缓存
  137. /// - note: 是所有的核心的总和
  138. public static var l2size: Int64 {
  139. var size = MemoryLayout.size(ofValue: Int.self)
  140. var count:Int64 = 0
  141. sysctlbyname("hw.l2cachesize", &count, &size, nil, 0)
  142. return count
  143. }
  144.  
  145. /// bytes
  146. /// cpu 三级缓存
  147. /// - note: 是所有的核心的总和
  148. public static var l3size: Int64 {
  149. var size = MemoryLayout.size(ofValue: Int.self)
  150. var count:Int64 = 0
  151. sysctlbyname("hw.l3cachesize", &count, &size, nil, 0)
  152. return count
  153. }
  154.  
  155. /// bytes
  156. /// cpu 缓存行大小
  157. public static var linesize: Int { /// 4.72ms
  158. var size = MemoryLayout.size(ofValue: Int.self)
  159. var count:Int64 = 0
  160. sysctlbyname("hw.cachelinesize", &count, &size, nil, 0)
  161. return Int(count)
  162. }
  163. }
  164.  
  165. public static var usage: Float? {
  166. let basicInfoCount = MemoryLayout<mach_task_basic_info_data_t>.size / MemoryLayout<natural_t>.size
  167.  
  168. var kern: kern_return_t
  169.  
  170. var threadList = UnsafeMutablePointer<thread_act_t>.allocate(capacity: 1)
  171. var threadCount = mach_msg_type_number_t(basicInfoCount)
  172.  
  173. var threadInfo = thread_basic_info.init()
  174. var threadInfoCount: mach_msg_type_number_t
  175.  
  176. var threadBasicInfo: thread_basic_info
  177. var threadStatistic: UInt32 = 0
  178.  
  179. kern = withUnsafeMutablePointer(to: &threadList) {
  180. $0.withMemoryRebound(to: (thread_act_array_t?.self)!, capacity: 1) {
  181. task_threads(mach_task_self_, $0, &threadCount)
  182. }
  183. }
  184.  
  185. if kern != KERN_SUCCESS {
  186. return nil
  187. }
  188.  
  189. if threadCount > 0 {
  190. threadStatistic += threadCount
  191. }
  192.  
  193. var totalUsageOfCPU: Float = 0.0
  194.  
  195. for i in 0..<threadCount {
  196. threadInfoCount = mach_msg_type_number_t(THREAD_INFO_MAX)
  197.  
  198. kern = withUnsafeMutablePointer(to: &threadInfo) {
  199. $0.withMemoryRebound(to: integer_t.self, capacity: 1) {
  200. thread_info(threadList[Int(i)], thread_flavor_t(THREAD_BASIC_INFO), $0, &threadInfoCount)
  201. }
  202. }
  203. if kern != KERN_SUCCESS {
  204. return nil
  205. }
  206.  
  207. threadBasicInfo = threadInfo as thread_basic_info
  208.  
  209. if threadBasicInfo.flags & TH_FLAGS_IDLE == 0 {
  210. totalUsageOfCPU = totalUsageOfCPU + Float(threadBasicInfo.cpu_usage) / Float(TH_USAGE_SCALE) * 100.0
  211. }
  212. }
  213. return totalUsageOfCPU
  214. }
  215. }
  216. }
  217.  
  218.  
  219. // MARK: - Memory
  220. extension Device {
  221.  
  222. /// Memory
  223. public struct Memory {
  224. /// MB
  225. public static var capacity: Double? {
  226. /// to MB
  227. /// 方案一
  228. // var size = MemoryLayout.size(ofValue: Int.self)
  229. // var count:Int64 = 0
  230. // sysctlbyname("hw.memsize", &count, &size, nil, 0)
  231. // return Double(count / (1024 * 1024))
  232. /// 方案二
  233. return Double(ProcessInfo.processInfo.physicalMemory / (1024 * 1024))
  234. }
  235.  
  236. /// virtual size of memory, in MB, nil for failure
  237. /// - Note: memory your process thinks it’s using
  238. public static var usage: Double? {
  239. guard let info = Device.Memory.taskBasicInfo else {
  240. return nil
  241. }
  242. return Double(info.virtual_size) / (1024 * 1024) /// to MB
  243. }
  244.  
  245. /// resident size of memory, in MB, nil for failure
  246. /// - Note: physical memory used
  247. public static var resident: Double? {
  248. guard let info = Device.Memory.taskBasicInfo else {
  249. return nil
  250. }
  251. return Double(info.resident_size) / (1024 * 1024) /// to MB
  252. }
  253.  
  254. public static var free: Double? {
  255. guard
  256. let capacity = Device.Memory.capacity,
  257. let usage = Device.Memory.usage else {
  258. return nil
  259. }
  260. return capacity - usage
  261. }
  262.  
  263. private static var taskBasicInfo: mach_task_basic_info? {
  264. var info = mach_task_basic_info()
  265. var count = mach_msg_type_number_t(MemoryLayout.size(ofValue: info) / MemoryLayout<integer_t>.size)
  266. let kerr = withUnsafeMutablePointer(to: &info) { infoPtr in
  267. return infoPtr.withMemoryRebound(to: integer_t.self, capacity: Int(count)) { (machPtr: UnsafeMutablePointer<integer_t>) in
  268. return task_info(
  269. mach_task_self_,
  270. task_flavor_t(MACH_TASK_BASIC_INFO),
  271. machPtr,
  272. &count
  273. )
  274. }
  275. }
  276. guard kerr == KERN_SUCCESS else {
  277. return nil
  278. }
  279. return info
  280. }
  281. }
  282. }
  283.  
  284. // MARK: - Disk
  285. extension Device {
  286.  
  287. /// Disk
  288. public struct Disk {
  289. /// GB
  290. public static var capacity: Float? {
  291. guard let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).last else { return nil
  292. }
  293. let attributes = try? FileManager.default.attributesOfFileSystem(forPath: path as String)
  294. guard let value = (attributes?[.systemSize] as? NSNumber)?.int64Value else { return nil
  295. }
  296. return Float(value) / (1024 * 1024 * 1024) /// to GB
  297. }
  298.  
  299. ///GB
  300. public static var free: Float? {
  301. guard let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).last else { return nil
  302. }
  303. let attributes = try? FileManager.default.attributesOfFileSystem(forPath: path as String)
  304. guard let value = (attributes?[.systemFreeSize] as? NSNumber)?.int64Value else { return nil
  305. }
  306. return Float(value) / (1024 * 1024 * 1024) /// to GB
  307. }
  308. }
  309. }
  310.  
  311.  
  312. // MARK: - Network
  313. extension Device {
  314.  
  315. /// Network
  316. public struct Network {
  317.  
  318. /// Connection
  319. // MARK: -
  320. public enum NetworkType {
  321. case wifi
  322. case wwan(String)
  323. }
  324.  
  325. /// check network connection to apple.com
  326. public static var isAvailable: Bool {
  327. guard let flags = Device.Network.flags else {
  328. return false
  329. }
  330. /*
  331. target host is reachable and no connection is required
  332. the connection is on-demand (or on-traffic) if the calling application is using the CFSocketStream or higher APIs
  333. */
  334. return flags.contains(.reachable) ||
  335. !flags.contains(.connectionRequired) ||
  336. (flags.contains(.connectionOnDemand) || flags.contains(.connectionOnTraffic) && !flags.contains(.interventionRequired))
  337. }
  338.  
  339. public static var type: NetworkType? {
  340.  
  341. guard let flags = Device.Network.flags else {
  342. return nil
  343. }
  344.  
  345. guard flags.contains(.reachable) else {
  346. return nil
  347. }
  348. #if os(iOS)
  349. if flags.contains(.isWWAN) {
  350. /// If the target host is reachable and carrier has no radio access technology, we assume you in wifi
  351. guard let accessTechnology = Device.Network.Carrier.currentRadioAccessTechnology else {
  352. return .wifi
  353. }
  354. return Device.Network.adpat(accessTechnology: accessTechnology)
  355. }
  356. #endif
  357.  
  358. if !flags.contains(.connectionRequired) {
  359. return .wifi
  360. }
  361.  
  362. if flags.contains(.connectionOnDemand) || flags.contains(.connectionOnTraffic) {
  363. if !flags.contains(.interventionRequired) {
  364. return .wifi
  365. }
  366. }
  367.  
  368. return nil
  369. }
  370.  
  371. private static var flags: SCNetworkReachabilityFlags? {
  372. var address = sockaddr_in()
  373. address.sin_len = UInt8(MemoryLayout<sockaddr_in>.size)
  374. address.sin_family = sa_family_t(AF_INET)
  375.  
  376. guard let reachability = withUnsafePointer(to: &address, { pointer in
  377. return pointer.withMemoryRebound(to: sockaddr.self, capacity: MemoryLayout<sockaddr>.size) {
  378. return SCNetworkReachabilityCreateWithAddress(nil, $0)
  379. }
  380. }) else { return nil }
  381.  
  382. var flags = SCNetworkReachabilityFlags()
  383.  
  384. if SCNetworkReachabilityGetFlags(reachability, &flags) {
  385. return flags
  386. }
  387. return nil
  388. }
  389.  
  390. /// 将 accessTechnology 变换成 2g 3g 4g
  391. private static func adpat(accessTechnology: String) -> NetworkType? {
  392. /// 4g
  393. if accessTechnology == CTRadioAccessTechnologyLTE {
  394. return .wwan("4G")
  395. }
  396.  
  397. if Set([CTRadioAccessTechnologyWCDMA,
  398. CTRadioAccessTechnologyHSDPA,
  399. CTRadioAccessTechnologyCDMA1x,
  400. CTRadioAccessTechnologyCDMAEVDORev0,
  401. CTRadioAccessTechnologyCDMAEVDORevA,
  402. CTRadioAccessTechnologyCDMAEVDORevB,
  403. CTRadioAccessTechnologyeHRPD]).contains(accessTechnology) {
  404. return .wwan("3g")
  405. }
  406.  
  407. if CTRadioAccessTechnologyGPRS == accessTechnology ||
  408. CTRadioAccessTechnologyEdge == accessTechnology {
  409. return .wwan("2g")
  410. }
  411.  
  412. return nil
  413. }
  414.  
  415. // MARK: -
  416. public struct Carrier {
  417. /// Carrier Name
  418. public static var name: String? {
  419. let carrier = Device.Network.Carrier.carrier
  420. guard let name = carrier?.carrierName, name.utf16.count != 0 else {
  421. return nil
  422. }
  423. return name
  424. }
  425.  
  426. /// Carrier Country iso Code
  427. public static var isoCountryCode: String? {
  428. let carrier = Device.Network.Carrier.carrier
  429. guard let isoCountryCode = carrier?.isoCountryCode, isoCountryCode.utf16.count != 0 else {
  430. return nil
  431. }
  432. return isoCountryCode
  433. }
  434.  
  435. /// current radio access technology
  436. public static var currentRadioAccessTechnology: String? {
  437. return CTTelephonyNetworkInfo().currentRadioAccessTechnology
  438. }
  439.  
  440. /// is VOIP allowed
  441. public static var allowsVOIP: Bool {
  442. return Device.Network.Carrier.carrier?.allowsVOIP ?? false
  443. }
  444.  
  445. private static var carrier: CTCarrier? {
  446. return CTTelephonyNetworkInfo().subscriberCellularProvider
  447. }
  448. }
  449.  
  450. // MARK: -
  451. public struct WIFI {
  452. /// WIFI
  453. public static var ssid: String? {
  454. guard let interfaces = CNCopySupportedInterfaces() as? [CFString] else {
  455. return nil
  456. }
  457. for interface in interfaces {
  458. guard let info = CNCopyCurrentNetworkInfo(interface) as? [String:Any] else { continue }
  459. if let ssid = info[kCNNetworkInfoKeySSID as String] as? String {
  460. return ssid
  461. }
  462. }
  463. return nil
  464. }
  465. }
  466. }
  467. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement