1 import ABI48_0_0ExpoModulesCore
2 import UIKit
3 import MachO
4
5 public class DeviceModule: Module {
definitionnull6 public func definition() -> ModuleDefinition {
7 Name("ExpoDevice")
8
9 Constants([
10 "isDevice": isDevice(),
11 "brand": "Apple",
12 "manufacturer": "Apple",
13 "modelId": UIDevice.modelIdentifier,
14 "modelName": UIDevice.DeviceMap.modelName,
15 "deviceYearClass": UIDevice.DeviceMap.deviceYearClass,
16 "totalMemory": ProcessInfo.processInfo.physicalMemory,
17 "osName": UIDevice.current.systemName,
18 "osVersion": UIDevice.current.systemVersion,
19 "osBuildId": osBuildId(),
20 "osInternalBuildId": osBuildId(),
21 "deviceName": UIDevice.current.name,
22 "supportedCpuArchitectures": cpuArchitectures()
23 ])
24
25 AsyncFunction("getDeviceTypeAsync") { () -> Int in
26 switch UIDevice.current.userInterfaceIdiom {
27 case UIUserInterfaceIdiom.phone:
28 return DeviceType.phone.rawValue
29 case UIUserInterfaceIdiom.pad:
30 return DeviceType.tablet.rawValue
31 case UIUserInterfaceIdiom.tv:
32 return DeviceType.tv.rawValue
33 default:
34 return DeviceType.unknown.rawValue
35 }
36 }
37
38 AsyncFunction("getUptimeAsync") { () -> Double in
39 let uptimeMs: Double = ProcessInfo.processInfo.systemUptime * 1000
40
41 return uptimeMs
42 }
43
44 AsyncFunction("isRootedExperimentalAsync") { () -> Bool in
45 return UIDevice.current.isJailbroken
46 }
47 }
48 }
49
isDevicenull50 func isDevice() -> Bool {
51 #if targetEnvironment(simulator)
52 return false
53 #else
54 return true
55 #endif
56 }
57
osBuildIdnull58 func osBuildId() -> String? {
59 #if os(tvOS)
60 return nil
61 #else
62 // Credit: https://stackoverflow.com/a/65858410
63 var mib: [Int32] = [CTL_KERN, KERN_OSVERSION]
64 let namelen = UInt32(MemoryLayout.size(ofValue: mib) / MemoryLayout.size(ofValue: mib[0]))
65 var bufferSize = 0
66
67 // Get the size for the buffer
68 sysctl(&mib, namelen, nil, &bufferSize, nil, 0)
69
70 var buildBuffer = [UInt8](repeating: 0, count: bufferSize)
71 let result = sysctl(&mib, namelen, &buildBuffer, &bufferSize, nil, 0)
72
73 if result >= 0 && bufferSize > 0 {
74 return String(bytesNoCopy: &buildBuffer, length: bufferSize - 1, encoding: .utf8, freeWhenDone: false)
75 }
76
77 return nil
78 #endif
79 }
80
cpuArchitecturesnull81 func cpuArchitectures() -> [String]? {
82 // Credit: https://stackoverflow.com/a/70134518
83 guard let archRaw = NXGetLocalArchInfo().pointee.name else {
84 return nil
85 }
86 return [String(cString: archRaw)]
87 }
88
89 enum DeviceType: Int {
90 case unknown = 0
91 case phone = 1
92 case tablet = 2
93 case desktop = 3
94 case tv = 4
95 }
96