@@ -7,62 +7,97 @@ import Logger
7
7
8
8
private let Log = Logger . get ( )
9
9
10
+ /// Device information that's not particularly convenient to retrieve.
10
11
public enum SystemCapabilities {
11
12
13
+ /// Whether the device's main screen is OLED.
12
14
public static let oled : Bool = {
13
15
// Models are listed at https://ipsw.me/ and/or http://theiphonewiki.com/wiki/Models
16
+ // Display technology is in each model's Wikipedia page.
14
17
// Not gonna bother trying to guess at future models.
15
- let scanner = Scanner ( string: modelIdentifier)
16
- guard scanner. scanString ( " iPhone " ) != nil ,
17
- let major = scanner. scanInt ( ) ,
18
- scanner. scanString ( " , " ) != nil ,
19
- let minor = scanner. scanInt ( )
20
- else { return false }
21
- switch ( major, minor) {
22
- case ( 10 , 3 ) , ( 10 , 6 ) , // iPhone X
23
- ( 11 , 2 ) , // iPhone XS
24
- ( 11 , 4 ) , ( 11 , 6 ) , // iPhone XS Max
25
- ( 12 , 3 ) , // iPhone 11 Pro
26
- ( 12 , 5 ) , // iPhone 11 Pro Max
27
- ( 13 , 1 ) , // iPhone 12 Mini
28
- ( 13 , 2 ) , // iPhone 12
29
- ( 13 , 3 ) , // iPhone 12 Pro
30
- ( 13 , 4 ) , // iPhone 12 Pro Max
31
- ( 14 , 2 ) , // iPhone 13 Pro
32
- ( 14 , 3 ) , // iPhone 13 Pro Max
33
- ( 14 , 4 ) , // iPhone 13 Mini
34
- ( 14 , 5 ) , // iPhone 13
35
- ( 14 , 7 ) , // iPhone 14
36
- ( 14 , 8 ) , // iPhone 14 Plus
37
- ( 15 , 2 ) , // iPhone 14 Pro
38
- ( 15 , 3 ) , // iPhone 14 Pro Max
39
- ( 15 , 4 ) , // iPhone 15
40
- ( 15 , 5 ) , // iPhone 15 Plus
41
- ( 16 , 1 ) , // iPhone 15 Pro
42
- ( 16 , 2 ) : // iPhone 15 Pro Max
43
- return true
44
- default :
45
- return false
18
+ guard let modelID = ModelIdentifier . makeFromSysctl ( ) else { return false }
19
+ switch modelID. device {
20
+ case . iPhone:
21
+ switch ( modelID. major, modelID. minor) {
22
+ case ( 10 , 3 ) , ( 10 , 6 ) , // iPhone X
23
+ ( 11 , 2 ) , // iPhone XS
24
+ ( 11 , 4 ) , ( 11 , 6 ) , // iPhone XS Max
25
+ ( 12 , 3 ) , // iPhone 11 Pro
26
+ ( 12 , 5 ) , // iPhone 11 Pro Max
27
+ ( 13 , 1 ) , // iPhone 12 Mini
28
+ ( 13 , 2 ) , // iPhone 12
29
+ ( 13 , 3 ) , // iPhone 12 Pro
30
+ ( 13 , 4 ) , // iPhone 12 Pro Max
31
+ ( 14 , 2 ) , // iPhone 13 Pro
32
+ ( 14 , 3 ) , // iPhone 13 Pro Max
33
+ ( 14 , 4 ) , // iPhone 13 Mini
34
+ ( 14 , 5 ) , // iPhone 13
35
+ ( 14 , 7 ) , // iPhone 14
36
+ ( 14 , 8 ) , // iPhone 14 Plus
37
+ ( 15 , 2 ) , // iPhone 14 Pro
38
+ ( 15 , 3 ) , // iPhone 14 Pro Max
39
+ ( 15 , 4 ) , // iPhone 15
40
+ ( 15 , 5 ) , // iPhone 15 Plus
41
+ ( 16 , 1 ) , // iPhone 15 Pro
42
+ ( 16 , 2 ) : // iPhone 15 Pro Max
43
+ return true
44
+ case ( _, _) :
45
+ return false
46
+ }
47
+ case . iPad:
48
+ switch ( modelID. major, modelID. minor) {
49
+ case ( 16 , 3 ) , ( 16 , 4 ) , ( 16 , 5 ) , ( 16 , 6 ) : // iPad Pro (M4) aka iPad Pro (7th generation)
50
+ return true
51
+ case ( _, _) :
52
+ return false
53
+ }
46
54
}
47
55
} ( )
48
56
}
49
57
50
- private let modelIdentifier : String = {
51
- var size : Int = 0
52
- guard sysctlbyname ( " hw.machine " , nil , & size, nil , 0 ) == 0 else {
53
- Log . e ( " could not find model identifier: could not get buffer size " )
54
- return " "
58
+ private struct ModelIdentifier {
59
+ let device : Device
60
+ let major : Int
61
+ let minor : Int
62
+
63
+ enum Device {
64
+ case iPad, iPhone
55
65
}
56
66
57
- let bufferSize = Int ( size) + 1
58
- let buffer = UnsafeMutablePointer< CChar> . allocate( capacity: bufferSize)
59
- defer { buffer. deallocate ( ) }
67
+ init ? ( _ rawValue: String ) {
68
+ let scanner = Scanner ( string: rawValue)
69
+ if scanner. scanString ( " iPhone " ) != nil {
70
+ device = . iPhone
71
+ } else if scanner. scanString ( " iPad " ) != nil {
72
+ device = . iPad
73
+ } else {
74
+ return nil
75
+ }
60
76
61
- guard sysctlbyname ( " hw.machine " , buffer, & size, nil , 0 ) == 0 else {
62
- Log . e ( " could not find model identifier " )
63
- return " "
77
+ guard let major = scanner. scanInt ( ) ,
78
+ scanner. scanString ( " , " ) != nil ,
79
+ let minor = scanner. scanInt ( )
80
+ else { return nil }
81
+ self . major = major
82
+ self . minor = minor
64
83
}
65
84
66
- buffer [ Int ( size) ] = 0
67
- return String ( cString: buffer)
68
- } ( )
85
+ static func makeFromSysctl( ) -> ModelIdentifier ? {
86
+ var size : Int = 0
87
+ guard sysctlbyname ( " hw.machine " , nil , & size, nil , 0 ) == 0 else {
88
+ Log . e ( " could not find model identifier: could not get buffer size " )
89
+ return nil
90
+ }
91
+
92
+ let buffer = UnsafeMutablePointer< CChar> . allocate( capacity: size + 1 )
93
+ defer { buffer. deallocate ( ) }
94
+
95
+ guard sysctlbyname ( " hw.machine " , buffer, & size, nil , 0 ) == 0 else {
96
+ Log . e ( " could not find model identifier " )
97
+ return nil
98
+ }
99
+
100
+ buffer [ Int ( size) ] = 0
101
+ return ModelIdentifier ( String ( cString: buffer) )
102
+ }
103
+ }
0 commit comments