├── .gitignore ├── devicehardware_icon.png ├── Tests ├── LinuxMain.swift └── DeviceHardwareTests │ ├── XCTestManifests.swift │ └── DeviceHardwareTests.swift ├── .swiftpm └── xcode │ └── package.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ └── IDEWorkspaceChecks.plist ├── .github └── workflows │ └── release.yml ├── LICENSE ├── Package.swift ├── Sources └── DeviceHardware │ ├── DeviceHardware.swift │ ├── MacDeviceHardware.swift │ └── UIDeviceHardware.swift └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | /.build 3 | /Packages 4 | /*.xcodeproj 5 | xcuserdata/ 6 | -------------------------------------------------------------------------------- /devicehardware_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shakshi3104/DeviceHardware/HEAD/devicehardware_icon.png -------------------------------------------------------------------------------- /Tests/LinuxMain.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | import DeviceHardwareTests 4 | 5 | var tests = [XCTestCaseEntry]() 6 | tests += DeviceHardwareTests.allTests() 7 | XCTMain(tests) 8 | -------------------------------------------------------------------------------- /.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Tests/DeviceHardwareTests/XCTestManifests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | #if !canImport(ObjectiveC) 4 | public func allTests() -> [XCTestCaseEntry] { 5 | return [ 6 | testCase(DeviceHardwareTests.allTests), 7 | ] 8 | } 9 | #endif 10 | -------------------------------------------------------------------------------- /.swiftpm/xcode/package.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release Package 2 | 3 | on: 4 | push: 5 | tags: 6 | - "*.*.*" 7 | 8 | jobs: 9 | build: 10 | name: Create Release 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: Checkout code 14 | uses: actions/checkout@v3 15 | - name: Set Version 16 | id: version 17 | run: | 18 | VERSION=$(echo ${{ github.ref }} | sed -e "s#refs/tags/##g") 19 | echo "version=$VERSION" >> $GITHUB_OUTPUT 20 | - name: Create Release 21 | id: create_release 22 | uses: softprops/action-gh-release@v1 23 | env: 24 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token 25 | with: 26 | tag_name: ${{ github.ref }} 27 | name: v${{ steps.version.outputs.VERSION }} 28 | generate_release_notes: true 29 | draft: false 30 | prerelease: false 31 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Shakshi3104 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.3 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "DeviceHardware", 8 | platforms: [ 9 | .iOS(.v12), 10 | .macOS(.v10_15) 11 | ], 12 | products: [ 13 | // Products define the executables and libraries a package produces, and make them visible to other packages. 14 | .library( 15 | name: "DeviceHardware", 16 | targets: ["DeviceHardware"]), 17 | ], 18 | dependencies: [ 19 | // Dependencies declare other packages that this package depends on. 20 | // .package(url: /* package url */, from: "1.0.0"), 21 | ], 22 | targets: [ 23 | // Targets are the basic building blocks of a package. A target can define a module or a test suite. 24 | // Targets can depend on other targets in this package, and on products in packages this package depends on. 25 | .target( 26 | name: "DeviceHardware", 27 | dependencies: []), 28 | .testTarget( 29 | name: "DeviceHardwareTests", 30 | dependencies: ["DeviceHardware"]), 31 | ] 32 | ) 33 | -------------------------------------------------------------------------------- /Tests/DeviceHardwareTests/DeviceHardwareTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | @testable import DeviceHardware 3 | 4 | final class DeviceHardwareTests: XCTestCase { 5 | 6 | func testModelIdentifier() { 7 | XCTAssertEqual(MacDeviceHardware.deviceHardware.modelIdentifier, "Mac14,12") 8 | XCTAssertEqual(UIDeviceHardware.deviceHardware.modelIdentifier, "arm64") 9 | } 10 | 11 | func testModelName() { 12 | XCTAssertEqual(MacDeviceHardware.deviceHardware.modelName, "Mac mini (2023)") 13 | } 14 | 15 | func testProcessorName() { 16 | XCTAssertEqual(MacDeviceHardware.deviceHardware.processorName, "Apple M2 Pro") 17 | } 18 | 19 | func testCpu() { 20 | XCTAssertEqual(MacDeviceHardware.deviceHardware.cpu, "3.49GHz 12-core") 21 | } 22 | 23 | func testGpu() { 24 | XCTAssertEqual(MacDeviceHardware.deviceHardware.gpu, "Apple M2 Pro") 25 | } 26 | 27 | func testNeuralEngine() { 28 | XCTAssertEqual(MacDeviceHardware.deviceHardware.neuralEngine, "16-core") 29 | } 30 | 31 | func testProcessorCount() { 32 | XCTAssertEqual(MacDeviceHardware.deviceHardware.processorCount, 12) 33 | } 34 | 35 | func testRamString() { 36 | XCTAssertEqual(MacDeviceHardware.deviceHardware.ramString, "32GB") 37 | } 38 | 39 | func testUINeuralEngine() { 40 | XCTAssertEqual(UIDeviceHardware.deviceHardware.neuralEngine, "N/A") 41 | } 42 | 43 | func testCallPerformance() { 44 | self.measure { 45 | for _ in 0..<10000 { 46 | _ = MacDeviceHardware.deviceHardware.modelName 47 | } 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Sources/DeviceHardware/DeviceHardware.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import Metal 3 | 4 | 5 | protocol DeviceHardware { 6 | /// model name, such as iPhone 8 7 | var modelName: String { get } 8 | /// processor name, such as A11 Bionic 9 | var processorName: String { get } 10 | /// CPU information, such as 2.39GHz 6-core 11 | var cpu: String { get } 12 | /// GPU information, such as Apple A11 GPU 13 | var gpu: String { get } 14 | /// Neural Engine, such as 2-core 15 | var neuralEngine: String { get } 16 | 17 | /// Model Identifier, such as iPhone10,1 18 | var modelIdentifier: String { get } 19 | /// number of processor, such as 6 20 | var processorCount: Int { get } 21 | /// physical memory size [B], such as 2071019520 22 | var ram: Int { get } 23 | /// physical memory size, such as 2GB 24 | var ramString: String { get } 25 | } 26 | 27 | extension DeviceHardware { 28 | func getMetalGpu() -> String { 29 | if #available(OSX 10.11, iOS 8.0, macCatalyst 13.0, *) { 30 | guard let device = MTLCreateSystemDefaultDevice() else { 31 | return "Unknown" 32 | } 33 | 34 | let deviceName = device.name 35 | .replacingOccurrences(of: "(R)", with: "") 36 | .replacingOccurrences(of: "(TM)", with: "") 37 | return deviceName 38 | } else { 39 | // Fallback on earlier versions 40 | // Not support Metal 41 | return "Not support Metal" 42 | } 43 | } 44 | 45 | func getRAM() -> Int { 46 | return Int(ProcessInfo.processInfo.physicalMemory) 47 | } 48 | 49 | func getRAMString() -> String { 50 | let bytes = getRAM() 51 | let formatter = ByteCountFormatter() 52 | formatter.countStyle = .memory 53 | return formatter.string(fromByteCount: Int64(bytes)).replacingOccurrences(of: " ", with: "") 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DeviceHardware 2 | 3 |
4 | 5 |
6 | 7 | DeviceHardware is a package for getting iPhone, iPad and Mac model names and hardware information, such as SoC name. 8 | 9 | Support for iOS devices and Macs by October 23, 2025 (JST). 10 | 11 | ## Usage 12 | 13 | ```swift 14 | import DeviceHardware 15 | ``` 16 | ### iOS 17 | 18 | At first 19 | 20 | ```swift 21 | let device = UIDeviceHardware.deviceHardware 22 | ``` 23 | 24 | Eample on iPhone 8 running iOS 14.2 25 | 26 | ```swift 27 | device.modelName // iPhone 8 28 | device.processorName // Apple A11 Bionic 29 | device.cpu // 2.39GHz 6-core 30 | device.gpu // Apple A11 GPU 31 | device.neuralEngine // 2-core 32 | device.modelIdentifier // iPhone10,1 33 | device.processorCount // 6 34 | device.ram // 2071019520 35 | device.ramString // 1.93GB 36 | ``` 37 | 38 | ### macOS 39 | 40 | At first 41 | 42 | ```swift 43 | let device = MacDeviceHardware.deviceHardware 44 | ``` 45 | 46 | Eample on MacBook Pro (13-inch, 2018, Four Thunderbolt 3 ports) running macOS 11.0.1 47 | 48 | ```swift 49 | device.modelName // MacBook Pro (13-inch, 2018, Four Thunderbolt 3 ports) 50 | device.processorName // Intel Core i5-8259U 51 | device.cpu // 2.30GHz 4-core 52 | device.gpu // Intel Iris Plus Graphics 655 53 | device.neuralEngine // None 54 | device.modelIdentifier // MacBookPro15,2 55 | device.processorCount // 8 56 | device.ram // 17179869184 57 | device.ramString // 16GB 58 | ``` 59 | 60 | Eample on MacBook Pro (13-inch, M1, 2020) running macOS 11.2.3 61 | 62 | ```swift 63 | device.modelName // MacBook Pro (13-inch, M1, 2020) 64 | device.processorName // Apple M1 65 | device.cpu // 3.2GHz 8-core 66 | device.gpu // Apple M1 67 | device.neuralEngine // 16-core 68 | device.modelIdentifier // MacBookPro17,1 69 | device.processorCount // 8 70 | device.ram // 17179869184 71 | device.ramString // 16GB 72 | ``` 73 | 74 | ### Mac models that cannot get the correct model name 75 | 76 | You may not get the correct model name on some Macs. In the following models, you may not get the correct model name if the Mac have been customized to Intel Core i7. 77 | 78 | - MacBook Air (13-inch, 2017) 79 | - MacBook Air (13-inch, Early 2015) 80 | - MacBook Air (13-inch, Early 2014) 81 | - MacBook Air (13-inch, Mid 2013) 82 | - MacBook Air (11-inch, Early 2014) 83 | - MacBook Air (11-inch, Mid 2013) 84 | 85 | ## Requirements 86 | 87 | This package is compatible with iOS 8 or higher and macOS 10.15 or higher. However, Mac device information can only be got for models that support macOS 11. 88 | 89 | ## Installation 90 | 91 | ### Swift Package Manager 92 | Add this Swift package in Xcode using its GitHub repository URL. (File > Swift Packages > Add Package Dependency...) 93 | 94 | ## License 95 | DeviceHardware is available under the MIT license. See the LICENSE file for more info. 96 | -------------------------------------------------------------------------------- /Sources/DeviceHardware/MacDeviceHardware.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | public class MacDeviceHardware: DeviceHardware { 4 | public static let deviceHardware = MacDeviceHardware() 5 | 6 | /// model name, such as MacBook Air (Retina, 13-inch, 2020) 7 | public var modelName: String { 8 | let modelName_ = getModelName() ?? "Unknown" 9 | return modelName_ 10 | } 11 | /// processor name, such as Intel Core i5-5250U 12 | public var processorName: String { 13 | let processorName_ = getProcessorName() ?? "Unknown" 14 | return processorName_ 15 | } 16 | /// CPU information, such as 1.60GHz 2-core 17 | public var cpu: String { 18 | let cpu_ = getCpu() ?? "Unknown" 19 | return cpu_ 20 | } 21 | /// GPU information, such as Intel Iris Plus Graphics 655 22 | public var gpu: String { 23 | return getMetalGpu() 24 | } 25 | /// Neural Engine, such as 16-core or None 26 | public var neuralEngine: String { 27 | let neuralEngine_ = getNeuralEngine() ?? "Unknown" 28 | return neuralEngine_ 29 | } 30 | 31 | /// Model Identifier, such as MacBookAir9,1 32 | public var modelIdentifier: String { 33 | let modelId = getModelIdentifier() ?? "Unknown" 34 | return modelId 35 | } 36 | /// number of (logical) processor, such as 4 37 | public var processorCount: Int { 38 | return ProcessInfo.processInfo.processorCount 39 | } 40 | /// physical memory size [B], such as 8589934592 41 | public var ram: Int { 42 | return getRAM() 43 | } 44 | /// physical memory size, such as 8GB 45 | public var ramString: String { 46 | return getRAMString() 47 | } 48 | 49 | // MARK: - Model Identifier 50 | enum ModelIdentifier: String { 51 | // MARK: MacBook Air 52 | /// MacBook Air (13-inch, M4, 2025) 53 | case Mac16_12 = "Mac16,12" 54 | /// MacBook Air (15-inch, M4, 2025) 55 | case Mac16_13 = "Mac16,13" 56 | /// MacBook Air (13-inch, M3, 2024) 57 | case Mac15_12 = "Mac15,12" 58 | /// MacBook Air (15-inch, M3, 2024) 59 | case Mac15_13 = "Mac15,13" 60 | /// MacBook Air (15-inch, M2, 2023) 61 | case Mac14_15 = "Mac14,15" 62 | /// MacBook Air (M2, 2022) 63 | case Mac14_2 = "Mac14,2" 64 | /// MacBook Air (M1, 2020) 65 | case MacBookAir10_1 = "MacBookAir10,1" 66 | /// MacBook Air (Retina, 13-inch, 2020) 67 | case MacBookAir9_1 = "MacBookAir9,1" 68 | /// MacBook Air (Retina, 13-inch, 2019) 69 | case MacBookAir8_2 = "MacBookAir8,2" 70 | /// MacBook Air (Retina, 13-inch, 2018) 71 | case MacBookAir8_1 = "MacBookAir8,1" 72 | /// MacBook Air (13-inch, 2017), MacBook Air (13-inch, Early 2015) 73 | case MacBookAir7_2 = "MacBookAir7,2" 74 | /// MacBook Air (11-inch, Early 2015) 75 | case MacBookAir7_1 = "MacBookAir7,1" 76 | /// MacBook Air (13-inch, Early 2014), MacBook Air (13-inch, Mid 2013) 77 | case MacBookAir6_2 = "MacBookAir6,2" 78 | /// MacBook Air (11-inch, Early 2014), MacBook Air (11-inch, Mid 2013) 79 | case MacBookAir6_1 = "MacBookAir6,1" 80 | 81 | // MARK: MacBook Pro 82 | /// MacBook Pro (M5, 2025) // 2025年10月発売モデル 83 | case Mac17_2 = "Mac17,2" 84 | /// MacBook Pro (14-inch, 2024) / M4 85 | case Mac16_1 = "Mac16,1" 86 | /// MacBook Pro (14-inch, 2024) / M4 Pro or M4 Max 87 | case Mac16_6 = "Mac16,6" 88 | case Mac16_8 = "Mac16,8" 89 | /// MacBook Pro (16-inch, 2024) / M4 Pro or M4 Max 90 | case Mac16_5 = "Mac16,5" 91 | case Mac16_7 = "Mac16,7" 92 | /// MacBook Pro (14-inch, Nov 2023) / M3 93 | case Mac15_3 = "Mac15,3" 94 | /// MacBook Pro (14-inch, Nov 2023) / M3 Pro or M3 Max 95 | case Mac15_6 = "Mac15,6" 96 | case Mac15_8 = "Mac15,8" 97 | case Mac15_10 = "Mac15,10" 98 | /// MacBook Pro (16-inch, Nov 2023) / M3 Pro or M3 Max 99 | case Mac15_7 = "Mac15,7" 100 | case Mac15_9 = "Mac15,9" 101 | case Mac15_11 = "Mac15,11" 102 | /// MacBook Pro (14-inch, 2023) / M2 Pro 103 | case Mac14_9 = "Mac14,9" 104 | /// MacBook Pro (14-inch, 2023) / M2 Max 105 | case Mac14_5 = "Mac14,5" 106 | /// MacBook Pro (16-inch, 2023) / M2 Pro 107 | case Mac14_10 = "Mac14,10" 108 | /// MacBook Pro (16-inch, 2023) / M2 Max 109 | case Mac14_6 = "Mac14,6" 110 | /// MacBook Pro (13-inch, M2, 2022) 111 | case Mac14_7 = "Mac14,7" 112 | /// MacBook Pro (16-inch, 2021) / M1 Pro 113 | case MacBookPro18_1 = "MacBookPro18,1" 114 | /// MacBook Pro (16-inch, 2021) / M1 Max 115 | case MacBookPro18_2 = "MacBookPro18,2" 116 | /// MacBook Pro (14-inch, 2021) / M1 Pro 117 | case MacBookPro18_3 = "MacBookPro18,3" 118 | /// MacBook Pro (14-inch, 2021) / M1 Max 119 | case MacBookPro18_4 = "MacBookPro18,4" 120 | /// MacBook Pro (13-inch, M1, 2020) 121 | case MacBookPro17_1 = "MacBookPro17,1" 122 | /// MacBook Pro (13-inch, 2020, Two Thunderbolt 3 ports) 123 | case MacBookPro16_3 = "MacBookPro16,3" 124 | /// MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports) 125 | case MacBookPro16_2 = "MacBookPro16,2" 126 | /// MacBook Pro (16-inch, 2019) 127 | case MacBookPro16_4 = "MacBookPro16,4" 128 | case MacBookPro16_1 = "MacBookPro16,1" 129 | /// MacBook Pro (13-inch, 2019, Two Thunderbolt 3 ports 130 | case MacBookPro15_4 = "MacBookPro15,4" 131 | /// MacBook Pro (15-inch, 2019) 132 | case MacBookPro15_3 = "MacBookPro15,3" 133 | /// MacBook Pro (15-inch, 2019), MacBook Pro (15-inch, 2018) 134 | case MacBookPro15_1 = "MacBookPro15,1" 135 | /// MacBook Pro (13-inch, 2019, Four Thunderbolt 3 ports), MacBook Pro (13-inch, 2018, Four Thunderbolt 3 ports) 136 | case MacBookPro15_2 = "MacBookPro15,2" 137 | /// MacBook Pro (15-inch, 2017) 138 | case MacBookPro14_3 = "MacBookPro14,3" 139 | /// MacBook Pro (13-inch, 2017, Four Thunderbolt 3 ports) 140 | case MacBookPro14_2 = "MacBookPro14,2" 141 | /// MacBook Pro (13-inch, 2017, Two Thunderbolt 3 ports) 142 | case MacBookPro14_1 = "MacBookPro14,1" 143 | /// MacBook Pro (15-inch, 2016) 144 | case MacBookPro13_3 = "MacBookPro13,3" 145 | /// MacBook Pro (13-inch, 2016, Four Thunderbolt 3 ports) 146 | case MacBookPro13_2 = "MacBookPro13,2" 147 | /// MacBook Pro (13-inch, 2016, Two Thunderbolt 3 ports) 148 | case MacBookPro13_1 = "MacBookPro13,1" 149 | /// MacBook Pro (Retina, 15-inch, Mid 2015) 150 | case MacBookPro11_5 = "MacBookPro11,5" 151 | case MacBookPro11_4 = "MacBookPro11,4" 152 | /// MacBook Pro (Retina, 13-inch, Early 2015) 153 | case MacBookPro12_1 = "MacBookPro12,1" 154 | /// MacBook Pro (Retina, 15-inch, Mid 2014), MacBook Pro (Retina, 15-inch, Late 2013) 155 | case MacBookPro11_3 = "MacBookPro11,3" 156 | case MacBookPro11_2 = "MacBookPro11,2" 157 | /// MacBook Pro (Retina, 13-inch, Mid 2014), MacBook Pro (Retina, 13-inch, Late 2013) 158 | case MacBookPro11_1 = "MacBookPro11,1" 159 | 160 | // MARK: MacBook (12-inch) 161 | /// MacBook (Retina, 12-inch, 2017) 162 | case MacBook10_1 = "MacBook10,1" 163 | /// MacBook (Retina, 12-inch, Early 2016) 164 | case MacBook9_1 = "MacBook9,1" 165 | /// MacBook (Retina, 12-inch, Early 2015) 166 | case MacBook8_1 = "MacBook8,1" 167 | 168 | // MARK: Mac Pro 169 | /// Mac Pro (2023) 170 | case Mac14_8 = "Mac14,8" 171 | /// Mac Pro (2019) 172 | case MacPro7_1 = "MacPro7,1" 173 | /// Mac Pro (Late 2013) 174 | case MacPro6_1 = "MacPro6,1" 175 | 176 | // MARK: Mac mini 177 | /// Mac mini (2024) / M4 178 | case Mac16_10 = "Mac16,10" 179 | /// Mac mini (2024) / M4 Pro 180 | case Mac16_15 = "Mac16,15" 181 | /// Mac mini (2023) / M2 182 | case Mac14_3 = "Mac14,3" 183 | /// Mac mini (2023) / M2 Pro 184 | case Mac14_12 = "Mac14,12" 185 | /// Mac mini (M1, 2020) 186 | case Macmini9_1 = "Macmini9,1" 187 | /// Mac mini (2018) 188 | case Macmini8_1 = "Macmini8,1" 189 | /// Mac mini (Late 2014) 190 | case Macmini7_1 = "Macmini7,1" 191 | 192 | // MARK: iMac Pro 193 | /// iMac Pro 194 | case iMacPro1_1 = "iMacPro1,1" 195 | 196 | // MARK: iMac 197 | /// iMac (24-inch, 2024, Two ports) 198 | case Mac16_2 = "Mac16,2" 199 | /// iMac (24-inch, 2024, Four ports) 200 | case Mac16_3 = "Mac16,3" 201 | /// iMac (24-inch, 2023, Two ports) 202 | case Mac15_4 = "Mac15,4" 203 | /// iMac (24-inch, 2023, Four ports) 204 | case Mac15_5 = "Mac15,5" 205 | /// iMac (24-inch, M1, 2021) 206 | case iMac21_1 = "iMac21,1" 207 | case iMac21_2 = "iMac21,2" 208 | /// iMac (Retina 5K, 27-inch, 2020) 209 | case iMac20_2 = "iMac20,2" 210 | case iMac20_1 = "iMac20,1" 211 | /// iMac (Retina 5K, 27-inch, 2019) 212 | case iMac19_1 = "iMac19,1" 213 | /// iMac (Retina 4K, 21.5-inch, 2019) 214 | case iMac19_2 = "iMac19,2" 215 | /// iMac (Retina 5K, 27-inch, 2017) 216 | case iMac18_3 = "iMac18,3" 217 | /// iMac (Retina 4K, 21.5-inch, 2017) 218 | case iMac18_2 = "iMac18,2" 219 | /// iMac (21.5-inch, 2017) 220 | case iMac18_1 = "iMac18,1" 221 | /// iMac (Retina 5K, 27-inch, Late 2015) 222 | case iMac17_1 = "iMac17,1" 223 | /// iMac (Retina 4K, 21.5-inch, Late 2015) 224 | case iMac16_2 = "iMac16,2" 225 | /// iMac (21.5-inch, Late 2015) 226 | case iMac16_1 = "iMac16,1" 227 | /// iMac (Retina 5K, 27-inch, Mid 2015), iMac (Retina 5K, 27-inch, Late 2014) 228 | case iMac15_1 = "iMac15,1" 229 | /// iMac (21.5-inch, Mid 2014) 230 | case iMac14_4 = "iMac14,4" 231 | /// iMac (27-inch, Late 2013) 232 | case iMac14_2 = "iMac14,2" 233 | /// iMac (21.5-inch, Late 2013) 234 | case iMac14_1 = "iMac14,1" 235 | /// iMac (27-inch, Late 2012) 236 | case iMac13_2 = "iMac13,2" 237 | /// iMac (21.5-inch, Late 2012) 238 | case iMac13_1 = "iMac13,1" 239 | 240 | // MARK: Mac Studio 241 | /// Mac Studio (2023) / M2 Max 242 | case Mac14_13 = "Mac14,13" 243 | /// Mac Studio (2023) / M2 Ultra 244 | case Mac14_14 = "Mac14,14" 245 | /// Mac Studio (2022) / M1 Max 246 | case Mac13_1 = "Mac13,1" 247 | /// Mac Studio (2022) / M1 Ultra 248 | case Mac13_2 = "Mac13,2" 249 | 250 | // TODO: Add core counts of Neural Engine when new Apple Silicon Series is announced. 251 | // Neural Engine Information 252 | func neuralEngine() -> String { 253 | switch self { 254 | /// M1 255 | case .MacBookAir10_1, .MacBookPro17_1, .Macmini9_1, .iMac21_1, .iMac21_2: 256 | return "16-core" 257 | /// M1 Pro 258 | case .MacBookPro18_1, .MacBookPro18_3: 259 | return "16-core" 260 | /// M1 Max 261 | case .MacBookPro18_2, .MacBookPro18_4, .Mac13_1: 262 | return "16-core" 263 | /// M1 Ultra 264 | case .Mac13_2: 265 | return "32-core" 266 | /// M2 267 | case .Mac14_2, .Mac14_7, .Mac14_15: 268 | return "16-core" 269 | /// M2 Pro 270 | case .Mac14_9, .Mac14_10, .Mac14_12: 271 | return "16-core" 272 | /// M2 Max 273 | case .Mac14_5, .Mac14_6, .Mac14_13: 274 | return "16-core" 275 | /// M2 Ultra 276 | case .Mac14_14, .Mac14_8: 277 | return "32-core" 278 | /// M3, M3 Pro, M3 Max 279 | case .Mac15_3, .Mac15_4, .Mac15_5, .Mac15_6, .Mac15_7, .Mac15_8, .Mac15_9, .Mac15_10, .Mac15_11, .Mac15_12, .Mac15_13: 280 | return "16-core" 281 | /// M4, M4 Pro, M4 Max 282 | case .Mac16_1, .Mac16_2, .Mac16_3, .Mac16_5, .Mac16_6, .Mac16_7, .Mac16_8, .Mac16_10, .Mac16_15, .Mac16_12, .Mac16_13: 283 | return "16-core" 284 | /// M5 285 | case .Mac17_2: 286 | return "16-core" 287 | default: 288 | return "None" 289 | } 290 | } 291 | 292 | // model name 293 | func modelName() -> String { 294 | switch self { 295 | // MARK: MacBook Air 296 | case .Mac16_12: 297 | return "MacBook Air (13-inch, M4, 2025)" 298 | case .Mac16_13: 299 | return "MacBook Air (15-inch, M4, 2025)" 300 | case .Mac15_12: 301 | return "MacBook Air (13-inch, M3, 2024)" 302 | case .Mac15_13: 303 | return "MacBook Air (15-inch, M3, 2024)" 304 | case .Mac14_15: 305 | return "MacBook Air (15-inch, M2, 2023)" 306 | case .Mac14_2: 307 | return "MacBook Air (M2, 2022)" 308 | case .MacBookAir10_1: 309 | return "MacBook Air (M1, 2020)" 310 | case .MacBookAir9_1: 311 | return "MacBook Air (Retina, 13-inch, 2020)" 312 | case .MacBookAir8_2: 313 | return "MacBook Air (Retina, 13-inch, 2019)" 314 | case .MacBookAir8_1: 315 | return "MacBook Air (Retina, 13-inch, 2018)" 316 | case .MacBookAir7_2: 317 | /// Need some decision processing 318 | return "MacBook Air (13-inch, 2017) / (13-inch, Early 2015)" 319 | case .MacBookAir7_1: 320 | return "MacBook Air (11-inch, Early 2015)" 321 | case .MacBookAir6_2: 322 | /// Need some decision processing 323 | return "MacBook Air (13-inch, Early 2014) / (13-inch, Mid 2013)" 324 | case .MacBookAir6_1: 325 | /// Need some decision processing 326 | return "MacBook Air (11-inch, Early 2014) / (11-inch, Mid 2013)" 327 | 328 | // MARK: MacBook Pro 329 | case .Mac17_2: 330 | return "MacBook Pro (14-inch, 2025)" 331 | case .Mac16_1, .Mac16_6, .Mac16_8: 332 | return "MacBook Pro (14-inch, 2024)" 333 | case .Mac16_7, .Mac16_5: 334 | return "MacBook Pro (16-inch, 2024)" 335 | case .Mac15_3, .Mac15_6, .Mac15_8, .Mac15_10: 336 | return "MacBook Pro (14-inch, Nov 2023)" 337 | case .Mac15_7, .Mac15_9, .Mac15_11: 338 | return "MacBook Pro (16-inch, Nov 2023)" 339 | case .Mac14_5, .Mac14_9: 340 | return "MacBook Pro (14-inch, 2023)" 341 | case .Mac14_6, .Mac14_10: 342 | return "MacBook Pro (16-inch, 2023)" 343 | case .Mac14_7: 344 | return "MacBook Pro (13-inch, M2, 2022)" 345 | case .MacBookPro18_1, .MacBookPro18_2: 346 | return "MacBook Pro (16-inch, 2021)" 347 | case .MacBookPro18_3, .MacBookPro18_4: 348 | return "MacBook Pro (14-inch, 2021)" 349 | case .MacBookPro17_1: 350 | return "MacBook Pro (13-inch, M1, 2020)" 351 | case .MacBookPro16_3: 352 | return "MacBook Pro (13-inch, 2020, Two Thunderbolt 3 ports)" 353 | case .MacBookPro16_2: 354 | return "MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports)" 355 | case .MacBookPro16_1, .MacBookPro16_4: 356 | return "MacBook Pro (16-inch, 2019)" 357 | case .MacBookPro15_4: 358 | return "MacBook Pro (13-inch, 2019, Two Thunderbolt 3 ports)" 359 | case .MacBookPro15_3: 360 | return "MacBook Pro (15-inch, 2019)" 361 | case .MacBookPro15_1: 362 | /// Need some decision processing 363 | return "MacBook Pro (15-inch, 2019) / (15-inch, 2018)" 364 | case .MacBookPro15_2: 365 | /// Need some decision processing 366 | return "MacBook Pro (13-inch, 2019, Four Thunderbolt 3 ports) / (13-inch, 2018, Four Thunderbolt 3 ports)" 367 | case .MacBookPro14_3: 368 | return "MacBook Pro (15-inch, 2017)" 369 | case .MacBookPro14_2: 370 | return "MacBook Pro (13-inch, 2017, Four Thunderbolt 3 ports)" 371 | case .MacBookPro14_1: 372 | return "MacBook Pro (13-inch, 2017, Two Thunderbolt 3 ports)" 373 | case .MacBookPro13_3: 374 | return "MacBook Pro (15-inch, 2016)" 375 | case .MacBookPro13_2: 376 | return "MacBook Pro (13-inch, 2016, Four Thunderbolt 3 ports)" 377 | case .MacBookPro13_1: 378 | return "MacBook Pro (13-inch, 2016, Two Thunderbolt 3 ports)" 379 | case .MacBookPro11_5, .MacBookPro11_4: 380 | return "MacBook Pro (Retina, 15-inch, Mid 2015)" 381 | case .MacBookPro12_1: 382 | return "MacBook Pro (Retina, 13-inch, Early 2015)" 383 | case .MacBookPro11_3, .MacBookPro11_2: 384 | /// Need some decision processing 385 | return "MacBook Pro (Retina, 15-inch, Mid 2014) / (Retina, 15-inch, Late 2013)" 386 | case .MacBookPro11_1: 387 | /// Need some decision processing 388 | return "MacBook Pro (Retina, 13-inch, Mid 2014) / (Retina, 13-inch, Late 2013)" 389 | 390 | // MARK: MacBook (12-inch) 391 | case .MacBook10_1: 392 | return "MacBook (Retina, 12-inch, 2017)" 393 | case .MacBook9_1: 394 | return "MacBook (Retina, 12-inch, Early 2016)" 395 | case .MacBook8_1: 396 | return "MacBook (Retina, 12-inch, Early 2015)" 397 | 398 | // MARK: Mac Pro 399 | case .Mac14_8: 400 | return "Mac Pro (2023)" 401 | case .MacPro7_1: 402 | return "Mac Pro (2019)" 403 | case .MacPro6_1: 404 | return "Mac Pro (Late 2013)" 405 | 406 | // MARK: Mac mini 407 | case .Mac16_15, .Mac16_10: 408 | return "Mac mini (2024)" 409 | case .Mac14_3, .Mac14_12: 410 | return "Mac mini (2023)" 411 | case .Macmini9_1: 412 | return "Mac mini (M1, 2020)" 413 | case .Macmini8_1: 414 | return "Mac mini (2018)" 415 | case .Macmini7_1: 416 | return "Mac mini (Late 2014)" 417 | 418 | // MARK: iMac Pro 419 | case .iMacPro1_1: 420 | return "iMac Pro (2017)" 421 | 422 | // MARK: iMac 423 | case .Mac16_2: 424 | return "iMac (24-inch, 2024, Two ports)" 425 | case .Mac16_3: 426 | return "iMac (24-inch, 2024, Four ports)" 427 | case .Mac15_5: 428 | return "iMac (24-inch, 2023, Four ports)" 429 | case .Mac15_4: 430 | return "iMac (24-inch, 2023, Two ports)" 431 | case .iMac21_1, .iMac21_2: 432 | return "iMac (24-inch, M1, 2021)" 433 | case .iMac20_2, .iMac20_1: 434 | return "iMac (Retina 5K, 27-inch, 2020)" 435 | case .iMac19_1: 436 | return "iMac (Retina 5K, 27-inch, 2019)" 437 | case .iMac19_2: 438 | return "iMac (Retina 4K, 21.5-inch, 2019)" 439 | case .iMac18_3: 440 | return "iMac (Retina 5K, 27-inch, 2017)" 441 | case .iMac18_2: 442 | return "iMac (Retina 4K, 21.5-inch, 2017)" 443 | case .iMac18_1: 444 | return "iMac (21.5-inch, 2017)" 445 | case .iMac17_1: 446 | return "iMac (Retina 5K, 27-inch, Late 2015)" 447 | case .iMac16_2: 448 | return "iMac (Retina 4K, 21.5-inch, Late 2015)" 449 | case .iMac16_1: 450 | return "iMac (21.5-inch, Late 2015)" 451 | case .iMac15_1: 452 | /// Need some decision processing 453 | return "iMac (Retina 5K, 27-inch, Mid 2015) / (Retina 5K, 27-inch, Late 2014)" 454 | case .iMac14_4: 455 | return "iMac (21.5-inch, Mid 2014)" 456 | case .iMac14_2: 457 | return "iMac (27-inch, Late 2013)" 458 | case .iMac14_1: 459 | return "iMac (21.5-inch, Late 2013)" 460 | case .iMac13_2: 461 | return "iMac (27-inch, Late 2012)" 462 | case .iMac13_1: 463 | return "iMac (21.5-inch, Late 2012)" 464 | 465 | // MARK: Mac Studio 466 | case .Mac14_13, .Mac14_14: 467 | return "Mac Studio (2023)" 468 | case .Mac13_1, .Mac13_2: 469 | return "Mac Studio (2022)" 470 | } 471 | } 472 | } 473 | } 474 | 475 | // MARK: - MacDeveiceHardware extensions 476 | public extension MacDeviceHardware { 477 | /// get Model Identifier 478 | private func getModelIdentifier() -> String? { 479 | var size: Int = 0 480 | sysctlbyname("hw.model", nil, &size, nil, 0) 481 | var machine = [CChar](repeating: 0, count: Int(size)) 482 | if sysctlbyname("hw.model", &machine, &size, nil, 0) != 0 { 483 | return nil 484 | } 485 | let code: String = String(cString:machine) 486 | 487 | return code 488 | } 489 | 490 | // MARK: - 491 | private func getCpuBrandString() -> String? { 492 | var size: Int = 0 493 | sysctlbyname("machdep.cpu.brand_string", nil, &size, nil, 0) 494 | var machine = [CChar](repeating: 0, count: Int(size)) 495 | if sysctlbyname("machdep.cpu.brand_string", &machine, &size, nil, 0) != 0 { 496 | return nil 497 | } 498 | let cpuInfo: String = String(cString:machine) 499 | 500 | return cpuInfo 501 | } 502 | 503 | 504 | private func generateIntelCPUString(number: String, frequency: String) -> String { 505 | return "Intel(R) Core(TM) \(number) CPU @ \(frequency)" 506 | } 507 | 508 | /// get Mac model name 509 | private func getModelName() -> String? { 510 | guard let id = getModelIdentifier() else { 511 | return nil 512 | } 513 | 514 | guard let modelId = ModelIdentifier(rawValue: id) else { 515 | return nil 516 | } 517 | 518 | let cpuString = getCpuBrandString() ?? "" 519 | 520 | // same model identifier model 521 | switch modelId { 522 | case .MacBookAir7_2: 523 | switch cpuString { 524 | case generateIntelCPUString(number: "i5-5350U", frequency: "1.80GHz"): 525 | return "MacBook Air (13-inch, 2017)" 526 | case generateIntelCPUString(number: "i5-5250U", frequency: "1.60GHz"): 527 | return "MacBook Air (13-inch, Early 2015)" 528 | default: 529 | // Core i7-5650U or other CPU 530 | return "MacBook Air (13-inch, Early 2017)" 531 | } 532 | case .MacBookAir6_2: 533 | switch cpuString { 534 | case generateIntelCPUString(number: "i5-4260U", frequency: "1.40GHz"): 535 | return "MacBook Air (13-inch, Early 2014)" 536 | case generateIntelCPUString(number: "i5-4250U", frequency: "1.30GHz"): 537 | return "MacBook Air (13-inch, Mid 2013)" 538 | default: 539 | // Core i7-4650U or other CPU 540 | return "MacBook Air (13-inch, Early 2014)" 541 | } 542 | case .MacBookAir6_1: 543 | switch cpuString { 544 | case generateIntelCPUString(number: "i5-4260U", frequency: "1.40GHz"): 545 | return "MacBook Air (11-inch, Early 2014)" 546 | case generateIntelCPUString(number: "i5-4250U", frequency: "1.30GHz"): 547 | return "MacBook Air (11-inch, Mid 2013)" 548 | default: 549 | // Core i7-4650U or other CPU 550 | return "MacBook Air (11-inch, Early 2014)" 551 | } 552 | case .MacBookPro15_1: 553 | switch cpuString { 554 | case generateIntelCPUString(number: "i7-9750H", frequency: "2.60GHz"), generateIntelCPUString(number: "i9-9880H", frequency: "2.30GHz"), generateIntelCPUString(number: "i9-9980HK", frequency: "2.40GHz"): 555 | return "MacBook Pro (15-inch, 2019)" 556 | case generateIntelCPUString(number: "i7-8750H", frequency: "2.20GHz"), generateIntelCPUString(number: "i7-8850H", frequency: "2.60GHz"), generateIntelCPUString(number: "i9-8950HK", frequency: "2.90GHz"): 557 | return "MacBook Pro (15-inch, 2018)" 558 | default: 559 | return "MacBook Pro (15-inch, 2019)" 560 | } 561 | case .MacBookPro15_2: 562 | switch cpuString { 563 | case generateIntelCPUString(number: "i5-8279U", frequency: "2.40GHz"), generateIntelCPUString(number: "i7-8569U", frequency: "2.80GHz"): 564 | return "MacBook Pro (13-inch, 2019, Four Thunderbolt 3 ports)" 565 | case generateIntelCPUString(number: "i5-8259U", frequency: "2.30GHz"), generateIntelCPUString(number: "i7-8559U", frequency: "2.70GHz"): 566 | return "MacBook Pro (13-inch, 2018, Four Thunderbolt 3 ports)" 567 | default: 568 | return "MacBook Pro (13-inch, 2019, Four Thunderbolt 3 ports)" 569 | } 570 | case .MacBookPro11_3, .MacBookPro11_2: 571 | switch cpuString { 572 | case generateIntelCPUString(number: "i7-4770HQ", frequency: "2.20GHz"), generateIntelCPUString(number: "i7-4870HQ", frequency: "2.50GHz"), generateIntelCPUString(number: "i7-4980HQ", frequency: "2.80GHz"): 573 | return "MacBook Pro (Retina, 15-inch, Mid 2014)" 574 | case generateIntelCPUString(number: "i7-4750HQ", frequency: "2.00GHz"), generateIntelCPUString(number: "i7-4850HQ", frequency: "2.30GHz"), generateIntelCPUString(number: "i7-4960HQ", frequency: "2.60GHz"): 575 | return "MacBook Pro (Retina, 15-inch, Late 2013)" 576 | default: 577 | return "MacBook Pro (Retina, 15-inch, Mid 2014)" 578 | } 579 | case .MacBookPro11_1: 580 | switch cpuString { 581 | case generateIntelCPUString(number: "i5-4278U", frequency: "2.60GHz"), generateIntelCPUString(number: "i5-4308U", frequency: "2.80GHz"), generateIntelCPUString(number: "i7-4578U", frequency: "3.00GHz"): 582 | return "MacBook Pro (Retina, 13-inch, Mid 2014)" 583 | case generateIntelCPUString(number: "i5-4258U", frequency: "2.40GHz"), generateIntelCPUString(number: "i5-4288U", frequency: "2.60GHz"), generateIntelCPUString(number: "i7-4558U", frequency: "3.00GHz"): 584 | return "MacBook Pro (Retina, 13-inch, Late 2013)" 585 | default: 586 | return "MacBook Pro (Retina, 13-inch, Mid 2014)" 587 | } 588 | case .iMac15_1: 589 | switch cpuString { 590 | case generateIntelCPUString(number: "i5-4590", frequency: "3.30GHz"): 591 | return "iMac (Retina 5K, 27-inch, Mid 2015)" 592 | case generateIntelCPUString(number: "i5-4690", frequency: "3.50GHz"), generateIntelCPUString(number: "i7-4790K", frequency: "4.00GHz"): 593 | return "iMac (Retina 5K, 27-inch, Late 2014)" 594 | default: 595 | return "iMac (Retina 5K, 27-inch, Mid 2015)" 596 | } 597 | default: 598 | // other model 599 | return modelId.modelName() 600 | } 601 | } 602 | 603 | // MARK: - 604 | /// get processor name 605 | private func getProcessorName() -> String? { 606 | guard let cpuInfo = getCpuBrandString() else { 607 | return nil 608 | } 609 | 610 | let cpuInfoArray = cpuInfo.split(separator: "@") 611 | let cpuBrand = cpuInfoArray[0] 612 | .replacingOccurrences(of: "CPU", with: "") 613 | .replacingOccurrences(of: "(R)", with: "") 614 | .replacingOccurrences(of: "(TM)", with: "") 615 | .trimmingCharacters(in: .whitespaces) 616 | 617 | return cpuBrand 618 | } 619 | 620 | /// get the number of physical core 621 | private func getPhysicalCore() -> Int? { 622 | var core: Int32 = 0 623 | var size = MemoryLayout.size 624 | 625 | if sysctlbyname("hw.physicalcpu", &core, &size, nil, 0) != 0 { 626 | return nil 627 | } 628 | 629 | return Int(core) 630 | } 631 | 632 | /// Returns true if running on Apple Silicon Mac (arm64), false otherwise. 633 | func isAppleSiliconMac() -> Bool? { 634 | var isARM: Int32 = 0 635 | var size = MemoryLayout.size 636 | if sysctlbyname("hw.optional.arm64", &isARM, &size, nil, 0) != 0 { 637 | return nil 638 | } 639 | return isARM == 1 640 | } 641 | 642 | /// get CPU info 643 | private func getCpu() -> String? { 644 | guard let id = getModelIdentifier() else { 645 | return nil 646 | } 647 | 648 | guard let modelId = ModelIdentifier(rawValue: id) else { 649 | return nil 650 | } 651 | 652 | // TODO: Add CPU frequency when new Apple Silicon Series is announced. 653 | // MARK: Apple silicon or not 654 | if isAppleSiliconMac() != nil { 655 | guard let core = getPhysicalCore() else { 656 | return nil 657 | } 658 | 659 | switch modelId { 660 | /// M1 family 661 | case .MacBookAir10_1, .MacBookPro17_1, .Macmini9_1, .iMac21_1, .iMac21_2, 662 | .MacBookPro18_1, .MacBookPro18_2, .MacBookPro18_3, .MacBookPro18_4, .Mac13_1, .Mac13_2: 663 | return "3.2GHz \(core)-core" 664 | /// M2 family 665 | case .Mac14_2, .Mac14_7, .Mac14_3, .Mac14_15, .Mac14_5, .Mac14_6, .Mac14_9, .Mac14_10, .Mac14_12, .Mac14_13, .Mac14_14, .Mac14_8: 666 | return "3.49GHz \(core)-core" 667 | /// M3 family 668 | case .Mac15_3, .Mac15_4, .Mac15_5, .Mac15_6, .Mac15_7, .Mac15_8, .Mac15_9, .Mac15_10, .Mac15_11, .Mac15_12, .Mac15_13: 669 | return "4.05GHz \(core)-core" 670 | /// M4 671 | case .Mac16_1, .Mac16_2, .Mac16_3, .Mac16_10, .Mac16_12, .Mac16_13: 672 | return "4.4GHz \(core)-core" 673 | /// M4 Pro, M4 Max 674 | case .Mac16_5, .Mac16_6, .Mac16_7, .Mac16_8, .Mac16_15: 675 | return "4.51GHz \(core)-core" 676 | /// M5 677 | case .Mac17_2: 678 | return "4.61GHz \(core)-core" 679 | default: 680 | return nil 681 | } 682 | } else { 683 | // Intel CPU Information 684 | guard let cpuInfo = getCpuBrandString() else { 685 | return nil 686 | } 687 | 688 | let cpuInfoArray = cpuInfo.split(separator: "@") 689 | let cpuFrequency = cpuInfoArray[1].trimmingCharacters(in: .whitespaces) 690 | 691 | guard let core = getPhysicalCore() else { 692 | return nil 693 | } 694 | 695 | return "\(cpuFrequency) \(core)-core" 696 | } 697 | } 698 | 699 | /// get neural engine info 700 | private func getNeuralEngine() -> String? { 701 | guard let id = getModelIdentifier() else { 702 | return nil 703 | } 704 | 705 | guard let modelId = ModelIdentifier(rawValue: id) else { 706 | return nil 707 | } 708 | 709 | return modelId.neuralEngine() 710 | } 711 | } 712 | 713 | -------------------------------------------------------------------------------- /Sources/DeviceHardware/UIDeviceHardware.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | public class UIDeviceHardware: DeviceHardware { 4 | public static let deviceHardware = UIDeviceHardware() 5 | 6 | /// model name, such as iPhone 8 7 | public var modelName: String { 8 | let modelName_ = getModelName() ?? "Unknown" 9 | return modelName_ 10 | } 11 | /// processor name, such as A11 Bionic 12 | public var processorName: String { 13 | let processorName_ = getProcessorName() ?? "Unknown" 14 | return processorName_ 15 | } 16 | /// CPU information, such as 2.39GHz 6-core 17 | public var cpu: String { 18 | let cpu_ = getCpu() ?? "Unknown" 19 | return cpu_ 20 | } 21 | /// GPU information, such as Apple A11 GPU 22 | public var gpu: String { 23 | let gpu_ = getGpu() ?? "Unknown" 24 | return gpu_ 25 | } 26 | /// Neural Engine, such as 2-core 27 | public var neuralEngine: String { 28 | let neuralEngine_ = getNeuralEngine() ?? "Unknown" 29 | return neuralEngine_ 30 | } 31 | 32 | /// Model Identifier, such as iPhone10,1 33 | public var modelIdentifier: String { 34 | let modelId = getModelIdentifier() ?? "Unknown" 35 | return modelId 36 | } 37 | /// number of processor, such as 6 38 | public var processorCount: Int { 39 | return ProcessInfo.processInfo.processorCount 40 | } 41 | /// physical memory size [B], such as 2071019520 42 | public var ram: Int { 43 | return getRAM() 44 | } 45 | /// physical memory size, such as 2GB 46 | public var ramString: String { 47 | return getRAMString() 48 | } 49 | /// The device has Dynamic Island 50 | public var hasDynamicIsland: Bool { 51 | return getHasDynamicIsland() ?? false 52 | } 53 | 54 | // MARK: - 55 | private func getModelIdentifier() -> String? { 56 | var size: Int = 0 57 | sysctlbyname("hw.machine", nil, &size, nil, 0) 58 | var machine = [CChar](repeating: 0, count: Int(size)) 59 | if sysctlbyname("hw.machine", &machine, &size, nil, 0) != 0 { 60 | return nil 61 | } 62 | let code: String = String(cString:machine) 63 | 64 | return code 65 | } 66 | 67 | private func getModelName() -> String? { 68 | guard let id = getModelIdentifier() else { 69 | return nil 70 | } 71 | 72 | guard let modelId = ModelIdentifier(rawValue: id) else { 73 | return nil 74 | } 75 | 76 | return modelId.modelName() 77 | } 78 | 79 | private func getProcessorName() -> String? { 80 | guard let id = getModelIdentifier() else { 81 | return nil 82 | } 83 | 84 | guard let modelId = ModelIdentifier(rawValue: id) else { 85 | return nil 86 | } 87 | 88 | return modelId.processorName() 89 | } 90 | 91 | private func getCpu() -> String? { 92 | guard let id = getModelIdentifier() else { 93 | return nil 94 | } 95 | 96 | guard let modelId = ModelIdentifier(rawValue: id) else { 97 | return nil 98 | } 99 | 100 | return modelId.cpu() 101 | } 102 | 103 | private func getGpu() -> String? { 104 | if #available(OSX 10.11, iOS 8.0, macCatalyst 13.0, *) { 105 | return getMetalGpu() 106 | } else { 107 | // Fallback on earlier versions 108 | guard let id = getModelIdentifier() else { 109 | return nil 110 | } 111 | 112 | guard let modelId = ModelIdentifier(rawValue: id) else { 113 | return nil 114 | } 115 | 116 | return modelId.gpu() 117 | } 118 | } 119 | 120 | private func getNeuralEngine() -> String? { 121 | guard let id = getModelIdentifier() else { 122 | return nil 123 | } 124 | 125 | guard let modelId = ModelIdentifier(rawValue: id) else { 126 | return nil 127 | } 128 | 129 | return modelId.neuralEngine() 130 | } 131 | 132 | private func getHasDynamicIsland() -> Bool? { 133 | guard let id = getModelIdentifier() else { 134 | return nil 135 | } 136 | 137 | guard let modelId = ModelIdentifier(rawValue: id) else { 138 | return nil 139 | } 140 | 141 | return modelId.hasDynamicIsland() 142 | } 143 | 144 | // MARK: - 145 | enum ModelIdentifier: String { 146 | // MARK: Simulator 147 | case i386 148 | case x86_64 149 | case arm64 150 | // MARK: iPod 151 | /// iPod touch (1st Generation) 152 | case iPod1_1 = "iPod1,1" 153 | /// iPod touch (2nd Generation) 154 | case iPod2_1 = "iPod2,1" 155 | /// iPod touch (3rd Generation) 156 | case iPod3_1 = "iPod3,1" 157 | /// iPod touch (4th Generation) 158 | case iPod4_1 = "iPod4,1" 159 | /// iPod touch (5th Generation) 160 | case iPod5_1 = "iPod5,1" 161 | /// iPod touch (6th Generation) 162 | case iPod7_1 = "iPod7,1" 163 | /// iPod touch (7th Generation) 164 | case iPod9_1 = "iPod9,1" 165 | 166 | // MARK: iPhone 167 | /// iPhone 168 | case iPhone1_1 = "iPhone1,1" 169 | /// iPhone 3G 170 | case iPhone1_2 = "iPhone1,2" 171 | /// iPhone 3GS 172 | case iPhone2_1 = "iPhone2,1" 173 | /// iPhone 4 GSM 174 | case iPhone3_1 = "iPhone3,1" 175 | /// iPhone 4 GSM 2012 176 | case iPhone3_2 = "iPhone3,2" 177 | /// iPhone 4 CDMA For Verizon,Sprint 178 | case iPhone3_3 = "iPhone3,3" 179 | /// iPhone 4S 180 | case iPhone4_1 = "iPhone4,1" 181 | /// iPhone 5 GSM 182 | case iPhone5_1 = "iPhone5,1" 183 | /// iPhone 5 Global 184 | case iPhone5_2 = "iPhone5,2" 185 | /// iPhone 5c GSM 186 | case iPhone5_3 = "iPhone5,3" 187 | /// iPhone 5c Global 188 | case iPhone5_4 = "iPhone5,4" 189 | /// iPhone 5s GSM 190 | case iPhone6_1 = "iPhone6,1" 191 | /// iPhone 5s Global 192 | case iPhone6_2 = "iPhone6,2" 193 | /// iPhone 6 Plus 194 | case iPhone7_1 = "iPhone7,1" 195 | /// iPhone 6 196 | case iPhone7_2 = "iPhone7,2" 197 | /// iPhone 6S 198 | case iPhone8_1 = "iPhone8,1" 199 | /// iPhone 6S Plus 200 | case iPhone8_2 = "iPhone8,2" 201 | /// iPhone SE 202 | case iPhone8_4 = "iPhone8,4" 203 | /// iPhone 7 A1660,A1779,A1780 204 | case iPhone9_1 = "iPhone9,1" 205 | /// iPhone 7 A1778 206 | case iPhone9_3 = "iPhone9,3" 207 | /// iPhone 7 Plus A1661,A1785,A1786 208 | case iPhone9_2 = "iPhone9,2" 209 | /// iPhone 7 Plus A1784 210 | case iPhone9_4 = "iPhone9,4" 211 | /// iPhone 8 A1863,A1906,A1907 212 | case iPhone10_1 = "iPhone10,1" 213 | /// iPhone 8 A1905 214 | case iPhone10_4 = "iPhone10,4" 215 | /// iPhone 8 Plus A1864,A1898,A1899 216 | case iPhone10_2 = "iPhone10,2" 217 | /// iPhone 8 Plus A1897 218 | case iPhone10_5 = "iPhone10,5" 219 | /// iPhone X A1865,A1902 220 | case iPhone10_3 = "iPhone10,3" 221 | /// iPhone X A1901 222 | case iPhone10_6 = "iPhone10,6" 223 | /// iPhone XR A1984,A2105,A2106,A2108 224 | case iPhone11_8 = "iPhone11,8" 225 | /// iPhone XS A2097,A2098 226 | case iPhone11_2 = "iPhone11,2" 227 | /// iPhone XS Max A1921,A2103 228 | case iPhone11_4 = "iPhone11,4" 229 | /// iPhone XS Max A2104 230 | case iPhone11_6 = "iPhone11,6" 231 | /// iPhone 11 232 | case iPhone12_1 = "iPhone12,1" 233 | /// iPhone 11 Pro 234 | case iPhone12_3 = "iPhone12,3" 235 | /// iPhone 11 Pro Max 236 | case iPhone12_5 = "iPhone12,5" 237 | /// iPhone SE (2nd Generation) 238 | case iPhone12_8 = "iPhone12,8" 239 | /// iPhone 12 mini 240 | case iPhone13_1 = "iPhone13,1" 241 | /// iPhone 12 242 | case iPhone13_2 = "iPhone13,2" 243 | /// iPhone 12 Pro 244 | case iPhone13_3 = "iPhone13,3" 245 | /// iPhone 12 Pro Max 246 | case iPhone13_4 = "iPhone13,4" 247 | /// iPhone 13 mini 248 | case iPhone14_4 = "iPhone14,4" 249 | /// iPhone 13 250 | case iPhone14_5 = "iPhone14,5" 251 | /// iPhone 13 Pro 252 | case iPhone14_2 = "iPhone14,2" 253 | /// iPhone 13 Pro Max 254 | case iPhone14_3 = "iPhone14,3" 255 | /// iPhone SE (3rg generation) 256 | case iPhone14_6 = "iPhone14,6" 257 | /// iPhone 14 258 | case iPhone14_7 = "iPhone14,7" 259 | /// iPhone 14 Plus 260 | case iPhone14_8 = "iPhone14,8" 261 | /// iPhone 14 Pro 262 | case iPhone15_2 = "iPhone15,2" 263 | /// iPhone 14 Pro Max 264 | case iPhone15_3 = "iPhone15,3" 265 | /// iPhone 15 266 | case iPhone15_4 = "iPhone15,4" 267 | /// iPhone 15 Plus 268 | case iPhone15_5 = "iPhone15,5" 269 | /// iPhone 15 Pro 270 | case iPhone16_1 = "iPhone16,1" 271 | /// iPhone 15 Pro Max 272 | case iPhone16_2 = "iPhone16,2" 273 | /// iPhone 16 274 | case iPhone17_3 = "iPhone17,3" 275 | /// iPhone 16 Plus 276 | case iPhone17_4 = "iPhone17,4" 277 | /// iPhone 16 Pro 278 | case iPhone17_1 = "iPhone17,1" 279 | /// iPhone 16 Pro Max 280 | case iPhone17_2 = "iPhone17,2" 281 | /// iPhone 16e 282 | case iPhone17_5 = "iPhone17,5" 283 | /// iPhone 17 284 | case iPhone18_3 = "iPhone18,3" 285 | /// iPhone 17 Pro 286 | case iPhone18_1 = "iPhone18,1" 287 | /// iPhone 17 Pro Max 288 | case iPhone18_2 = "iPhone18,2" 289 | /// iPhone Air 290 | case iPhone18_4 = "iPhone18,4" 291 | 292 | // MARK: iPad 293 | /// iPad 294 | case iPad1_1 = "iPad1,1" 295 | /// iPad 2 296 | case iPad2_1 = "iPad2,1" 297 | /// iPad 2 GSM 298 | case iPad2_2 = "iPad2,2" 299 | /// iPad 2 CDMA (Cellular) 300 | case iPad2_3 = "iPad2,3" 301 | /// iPad 2 Mid2012 302 | case iPad2_4 = "iPad2,4" 303 | /// iPad mini WiFi 304 | case iPad2_5 = "iPad2,5" 305 | /// iPad mini GSM (Cellular) 306 | case iPad2_6 = "iPad2,6" 307 | /// iPad mini Global (Cellular) 308 | case iPad2_7 = "iPad2,7" 309 | /// iPad 3 WiFi 310 | case iPad3_1 = "iPad3,1" 311 | /// iPad 3 CDMA (Cellular) 312 | case iPad3_2 = "iPad3,2" 313 | /// iPad 3 GSM (Cellular) 314 | case iPad3_3 = "iPad3,3" 315 | /// iPad 4 WiFi 316 | case iPad3_4 = "iPad3,4" 317 | /// iPad 4 GSM (Cellular) 318 | case iPad3_5 = "iPad3,5" 319 | /// iPad 4 Global (Cellular) 320 | case iPad3_6 = "iPad3,6" 321 | /// iPad Air WiFi 322 | case iPad4_1 = "iPad4,1" 323 | /// iPad Air Cellular 324 | case iPad4_2 = "iPad4,2" 325 | /// iPad Air ChinaModel 326 | case iPad4_3 = "iPad4,3" 327 | /// iPad mini 2 WiFi 328 | case iPad4_4 = "iPad4,4" 329 | /// iPad mini 2 Cellular 330 | case iPad4_5 = "iPad4,5" 331 | /// iPad mini 2 ChinaModel 332 | case iPad4_6 = "iPad4,6" 333 | /// iPad mini 3 WiFi 334 | case iPad4_7 = "iPad4,7" 335 | /// iPad mini 3 Cellular 336 | case iPad4_8 = "iPad4,8" 337 | /// iPad mini 3 ChinaModel 338 | case iPad4_9 = "iPad4,9" 339 | /// iPad mini 4 WiFi 340 | case iPad5_1 = "iPad5,1" 341 | /// iPad mini 4 Cellular 342 | case iPad5_2 = "iPad5,2" 343 | /// iPad Air 2 WiFi 344 | case iPad5_3 = "iPad5,3" 345 | /// iPad Air 2 Cellular 346 | case iPad5_4 = "iPad5,4" 347 | /// iPad Pro 9.7inch WiFi 348 | case iPad6_3 = "iPad6,3" 349 | /// iPad Pro 9.7inch Cellular 350 | case iPad6_4 = "iPad6,4" 351 | /// iPad Pro 12.9inch WiFi 352 | case iPad6_7 = "iPad6,7" 353 | /// iPad Pro 12.9inch Cellular 354 | case iPad6_8 = "iPad6,8" 355 | /// iPad (5th Generation) WiFi 356 | case iPad6_11 = "iPad6,11" 357 | /// iPad (5th Generation) Cellular 358 | case iPad6_12 = "iPad6,12" 359 | /// iPad Pro 12.9inch (2nd Generation) WiFi 360 | case iPad7_1 = "iPad7,1" 361 | /// iPad Pro 12.9inch (2nd Generation) Cellular 362 | case iPad7_2 = "iPad7,2" 363 | /// iPad Pro 10.5inch A1701 WiFi 364 | case iPad7_3 = "iPad7,3" 365 | /// iPad Pro 10.5inch A1709 Cellular 366 | case iPad7_4 = "iPad7,4" 367 | /// iPad 6th Generation WiFi 368 | case iPad7_5 = "iPad7,5" 369 | /// iPad 6th Generation Cellular 370 | case iPad7_6 = "iPad7,6" 371 | /// iPad 7th Generation WiFi 372 | case iPad7_11 = "iPad7,11" 373 | /// iPad 7th Generation Cellular 374 | case iPad7_12 = "iPad7,12" 375 | /// iPad Pro 11inch WiFi 376 | case iPad8_1 = "iPad8,1" 377 | /// iPad Pro 11inch WiFi 378 | case iPad8_2 = "iPad8,2" 379 | /// iPad Pro 11inch Cellular 380 | case iPad8_3 = "iPad8,3" 381 | /// iPad Pro 11inch Cellular 382 | case iPad8_4 = "iPad8,4" 383 | /// iPad Pro 12.9inch WiFi 384 | case iPad8_5 = "iPad8,5" 385 | /// iPad Pro 12.9inch WiFi 386 | case iPad8_6 = "iPad8,6" 387 | /// iPad Pro 12.9inch Cellular 388 | case iPad8_7 = "iPad8,7" 389 | /// iPad Pro 12.9inch Cellular 390 | case iPad8_8 = "iPad8,8" 391 | /// iPad Pro 11inch (2nd generation) WiFi 392 | case iPad8_9 = "iPad8,9" 393 | /// iPad Pro 11inch (2nd generation) Cellular 394 | case iPad8_10 = "iPad8,10" 395 | /// iPad Pro 12.9inch (4th generation) WiFi 396 | case iPad8_11 = "iPad8,11" 397 | /// iPad Pro 12.9inch (4th generation) Cellular 398 | case iPad8_12 = "iPad8,12" 399 | /// iPad mini 5th WiFi 400 | case iPad11_1 = "iPad11,1" 401 | /// iPad mini 5th Cellular 402 | case iPad11_2 = "iPad11,2" 403 | /// iPad Air (3rd generation) WiFi 404 | case iPad11_3 = "iPad11,3" 405 | /// iPad Air (3rd generation) Cellular 406 | case iPad11_4 = "iPad11,4" 407 | /// iPad (8th generation) WiFi 408 | case iPad11_6 = "iPad11,6" 409 | /// iPad (8th generation) Cellular 410 | case iPad11_7 = "iPad11,7" 411 | /// iPad Air (4th generation) WiFi 412 | case iPad13_1 = "iPad13,1" 413 | /// iPad Air (4th generation) Cellular 414 | case iPad13_2 = "iPad13,2" 415 | /// iPad Pro 11-inch (3rd generation) 416 | case iPad13_4 = "iPad13,4" 417 | case iPad13_5 = "iPad13,5" 418 | case iPad13_6 = "iPad13,6" 419 | case iPad13_7 = "iPad13,7" 420 | /// iPad Pro 12.9-inch (5th generation) 421 | case iPad13_8 = "iPad13,8" 422 | case iPad13_9 = "iPad13,9" 423 | case iPad13_10 = "iPad13,10" 424 | case iPad13_11 = "iPad13,11" 425 | /// iPad (9th generation) Wi-Fi + Cellular 426 | case iPad12_2 = "iPad12,2" 427 | /// iPad (9th generation) Wi-Fi 428 | case iPad12_1 = "iPad12,1" 429 | /// iPad mini (6th generation) Wi-Fi + Cellular 430 | case iPad14_2 = "iPad14,2" 431 | /// iPad mini (6th generation) Wi-Fi 432 | case iPad14_1 = "iPad14,1" 433 | /// iPad Air (5th generation) 434 | case iPad13_16 = "iPad13,16" 435 | case iPad13_17 = "iPad13,17" 436 | /// iPad (10th generation) 437 | case iPad13_18 = "iPad13,18" 438 | case iPad13_19 = "iPad13,19" 439 | /// iPad Pro 11-inch (4th generation) 440 | case iPad14_3_A = "iPad14,3-A" 441 | case iPad14_3_B = "iPad14,3-B" 442 | case iPad14_4_A = "iPad14,4-A" 443 | case iPad14_4_B = "iPad14,4-B" 444 | /// iPad Pro 12.9-inch (6th generation) 445 | case iPad14_5_A = "iPad14,5-A" 446 | case iPad14_5_B = "iPad14,5-B" 447 | case iPad14_6_A = "iPad14,6-A" 448 | case iPad14_6_B = "iPad14,6-B" 449 | /// iPad Air 11-inch (6th generation) Wi-Fi 450 | case iPad14_8 = "iPad14,8" 451 | /// iPad Air 11-inch (6th generation) Wi-Fi + Cellular 452 | case iPad14_9 = "iPad14,9" 453 | /// iPad Air 13-inch (6th generation) Wi-Fi 454 | case iPad14_10 = "iPad14,10" 455 | /// iPad Air 13-inch (6th generation) Wi-Fi + Cellular 456 | case iPad14_11 = "iPad14,11" 457 | /// iPad Pro 11-inch M4 Wi-Fi 458 | case iPad16_3 = "iPad16,3" 459 | /// iPad Pro 11-inch M4 Wi-Fi + Cellular 460 | case iPad16_4 = "iPad16,4" 461 | /// iPad Pro 13-inch M4 Wi-Fi 462 | case iPad16_5 = "iPad16,5" 463 | /// iPad Pro 13-inch M4 Wi-Fi + Cellular 464 | case iPad16_6 = "iPad16,6" 465 | /// iPad mini (A17 Pro) 466 | case iPad16_1 = "iPad16,1" 467 | case iPad16_2 = "iPad16,2" 468 | /// iPad Pro 11-inch (M5, 2025) Wi-Fi 469 | case iPad17_1 = "iPad17,1" 470 | /// iPad Pro 11-inch (M5, 2025) Wi-Fi + Cellular 471 | case iPad17_2 = "iPad17,2" 472 | /// iPad Pro 13-inch (M5, 2025) Wi-Fi 473 | case iPad17_3 = "iPad17,3" 474 | /// iPad Pro 13-inch (M5, 2025) Wi-Fi + Cellular 475 | case iPad17_4 = "iPad17,4" 476 | 477 | /// model name 478 | func modelName() -> String { 479 | switch self { 480 | case .i386, .x86_64, .arm64: 481 | return "Simulator" 482 | case .iPod1_1: 483 | return "iPod touch (1st generation)" 484 | case .iPod2_1: 485 | return "iPod touch (2nd generation)" 486 | case .iPod3_1: 487 | return "iPod touch (3rd generation)" 488 | case .iPod4_1: 489 | return "iPod touch (4th generation)" 490 | case .iPod5_1: 491 | return "iPod touch (5th generation)" 492 | case .iPod7_1: 493 | return "iPod touch (6th generation)" 494 | case .iPod9_1: 495 | return "iPod touch (7th generation)" 496 | case .iPhone1_1: 497 | return "iPhone (the original iPhone)" 498 | case .iPhone1_2: 499 | return "iPhone 3G" 500 | case .iPhone2_1: 501 | return "iPhone 3GS" 502 | case .iPhone3_1, .iPhone3_2, .iPhone3_3: 503 | return "iPhone4" 504 | case .iPhone4_1: 505 | return "iPhone 4S" 506 | case .iPhone5_1, .iPhone5_2: 507 | return "iPhone 5" 508 | case .iPhone5_3, .iPhone5_4: 509 | return "iPhone 5c" 510 | case .iPhone6_1, .iPhone6_2: 511 | return "iPhone 5s" 512 | case .iPhone7_1: 513 | return "iPhone 6 Plus" 514 | case .iPhone7_2: 515 | return "iPhone 6" 516 | case .iPhone8_1: 517 | return "iPhone 6s" 518 | case .iPhone8_2: 519 | return "iPhone 6s Plus" 520 | case .iPhone8_4: 521 | return "iPhone SE (1th generation)" 522 | case .iPhone9_1, .iPhone9_3: 523 | return "iPhone 7" 524 | case .iPhone9_2, .iPhone9_4: 525 | return "iPhone 7 Plus" 526 | case .iPhone10_1, .iPhone10_4: 527 | return "iPhone 8" 528 | case .iPhone10_2, .iPhone10_5: 529 | return "iPhone 8 Plus" 530 | case .iPhone10_3, .iPhone10_6: 531 | return "iPhone X" 532 | case .iPhone11_8: 533 | return "iPhone XR" 534 | case .iPhone11_2: 535 | return "iPhone XS" 536 | case .iPhone11_4, .iPhone11_6: 537 | return "iPhone XS Max" 538 | case .iPhone12_1: 539 | return "iPhone 11" 540 | case .iPhone12_3: 541 | return "iPhone 11 Pro" 542 | case .iPhone12_5: 543 | return "iPhone 11 Pro Max" 544 | case .iPhone12_8: 545 | return "iPhone SE (2nd generation)" 546 | case .iPhone13_1: 547 | return "iPhone 12 mini" 548 | case .iPhone13_2: 549 | return "iPhone 12" 550 | case .iPhone13_3: 551 | return "iPhone 12 Pro" 552 | case .iPhone13_4: 553 | return "iPhone 12 Pro Max" 554 | case .iPad1_1: 555 | return "iPad (1st generation)" 556 | case .iPad2_1, .iPad2_4, .iPad2_2, .iPad2_3: 557 | return "iPad 2" 558 | case .iPad2_5, .iPad2_6, .iPad2_7: 559 | return "iPad mini" 560 | case .iPad3_1, .iPad3_2, .iPad3_3: 561 | return "iPad (3rd generation) (The new iPad)" 562 | case .iPad3_4, .iPad3_5, .iPad3_6: 563 | return "iPad (4th generation) (iPad with Retina display)" 564 | case .iPad4_1, .iPad4_2, .iPad4_3: 565 | return "iPad Air (1th generation)" 566 | case .iPad4_4, .iPad4_5, .iPad4_6: 567 | return "iPad mini 2" 568 | case .iPad4_7, .iPad4_8, .iPad4_9: 569 | return "iPad mini 3" 570 | case .iPad5_1, .iPad5_2: 571 | return "iPad mini 4" 572 | case .iPad5_3, .iPad5_4: 573 | return "iPad Air 2" 574 | case .iPad6_3, .iPad6_4: 575 | return "iPad Pro (9.7-inch)" 576 | case .iPad6_7, .iPad6_8: 577 | return "iPad Pro (12.9-inch) (1st generation)" 578 | case .iPad6_11, .iPad6_12: 579 | return "iPad (5th generation)" 580 | case .iPad7_1, .iPad7_2: 581 | return "iPad Pro (12.9-inch) (2nd generation)" 582 | case .iPad7_3, .iPad7_4: 583 | return "iPad Pro (10.5-inch)" 584 | case .iPad7_5, .iPad7_6: 585 | return "iPad (6th generation)" 586 | case .iPad7_11, .iPad7_12: 587 | return "iPad (7th generation)" 588 | case .iPad8_1, .iPad8_2, .iPad8_3, .iPad8_4: 589 | return "iPad Pro (11-inch)" 590 | case .iPad8_5, .iPad8_6, .iPad8_7, .iPad8_8: 591 | return "iPad Pro (12.9-inch) (3rd generation)" 592 | case .iPad8_9, .iPad8_10: 593 | return "iPad Pro (11-inch) (2nd generation)" 594 | case .iPad8_11, .iPad8_12: 595 | return "iPad Pro (12.9-inch) (4th generation)" 596 | case .iPad11_1, .iPad11_2: 597 | return "iPad mini (5th generation)" 598 | case .iPad11_3, .iPad11_4: 599 | return "iPad Air (3rd generation)" 600 | case .iPad11_6, .iPad11_7: 601 | return "iPad (8th generation)" 602 | case .iPad13_1, .iPad13_2: 603 | return "iPad Air (4th generation)" 604 | case .iPad13_4, .iPad13_5, .iPad13_6, .iPad13_7: 605 | return "iPad Pro (11-inch) (3rd generation)" 606 | case .iPad13_8, .iPad13_9, .iPad13_10, .iPad13_11: 607 | return "iPad Pro (12.9-inch) (5th generation)" 608 | case .iPhone14_4: 609 | return "iPhone 13 mini" 610 | case .iPhone14_5: 611 | return "iPhone 13" 612 | case .iPhone14_2: 613 | return "iPhone 13 Pro" 614 | case .iPhone14_3: 615 | return "iPhone 13 Pro Max" 616 | case .iPad12_2, .iPad12_1: 617 | return "iPad (9th generation)" 618 | case .iPad14_2, .iPad14_1: 619 | return "iPad mini (6th generation)" 620 | case .iPhone14_6: 621 | return "iPhone SE (3rd generation)" 622 | case .iPad13_16, .iPad13_17: 623 | return "iPad Air (5th generation)" 624 | case .iPhone14_7: 625 | return "iPhone 14" 626 | case .iPhone14_8: 627 | return "iPhone 14 Plus" 628 | case .iPhone15_2: 629 | return "iPhone 14 Pro" 630 | case .iPhone15_3: 631 | return "iPhone 14 Pro Max" 632 | case .iPad13_18, .iPad13_19: 633 | return "iPad (10th generation)" 634 | case .iPad14_3_A, .iPad14_3_B, .iPad14_4_A, .iPad14_4_B: 635 | return "iPad Pro (11-inch) (4th generation)" 636 | case .iPad14_5_A, .iPad14_5_B, .iPad14_6_A, .iPad14_6_B: 637 | return "iPad Pro (12.9-inch) (6th generation)" 638 | case .iPhone15_4: 639 | return "iPhone 15" 640 | case .iPhone15_5: 641 | return "iPhone 15 Plus" 642 | case .iPhone16_1: 643 | return "iPhone 15 Pro" 644 | case .iPhone16_2: 645 | return "iPhone 15 Pro Max" 646 | case .iPad14_8, .iPad14_9: 647 | return "iPad Air (6th generation) (11-inch)" 648 | case .iPad14_10, .iPad14_11: 649 | return "iPad Air (6th generation) (13-inch)" 650 | case .iPad16_3, .iPad16_4: 651 | return "iPad Pro (M4) (11-inch)" 652 | case .iPad16_5, .iPad16_6: 653 | return "iPad Pro (M4) (13-inch)" 654 | case .iPhone17_3: 655 | return "iPhone 16" 656 | case .iPhone17_4: 657 | return "iPhone 16 Plus" 658 | case .iPhone17_1: 659 | return "iPhone 16 Pro" 660 | case .iPhone17_2: 661 | return "iPhone 16 Pro Max" 662 | case .iPad16_1, .iPad16_2: 663 | return "iPad mini (A17 Pro)" 664 | case .iPhone17_5: 665 | return "iPhone 16e" 666 | case .iPhone18_1: 667 | return "iPhone 17 Pro" 668 | case .iPhone18_2: 669 | return "iPhone 17 Pro Max" 670 | case .iPhone18_3: 671 | return "iPhone 17" 672 | case .iPhone18_4: 673 | return "iPhone Air" 674 | case .iPad17_1, .iPad17_2: 675 | return "iPad Pro (M5) (11-inch)" 676 | case .iPad17_3, .iPad17_4: 677 | return "iPad Pro (M5) (13-inch)" 678 | } 679 | } 680 | 681 | // Processor (SoC) Name 682 | func processorName() -> String { 683 | switch self { 684 | /// Simulator 685 | case .i386, .x86_64, .arm64: 686 | return "N/A" 687 | /// iPhone, iPod touch (1st), iPhone 3G 688 | case .iPod1_1, .iPhone1_1, .iPhone1_2: 689 | return "APL0098" 690 | /// iPod touch (2nd) 691 | case .iPod2_1: 692 | return "APL0278" 693 | /// iPhone 3GS 694 | case .iPhone2_1: 695 | return "APL0298" 696 | /// iPod touch (3rd) 697 | case .iPod3_1: 698 | return "APL2298" 699 | /// iPhone 4, iPad (1st), iPod touch (4th) 700 | case .iPod4_1, .iPhone3_1, .iPhone3_2, .iPhone3_3, .iPad1_1: 701 | return "Apple A4" 702 | /// iPhone 4s, iPad 2, iPod touch (5th), iPad mini (1st) 703 | case .iPhone4_1, .iPod5_1, .iPad2_5, .iPad2_6, .iPad2_7, .iPad2_1, .iPad2_2, .iPad2_3, .iPad2_4: 704 | return "Apple A5" 705 | /// iPad (3rd) 706 | case .iPad3_1, .iPad3_2, .iPad3_3: 707 | return "Apple A5X" 708 | /// iPhone 5, iPhone 5c 709 | case .iPhone5_1, .iPhone5_2, .iPhone5_3, .iPhone5_4: 710 | return "Apple A6" 711 | /// iPad (4th) 712 | case .iPad3_4, .iPad3_5, .iPad3_6: 713 | return "Apple A6X" 714 | /// iPhone 5s, iPad mini 2, iPad mini 3, iPad Air (1st) 715 | case .iPhone6_1, .iPhone6_2, .iPad4_4, .iPad4_5, .iPad4_6, .iPad4_7, .iPad4_8, .iPad4_9, .iPad4_1, .iPad4_2, .iPad4_3: 716 | return "Apple A7" 717 | /// iPhone 6/6 Plus, iPod touch (6th), iPad mini 4 718 | case .iPhone7_1, .iPhone7_2, .iPod7_1, .iPad5_1, .iPad5_2: 719 | return "Apple A8" 720 | /// iPad Air (2nd) 721 | case .iPad5_4, .iPad5_3: 722 | return "Apple A8X" 723 | /// iPhone 6s/6s Plus, iPhone SE (1st), iPad (5th) 724 | case .iPhone8_1, .iPhone8_2, .iPhone8_4, .iPad6_11, .iPad6_12: 725 | return "Apple A9" 726 | /// iPad Pro (1st) 727 | case .iPad6_3, .iPad6_4, .iPad6_7, .iPad6_8: 728 | return "Apple A9X" 729 | /// iPhone 7/7 Plus, iPad (6th), iPod touch (7th), iPad (7th) 730 | case .iPhone9_1, .iPhone9_2, .iPhone9_3, .iPhone9_4, .iPad7_5, .iPad7_6, .iPod9_1, .iPad7_11, .iPad7_12: 731 | return "Apple A10 Fusion" 732 | /// iPad Pro (2nd) 733 | case .iPad7_1, .iPad7_2, .iPad7_3, .iPad7_4: 734 | return "Apple A10X Fusion" 735 | /// iPhone 8/8 Plus, iPhone X 736 | case .iPhone10_1, .iPhone10_2, .iPhone10_3, .iPhone10_4, .iPhone10_5, .iPhone10_6: 737 | return "Apple A11 Bionic" 738 | /// iPhone XS/XS Max, iPhone XR, iPad Air (3rd), iPad mini (5th), iPad (8th) 739 | case .iPhone11_2, .iPhone11_4, .iPhone11_6, .iPhone11_8, .iPad11_3, .iPad11_4, .iPad11_1, .iPad11_2, .iPad11_6, .iPad11_7: 740 | return "Apple A12 Bionic" 741 | /// iPad Pro (3rd) 742 | case .iPad8_1, .iPad8_2, .iPad8_3, .iPad8_4, .iPad8_5, .iPad8_6, .iPad8_7, .iPad8_8: 743 | return "Apple A12X Bionic" 744 | /// iPad Pro (4th) 745 | case .iPad8_9, .iPad8_10, .iPad8_11, .iPad8_12: 746 | return "Apple A12Z Bionic" 747 | /// iPhone 11, iPhone 11 Pro/11 Pro Max, iPhone SE (2nd), iPad (9th) 748 | case .iPhone12_1, .iPhone12_3, .iPhone12_5, .iPhone12_8, .iPad12_2, .iPad12_1: 749 | return "Apple A13 Bionic" 750 | /// iPhone 12/12 mini, iPhone 12 Pro/12 Pro Max, iPad Air (4th), iPad (10th) 751 | case .iPhone13_1, .iPhone13_2, .iPhone13_3, .iPhone13_4, .iPad13_1, .iPad13_2, .iPad13_18, .iPad13_19: 752 | return "Apple A14 Bionic" 753 | /// iPad Pro (5th), iPad Air (5th) 754 | case .iPad13_4, .iPad13_5, .iPad13_6, .iPad13_7, .iPad13_8, .iPad13_9, .iPad13_10, .iPad13_11, .iPad13_16, .iPad13_17: 755 | return "Apple M1" 756 | /// iPhone 13/13 mini, iPhone 13 Pro/13 Pro Max, iPad mini (6th), iPhone SE (3rd), iPhone 14/14 Plus 757 | case .iPhone14_4, .iPhone14_5, .iPhone14_2, .iPhone14_3, .iPad14_2, .iPad14_1, .iPhone14_6, .iPhone14_7, .iPhone14_8: 758 | return "Apple A15 Bionic" 759 | /// iPhone 14 Pro/14 Pro Max, iPhone 15/15 Plus 760 | case .iPhone15_2, .iPhone15_3, .iPhone15_4, .iPhone15_5: 761 | return "Apple A16 Bionic" 762 | /// iPad Pro (6th) 763 | case .iPad14_3_A, .iPad14_3_B, .iPad14_4_A, .iPad14_4_B, .iPad14_5_A, .iPad14_5_B, .iPad14_6_A, .iPad14_6_B, .iPad14_8, .iPad14_9, .iPad14_10, .iPad14_11: 764 | return "Apple M2" 765 | /// iPhone 15 Pro/15 Pro Max 766 | case .iPhone16_1, .iPhone16_2, .iPad16_1, .iPad16_2: 767 | return "Apple A17 Pro" 768 | /// iPad Pro (M4) 769 | case .iPad16_3, .iPad16_4, .iPad16_5, .iPad16_6: 770 | return "Apple M4" 771 | /// iPhone 16/16 Plus 772 | case .iPhone17_3, .iPhone17_4, .iPhone17_5: 773 | return "Apple A18" 774 | /// iPhone 16 Pro/16 Pro Max 775 | case .iPhone17_1, .iPhone17_2: 776 | return "Apple A18 Pro" 777 | /// iPhone 17 778 | case .iPhone18_3: 779 | return "Apple A19" 780 | /// iPhone 17 Pro/17 Pro Max, iPhone Aie 781 | case .iPhone18_4, .iPhone18_2, .iPhone18_1: 782 | return "Apple A19 Pro" 783 | /// iPad Pro (M5) 784 | case .iPad17_1, .iPad17_2, .iPad17_3, .iPad17_4: 785 | return "Apple M5" 786 | } 787 | } 788 | 789 | 790 | // CPU Information 791 | func cpu() -> String { 792 | switch self { 793 | /// Simulator 794 | case .i386, .x86_64, .arm64: 795 | return "N/A" 796 | /// iPhone, iPod touch (1st), iPhone 3G 797 | case .iPod1_1, .iPhone1_1, .iPhone1_2: 798 | return "412MHz 1-core" 799 | /// iPod touch (2nd) 800 | case .iPod2_1: 801 | return "533MHz 1-core" 802 | /// iPhone 3GS 803 | case .iPhone2_1: 804 | return "600MHz 1-core" 805 | /// iPod touch (3rd) 806 | case .iPod3_1: 807 | return "800MHz 1-core" 808 | /// iPhone 4, iPad (1st), iPod touch (4th) 809 | /// Apple A4 810 | case .iPod4_1, .iPhone3_1, .iPhone3_2, .iPhone3_3, .iPad1_1: 811 | return "1.0GHz 1-core" 812 | /// iPhone 4s, iPad 2, iPod touch (5th), iPad mini (1st) 813 | /// Apple A5 814 | case .iPhone4_1, .iPod5_1, .iPad2_5, .iPad2_6, .iPad2_7, .iPad2_1, .iPad2_2, .iPad2_3, .iPad2_4: 815 | return "1.0GHz 2-core" 816 | /// iPad (3rd) 817 | /// Apple A5X 818 | case .iPad3_1, .iPad3_2, .iPad3_3: 819 | return "1.0GHz 2-core" 820 | /// iPhone 5, iPhone 5c 821 | /// Apple A6 822 | case .iPhone5_1, .iPhone5_2, .iPhone5_3, .iPhone5_4: 823 | return "1.3GHz 2-core" 824 | /// iPad (4th) 825 | /// Apple A6X 826 | case .iPad3_4, .iPad3_5, .iPad3_6: 827 | return "1.4GHz 2-core" 828 | /// iPhone 5s, iPad mini 2, iPad mini 3 829 | /// Apple A7 830 | case .iPhone6_1, .iPhone6_2, .iPad4_4, .iPad4_5, .iPad4_6, .iPad4_7, .iPad4_8, .iPad4_9: 831 | return "1.3GHz 2-core" 832 | /// iPad Air (1st) 833 | /// Apple A7 834 | case .iPad4_1, .iPad4_2, .iPad4_3: 835 | return "1.4GHz 2-core" 836 | /// iPhone 6/6 Plus, iPod touch (6th), iPad mini 4 837 | /// Apple A8 838 | case .iPhone7_1, .iPhone7_2, .iPod7_1, .iPad5_1, .iPad5_2: 839 | return "1.5GHz 2-core" 840 | /// iPad Air (2nd) 841 | /// Apple A8 842 | case .iPad5_4, .iPad5_3: 843 | return "1.5GHz 3-core" 844 | /// iPhone 6s/6s Plus, iPhone SE (1st), iPad (5th) 845 | /// Apple A9 846 | case .iPhone8_1, .iPhone8_2, .iPhone8_4, .iPad6_11, .iPad6_12: 847 | return "1.85GHz 2-core" 848 | /// iPad Pro (1st) 849 | /// Apple A9X 850 | case .iPad6_3, .iPad6_4, .iPad6_7, .iPad6_8: 851 | return "2.26GHz 2-core" 852 | /// iPhone 7/7 Plus, iPad (6th), iPod touch (7th), iPad (7th) 853 | /// Apple A10 Fusion 854 | case .iPhone9_1, .iPhone9_2, .iPhone9_3, .iPhone9_4, .iPad7_5, .iPad7_6, .iPod9_1, .iPad7_11, .iPad7_12: 855 | return "2.34GHz 4-core" 856 | /// iPad Pro (2nd) 857 | /// Apple A10X Fusion 858 | case .iPad7_1, .iPad7_2, .iPad7_3, .iPad7_4: 859 | return "2.36GHz 6-core" 860 | /// iPhone 8/8 Plus, iPhone X 861 | /// Apple A11 Bionic 862 | case .iPhone10_1, .iPhone10_2, .iPhone10_3, .iPhone10_4, .iPhone10_5, .iPhone10_6: 863 | return "2.39GHz 6-core" 864 | /// iPhone XS/XS Max, iPhone XR, iPad Air (3rd), iPad mini (5th), iPad (8th) 865 | /// Apple A12 Bionic 866 | case .iPhone11_2, .iPhone11_4, .iPhone11_6, .iPhone11_8, .iPad11_3, .iPad11_4, .iPad11_1, .iPad11_2, .iPad11_6, .iPad11_7: 867 | return "2.49 GHz 6-core" 868 | /// iPad Pro (3rd), iPad Pro (4th) 869 | /// Apple A12X/A12Z Bionic 870 | case .iPad8_1, .iPad8_2, .iPad8_3, .iPad8_4, .iPad8_5, .iPad8_6, .iPad8_7, .iPad8_8, .iPad8_9, .iPad8_10, .iPad8_11, .iPad8_12: 871 | return "2.49GHz 8-core" 872 | /// iPhone 11, iPhone 11 Pro/11 Pro Max, iPhone SE (2nd), iPad (9th) 873 | /// Apple A13 Bionic 874 | case .iPhone12_1, .iPhone12_3, .iPhone12_5, .iPhone12_8, .iPad12_2, .iPad12_1: 875 | return "2.65GHz 6-core" 876 | /// iPhone 12/12 mini, iPhone 12 Pro/12 Pro Max, iPad Air (4th), iPad (10th) 877 | /// Apple A14 Bionic 878 | case .iPhone13_1, .iPhone13_2, .iPhone13_3, .iPhone13_4, .iPad13_1, .iPad13_2, .iPad13_18, .iPad13_19: 879 | return "2.99GHz 6-core" 880 | /// iPad Pro (5th), iPad Air (5th) 881 | /// Apple M1 882 | case .iPad13_4, .iPad13_5, .iPad13_6, .iPad13_7, .iPad13_8, .iPad13_9, .iPad13_10, .iPad13_11, .iPad13_16, .iPad13_17: 883 | return "3.2GHz 8-core" 884 | /// iPhone 13/13 mini, iPhone 13 Pro/13 Pro Max, iPhone SE (3rd), iPhone 14/14 Plus 885 | /// Apple A15 Bionic 886 | case .iPhone14_4, .iPhone14_5, .iPhone14_2, .iPhone14_3, .iPhone14_6, .iPhone14_7, .iPhone14_8: 887 | return "3.23GHz 6-core" 888 | /// iPad mini (6th) 889 | /// Apple A15 Bionic 890 | case .iPad14_2, .iPad14_1: 891 | return "2.93GHz 6-core" 892 | /// iPhone 14 Pro/14 Pro Max, iPhone 15/15 Plus 893 | /// Apple A16 Bionic 894 | case .iPhone15_2, .iPhone15_3, .iPhone15_4, .iPhone15_5: 895 | return "3.46GHz 6-core" 896 | /// iPad Pro (6th) 897 | /// Apple M2 898 | case .iPad14_3_A, .iPad14_3_B, .iPad14_4_A, .iPad14_4_B, .iPad14_5_A, .iPad14_5_B, .iPad14_6_A, .iPad14_6_B, .iPad14_8, .iPad14_9, .iPad14_10, .iPad14_11: 899 | return "3.49GHz 6-core" 900 | /// iPhone 15 Pro/15 Pro Max 901 | /// Apple A17 Pro 902 | case .iPhone16_1, .iPhone16_2, .iPad16_1, .iPad16_2: 903 | return "3.78GHz 6-core" 904 | /// iPad Pro M4 905 | /// Apple M4 906 | case .iPad16_3, .iPad16_4, .iPad16_5, .iPad16_6: 907 | return "4.4GHz 10-core" 908 | /// iPhone 16/16Plus, iPhone 16Pro/16 Pro Max 909 | /// Apple A18, Apple A18 Pro 910 | case .iPhone17_1, .iPhone17_2, .iPhone17_3, .iPhone17_4, .iPhone17_5: 911 | return "4.05GHz 6-core" 912 | /// iPhone 17, iPhone 17 Pro/17 Pro Max, iPhone Air 913 | /// Apple A19, Apple A19 Pro 914 | case .iPhone18_1, .iPhone18_2, .iPhone18_3, .iPhone18_4: 915 | return "4.26GHz 6-core" 916 | /// iPad Pro (M5) 917 | case .iPad17_1, .iPad17_2, .iPad17_3, .iPad17_4: 918 | return "4.43GHz 10-core" 919 | } 920 | } 921 | 922 | // GPU Information 923 | func gpu() -> String { 924 | switch self { 925 | /// Simulator 926 | case .i386, .x86_64, .arm64: 927 | return "N/A" 928 | /// iPhone, iPod touch (1st), iPhone 3G 929 | case .iPod1_1, .iPhone1_1, .iPhone1_2: 930 | return "PowerVR MBX Lite" 931 | /// iPod touch (2nd) 932 | case .iPod2_1: 933 | return "PowerVR MBX Lite" 934 | /// iPhone 3GS 935 | case .iPhone2_1: 936 | return "PowerVR SGX535" 937 | /// iPod touch (3rd) 938 | case .iPod3_1: 939 | return "PowerVR SGX535" 940 | /// iPhone 4, iPad (1st), iPod touch (4th) 941 | case .iPod4_1, .iPhone3_1, .iPhone3_2, .iPhone3_3, .iPad1_1: 942 | return "PowerVR SGX535" 943 | /// iPhone 4s, iPad 2, iPod touch (5th), iPad mini (1st) 944 | case .iPhone4_1, .iPod5_1, .iPad2_5, .iPad2_6, .iPad2_7, .iPad2_1, .iPad2_2, .iPad2_3, .iPad2_4: 945 | return "PowerVR SGX543MP2 2-core" 946 | /// iPad (3rd) 947 | case .iPad3_1, .iPad3_2, .iPad3_3: 948 | return "PowerVR SGX554MP4 4-core" 949 | /// iPhone 5, iPhone 5c 950 | case .iPhone5_1, .iPhone5_2, .iPhone5_3, .iPhone5_4: 951 | return "PowerVR SGX543MP3 3-core" 952 | /// iPad (4th) 953 | case .iPad3_4, .iPad3_5, .iPad3_6: 954 | return "PowerVR SGX554MP4 4-core" 955 | /// iPhone 5s, iPad mini 2, iPad mini 3, iPad Air (1st) 956 | case .iPhone6_1, .iPhone6_2, .iPad4_4, .iPad4_5, .iPad4_6, .iPad4_7, .iPad4_8, .iPad4_9, .iPad4_1, .iPad4_2, .iPad4_3: 957 | return "PowerVR G6430 4-core" 958 | /// iPhone 6/6 Plus, iPod touch (6th), iPad mini 4 959 | case .iPhone7_1, .iPhone7_2, .iPod7_1, .iPad5_1, .iPad5_2: 960 | return "PowerVR GXA6450 4-core" 961 | /// iPad Air (2nd) 962 | case .iPad5_4, .iPad5_3: 963 | return "PowerVR GXA6850 8-core" 964 | /// iPhone 6s/6s Plus, iPhone SE (1st), iPad (5th) 965 | case .iPhone8_1, .iPhone8_2, .iPhone8_4, .iPad6_11, .iPad6_12: 966 | return "PowerVR GT7600 6-core" 967 | /// iPad Pro (1st) 968 | case .iPad6_3, .iPad6_4, .iPad6_7, .iPad6_8: 969 | return "PowerVR GTA7850 12-core" 970 | /// iPhone 7/7 Plus, iPad (6th), iPod touch (7th), iPad (7th) 971 | case .iPhone9_1, .iPhone9_2, .iPhone9_3, .iPhone9_4, .iPad7_5, .iPad7_6, .iPod9_1, .iPad7_11, .iPad7_12: 972 | return "PowerVR GT7600 Plus 6-core" 973 | /// iPad Pro (2nd) 974 | case .iPad7_1, .iPad7_2, .iPad7_3, .iPad7_4: 975 | return "PowerVR GT7600 Plus 12-core" 976 | /// iPhone 8/8 Plus, iPhone X 977 | /// Apple A11 Bionic 978 | case .iPhone10_1, .iPhone10_2, .iPhone10_3, .iPhone10_4, .iPhone10_5, .iPhone10_6: 979 | return "3-core" 980 | /// iPhone XS/XS Max, iPhone XR, iPad Air (3rd), iPad mini (5th), iPad (8th) 981 | /// Apple A12 Bionic 982 | case .iPhone11_2, .iPhone11_4, .iPhone11_6, .iPhone11_8, .iPad11_3, .iPad11_4, .iPad11_1, .iPad11_2, .iPad11_6, .iPad11_7: 983 | return "4-core" 984 | /// iPad Pro (3rd) 985 | /// Apple A12X Bionic 986 | case .iPad8_1, .iPad8_2, .iPad8_3, .iPad8_4, .iPad8_5, .iPad8_6, .iPad8_7, .iPad8_8: 987 | return "7-core" 988 | /// iPad Pro (4th) 989 | /// Apple A12Z Bionic 990 | case .iPad8_9, .iPad8_10, .iPad8_11, .iPad8_12: 991 | return "8-core" 992 | /// iPhone 11, iPhone 11 Pro/11 Pro Max, iPhone SE (2nd), iPad (9th) 993 | /// Apple A13 Bionic 994 | case .iPhone12_1, .iPhone12_3, .iPhone12_5, .iPhone12_8, .iPad12_2, .iPad12_1: 995 | return "4-core" 996 | /// iPhone 12/12 mini, iPhone 12 Pro/12 Pro Max, iPad Air (4th), iPad (10th) 997 | /// Apple A14 Bionic 998 | case .iPhone13_1, .iPhone13_2, .iPhone13_3, .iPhone13_4, .iPad13_1, .iPad13_2, .iPad13_18, .iPad13_19: 999 | return "4-core" 1000 | /// iPad Pro (5th), iPad Air (5th) 1001 | /// Apple M1 1002 | case .iPad13_4, .iPad13_5, .iPad13_6, .iPad13_7, .iPad13_8, .iPad13_9, .iPad13_10, .iPad13_11, .iPad13_16, .iPad13_17: 1003 | return "8-core" 1004 | /// iPhone 13 Pro/13 Pro Max, iPad mini (6th), iPhone 14/14 Plus 1005 | /// Apple A15 Bionic 1006 | case .iPhone14_2, .iPhone14_3, .iPad14_2, .iPad14_1, .iPhone14_7, .iPhone14_8: 1007 | return "5-core" 1008 | /// iPhone 13/13 mini, iPhone SE (3rd) 1009 | /// Apple A15 Bionic 1010 | case .iPhone14_4, .iPhone14_5, .iPhone14_6: 1011 | return "4-core" 1012 | /// iPhone 14 Pro/14 Pro Max, iPhone 15/15 Plus 1013 | /// Apple A15 Bionic 1014 | case .iPhone15_2, .iPhone15_3, .iPhone15_4, .iPhone15_5: 1015 | return "5-core" 1016 | /// iPad Pro (6th) 1017 | /// Apple M2 1018 | case .iPad14_3_A, .iPad14_3_B, .iPad14_4_A, .iPad14_4_B, .iPad14_5_A, .iPad14_5_B, .iPad14_6_A, .iPad14_6_B, .iPad14_8, .iPad14_9, .iPad14_10, .iPad14_11: 1019 | return "10-core" 1020 | /// iPhone 15 Pro/15 Pro Max 1021 | /// Apple A17 Pro 1022 | case .iPhone16_1, .iPhone16_2, .iPad16_1, .iPad16_2: 1023 | return "6-core" 1024 | /// iPad Pro M4 1025 | /// Apple M4 1026 | case .iPad16_3, .iPad16_4, .iPad16_5, .iPad16_6: 1027 | return "10-core" 1028 | /// iPhone 16/16 Plus 1029 | /// Apple A18 1030 | case .iPhone17_3, .iPhone17_4: 1031 | return "5-core" 1032 | /// iPhone 16Pro/16 Pro Max 1033 | /// Apple A18 Pro 1034 | case .iPhone17_1, .iPhone17_2: 1035 | return "6-core" 1036 | /// iPhone 16e 1037 | /// Apple A18 1038 | case .iPhone17_5: 1039 | return "4-core" 1040 | /// iPhone 17 1041 | /// Apple A19 1042 | case .iPhone18_3: 1043 | return "5-core" 1044 | /// iPhone Air 1045 | /// Apple A19 Pro 1046 | case .iPhone18_4: 1047 | return "5-core" 1048 | /// iPhone 17 Pro/17 Pro Max 1049 | /// Apple A19 Pro 1050 | case .iPhone18_1, .iPhone18_2: 1051 | return "6-core" 1052 | /// iPad Pro (M5) 1053 | case .iPad17_1, .iPad17_2, .iPad17_3, .iPad17_4: 1054 | return "10-core" 1055 | } 1056 | } 1057 | 1058 | // Neural Engine Information 1059 | func neuralEngine() -> String { 1060 | switch self { 1061 | /// Simulator 1062 | case .i386, .x86_64, .arm64: 1063 | return "N/A" 1064 | /// Apple A11 Bionic 1065 | case .iPhone10_1, .iPhone10_2, .iPhone10_3, .iPhone10_4, .iPhone10_5, .iPhone10_6: 1066 | return "2-core" 1067 | /// iPhone XS/XS Max, iPhone XR, iPad Air (3rd), iPad mini (5th), iPad (8th) 1068 | /// Apple A12 Bionic 1069 | case .iPhone11_2, .iPhone11_4, .iPhone11_6, .iPhone11_8, .iPad11_3, .iPad11_4, .iPad11_1, .iPad11_2, .iPad11_6, .iPad11_7: 1070 | return "8-core" 1071 | /// iPad Pro (3rd), iPad Pro (4th) 1072 | /// Apple A12X/A12Z Bionic 1073 | case .iPad8_1, .iPad8_2, .iPad8_3, .iPad8_4, .iPad8_5, .iPad8_6, .iPad8_7, .iPad8_8, .iPad8_9, .iPad8_10, .iPad8_11, .iPad8_12: 1074 | return "8-core" 1075 | /// iPhone 11, iPhone 11 Pro/11 Pro Max, iPhone SE (2nd), iPad (6th) 1076 | /// Apple A13 Bionic 1077 | case .iPhone12_1, .iPhone12_3, .iPhone12_5, .iPhone12_8, .iPad12_2, .iPad12_1: 1078 | return "8-core" 1079 | /// iPhone 12/12 mini, iPhone 12 Pro/12 Pro Max, iPad Air (4th), iPad (10th) 1080 | /// Apple A14 Bionic 1081 | /// 11 TOPS 1082 | case .iPhone13_1, .iPhone13_2, .iPhone13_3, .iPhone13_4, .iPad13_1, .iPad13_2, .iPad13_18, .iPad13_19: 1083 | return "16-core" 1084 | /// iPad Pro (5th), iPad Air (3rd) 1085 | /// Apple M1 1086 | /// 11 TOPS 1087 | case .iPad13_4, .iPad13_5, .iPad13_6, .iPad13_7, .iPad13_8, .iPad13_9, .iPad13_10, .iPad13_11, .iPad13_16, .iPad13_17: 1088 | return "16-core" 1089 | /// iPhone 13/13 mini, iPhone 13 Pro/13 Pro Max, iPad mini (6th), iPhone SE (3rd) 1090 | /// Apple A15 Bionic 1091 | /// 15.8 TOPS 1092 | case .iPhone14_4, .iPhone14_5, .iPhone14_2, .iPhone14_3, .iPad14_2, .iPad14_1, .iPhone14_6, .iPhone14_7, .iPhone14_8: 1093 | return "16-core" 1094 | /// iPhone 14 Pro/14 Pro Max, iPhone 15/15 Plus 1095 | /// Apple A16 Bionic 1096 | /// 17 TOPS 1097 | case .iPhone15_2, .iPhone15_3, .iPhone15_4, .iPhone15_5: 1098 | return "16-core" 1099 | /// iPad Pro (6th) 1100 | /// Apple M2 1101 | /// 15.8 TOPS 1102 | case .iPad14_3_A, .iPad14_3_B, .iPad14_4_A, .iPad14_4_B, .iPad14_5_A, .iPad14_5_B, .iPad14_6_A, .iPad14_6_B, .iPad14_8, .iPad14_9, .iPad14_10, .iPad14_11: 1103 | return "16-core" 1104 | /// iPhone 15 Pro/15 Pro Max 1105 | /// Apple A17 Pro 1106 | /// 35 TOPS 1107 | case .iPhone16_1, .iPhone16_2, .iPad16_1, .iPad16_2: 1108 | return "16-core" 1109 | /// iPad Pro M4 1110 | /// Apple M4 1111 | /// 38 TOPS 1112 | case .iPad16_3, .iPad16_4, .iPad16_5, .iPad16_6: 1113 | return "16-core" 1114 | /// iPhone 16/16 Plus, iPhone 16 Pro/16 Pro Max 1115 | /// Apple A18, Apple A18 Pro 1116 | /// 35 TOPS 1117 | case .iPhone17_1, .iPhone17_2, .iPhone17_3, .iPhone17_4, .iPhone17_5: 1118 | return "16-core" 1119 | /// iPhone 17, iPhone 17 Pro/17 Pro Max, iPhone Air 1120 | /// Apple A19, Apple A19 Pro 1121 | case .iPhone18_1, .iPhone18_2, .iPhone18_3, .iPhone18_4: 1122 | return "16-core" 1123 | /// iPad Pro (M5) 1124 | case .iPad17_1, .iPad17_2, .iPad17_3, .iPad17_4: 1125 | return "16-core" 1126 | /// Other device 1127 | default: 1128 | return "None" 1129 | } 1130 | } 1131 | 1132 | // TODO: Add devices when new iPhone with the Dynamic Island is announced. 1133 | // Dynamic Island 1134 | func hasDynamicIsland() -> Bool { 1135 | switch self { 1136 | // 14 Pro/Pro Max, 15/15 Plus, 15 Pro/Pro Max, 16/16 Plus, 16 Pro/16 Pro Max, 17, 17 Pro/17 Pro Max, Air 1137 | case .iPhone15_2, .iPhone15_3, .iPhone15_4, .iPhone15_5, 1138 | .iPhone16_1, .iPhone16_2, 1139 | .iPhone17_1, .iPhone17_2, .iPhone17_3, .iPhone17_4, 1140 | .iPhone18_1, .iPhone18_2, .iPhone18_3, .iPhone18_4: 1141 | return true 1142 | default: 1143 | return false 1144 | } 1145 | } 1146 | } 1147 | } 1148 | --------------------------------------------------------------------------------