1import sys 2try: 3 from ctypes import cdll, c_void_p, c_char_p, util 4except ImportError: 5 # ctypes is an optional module. If it's not present, we're limited in what 6 # we can tell about the system, but we don't want to prevent the module 7 # from working. 8 print("ctypes isn't available; iOS system calls will not be available", file=sys.stderr) 9 objc = None 10else: 11 # ctypes is available. Load the ObjC library, and wrap the objc_getClass, 12 # sel_registerName methods 13 lib = util.find_library("objc") 14 if lib is None: 15 # Failed to load the objc library 16 raise ImportError("ObjC runtime library couldn't be loaded") 17 18 objc = cdll.LoadLibrary(lib) 19 objc.objc_getClass.restype = c_void_p 20 objc.objc_getClass.argtypes = [c_char_p] 21 objc.sel_registerName.restype = c_void_p 22 objc.sel_registerName.argtypes = [c_char_p] 23 24 25def get_platform_ios(): 26 # Determine if this is a simulator using the multiarch value 27 is_simulator = sys.implementation._multiarch.endswith("simulator") 28 29 # We can't use ctypes; abort 30 if not objc: 31 return None 32 33 # Most of the methods return ObjC objects 34 objc.objc_msgSend.restype = c_void_p 35 # All the methods used have no arguments. 36 objc.objc_msgSend.argtypes = [c_void_p, c_void_p] 37 38 # Equivalent of: 39 # device = [UIDevice currentDevice] 40 UIDevice = objc.objc_getClass(b"UIDevice") 41 SEL_currentDevice = objc.sel_registerName(b"currentDevice") 42 device = objc.objc_msgSend(UIDevice, SEL_currentDevice) 43 44 # Equivalent of: 45 # device_systemVersion = [device systemVersion] 46 SEL_systemVersion = objc.sel_registerName(b"systemVersion") 47 device_systemVersion = objc.objc_msgSend(device, SEL_systemVersion) 48 49 # Equivalent of: 50 # device_systemName = [device systemName] 51 SEL_systemName = objc.sel_registerName(b"systemName") 52 device_systemName = objc.objc_msgSend(device, SEL_systemName) 53 54 # Equivalent of: 55 # device_model = [device model] 56 SEL_model = objc.sel_registerName(b"model") 57 device_model = objc.objc_msgSend(device, SEL_model) 58 59 # UTF8String returns a const char*; 60 SEL_UTF8String = objc.sel_registerName(b"UTF8String") 61 objc.objc_msgSend.restype = c_char_p 62 63 # Equivalent of: 64 # system = [device_systemName UTF8String] 65 # release = [device_systemVersion UTF8String] 66 # model = [device_model UTF8String] 67 system = objc.objc_msgSend(device_systemName, SEL_UTF8String).decode() 68 release = objc.objc_msgSend(device_systemVersion, SEL_UTF8String).decode() 69 model = objc.objc_msgSend(device_model, SEL_UTF8String).decode() 70 71 return system, release, model, is_simulator 72