ios-devices 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d6aaf353aa24266e1ea4d7d671ca687878b7043d2313e209b904f1aacc89d474
4
- data.tar.gz: 9b5f83d2d3a87964acdab879e648082ae42c5ca34fcc6b6d6a4e7a48af73ceab
3
+ metadata.gz: aad72b7db1da93d13e43f146dc9586e852200b5bc600e7d5fd7592a5adb5460d
4
+ data.tar.gz: 68739035271e0876abaf70fa234132ff3d11520fe623719ac74687aed9b6d640
5
5
  SHA512:
6
- metadata.gz: be1ea9bdb428121177ebf860fae0528cc375fb1ba354876cc52edadcbec3e61580cebf170a7febd0e1191135bf90a16ca63c00766ef745bd19dc544d50d1a217
7
- data.tar.gz: e513323cb511db4cba55102e98b53a44eaa9cd6bc120d646c1db48e27e8eeeb4815359534cca9c7b751f84b9d09e500b00b3240908ebe003dff7dee158fa716f
6
+ metadata.gz: 91d191c54272b266cc7043f72c17ba301221b36878befcceaeb73e72b83b5d38ecad1c6fcbedbc5a6b7a3e940179fcac8307e7cc9bfc3b84b64d783ed29b8a3d
7
+ data.tar.gz: e461a29627ce9777f6adb6a19f9df4a221f4593a6c607e0426610d170e0219eda6151ea4ed37cd086cadee2cffbb21a620abfadbdf9d3872cfdb9445635e6c7a
data/CHANGELOG.md CHANGED
@@ -2,6 +2,53 @@
2
2
 
3
3
  All notable changes to this project are documented in this file.
4
4
 
5
+ ## 0.5.0 - 2026-11-06
6
+
7
+ ### Breaking changes
8
+
9
+ Many `name` and `extra` values changed to follow one naming convention, based on Apple's official
10
+ product names (see "Naming" in the README). If you store or compare these values, check the changes
11
+ below.
12
+
13
+ - **Apple Watch:** the series, SE or Ultra is now part of `name`, e.g. `"Apple Watch Series 5"` /
14
+ `"44mm, GPS+Cellular"` instead of `"Apple Watch"` / `"Series 5, 44mm, GPS+Cellular"`. Ultra models
15
+ have no `extra`. The SE 2 is `"Apple Watch SE"` / `"2nd gen, …"`; the original watch is
16
+ `"Apple Watch"` / `"1st gen, …"`.
17
+ - **Generations and chips move from `name` to `extra`:** iPad mini 5, 6 and 7 are now
18
+ `"iPad mini"` with `"5th gen"`, `"6th gen"` and `"A17 Pro"`; iPad Air 3 and 4 are `"iPad Air"` with
19
+ `"3rd gen"` and `"4th gen"`; the 7th-gen iPad is `"iPad"` instead of `"iPad 10.2\""`; the 11th-gen
20
+ iPad is `"iPad"` / `"A16, …"`.
21
+ - **Cellular iPads say `Wi-Fi+Cellular`** instead of `Wi-Fi+LTE` or `3G`.
22
+ - **Missing or unclear extras are filled in:** cellular variants of the original iPad, iPad 2,
23
+ iPad mini, iPad 3rd/4th gen and iPad mini 3 now have their connectivity and `GSM`/`CDMA`, and the
24
+ China models (`iPad4,3`, `iPad4,6`, `iPad4,9`) say `China` instead of `Rev` or nothing. First-gen
25
+ 11" and 12.9" iPad Pros say `1st gen`, and the 1TB models say `1TB`.
26
+ - **Wording fixes:** `"iPhone 12 mini"` and `"iPhone 13 mini"` (was `Mini`), `4th gen`/`6th gen`
27
+ (was `Gen`), and `Rev A` for revised models.
28
+ - **`Ios::Devices::Model` is immutable:** `device_type=`, `name=` and `extra=` are gone and models
29
+ are frozen. `search` returns the same shared instance each time for a known device type.
30
+ - **`Ios::UNKNOWN_IOS_DEVICE` is deprecated** in favour of `Ios::Devices::UNKNOWN_IOS_DEVICE`. The old
31
+ constant still works; Ruby warns about it when deprecation warnings are on (`-W:deprecated`).
32
+
33
+ ### Added
34
+
35
+ - `Ios::Devices.all` lists every known device model, and `Ios::Devices.known?(device_type)` checks
36
+ whether a device type is known.
37
+ - `Model#known?` and `Model#unknown?`.
38
+ - `Model#to_s` returns the full name, e.g. `"iPad mini (A17 Pro, Wi-Fi+Cellular)"`, and `Model#to_h`
39
+ returns the attributes as a hash.
40
+ - Models with the same attributes are equal (`==`, `eql?`, `hash`).
41
+ - Add iPhone Duo (`iPhone19,4`).
42
+ - Add Apple Watch Ultra 4 (`Watch8,1`) and Apple Watch Series 12 (`Watch8,2`–`Watch8,5`).
43
+
44
+ ### Other changes
45
+
46
+ - Rename the default branch from `master` to `main`.
47
+ - Add RuboCop (run by `bundle exec rake` and in CI).
48
+ - Test against Ruby 4.0 in CI.
49
+ - Move the device list out of a `case` statement into a frozen hash, with specs that check it for
50
+ duplicates and malformed entries.
51
+
5
52
  ## 0.4.0 - 2026-10-20
6
53
 
7
54
  - **Require Ruby 3.1 or later.** Ruby 2.6, 2.7 and 3.0 are end-of-life and no longer tested.
@@ -16,7 +63,7 @@ All notable changes to this project are documented in this file.
16
63
  - Add Apple Watch Series 10, Ultra 3, SE 3 and Series 11.
17
64
  - Remove a duplicate "Apple Watch SE 2, 40mm, GPS" entry.
18
65
 
19
- ## 0.3.5 - 2025-10-22
66
+ ## 0.3.5 - 2025-10-27
20
67
 
21
68
  - Add iPhone 17, iPhone 17 Pro, iPhone 17 Pro Max and iPhone Air.
22
69
 
data/README.md CHANGED
@@ -22,35 +22,79 @@ Or install it yourself as:
22
22
  ## Usage
23
23
 
24
24
  Just use the `Ios::Devices.search` method with the Apple string and you should get a
25
- `Ios::Devices::Model` object. This object has an `extra` attribute for things like internet
26
- connection, revision model, etc.
25
+ `Ios::Devices::Model` object. Its `name` is the product name (for example "iPad mini" or
26
+ "Apple Watch Series 5"), and its `extra` attribute has details like the generation or chip, size,
27
+ connectivity and variant (see [Naming](#naming)).
27
28
 
28
29
  ```ruby
29
30
  device = Ios::Devices.search('iPhone6,1')
30
- => #<Ios::Devices::Model:0x007fa55ba1a948 @extra=nil, @name="iPhone 5s", @device_type="iPhone6,1">
31
+ => #<Ios::Devices::Model:0x007fa55ba1a948 @device_type="iPhone6,1", @name="iPhone 5s", @extra=nil>
31
32
 
32
33
  device.name
33
34
  => "iPhone 5s"
34
35
 
35
36
  device = Ios::Devices.search('iPad2,2')
36
- => #<Ios::Devices::Model:0x007fa55b957308 @extra="GSM", @name="iPad 2", @device_type="iPad2,2">
37
+ => #<Ios::Devices::Model:0x007fa55b957308 @device_type="iPad2,2", @name="iPad 2", @extra="Wi-Fi+Cellular, GSM">
37
38
 
38
39
  device.name
39
40
  => "iPad 2"
40
41
 
41
42
  device.extra
42
- => "GSM"
43
+ => "Wi-Fi+Cellular, GSM"
44
+
45
+ device.to_s
46
+ => "iPad 2 (Wi-Fi+Cellular, GSM)"
47
+
48
+ device.to_h
49
+ => {device_type: "iPad2,2", name: "iPad 2", extra: "Wi-Fi+Cellular, GSM"}
43
50
 
44
51
  device = Ios::Devices.search('iPhone99,1')
45
52
  device.name
46
- => "Unknown iOS device" # Ios::UNKNOWN_IOS_DEVICE
53
+ => "Unknown iOS device" # Ios::Devices::UNKNOWN_IOS_DEVICE
54
+
55
+ device.known?
56
+ => false
47
57
  ```
48
58
 
49
59
  Simulator identifiers (`i386`, `x86_64`, `arm64`) return `"iOS Simulator"`.
50
60
 
61
+ Models are immutable, and two models with the same attributes are equal (`==`, `eql?` and
62
+ `hash`), so they work as hash keys and with `uniq`.
63
+
64
+ You can also check a device type or list every known device:
65
+
66
+ ```ruby
67
+ Ios::Devices.known?('iPhone6,1')
68
+ => true
69
+
70
+ Ios::Devices.all.size
71
+ => 245
72
+
73
+ Ios::Devices.all.select { |device| device.name == 'iPad mini' }.map(&:to_s)
74
+ => ["iPad mini (Wi-Fi)", "iPad mini (Wi-Fi+Cellular, GSM)", ...]
75
+ ```
76
+
77
+ ## Naming
78
+
79
+ Names follow Apple's official product names, as on Apple's "Identify your model" support pages:
80
+
81
+ - `name` is Apple's name without the part in brackets: "iPad mini (6th generation)" is
82
+ `"iPad mini"`, "iPad Pro 11-inch (M4)" is `"iPad Pro 11\""`, and "Apple Watch Series 5" stays
83
+ `"Apple Watch Series 5"`. Numbers that are part of the name itself stay (`"iPad mini 4"`,
84
+ `"iPad Air 2"`, `"Apple Watch SE 3"`).
85
+ - `extra` is a comma-separated list of what's left, in this order (each part is optional):
86
+ 1. generation or chip: `6th gen`, `M4`, `A17 Pro`
87
+ 2. size: `44mm`
88
+ 3. connectivity: `Wi-Fi`, `Wi-Fi+Cellular`, `GPS`, `GPS+Cellular`
89
+ 4. variant: `GSM`, `CDMA`, `China`, `Rev A`, `1TB`
90
+
91
+ For example, `iPad16,2` is `"iPad mini"` / `"A17 Pro, Wi-Fi+Cellular"` and `Watch6,10` is
92
+ `"Apple Watch SE"` / `"2nd gen, 40mm, GPS"`. The specs check that every entry follows these rules.
93
+
51
94
  ## Adding new devices
52
95
 
53
- Device identifiers live in `lib/ios/devices.rb`. When adding new ones:
96
+ Device identifiers live in the `DEVICE_TYPES` hash in `lib/ios/devices/device_types.rb`, grouped
97
+ by family. When adding new ones:
54
98
 
55
99
  1. Check the identifiers against at least two of these sources:
56
100
  - [AppleDB](https://appledb.dev/device-selection/iPhone.html): identifiers per model, including
@@ -63,12 +107,14 @@ Device identifiers live in `lib/ios/devices.rb`. When adding new ones:
63
107
 
64
108
  Identifiers for unreleased devices often show up in Xcode betas before Apple ships the
65
109
  hardware, and they can change. Prefer adding them after the device is released.
66
- 2. Follow the naming of the existing entries in the same family (iPhone, iPad, Watch, etc.).
67
- 3. Make sure the identifier isn't already listed, since a duplicate is silently ignored.
68
- 4. Add a spec for at least one of the new identifiers in `spec/ios_devices_spec.rb`.
110
+ 2. Follow the [naming rules](#naming). If you need a new kind of `extra` part, add it to the
111
+ vocabulary in `spec/ios/devices/device_types_spec.rb`.
112
+ 3. Make sure the identifier isn't already listed. Ruby warns about duplicate keys and the specs
113
+ fail on them.
114
+ 4. Add a spec for at least one of the new identifiers in `spec/ios/devices_spec.rb`.
69
115
  5. Add an entry to `CHANGELOG.md` under the upcoming version.
70
116
 
71
- Run the tests with `bundle exec rake`.
117
+ Run the tests and RuboCop with `bundle exec rake` (or just the tests with `bundle exec rake spec`).
72
118
 
73
119
  ## Contributing
74
120
 
@@ -0,0 +1,267 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ios
4
+ module Devices
5
+ # Maps every known Apple device type to the name and, optionally, the extra
6
+ # information (connectivity, generation, size, etc.) of its model.
7
+ #
8
+ # See "Adding new devices" in the README before adding entries here.
9
+ DEVICE_TYPES = {
10
+ # Simulators
11
+ 'i386' => ['iOS Simulator'],
12
+ 'x86_64' => ['iOS Simulator'],
13
+ 'arm64' => ['iOS Simulator'],
14
+
15
+ # iPhone
16
+ 'iPhone1,1' => ['iPhone'],
17
+ 'iPhone1,2' => ['iPhone 3G'],
18
+ 'iPhone2,1' => ['iPhone 3GS'],
19
+ 'iPhone3,1' => ['iPhone 4', 'GSM'],
20
+ 'iPhone3,2' => ['iPhone 4', 'GSM, Rev A'],
21
+ 'iPhone3,3' => ['iPhone 4', 'CDMA'],
22
+ 'iPhone4,1' => ['iPhone 4S'],
23
+ 'iPhone5,1' => ['iPhone 5'],
24
+ 'iPhone5,2' => ['iPhone 5'],
25
+ 'iPhone5,3' => ['iPhone 5c'],
26
+ 'iPhone5,4' => ['iPhone 5c'],
27
+ 'iPhone6,1' => ['iPhone 5s'],
28
+ 'iPhone6,2' => ['iPhone 5s'],
29
+ 'iPhone7,1' => ['iPhone 6 Plus'],
30
+ 'iPhone7,2' => ['iPhone 6'],
31
+ 'iPhone8,1' => ['iPhone 6s'],
32
+ 'iPhone8,2' => ['iPhone 6s Plus'],
33
+ 'iPhone8,4' => ['iPhone SE'],
34
+ 'iPhone9,1' => ['iPhone 7'],
35
+ 'iPhone9,3' => ['iPhone 7'],
36
+ 'iPhone9,2' => ['iPhone 7 Plus'],
37
+ 'iPhone9,4' => ['iPhone 7 Plus'],
38
+ 'iPhone10,1' => ['iPhone 8'],
39
+ 'iPhone10,4' => ['iPhone 8'],
40
+ 'iPhone10,2' => ['iPhone 8 Plus'],
41
+ 'iPhone10,5' => ['iPhone 8 Plus'],
42
+ 'iPhone10,3' => ['iPhone X'],
43
+ 'iPhone10,6' => ['iPhone X'],
44
+ 'iPhone11,2' => ['iPhone XS'],
45
+ 'iPhone11,4' => ['iPhone XS Max'],
46
+ 'iPhone11,6' => ['iPhone XS Max'],
47
+ 'iPhone11,8' => ['iPhone XR'],
48
+ 'iPhone12,1' => ['iPhone 11'],
49
+ 'iPhone12,3' => ['iPhone 11 Pro'],
50
+ 'iPhone12,5' => ['iPhone 11 Pro Max'],
51
+ 'iPhone12,8' => ['iPhone SE', '2nd gen'],
52
+ 'iPhone13,1' => ['iPhone 12 mini'],
53
+ 'iPhone13,2' => ['iPhone 12'],
54
+ 'iPhone13,3' => ['iPhone 12 Pro'],
55
+ 'iPhone13,4' => ['iPhone 12 Pro Max'],
56
+ 'iPhone14,2' => ['iPhone 13 Pro'],
57
+ 'iPhone14,3' => ['iPhone 13 Pro Max'],
58
+ 'iPhone14,4' => ['iPhone 13 mini'],
59
+ 'iPhone14,5' => ['iPhone 13'],
60
+ 'iPhone14,6' => ['iPhone SE', '3rd gen'],
61
+ 'iPhone14,7' => ['iPhone 14'],
62
+ 'iPhone14,8' => ['iPhone 14 Plus'],
63
+ 'iPhone15,2' => ['iPhone 14 Pro'],
64
+ 'iPhone15,3' => ['iPhone 14 Pro Max'],
65
+ 'iPhone15,4' => ['iPhone 15'],
66
+ 'iPhone15,5' => ['iPhone 15 Plus'],
67
+ 'iPhone16,1' => ['iPhone 15 Pro'],
68
+ 'iPhone16,2' => ['iPhone 15 Pro Max'],
69
+ 'iPhone17,1' => ['iPhone 16 Pro'],
70
+ 'iPhone17,2' => ['iPhone 16 Pro Max'],
71
+ 'iPhone17,3' => ['iPhone 16'],
72
+ 'iPhone17,4' => ['iPhone 16 Plus'],
73
+ 'iPhone17,5' => ['iPhone 16e'],
74
+ 'iPhone18,1' => ['iPhone 17 Pro'],
75
+ 'iPhone18,2' => ['iPhone 17 Pro Max'],
76
+ 'iPhone18,3' => ['iPhone 17'],
77
+ 'iPhone18,4' => ['iPhone Air'],
78
+ 'iPhone18,5' => ['iPhone 17e'],
79
+ 'iPhone19,2' => ['iPhone 18 Pro'],
80
+ 'iPhone19,3' => ['iPhone 18 Pro Max'],
81
+ 'iPhone19,4' => ['iPhone Duo'],
82
+ 'iPhone19,7' => ['iPhone 18 Pro Max'],
83
+
84
+ # iPad
85
+ 'iPad1,1' => ['iPad', 'Wi-Fi'],
86
+ 'iPad1,2' => ['iPad', 'Wi-Fi+Cellular'],
87
+ 'iPad2,1' => ['iPad 2', 'Wi-Fi'],
88
+ 'iPad2,2' => ['iPad 2', 'Wi-Fi+Cellular, GSM'],
89
+ 'iPad2,3' => ['iPad 2', 'Wi-Fi+Cellular, CDMA'],
90
+ 'iPad2,4' => ['iPad 2', 'Wi-Fi, Rev A'],
91
+ 'iPad2,5' => ['iPad mini', 'Wi-Fi'],
92
+ 'iPad2,6' => ['iPad mini', 'Wi-Fi+Cellular, GSM'],
93
+ 'iPad2,7' => ['iPad mini', 'Wi-Fi+Cellular, CDMA'],
94
+ 'iPad3,1' => ['iPad', '3rd gen, Wi-Fi'],
95
+ 'iPad3,2' => ['iPad', '3rd gen, Wi-Fi+Cellular, CDMA'],
96
+ 'iPad3,3' => ['iPad', '3rd gen, Wi-Fi+Cellular, GSM'],
97
+ 'iPad3,4' => ['iPad', '4th gen, Wi-Fi'],
98
+ 'iPad3,5' => ['iPad', '4th gen, Wi-Fi+Cellular, GSM'],
99
+ 'iPad3,6' => ['iPad', '4th gen, Wi-Fi+Cellular, CDMA'],
100
+ 'iPad4,1' => ['iPad Air', 'Wi-Fi'],
101
+ 'iPad4,2' => ['iPad Air', 'Wi-Fi+Cellular'],
102
+ 'iPad4,3' => ['iPad Air', 'Wi-Fi+Cellular, China'],
103
+ 'iPad4,4' => ['iPad mini 2', 'Wi-Fi'],
104
+ 'iPad4,5' => ['iPad mini 2', 'Wi-Fi+Cellular'],
105
+ 'iPad4,6' => ['iPad mini 2', 'Wi-Fi+Cellular, China'],
106
+ 'iPad4,7' => ['iPad mini 3', 'Wi-Fi'],
107
+ 'iPad4,8' => ['iPad mini 3', 'Wi-Fi+Cellular'],
108
+ 'iPad4,9' => ['iPad mini 3', 'Wi-Fi+Cellular, China'],
109
+ 'iPad5,1' => ['iPad mini 4', 'Wi-Fi'],
110
+ 'iPad5,2' => ['iPad mini 4', 'Wi-Fi+Cellular'],
111
+ 'iPad5,3' => ['iPad Air 2', 'Wi-Fi'],
112
+ 'iPad5,4' => ['iPad Air 2', 'Wi-Fi+Cellular'],
113
+ 'iPad6,3' => ['iPad Pro 9.7"', 'Wi-Fi'],
114
+ 'iPad6,4' => ['iPad Pro 9.7"', 'Wi-Fi+Cellular'],
115
+ 'iPad6,7' => ['iPad Pro 12.9"', '1st gen, Wi-Fi'],
116
+ 'iPad6,8' => ['iPad Pro 12.9"', '1st gen, Wi-Fi+Cellular'],
117
+ 'iPad6,11' => ['iPad', '5th gen, Wi-Fi'],
118
+ 'iPad6,12' => ['iPad', '5th gen, Wi-Fi+Cellular'],
119
+ 'iPad7,1' => ['iPad Pro 12.9"', '2nd gen, Wi-Fi'],
120
+ 'iPad7,2' => ['iPad Pro 12.9"', '2nd gen, Wi-Fi+Cellular'],
121
+ 'iPad7,3' => ['iPad Pro 10.5"', 'Wi-Fi'],
122
+ 'iPad7,4' => ['iPad Pro 10.5"', 'Wi-Fi+Cellular'],
123
+ 'iPad7,5' => ['iPad', '6th gen, Wi-Fi'],
124
+ 'iPad7,6' => ['iPad', '6th gen, Wi-Fi+Cellular'],
125
+ 'iPad7,11' => ['iPad', '7th gen, Wi-Fi'],
126
+ 'iPad7,12' => ['iPad', '7th gen, Wi-Fi+Cellular'],
127
+ 'iPad8,1' => ['iPad Pro 11"', '1st gen, Wi-Fi'],
128
+ 'iPad8,2' => ['iPad Pro 11"', '1st gen, Wi-Fi, 1TB'],
129
+ 'iPad8,3' => ['iPad Pro 11"', '1st gen, Wi-Fi+Cellular'],
130
+ 'iPad8,4' => ['iPad Pro 11"', '1st gen, Wi-Fi+Cellular, 1TB'],
131
+ 'iPad8,5' => ['iPad Pro 12.9"', '3rd gen, Wi-Fi'],
132
+ 'iPad8,6' => ['iPad Pro 12.9"', '3rd gen, Wi-Fi, 1TB'],
133
+ 'iPad8,7' => ['iPad Pro 12.9"', '3rd gen, Wi-Fi+Cellular'],
134
+ 'iPad8,8' => ['iPad Pro 12.9"', '3rd gen, Wi-Fi+Cellular, 1TB'],
135
+ 'iPad8,9' => ['iPad Pro 11"', '2nd gen, Wi-Fi'],
136
+ 'iPad8,10' => ['iPad Pro 11"', '2nd gen, Wi-Fi+Cellular'],
137
+ 'iPad8,11' => ['iPad Pro 12.9"', '4th gen, Wi-Fi'],
138
+ 'iPad8,12' => ['iPad Pro 12.9"', '4th gen, Wi-Fi+Cellular'],
139
+ 'iPad11,1' => ['iPad mini', '5th gen, Wi-Fi'],
140
+ 'iPad11,2' => ['iPad mini', '5th gen, Wi-Fi+Cellular'],
141
+ 'iPad11,3' => ['iPad Air', '3rd gen, Wi-Fi'],
142
+ 'iPad11,4' => ['iPad Air', '3rd gen, Wi-Fi+Cellular'],
143
+ 'iPad11,6' => ['iPad', '8th gen, Wi-Fi'],
144
+ 'iPad11,7' => ['iPad', '8th gen, Wi-Fi+Cellular'],
145
+ 'iPad12,1' => ['iPad', '9th gen, Wi-Fi'],
146
+ 'iPad12,2' => ['iPad', '9th gen, Wi-Fi+Cellular'],
147
+ 'iPad13,1' => ['iPad Air', '4th gen, Wi-Fi'],
148
+ 'iPad13,2' => ['iPad Air', '4th gen, Wi-Fi+Cellular'],
149
+ 'iPad13,4' => ['iPad Pro 11"', '3rd gen, Wi-Fi'],
150
+ 'iPad13,5' => ['iPad Pro 11"', '3rd gen, Wi-Fi+Cellular'],
151
+ 'iPad13,6' => ['iPad Pro 11"', '3rd gen, Wi-Fi+Cellular'],
152
+ 'iPad13,7' => ['iPad Pro 11"', '3rd gen, Wi-Fi+Cellular'],
153
+ 'iPad13,8' => ['iPad Pro 12.9"', '5th gen, Wi-Fi'],
154
+ 'iPad13,9' => ['iPad Pro 12.9"', '5th gen, Wi-Fi+Cellular'],
155
+ 'iPad13,10' => ['iPad Pro 12.9"', '5th gen, Wi-Fi+Cellular'],
156
+ 'iPad13,11' => ['iPad Pro 12.9"', '5th gen, Wi-Fi+Cellular'],
157
+ 'iPad13,16' => ['iPad Air', '5th gen, Wi-Fi'],
158
+ 'iPad13,17' => ['iPad Air', '5th gen, Wi-Fi+Cellular'],
159
+ 'iPad13,18' => ['iPad', '10th gen, Wi-Fi'],
160
+ 'iPad13,19' => ['iPad', '10th gen, Wi-Fi+Cellular'],
161
+ 'iPad14,1' => ['iPad mini', '6th gen, Wi-Fi'],
162
+ 'iPad14,2' => ['iPad mini', '6th gen, Wi-Fi+Cellular'],
163
+ 'iPad14,3' => ['iPad Pro 11"', '4th gen, Wi-Fi'],
164
+ 'iPad14,4' => ['iPad Pro 11"', '4th gen, Wi-Fi+Cellular'],
165
+ 'iPad14,5' => ['iPad Pro 12.9"', '6th gen, Wi-Fi'],
166
+ 'iPad14,6' => ['iPad Pro 12.9"', '6th gen, Wi-Fi+Cellular'],
167
+ 'iPad14,8' => ['iPad Air 11"', 'M2, Wi-Fi'],
168
+ 'iPad14,9' => ['iPad Air 11"', 'M2, Wi-Fi+Cellular'],
169
+ 'iPad14,10' => ['iPad Air 13"', 'M2, Wi-Fi'],
170
+ 'iPad14,11' => ['iPad Air 13"', 'M2, Wi-Fi+Cellular'],
171
+ 'iPad15,3' => ['iPad Air 11"', 'M3, Wi-Fi'],
172
+ 'iPad15,4' => ['iPad Air 11"', 'M3, Wi-Fi+Cellular'],
173
+ 'iPad15,5' => ['iPad Air 13"', 'M3, Wi-Fi'],
174
+ 'iPad15,6' => ['iPad Air 13"', 'M3, Wi-Fi+Cellular'],
175
+ 'iPad15,7' => ['iPad', 'A16, Wi-Fi'],
176
+ 'iPad15,8' => ['iPad', 'A16, Wi-Fi+Cellular'],
177
+ 'iPad16,1' => ['iPad mini', 'A17 Pro, Wi-Fi'],
178
+ 'iPad16,2' => ['iPad mini', 'A17 Pro, Wi-Fi+Cellular'],
179
+ 'iPad16,3' => ['iPad Pro 11"', 'M4, Wi-Fi'],
180
+ 'iPad16,4' => ['iPad Pro 11"', 'M4, Wi-Fi+Cellular'],
181
+ 'iPad16,5' => ['iPad Pro 13"', 'M4, Wi-Fi'],
182
+ 'iPad16,6' => ['iPad Pro 13"', 'M4, Wi-Fi+Cellular'],
183
+ 'iPad16,8' => ['iPad Air 11"', 'M4, Wi-Fi'],
184
+ 'iPad16,9' => ['iPad Air 11"', 'M4, Wi-Fi+Cellular'],
185
+ 'iPad16,10' => ['iPad Air 13"', 'M4, Wi-Fi'],
186
+ 'iPad16,11' => ['iPad Air 13"', 'M4, Wi-Fi+Cellular'],
187
+ 'iPad17,1' => ['iPad Pro 11"', 'M5, Wi-Fi'],
188
+ 'iPad17,2' => ['iPad Pro 11"', 'M5, Wi-Fi+Cellular'],
189
+ 'iPad17,3' => ['iPad Pro 13"', 'M5, Wi-Fi'],
190
+ 'iPad17,4' => ['iPad Pro 13"', 'M5, Wi-Fi+Cellular'],
191
+
192
+ # iPod touch
193
+ 'iPod1,1' => ['iPod touch'],
194
+ 'iPod2,1' => ['iPod touch', '2nd gen'],
195
+ 'iPod3,1' => ['iPod touch', '3rd gen'],
196
+ 'iPod4,1' => ['iPod touch', '4th gen'],
197
+ 'iPod5,1' => ['iPod touch', '5th gen'],
198
+ 'iPod7,1' => ['iPod touch', '6th gen'],
199
+ 'iPod9,1' => ['iPod touch', '7th gen'],
200
+
201
+ # Apple Watch
202
+ 'Watch1,1' => ['Apple Watch', '1st gen, 38mm'],
203
+ 'Watch1,2' => ['Apple Watch', '1st gen, 42mm'],
204
+ 'Watch2,6' => ['Apple Watch Series 1', '38mm'],
205
+ 'Watch2,7' => ['Apple Watch Series 1', '42mm'],
206
+ 'Watch2,3' => ['Apple Watch Series 2', '38mm'],
207
+ 'Watch2,4' => ['Apple Watch Series 2', '42mm'],
208
+ 'Watch3,1' => ['Apple Watch Series 3', '38mm, GPS+Cellular'],
209
+ 'Watch3,2' => ['Apple Watch Series 3', '42mm, GPS+Cellular'],
210
+ 'Watch3,3' => ['Apple Watch Series 3', '38mm, GPS'],
211
+ 'Watch3,4' => ['Apple Watch Series 3', '42mm, GPS'],
212
+ 'Watch4,1' => ['Apple Watch Series 4', '40mm, GPS'],
213
+ 'Watch4,2' => ['Apple Watch Series 4', '44mm, GPS'],
214
+ 'Watch4,3' => ['Apple Watch Series 4', '40mm, GPS+Cellular'],
215
+ 'Watch4,4' => ['Apple Watch Series 4', '44mm, GPS+Cellular'],
216
+ 'Watch5,1' => ['Apple Watch Series 5', '40mm, GPS'],
217
+ 'Watch5,2' => ['Apple Watch Series 5', '44mm, GPS'],
218
+ 'Watch5,3' => ['Apple Watch Series 5', '40mm, GPS+Cellular'],
219
+ 'Watch5,4' => ['Apple Watch Series 5', '44mm, GPS+Cellular'],
220
+ 'Watch5,9' => ['Apple Watch SE', '40mm, GPS'],
221
+ 'Watch5,10' => ['Apple Watch SE', '44mm, GPS'],
222
+ 'Watch5,11' => ['Apple Watch SE', '40mm, GPS+Cellular'],
223
+ 'Watch5,12' => ['Apple Watch SE', '44mm, GPS+Cellular'],
224
+ 'Watch6,1' => ['Apple Watch Series 6', '40mm, GPS'],
225
+ 'Watch6,2' => ['Apple Watch Series 6', '44mm, GPS'],
226
+ 'Watch6,3' => ['Apple Watch Series 6', '40mm, GPS+Cellular'],
227
+ 'Watch6,4' => ['Apple Watch Series 6', '44mm, GPS+Cellular'],
228
+ 'Watch6,6' => ['Apple Watch Series 7', '41mm, GPS'],
229
+ 'Watch6,7' => ['Apple Watch Series 7', '45mm, GPS'],
230
+ 'Watch6,8' => ['Apple Watch Series 7', '41mm, GPS+Cellular'],
231
+ 'Watch6,9' => ['Apple Watch Series 7', '45mm, GPS+Cellular'],
232
+ 'Watch6,10' => ['Apple Watch SE', '2nd gen, 40mm, GPS'],
233
+ 'Watch6,11' => ['Apple Watch SE', '2nd gen, 44mm, GPS'],
234
+ 'Watch6,12' => ['Apple Watch SE', '2nd gen, 40mm, GPS+Cellular'],
235
+ 'Watch6,13' => ['Apple Watch SE', '2nd gen, 44mm, GPS+Cellular'],
236
+ 'Watch6,14' => ['Apple Watch Series 8', '41mm, GPS'],
237
+ 'Watch6,15' => ['Apple Watch Series 8', '45mm, GPS'],
238
+ 'Watch6,16' => ['Apple Watch Series 8', '41mm, GPS+Cellular'],
239
+ 'Watch6,17' => ['Apple Watch Series 8', '45mm, GPS+Cellular'],
240
+ 'Watch6,18' => ['Apple Watch Ultra'],
241
+ 'Watch7,1' => ['Apple Watch Series 9', '41mm, GPS'],
242
+ 'Watch7,2' => ['Apple Watch Series 9', '45mm, GPS'],
243
+ 'Watch7,3' => ['Apple Watch Series 9', '41mm, GPS+Cellular'],
244
+ 'Watch7,4' => ['Apple Watch Series 9', '45mm, GPS+Cellular'],
245
+ 'Watch7,5' => ['Apple Watch Ultra 2'],
246
+ 'Watch7,8' => ['Apple Watch Series 10', '42mm, GPS'],
247
+ 'Watch7,9' => ['Apple Watch Series 10', '46mm, GPS'],
248
+ 'Watch7,10' => ['Apple Watch Series 10', '42mm, GPS+Cellular'],
249
+ 'Watch7,11' => ['Apple Watch Series 10', '46mm, GPS+Cellular'],
250
+ 'Watch7,12' => ['Apple Watch Ultra 3'],
251
+ 'Watch7,13' => ['Apple Watch SE 3', '40mm, GPS'],
252
+ 'Watch7,14' => ['Apple Watch SE 3', '44mm, GPS'],
253
+ 'Watch7,15' => ['Apple Watch SE 3', '40mm, GPS+Cellular'],
254
+ 'Watch7,16' => ['Apple Watch SE 3', '44mm, GPS+Cellular'],
255
+ 'Watch7,17' => ['Apple Watch Series 11', '42mm, GPS'],
256
+ 'Watch7,18' => ['Apple Watch Series 11', '46mm, GPS'],
257
+ 'Watch7,19' => ['Apple Watch Series 11', '42mm, GPS+Cellular'],
258
+ 'Watch7,20' => ['Apple Watch Series 11', '46mm, GPS+Cellular'],
259
+ 'Watch8,1' => ['Apple Watch Ultra 4'],
260
+ 'Watch8,2' => ['Apple Watch Series 12', '42mm, GPS'],
261
+ 'Watch8,3' => ['Apple Watch Series 12', '46mm, GPS'],
262
+ 'Watch8,4' => ['Apple Watch Series 12', '42mm, GPS+Cellular'],
263
+ 'Watch8,5' => ['Apple Watch Series 12', '46mm, GPS+Cellular']
264
+ }.transform_values(&:freeze).freeze
265
+ private_constant :DEVICE_TYPES
266
+ end
267
+ end
@@ -3,14 +3,44 @@
3
3
  module Ios
4
4
  module Devices
5
5
  # Represents an iOS device model. Every device has a type and name and some
6
- # of them also have extra information (Revision, Wi-fi, etc.)
6
+ # of them also have extra information (generation, size, connectivity, etc.)
7
+ #
8
+ # Models are immutable and compare equal when all their attributes are equal.
7
9
  class Model
8
- attr_accessor :device_type, :name, :extra
10
+ attr_reader :device_type, :name, :extra
9
11
 
10
12
  def initialize(device_type, name, extra = nil)
11
13
  @device_type = device_type
12
14
  @name = name
13
15
  @extra = extra
16
+ freeze
17
+ end
18
+
19
+ # Whether the device type is in the list of known devices.
20
+ def known?
21
+ name != UNKNOWN_IOS_DEVICE
22
+ end
23
+
24
+ def unknown?
25
+ !known?
26
+ end
27
+
28
+ # The full model name, e.g. "iPad mini (A17 Pro, Wi-Fi+Cellular)".
29
+ def to_s
30
+ extra ? "#{name} (#{extra})" : name
31
+ end
32
+
33
+ def to_h
34
+ { device_type: device_type, name: name, extra: extra }
35
+ end
36
+
37
+ def ==(other)
38
+ other.instance_of?(self.class) && other.to_h == to_h
39
+ end
40
+ alias eql? ==
41
+
42
+ def hash
43
+ [self.class, device_type, name, extra].hash
14
44
  end
15
45
  end
16
46
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Ios
4
4
  module Devices
5
- VERSION = '0.4.0'
5
+ VERSION = '0.5.0'
6
6
  end
7
7
  end
data/lib/ios/devices.rb CHANGED
@@ -2,11 +2,20 @@
2
2
 
3
3
  require 'ios/devices/version'
4
4
  require 'ios/devices/model'
5
+ require 'ios/devices/device_types'
5
6
 
7
+ # Namespace for the ios-devices gem.
6
8
  module Ios
7
- UNKNOWN_IOS_DEVICE = 'Unknown iOS device'
8
-
9
+ # Translates Apple device types (like "iPhone6,1") to device models.
9
10
  module Devices
11
+ UNKNOWN_IOS_DEVICE = 'Unknown iOS device'
12
+
13
+ # Models are immutable, so every known device type gets one shared instance.
14
+ MODELS = DEVICE_TYPES.to_h do |device_type, (name, extra)|
15
+ [device_type, Model.new(device_type, name, extra)]
16
+ end.freeze
17
+ private_constant :MODELS
18
+
10
19
  # Gets the official device for the given device type from the iOS devices.
11
20
  #
12
21
  # Examples:
@@ -15,455 +24,32 @@ module Ios
15
24
  # => #<Ios::Devices::Model:0x007fa55ba1a948 @device_type="iPhone6,1", @name="iPhone 5s", @extra=nil>
16
25
  #
17
26
  # Ios::Devices.search('iPad2,2')
18
- # => #<Ios::Devices::Model:0x007fa55b957308 @device_type="iPad2,2", @name="iPad 2", @extra="GSM">
27
+ # => #<Ios::Devices::Model:0x007fa55b957308 @device_type="iPad2,2", @name="iPad 2", @extra="Wi-Fi+Cellular, GSM">
19
28
  #
20
- # Unknown device types return a Model named Ios::UNKNOWN_IOS_DEVICE.
29
+ # Unknown device types return a Model named Ios::Devices::UNKNOWN_IOS_DEVICE.
21
30
  def self.search(device_type)
22
- # See "Adding new devices" in the README for sources to check identifiers against.
23
- case device_type
24
- when 'i386', 'x86_64', 'arm64'
25
- Model.new(device_type, 'iOS Simulator')
26
- when 'iPhone1,1'
27
- Model.new(device_type, 'iPhone')
28
- when 'iPhone1,2'
29
- Model.new(device_type, 'iPhone 3G')
30
- when 'iPhone2,1'
31
- Model.new(device_type, 'iPhone 3GS')
32
- when 'iPhone3,1'
33
- Model.new(device_type, 'iPhone 4', 'GSM')
34
- when 'iPhone3,2'
35
- Model.new(device_type, 'iPhone 4', 'GSM Rev A')
36
- when 'iPhone3,3'
37
- Model.new(device_type, 'iPhone 4', 'CDMA')
38
- when 'iPhone4,1'
39
- Model.new(device_type, 'iPhone 4S')
40
- when 'iPhone5,1', 'iPhone5,2'
41
- Model.new(device_type, 'iPhone 5')
42
- when 'iPhone5,3', 'iPhone5,4'
43
- Model.new(device_type, 'iPhone 5c')
44
- when 'iPhone6,1', 'iPhone6,2'
45
- Model.new(device_type, 'iPhone 5s')
46
- when 'iPhone7,1'
47
- Model.new(device_type, 'iPhone 6 Plus')
48
- when 'iPhone7,2'
49
- Model.new(device_type, 'iPhone 6')
50
- when 'iPhone8,1'
51
- Model.new(device_type, 'iPhone 6s')
52
- when 'iPhone8,2'
53
- Model.new(device_type, 'iPhone 6s Plus')
54
- when 'iPhone8,4'
55
- Model.new(device_type, 'iPhone SE')
56
- when 'iPhone9,1', 'iPhone9,3'
57
- Model.new(device_type, 'iPhone 7')
58
- when 'iPhone9,2', 'iPhone9,4'
59
- Model.new(device_type, 'iPhone 7 Plus')
60
- when 'iPhone10,1', 'iPhone10,4'
61
- Model.new(device_type, 'iPhone 8')
62
- when 'iPhone10,2', 'iPhone10,5'
63
- Model.new(device_type, 'iPhone 8 Plus')
64
- when 'iPhone10,3', 'iPhone10,6'
65
- Model.new(device_type, 'iPhone X')
66
- when 'iPhone11,2'
67
- Model.new(device_type, 'iPhone XS')
68
- when 'iPhone11,4', 'iPhone11,6'
69
- Model.new(device_type, 'iPhone XS Max')
70
- when 'iPhone11,8'
71
- Model.new(device_type, 'iPhone XR')
72
- when 'iPhone12,1'
73
- Model.new(device_type, 'iPhone 11')
74
- when 'iPhone12,3'
75
- Model.new(device_type, 'iPhone 11 Pro')
76
- when 'iPhone12,5'
77
- Model.new(device_type, 'iPhone 11 Pro Max')
78
- when 'iPhone12,8'
79
- Model.new(device_type, 'iPhone SE', '2nd gen')
80
- when 'iPhone13,1'
81
- Model.new(device_type, 'iPhone 12 Mini')
82
- when 'iPhone13,2'
83
- Model.new(device_type, 'iPhone 12')
84
- when 'iPhone13,3'
85
- Model.new(device_type, 'iPhone 12 Pro')
86
- when 'iPhone13,4'
87
- Model.new(device_type, 'iPhone 12 Pro Max')
88
- when 'iPhone14,2'
89
- Model.new(device_type, 'iPhone 13 Pro')
90
- when 'iPhone14,3'
91
- Model.new(device_type, 'iPhone 13 Pro Max')
92
- when 'iPhone14,4'
93
- Model.new(device_type, 'iPhone 13 Mini')
94
- when 'iPhone14,5'
95
- Model.new(device_type, 'iPhone 13')
96
- when 'iPhone14,6'
97
- Model.new(device_type, 'iPhone SE', '3rd gen')
98
- when 'iPhone14,7'
99
- Model.new(device_type, 'iPhone 14')
100
- when 'iPhone14,8'
101
- Model.new(device_type, 'iPhone 14 Plus')
102
- when 'iPhone15,2'
103
- Model.new(device_type, 'iPhone 14 Pro')
104
- when 'iPhone15,3'
105
- Model.new(device_type, 'iPhone 14 Pro Max')
106
- when 'iPhone15,4'
107
- Model.new(device_type, 'iPhone 15')
108
- when 'iPhone15,5'
109
- Model.new(device_type, 'iPhone 15 Plus')
110
- when 'iPhone16,1'
111
- Model.new(device_type, 'iPhone 15 Pro')
112
- when 'iPhone16,2'
113
- Model.new(device_type, 'iPhone 15 Pro Max')
114
- when 'iPhone17,1'
115
- Model.new(device_type, 'iPhone 16 Pro')
116
- when 'iPhone17,2'
117
- Model.new(device_type, 'iPhone 16 Pro Max')
118
- when 'iPhone17,3'
119
- Model.new(device_type, 'iPhone 16')
120
- when 'iPhone17,4'
121
- Model.new(device_type, 'iPhone 16 Plus')
122
- when 'iPhone17,5'
123
- Model.new(device_type, 'iPhone 16e')
124
- when 'iPhone18,1'
125
- Model.new(device_type, 'iPhone 17 Pro')
126
- when 'iPhone18,2'
127
- Model.new(device_type, 'iPhone 17 Pro Max')
128
- when 'iPhone18,3'
129
- Model.new(device_type, 'iPhone 17')
130
- when 'iPhone18,4'
131
- Model.new(device_type, 'iPhone Air')
132
- when 'iPhone18,5'
133
- Model.new(device_type, 'iPhone 17e')
134
- when 'iPhone19,2'
135
- Model.new(device_type, 'iPhone 18 Pro')
136
- when 'iPhone19,3', 'iPhone19,7'
137
- Model.new(device_type, 'iPhone 18 Pro Max')
138
- when 'iPad1,1'
139
- Model.new(device_type, 'iPad')
140
- when 'iPad1,2'
141
- Model.new(device_type, 'iPad', '3G')
142
- when 'iPad2,1'
143
- Model.new(device_type, 'iPad 2', 'Wi-Fi')
144
- when 'iPad2,2'
145
- Model.new(device_type, 'iPad 2', 'GSM')
146
- when 'iPad2,3'
147
- Model.new(device_type, 'iPad 2', 'CDMA')
148
- when 'iPad2,4'
149
- Model.new(device_type, 'iPad 2', 'Wi-Fi, revised')
150
- when 'iPad2,5'
151
- Model.new(device_type, 'iPad mini', 'Wi-Fi')
152
- when 'iPad2,6', 'iPad2,7'
153
- Model.new(device_type, 'iPad mini')
154
- when 'iPad3,1'
155
- Model.new(device_type, 'iPad', '3rd gen, Wi-Fi')
156
- when 'iPad3,2'
157
- Model.new(device_type, 'iPad', '3rd gen, Wi-Fi+LTE Verizon')
158
- when 'iPad3,3'
159
- Model.new(device_type, 'iPad', '3rd gen, Wi-Fi+LTE AT&T')
160
- when 'iPad3,4'
161
- Model.new(device_type, 'iPad', '4th gen, Wi-Fi')
162
- when 'iPad3,5', 'iPad3,6'
163
- Model.new(device_type, 'iPad', '4th gen')
164
- when 'iPad4,1'
165
- Model.new(device_type, 'iPad Air', 'Wi-Fi')
166
- when 'iPad4,2'
167
- Model.new(device_type, 'iPad Air', 'Wi-Fi+LTE')
168
- when 'iPad4,3'
169
- Model.new(device_type, 'iPad Air', 'Rev')
170
- when 'iPad4,4'
171
- Model.new(device_type, 'iPad mini 2', 'Wi-Fi')
172
- when 'iPad4,5'
173
- Model.new(device_type, 'iPad mini 2', 'Wi-Fi+LTE')
174
- when 'iPad4,6'
175
- Model.new(device_type, 'iPad mini 2', 'Rev')
176
- when 'iPad4,7'
177
- Model.new(device_type, 'iPad mini 3', 'Wi-Fi')
178
- when 'iPad4,8', 'iPad4,9'
179
- Model.new(device_type, 'iPad mini 3')
180
- when 'iPad5,1'
181
- Model.new(device_type, 'iPad mini 4', 'Wi-Fi')
182
- when 'iPad5,2'
183
- Model.new(device_type, 'iPad mini 4', 'Wi-Fi+LTE')
184
- when 'iPad5,3'
185
- Model.new(device_type, 'iPad Air 2', 'Wi-Fi')
186
- when 'iPad5,4'
187
- Model.new(device_type, 'iPad Air 2', 'Wi-Fi+LTE')
188
- when 'iPad6,3'
189
- Model.new(device_type, 'iPad Pro 9.7"', 'Wi-Fi')
190
- when 'iPad6,4'
191
- Model.new(device_type, 'iPad Pro 9.7"', 'Wi-Fi+LTE')
192
- when 'iPad6,7'
193
- Model.new(device_type, 'iPad Pro 12.9"', 'Wi-Fi')
194
- when 'iPad6,8'
195
- Model.new(device_type, 'iPad Pro 12.9"', 'Wi-Fi+LTE')
196
- when 'iPad6,11'
197
- Model.new(device_type, 'iPad', '5th gen, Wi-Fi')
198
- when 'iPad6,12'
199
- Model.new(device_type, 'iPad', '5th gen, Wi-Fi+LTE')
200
- when 'iPad7,1'
201
- Model.new(device_type, 'iPad Pro 12.9"', '2nd gen, Wi-Fi')
202
- when 'iPad7,2'
203
- Model.new(device_type, 'iPad Pro 12.9"', '2nd gen, Wi-Fi+LTE')
204
- when 'iPad7,3'
205
- Model.new(device_type, 'iPad Pro 10.5"', 'Wi-Fi')
206
- when 'iPad7,4'
207
- Model.new(device_type, 'iPad Pro 10.5"', 'Wi-Fi+LTE')
208
- when 'iPad7,5'
209
- Model.new(device_type, 'iPad', '6th gen, Wi-Fi')
210
- when 'iPad7,6'
211
- Model.new(device_type, 'iPad', '6th gen, Wi-Fi+LTE')
212
- when 'iPad7,11'
213
- Model.new(device_type, 'iPad 10.2"', '7th gen, Wi-Fi')
214
- when 'iPad7,12'
215
- Model.new(device_type, 'iPad 10.2"', '7th gen, Wi-Fi+LTE')
216
- when 'iPad8,1'
217
- Model.new(device_type, 'iPad Pro 11"', 'Wi-Fi')
218
- when 'iPad8,2'
219
- Model.new(device_type, 'iPad Pro 11"', 'Wi-Fi')
220
- when 'iPad8,3'
221
- Model.new(device_type, 'iPad Pro 11"', 'Wi-Fi+LTE')
222
- when 'iPad8,4'
223
- Model.new(device_type, 'iPad Pro 11"', 'Wi-Fi+LTE')
224
- when 'iPad8,5'
225
- Model.new(device_type, 'iPad Pro 12.9"', '3rd gen, Wi-Fi')
226
- when 'iPad8,6'
227
- Model.new(device_type, 'iPad Pro 12.9"', '3rd gen, Wi-Fi')
228
- when 'iPad8,7'
229
- Model.new(device_type, 'iPad Pro 12.9"', '3rd gen, Wi-Fi+LTE')
230
- when 'iPad8,8'
231
- Model.new(device_type, 'iPad Pro 12.9"', '3rd gen, Wi-Fi+LTE')
232
- when 'iPad8,9'
233
- Model.new(device_type, 'iPad Pro 11"', '2nd gen, Wi-Fi')
234
- when 'iPad8,10'
235
- Model.new(device_type, 'iPad Pro 11"', '2nd gen, Wi-Fi+LTE')
236
- when 'iPad8,11'
237
- Model.new(device_type, 'iPad Pro 12.9"', '4th gen, Wi-Fi')
238
- when 'iPad8,12'
239
- Model.new(device_type, 'iPad Pro 12.9"', '4th gen, Wi-Fi+LTE')
240
- when 'iPad11,1'
241
- Model.new(device_type, 'iPad mini 5', 'Wi-Fi')
242
- when 'iPad11,2'
243
- Model.new(device_type, 'iPad mini 5', 'Wi-Fi+LTE')
244
- when 'iPad11,3'
245
- Model.new(device_type, 'iPad Air 3', 'Wi-Fi')
246
- when 'iPad11,4'
247
- Model.new(device_type, 'iPad Air 3', 'Wi-Fi+LTE')
248
- when 'iPad11,6'
249
- Model.new(device_type, 'iPad', '8th gen, Wi-Fi')
250
- when 'iPad11,7'
251
- Model.new(device_type, 'iPad', '8th gen, Wi-Fi+LTE')
252
- when 'iPad12,1'
253
- Model.new(device_type, 'iPad', '9th gen, Wi-Fi')
254
- when 'iPad12,2'
255
- Model.new(device_type, 'iPad', '9th gen, Wi-Fi+LTE')
256
- when 'iPad13,1'
257
- Model.new(device_type, 'iPad Air 4', 'Wi-Fi')
258
- when 'iPad13,2'
259
- Model.new(device_type, 'iPad Air 4', 'Wi-Fi+LTE')
260
- when 'iPad13,4'
261
- Model.new(device_type, 'iPad Pro 11"', '3rd gen, Wi-Fi')
262
- when 'iPad13,5', 'iPad13,6', 'iPad13,7'
263
- Model.new(device_type, 'iPad Pro 11"', '3rd gen, Wi-Fi+LTE')
264
- when 'iPad13,8'
265
- Model.new(device_type, 'iPad Pro 12.9"', '5th gen, Wi-Fi')
266
- when 'iPad13,9', 'iPad13,10', 'iPad13,11'
267
- Model.new(device_type, 'iPad Pro 12.9"', '5th gen, Wi-Fi+LTE')
268
- when 'iPad13,16'
269
- Model.new(device_type, 'iPad Air', '5th gen, Wi-Fi')
270
- when 'iPad13,17'
271
- Model.new(device_type, 'iPad Air', '5th gen, Wi-Fi+LTE')
272
- when 'iPad13,18'
273
- Model.new(device_type, 'iPad', '10th gen, Wi-Fi')
274
- when 'iPad13,19'
275
- Model.new(device_type, 'iPad', '10th gen, Wi-Fi+LTE')
276
- when 'iPad14,1'
277
- Model.new(device_type, 'iPad mini 6', 'Wi-Fi')
278
- when 'iPad14,2'
279
- Model.new(device_type, 'iPad mini 6', 'Wi-Fi+LTE')
280
- when 'iPad14,3'
281
- Model.new(device_type, 'iPad Pro 11"', '4th Gen, Wi-Fi')
282
- when 'iPad14,4'
283
- Model.new(device_type, 'iPad Pro 11"', '4th Gen, Wi-Fi+LTE')
284
- when 'iPad14,5'
285
- Model.new(device_type, 'iPad Pro 12.9"', '6th Gen, Wi-Fi')
286
- when 'iPad14,6'
287
- Model.new(device_type, 'iPad Pro 12.9"', '6th Gen, Wi-Fi+LTE')
288
- when 'iPad14,8'
289
- Model.new(device_type, 'iPad Air 11"', 'M2, Wi-Fi')
290
- when 'iPad14,9'
291
- Model.new(device_type, 'iPad Air 11"', 'M2, Wi-Fi+LTE')
292
- when 'iPad14,10'
293
- Model.new(device_type, 'iPad Air 13"', 'M2, Wi-Fi')
294
- when 'iPad14,11'
295
- Model.new(device_type, 'iPad Air 13"', 'M2, Wi-Fi+LTE')
296
- when 'iPad15,3'
297
- Model.new(device_type, 'iPad Air 11"', 'M3, Wi-Fi')
298
- when 'iPad15,4'
299
- Model.new(device_type, 'iPad Air 11"', 'M3, Wi-Fi+LTE')
300
- when 'iPad15,5'
301
- Model.new(device_type, 'iPad Air 13"', 'M3, Wi-Fi')
302
- when 'iPad15,6'
303
- Model.new(device_type, 'iPad Air 13"', 'M3, Wi-Fi+LTE')
304
- when 'iPad15,7'
305
- Model.new(device_type, 'iPad', '11th gen, Wi-Fi')
306
- when 'iPad15,8'
307
- Model.new(device_type, 'iPad', '11th gen, Wi-Fi+LTE')
308
- when 'iPad16,1'
309
- Model.new(device_type, 'iPad mini 7', 'Wi-Fi')
310
- when 'iPad16,2'
311
- Model.new(device_type, 'iPad mini 7', 'Wi-Fi+LTE')
312
- when 'iPad16,3'
313
- Model.new(device_type, 'iPad Pro 11"', 'M4, Wi-Fi')
314
- when 'iPad16,4'
315
- Model.new(device_type, 'iPad Pro 11"', 'M4, Wi-Fi+LTE')
316
- when 'iPad16,5'
317
- Model.new(device_type, 'iPad Pro 13"', 'M4, Wi-Fi')
318
- when 'iPad16,6'
319
- Model.new(device_type, 'iPad Pro 13"', 'M4, Wi-Fi+LTE')
320
- when 'iPad16,8'
321
- Model.new(device_type, 'iPad Air 11"', 'M4, Wi-Fi')
322
- when 'iPad16,9'
323
- Model.new(device_type, 'iPad Air 11"', 'M4, Wi-Fi+LTE')
324
- when 'iPad16,10'
325
- Model.new(device_type, 'iPad Air 13"', 'M4, Wi-Fi')
326
- when 'iPad16,11'
327
- Model.new(device_type, 'iPad Air 13"', 'M4, Wi-Fi+LTE')
328
- when 'iPad17,1'
329
- Model.new(device_type, 'iPad Pro 11"', 'M5, Wi-Fi')
330
- when 'iPad17,2'
331
- Model.new(device_type, 'iPad Pro 11"', 'M5, Wi-Fi+LTE')
332
- when 'iPad17,3'
333
- Model.new(device_type, 'iPad Pro 13"', 'M5, Wi-Fi')
334
- when 'iPad17,4'
335
- Model.new(device_type, 'iPad Pro 13"', 'M5, Wi-Fi+LTE')
336
- when 'iPod1,1'
337
- Model.new(device_type, 'iPod touch')
338
- when 'iPod2,1'
339
- Model.new(device_type, 'iPod touch', '2nd gen')
340
- when 'iPod3,1'
341
- Model.new(device_type, 'iPod touch', '3rd gen')
342
- when 'iPod4,1'
343
- Model.new(device_type, 'iPod touch', '4th gen')
344
- when 'iPod5,1'
345
- Model.new(device_type, 'iPod touch', '5th gen')
346
- when 'iPod7,1'
347
- Model.new(device_type, 'iPod touch', '6th gen')
348
- when 'iPod9,1'
349
- Model.new(device_type, 'iPod touch', '7th gen')
350
- when 'Watch1,1'
351
- Model.new(device_type, 'Apple Watch', '38mm')
352
- when 'Watch1,2'
353
- Model.new(device_type, 'Apple Watch', '42mm')
354
- when 'Watch2,6'
355
- Model.new(device_type, 'Apple Watch', 'Series 1, 38mm')
356
- when 'Watch2,7'
357
- Model.new(device_type, 'Apple Watch', 'Series 1, 42mm')
358
- when 'Watch2,3'
359
- Model.new(device_type, 'Apple Watch', 'Series 2, 38mm')
360
- when 'Watch2,4'
361
- Model.new(device_type, 'Apple Watch', 'Series 2, 42mm')
362
- when 'Watch3,1'
363
- Model.new(device_type, 'Apple Watch', 'Series 3, 38mm, GPS+Cellular')
364
- when 'Watch3,2'
365
- Model.new(device_type, 'Apple Watch', 'Series 3, 42mm, GPS+Cellular')
366
- when 'Watch3,3'
367
- Model.new(device_type, 'Apple Watch', 'Series 3, 38mm, GPS')
368
- when 'Watch3,4'
369
- Model.new(device_type, 'Apple Watch', 'Series 3, 42mm, GPS')
370
- when 'Watch4,1'
371
- Model.new(device_type, 'Apple Watch', 'Series 4, 40mm, GPS')
372
- when 'Watch4,2'
373
- Model.new(device_type, 'Apple Watch', 'Series 4, 44mm, GPS')
374
- when 'Watch4,3'
375
- Model.new(device_type, 'Apple Watch', 'Series 4, 40mm, GPS+Cellular')
376
- when 'Watch4,4'
377
- Model.new(device_type, 'Apple Watch', 'Series 4, 44mm, GPS+Cellular')
378
- when 'Watch5,1'
379
- Model.new(device_type, 'Apple Watch', 'Series 5, 40mm, GPS')
380
- when 'Watch5,2'
381
- Model.new(device_type, 'Apple Watch', 'Series 5, 44mm, GPS')
382
- when 'Watch5,3'
383
- Model.new(device_type, 'Apple Watch', 'Series 5, 40mm, GPS+Cellular')
384
- when 'Watch5,4'
385
- Model.new(device_type, 'Apple Watch', 'Series 5, 44mm, GPS+Cellular')
386
- when 'Watch5,9'
387
- Model.new(device_type, 'Apple Watch', 'SE, 40mm, GPS')
388
- when 'Watch5,10'
389
- Model.new(device_type, 'Apple Watch', 'SE, 44mm, GPS')
390
- when 'Watch5,11'
391
- Model.new(device_type, 'Apple Watch', 'SE, 40mm, GPS+Cellular')
392
- when 'Watch5,12'
393
- Model.new(device_type, 'Apple Watch', 'SE, 44mm, GPS+Cellular')
394
- when 'Watch6,1'
395
- Model.new(device_type, 'Apple Watch', 'Series 6, 40mm, GPS')
396
- when 'Watch6,2'
397
- Model.new(device_type, 'Apple Watch', 'Series 6, 44mm, GPS')
398
- when 'Watch6,3'
399
- Model.new(device_type, 'Apple Watch', 'Series 6, 40mm, GPS+Cellular')
400
- when 'Watch6,4'
401
- Model.new(device_type, 'Apple Watch', 'Series 6, 44mm, GPS+Cellular')
402
- when 'Watch6,6'
403
- Model.new(device_type, 'Apple Watch', 'Series 7, 41mm, GPS')
404
- when 'Watch6,7'
405
- Model.new(device_type, 'Apple Watch', 'Series 7, 45mm, GPS')
406
- when 'Watch6,8'
407
- Model.new(device_type, 'Apple Watch', 'Series 7, 41mm, GPS+Cellular')
408
- when 'Watch6,9'
409
- Model.new(device_type, 'Apple Watch', 'Series 7, 45mm, GPS+Cellular')
410
- when 'Watch6,10'
411
- Model.new(device_type, 'Apple Watch', 'SE 2, 40mm, GPS')
412
- when 'Watch6,11'
413
- Model.new(device_type, 'Apple Watch', 'SE 2, 44mm, GPS')
414
- when 'Watch6,12'
415
- Model.new(device_type, 'Apple Watch', 'SE 2, 40mm, GPS+Cellular')
416
- when 'Watch6,13'
417
- Model.new(device_type, 'Apple Watch', 'SE 2, 44mm, GPS+Cellular')
418
- when 'Watch6,14'
419
- Model.new(device_type, 'Apple Watch', 'Series 8, 41mm, GPS')
420
- when 'Watch6,15'
421
- Model.new(device_type, 'Apple Watch', 'Series 8, 45mm, GPS')
422
- when 'Watch6,16'
423
- Model.new(device_type, 'Apple Watch', 'Series 8, 41mm, GPS+Cellular')
424
- when 'Watch6,17'
425
- Model.new(device_type, 'Apple Watch', 'Series 8, 45mm, GPS+Cellular')
426
- when 'Watch6,18'
427
- Model.new(device_type, 'Apple Watch', 'Ultra')
428
- when 'Watch7,1'
429
- Model.new(device_type, 'Apple Watch', 'Series 9, 41mm, GPS')
430
- when 'Watch7,2'
431
- Model.new(device_type, 'Apple Watch', 'Series 9, 45mm, GPS')
432
- when 'Watch7,3'
433
- Model.new(device_type, 'Apple Watch', 'Series 9, 41mm, GPS+Cellular')
434
- when 'Watch7,4'
435
- Model.new(device_type, 'Apple Watch', 'Series 9, 45mm, GPS+Cellular')
436
- when 'Watch7,5'
437
- Model.new(device_type, 'Apple Watch', 'Ultra 2')
438
- when 'Watch7,8'
439
- Model.new(device_type, 'Apple Watch', 'Series 10, 42mm, GPS')
440
- when 'Watch7,9'
441
- Model.new(device_type, 'Apple Watch', 'Series 10, 46mm, GPS')
442
- when 'Watch7,10'
443
- Model.new(device_type, 'Apple Watch', 'Series 10, 42mm, GPS+Cellular')
444
- when 'Watch7,11'
445
- Model.new(device_type, 'Apple Watch', 'Series 10, 46mm, GPS+Cellular')
446
- when 'Watch7,12'
447
- Model.new(device_type, 'Apple Watch', 'Ultra 3')
448
- when 'Watch7,13'
449
- Model.new(device_type, 'Apple Watch', 'SE 3, 40mm, GPS')
450
- when 'Watch7,14'
451
- Model.new(device_type, 'Apple Watch', 'SE 3, 44mm, GPS')
452
- when 'Watch7,15'
453
- Model.new(device_type, 'Apple Watch', 'SE 3, 40mm, GPS+Cellular')
454
- when 'Watch7,16'
455
- Model.new(device_type, 'Apple Watch', 'SE 3, 44mm, GPS+Cellular')
456
- when 'Watch7,17'
457
- Model.new(device_type, 'Apple Watch', 'Series 11, 42mm, GPS')
458
- when 'Watch7,18'
459
- Model.new(device_type, 'Apple Watch', 'Series 11, 46mm, GPS')
460
- when 'Watch7,19'
461
- Model.new(device_type, 'Apple Watch', 'Series 11, 42mm, GPS+Cellular')
462
- when 'Watch7,20'
463
- Model.new(device_type, 'Apple Watch', 'Series 11, 46mm, GPS+Cellular')
464
- else
465
- Model.new(device_type, UNKNOWN_IOS_DEVICE)
466
- end
31
+ MODELS.fetch(device_type) { Model.new(device_type, UNKNOWN_IOS_DEVICE) }
32
+ end
33
+
34
+ # Whether the given device type is in the list of known devices.
35
+ #
36
+ # Ios::Devices.known?('iPhone6,1') # => true
37
+ # Ios::Devices.known?('iPhone0,0') # => false
38
+ def self.known?(device_type)
39
+ MODELS.key?(device_type)
40
+ end
41
+
42
+ # All known device models, grouped by family (simulators, iPhone, iPad, iPod
43
+ # touch, Apple Watch).
44
+ #
45
+ # Ios::Devices.all.select { |model| model.name == 'iPad mini' }
46
+ def self.all
47
+ MODELS.values
467
48
  end
468
49
  end
50
+
51
+ # Deprecated: use Ios::Devices::UNKNOWN_IOS_DEVICE. Ruby warns about it when
52
+ # deprecation warnings are on (ruby -W:deprecated).
53
+ UNKNOWN_IOS_DEVICE = Devices::UNKNOWN_IOS_DEVICE
54
+ deprecate_constant :UNKNOWN_IOS_DEVICE
469
55
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ios-devices
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ricardo Otero
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2026-10-20 00:00:00.000000000 Z
10
+ date: 2026-11-06 00:00:00.000000000 Z
11
11
  dependencies: []
12
12
  description: |-
13
13
  With this gem you can read the device type that every iOS device can send
@@ -22,6 +22,7 @@ files:
22
22
  - LICENSE.txt
23
23
  - README.md
24
24
  - lib/ios/devices.rb
25
+ - lib/ios/devices/device_types.rb
25
26
  - lib/ios/devices/model.rb
26
27
  - lib/ios/devices/version.rb
27
28
  homepage: https://github.com/rikas/iosdevices
@@ -29,7 +30,7 @@ licenses:
29
30
  - MIT
30
31
  metadata:
31
32
  source_code_uri: https://github.com/rikas/iosdevices
32
- changelog_uri: https://github.com/rikas/iosdevices/blob/master/CHANGELOG.md
33
+ changelog_uri: https://github.com/rikas/iosdevices/blob/main/CHANGELOG.md
33
34
  bug_tracker_uri: https://github.com/rikas/iosdevices/issues
34
35
  rdoc_options: []
35
36
  require_paths: