Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

### New features

- Add `allDevicesWithVariableAperture` and `hasVariableAperture` for iPhone 18 Pro and iPhone 18 Pro Max. The instance property also supports their simulators. ([#516](https://github.com/devicekit/DeviceKit/issues/516))

## Version 5.10.0

Releasedate: 2026-11-01
Expand Down
11 changes: 11 additions & 0 deletions Source/Device.generated.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2489,6 +2489,17 @@ extension Device {
return [.iPhone11, .iPhone11Pro, .iPhone11ProMax, .iPhone12, .iPhone12Mini, .iPhone12Pro, .iPhone12ProMax, .iPhone13, .iPhone13Mini, .iPhone13Pro, .iPhone13ProMax, .iPhone14, .iPhone14Plus, .iPhone14Pro, .iPhone14ProMax, .iPhone15, .iPhone15Plus, .iPhone15Pro, .iPhone15ProMax, .iPhone16, .iPhone16Plus, .iPhone16Pro, .iPhone16ProMax, .iPhone17, .iPhone17Pro, .iPhone17ProMax, .iPhone18Pro, .iPhone18ProMax, .iPhoneDuo, .iPadPro11Inch2, .iPadPro12Inch4, .iPadPro11Inch3, .iPadPro12Inch5, .iPadPro11Inch4, .iPadPro12Inch6]
}

/// All device models that feature a camera with a variable aperture, excluding simulators.
public static var allDevicesWithVariableAperture: [Device] {
return [.iPhone18Pro, .iPhone18ProMax]
}

/// Returns whether the device model has a camera with a variable aperture.
/// Simulators use their simulated model's capability.
public var hasVariableAperture: Bool {
return isOneOf(Device.allDevicesWithVariableAperture) || isOneOf(Device.allDevicesWithVariableAperture.map(Device.simulator))
}

/// Returns whether or not the current device has a camera
public var hasCamera: Bool {
return !self.cameras.isEmpty
Expand Down
15 changes: 15 additions & 0 deletions Source/Device.swift.gyb
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class Device:
applePencilSupport=0,
hasForce3dTouchSupport=False,
cameras=0,
hasVariableAperture=False,
hasLidarSensor=False,
hasUSBCConnectivity=False,
has5gSupport=False,
Expand Down Expand Up @@ -56,6 +57,7 @@ class Device:
self.applePencilSupport = applePencilSupport
self.hasForce3dTouchSupport = hasForce3dTouchSupport
self.cameras = cameras
self.hasVariableAperture = hasVariableAperture
self.hasLidarSensor = hasLidarSensor
self.cpu = cpu
self.hasUSBCConnectivity = hasUSBCConnectivity
Expand Down Expand Up @@ -277,11 +279,13 @@ iPhones = [
# iPhone19,3 and iPhone19,7 are regional variants of iPhone 18 Pro Max.
Device("iPhone18Pro", "Device is an [iPhone 18 Pro](https://support.apple.com/en-us/148590)", "", ["iPhone19,2"], 6.3, (9, 19.5), "iPhone 18 Pro", "iPhone 18 Pro", 460,
cpu="a20Pro", isPro=True, isXSeries=True, hasFaceID=True,
hasVariableAperture=True,
hasSensorHousing=True, supportsWirelessCharging=True, hasRoundedDisplayCorners=True, hasDynamicIsland=True,
cameras=123, hasLidarSensor=True, hasUSBCConnectivity=True, has5gSupport=True,
hasEsimSupport=True, hasDualEsimSupport=True),
Device("iPhone18ProMax", "Device is an [iPhone 18 Pro Max](https://support.apple.com/en-us/148591)", "", ["iPhone19,3", "iPhone19,7"], 6.9, (9, 19.5), "iPhone 18 Pro Max", "iPhone 18 Pro Max", 460,
cpu="a20Pro", isPlusFormFactor=True, isPro=True, isXSeries=True,
hasVariableAperture=True,
hasFaceID=True, hasSensorHousing=True, supportsWirelessCharging=True, hasRoundedDisplayCorners=True,
hasDynamicIsland=True, cameras=123, hasLidarSensor=True, hasUSBCConnectivity=True,
has5gSupport=True,
Expand Down Expand Up @@ -1844,6 +1848,17 @@ extension Device {
return [${', '.join(list(map(lambda device: "." + device.caseName, list(filter(lambda device: device.cameras == 3 or device.cameras == 13 or device.cameras == 123, iOSDevices)))))}]
}

/// All device models that feature a camera with a variable aperture, excluding simulators.
public static var allDevicesWithVariableAperture: [Device] {
return [${', '.join(list(map(lambda device: "." + device.caseName, list(filter(lambda device: device.hasVariableAperture == True, iOSDevices)))))}]
}

/// Returns whether the device model has a camera with a variable aperture.
/// Simulators use their simulated model's capability.
public var hasVariableAperture: Bool {
return isOneOf(Device.allDevicesWithVariableAperture) || isOneOf(Device.allDevicesWithVariableAperture.map(Device.simulator))
}

/// Returns whether or not the current device has a camera
public var hasCamera: Bool {
return !self.cameras.isEmpty
Expand Down
14 changes: 14 additions & 0 deletions Tests/Tests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -865,6 +865,20 @@ class DeviceKitTests: XCTestCase {
}
}

func testVariableAperture() {
let expectedDevices: [Device] = [.iPhone18Pro, .iPhone18ProMax]
XCTAssertEqual(Device.allDevicesWithVariableAperture, expectedDevices)

for model in Device.allRealDevices {
let expected = expectedDevices.contains(model)
XCTAssertEqual(model.hasVariableAperture, expected, model.description)
XCTAssertEqual(Device.simulator(model).hasVariableAperture, expected, model.description)
}

XCTAssertFalse(Device.unknown("unrecognized").hasVariableAperture)
XCTAssertFalse(Device.simulator(.unknown("unrecognized")).hasVariableAperture)
}

func testLidarValues() {
let lidarDevices: [Device] = [
.iPhone12Pro,
Expand Down
Loading