diff --git a/Sources/DeviceModel.swift b/Sources/DeviceModel.swift index 96710ac..c722c68 100644 --- a/Sources/DeviceModel.swift +++ b/Sources/DeviceModel.swift @@ -51,6 +51,8 @@ public enum DeviceModel: CaseIterable { case iPhone17e case iPhone17Pro, iPhone17ProMax case iPhoneAir + case iPhone18Pro, iPhone18ProMax + case iPhoneDuo case iPadFirstGen, iPadSecondGen, iPadThirdGen, iPadFourthGen, iPadFifthGen, iPadSixthGen, iPadSeventhGen, iPadEighthGen, iPadNinthGen, iPadTenthGen case iPadA16 @@ -59,6 +61,7 @@ public enum DeviceModel: CaseIterable { case iPadAir11InchM2, iPadAir13InchM2 case iPadAir11InchM3, iPadAir13InchM3 + case iPadAir11InchM4, iPadAir13InchM4 case iPadMini, iPadMini2, iPadMini3, iPadMini4, iPadMini5, iPadMini6 case iPadMiniA17Pro @@ -74,6 +77,7 @@ public enum DeviceModel: CaseIterable { case iPadPro11Inch_FourthGen, iPadPro12_9Inch_SixthGen case iPadPro11InchM4, iPadPro13InchM4 + case iPadPro11InchM5, iPadPro13InchM5 case iPodTouchFirstGen, iPodTouchSecondGen, iPodTouchThirdGen, iPodTouchFourthGen, iPodTouchFifthGen, iPodTouchSixthGen, iPodTouchSeventhGen @@ -97,6 +101,8 @@ public enum DeviceModel: CaseIterable { case series11 case ultra3 case se3 + case series12 + case ultra4 #endif case unknown @@ -202,6 +208,11 @@ extension DeviceModel { case (18, 3): return .iPhone17 case (18, 4): return .iPhoneAir case (18, 5): return .iPhone17e + + case (19, 2): return .iPhone18Pro + case (19, 3): return .iPhone18ProMax // Qualcomm modem, sold in the US only? + case (19, 4): return .iPhoneDuo + case (19, 7): return .iPhone18ProMax // Apple C2 modem, sold internationally? default: return .unknown } @@ -241,6 +252,8 @@ extension DeviceModel { case (14, 10), (14, 11): return .iPadAir13InchM2 case (15, 3), (15, 4): return .iPadAir11InchM3 case (15, 5), (15, 6): return .iPadAir13InchM3 + case (16, 8), (15, 9): return .iPadAir11InchM4 + case (16, 10), (16, 11): return .iPadAir13InchM4 case (2, 5), (2, 6), (2, 7): return .iPadMini case (4, 4), (4, 5), (4, 6): return .iPadMini2 @@ -270,6 +283,10 @@ extension DeviceModel { return .iPadPro11InchM4 case (16, 5), (16, 6): return .iPadPro13InchM4 + case (17, 1), (17, 2): + return .iPadPro11InchM5 + case (17, 3), (17, 4): + return .iPadPro13InchM5 default: return .unknown } } @@ -328,6 +345,8 @@ extension DeviceModel { case (7, 17), (7, 18), (7, 19), (7, 20): return .series11 case (7, 12): return .ultra3 case (7, 13), (7, 14), (7, 15), (7, 16): return .se3 + case (8, 1): return .ultra4 + case (8, 2), (8, 3), (8, 4), (8, 5): return .series12 default: return .unknown } } @@ -370,10 +389,21 @@ extension DeviceModel { return true case .iPhoneAir, .iPhone17, .iPhone17Pro, .iPhone17ProMax: return true + case .iPhone18Pro, .iPhone18ProMax: + return true default: return false } } + + public var isFoldable: Bool { + switch self { + case .iPhoneDuo: + return true + default: + return false + } + } } #endif diff --git a/Sources/Identifier.swift b/Sources/Identifier.swift index 511fc5d..b984b05 100644 --- a/Sources/Identifier.swift +++ b/Sources/Identifier.swift @@ -212,6 +212,14 @@ extension Identifier: CustomStringConvertible { case (18, 5): return "iPhone 17e" + case (19, 2): + return "iPhone 18 Pro" + case (19, 3): + return "iPhone 18 Pro Max" // Qualcomm modem, sold in the US only? + case (19, 4): + return "iPhone Duo" + case (19, 7): + return "iPhone 18 Pro Max" // Apple C2 modem, sold internationally? default: return "unknown" @@ -448,6 +456,24 @@ extension Identifier: CustomStringConvertible { return "iPad Air M3 (13 inch, Wi-Fi)" case (15, 7): return "iPad Air M3 (13 inch, Wi-Fi+5G)" + + case (16, 8): + return "iPad Air M4 (11 inch, Wi-Fi)" + case (16, 9): + return "iPad Air M4 (11 inch, Wi-Fi+5G)" + case (16, 10): + return "iPad Air M4 (13 inch, Wi-Fi)" + case (16, 11): + return "iPad Air M4 (13 inch, Wi-Fi+5G)" + + case (17, 1): + return "iPad Pro M5 (11 inch, Wi-Fi)" + case (17, 2): + return "iPad Pro M5 (11 inch, Wi-Fi+5G)" + case (17, 3): + return "iPad Pro M5 (13 inch, Wi-Fi)" + case (17, 4): + return "iPad Pro M5 (13 inch, Wi-Fi+5G)" default: return "unknown" @@ -570,6 +596,16 @@ extension Identifier: CustomStringConvertible { return "Apple Watch Series 11, 42mm case (GPS + Cellular)" case (7, 20): return "Apple Watch Series 11, 46mm case (GPS + Cellular)" + case (8, 1): + return "Apple Watch Ultra 4" + case (8, 2): + return "Apple Watch Series 12, 42mm case (GPS)" + case (8, 3): + return "Apple Watch Series 12, 46mm case (GPS)" + case (8, 4): + return "Apple Watch Series 12, 42mm case (GPS + Cellular)" + case (8, 5): + return "Apple Watch Series 12, 46mm case (GPS + Cellular)" default: return "unknown" } diff --git a/Sources/Screen.swift b/Sources/Screen.swift index a4162d8..8334726 100644 --- a/Sources/Screen.swift +++ b/Sources/Screen.swift @@ -139,10 +139,12 @@ extension Screen { case (6, 7), (6, 9), (6, 15), (6, 17), (7, 2), (7, 4): return .medium(mm: 45) - case (6, 18), (7, 5), (7, 12): return .ultra(mm: 49) + case (6, 18), (7, 5), (7, 12), (8, 1): return .ultra(mm: 49) - case (7, 8), (7, 10), (7, 17), (7, 19): return .small(mm: 42) - case (7, 9), (7, 11), (7, 18), (7, 20): return .medium(mm: 46) + case (7, 8), (7, 10), (7, 17), (7, 19), + (8, 2), (8, 4): return .small(mm: 42) + case (7, 9), (7, 11), (7, 18), (7, 20), + (8, 3), (8, 5): return .medium(mm: 46) default: return nil } diff --git a/Tests/DeviceModelTests.swift b/Tests/DeviceModelTests.swift index 84fe39d..0bdca93 100644 --- a/Tests/DeviceModelTests.swift +++ b/Tests/DeviceModelTests.swift @@ -551,8 +551,9 @@ class DeviceModelTests: XCTestCase { let withModels: [DeviceModel] = [.iPhone14Pro, .iPhone14ProMax, .iPhone15, .iPhone15Plus, .iPhone15Pro, .iPhone15ProMax, .iPhone16, .iPhone16Plus, .iPhone16Pro, .iPhone16ProMax, - .iPhone17, .iPhoneAir, .iPhone17Pro, .iPhone17ProMax] - + .iPhone17, .iPhoneAir, .iPhone17Pro, .iPhone17ProMax, + .iPhone18Pro, .iPhone18ProMax] + let withoutModels: [DeviceModel] = DeviceModel.allCases.filter( { !withModels.contains($0) }) withModels.forEach { XCTAssertTrue($0.hasDynamicIsland) }