• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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