1 import ABI48_0_0ExpoModulesCore 2 import UIKit 3 import MachO 4 5 public class DeviceModule: Module { 6 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 50 func isDevice() -> Bool { 51 #if targetEnvironment(simulator) 52 return false 53 #else 54 return true 55 #endif 56 } 57 58 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 81 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