From 810ceb5d51cb089472f9dfc61e25eabadd41a3a2 Mon Sep 17 00:00:00 2001 From: Tsungyu Yu Date: Thu, 25 Mar 2021 16:16:54 +0800 Subject: [PATCH] Add macOS from https://github.com/devicekit/DeviceKit/pull/217 --- Package.swift | 3 +- Source/Device.generated.swift | 627 ++++++++++++++++++++++++--------- Source/Device.swift.gyb | 638 ++++++++++++++++++++++++++-------- Tests/Tests.swift | 43 +-- 4 files changed, 981 insertions(+), 330 deletions(-) diff --git a/Package.swift b/Package.swift index cdd16330..ebefbab5 100644 --- a/Package.swift +++ b/Package.swift @@ -17,7 +17,8 @@ let package = Package( platforms: [ .iOS(.v9), .tvOS(.v9), - .watchOS(.v2) + .watchOS(.v2), + .macOS(.v10_12), ], products: [ // Products define the executables and libraries produced by a package, and make them visible to other packages. diff --git a/Source/Device.generated.swift b/Source/Device.generated.swift index 43d80965..f2cd335e 100644 --- a/Source/Device.generated.swift +++ b/Source/Device.generated.swift @@ -11,11 +11,13 @@ #if os(watchOS) import WatchKit +#elseif os(macOS) +import AppKit #else import UIKit #endif -// MARK: Device +// MARK: - Device /// This enum is a value-type wrapper and extension of /// [`UIDevice`](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIDevice_Class/). @@ -144,26 +146,6 @@ public enum Device { /// /// ![Image](https://support.apple.com/library/APPLE/APPLECARE_ALLGEOS/SP806/sp806-iphone11pro-max_2x.png) case iPhone11ProMax - /// Device is an [iPhone SE (2nd generation)](https://support.apple.com/kb/SP820) - /// - /// ![Image](https://support.apple.com/library/APPLE/APPLECARE_ALLGEOS/SP820/iphone-se-2nd-gen_2x.png) - case iPhoneSE2 - /// Device is an [iPhone 12](https://support.apple.com/kb/SP830) - /// - /// ![Image](https://support.apple.com/library/APPLE/APPLECARE_ALLGEOS/SP830/sp830-iphone12-ios14_2x.png) - case iPhone12 - /// Device is an [iPhone 12 mini](https://support.apple.com/kb/SP829) - /// - /// ![Image](https://support.apple.com/library/APPLE/APPLECARE_ALLGEOS/SP829/sp829-iphone12mini-ios14_2x.png) - case iPhone12Mini - /// Device is an [iPhone 12 Pro](https://support.apple.com/kb/SP831) - /// - /// ![Image](https://support.apple.com/library/APPLE/APPLECARE_ALLGEOS/SP831/iphone12pro-ios14_2x.png) - case iPhone12Pro - /// Device is an [iPhone 12 Pro Max](https://support.apple.com/kb/SP832) - /// - /// ![Image](https://support.apple.com/library/APPLE/APPLECARE_ALLGEOS/SP832/iphone12promax-ios14_2x.png) - case iPhone12ProMax /// Device is an [iPad 2](https://support.apple.com/kb/SP622) /// /// ![Image](https://support.apple.com/library/APPLE/APPLECARE_ALLGEOS/SP622/SP622_01-ipad2-mul.png) @@ -200,14 +182,6 @@ public enum Device { /// /// ![Image](https://support.apple.com/library/APPLE/APPLECARE_ALLGEOS/SP807/sp807-ipad-7th-gen_2x.png) case iPad7 - /// Device is an [iPad (8th generation)](https://support.apple.com/kb/SP822) - /// - /// ![Image](https://support.apple.com/library/APPLE/APPLECARE_ALLGEOS/SP822/sp822-ipad-8gen_2x.png) - case iPad8 - /// Device is an [iPad Air (4th generation)](https://support.apple.com/kb/SP828) - /// - /// ![Image](https://support.apple.com/library/APPLE/APPLECARE_ALLGEOS/SP828/sp828ipad-air-ipados14-960_2x.png) - case iPadAir4 /// Device is an [iPad Mini](https://support.apple.com/kb/SP661) /// /// ![Image](https://support.apple.com/library/APPLE/APPLECARE_ALLGEOS/SP661/sp661_ipad_mini_color.jpg) @@ -334,22 +308,255 @@ public enum Device { /// /// ![Image](https://support.apple.com/library/APPLE/APPLECARE_ALLGEOS/SP808/sp808-apple-watch-series-5_2x.png) case appleWatchSeries5_44mm - /// Device is an [Apple Watch Series 6](https://support.apple.com/kb/SP826) + #elseif os(macOS) + /// Device is a [Mac mini (2018)](https://support.apple.com/kb/SP782) + /// + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macmini/mac-mini-2018-space-gray.jpg) + case macMini2018 + /// Device is a [Mac mini (Late 2014)](https://support.apple.com/kb/SP710) + /// + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macmini/mac-mini-2014.jpg) + case macMiniLate2014 + /// Device is a [Mac mini (Late 2012)](https://support.apple.com/kb/SP659) + /// + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macmini/mac-mini-2011-2012-2014-device.jpg) + case macMiniLate2012 + /// Device is a [Mac mini (Mid 2011)](https://support.apple.com/kb/SP632) + /// + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macmini/mac-mini-2011-2012-2014-device.jpg) + case macMiniMid2011 + /// Device is a [Mac mini (Mid 2010)](https://support.apple.com/kb/SP585) + /// + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macmini/mac-mini-2010-device.jpg) + case macMiniMid2010 + /// Device is a [Mac mini (Late 2009)](https://support.apple.com/kb/SP577) or [Mac mini (Early 2009)](https://support.apple.com/kb/SP505) + /// + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macmini/mac-mini-2009-device.jpg) + case macMini2009 + /// Device is a [iMac (Retina 5K, 27-inch, 2019)](https://support.apple.com/kb/SP790) + /// + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/imac/imac-27-2017.jpg) + case iMacRetina5K27Inch2019 + /// Device is a [iMac (Retina 4K, 21.5-inch, 2019)](https://support.apple.com/kb/SP789) + /// + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/imac/imac-21-5-2017.jpg) + case iMacRetina4K215Inch2019 + /// Device is a [iMac (Retina 5K, 27-inch, 2017)](https://support.apple.com/kb/SP760) + /// + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/imac/imac-27-2017.jpg) + case iMacRetina5K27Inch2017 + /// Device is a [iMac (Retina 4K, 21.5-inch, 2017)](https://support.apple.com/kb/SP759) + /// + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/imac/imac-21-5-2017.jpg) + case iMacRetina4K215Inch2017 + /// Device is a [iMac (21.5-inch, 2017)](https://support.apple.com/kb/SP758) + /// + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/imac/imac-21-5-2017.jpg) + case iMac215Inch2017 + /// Device is a [iMac (Retina 5K, 27-inch, Late 2015)](https://support.apple.com/kb/SP731) + /// + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/imac/imac-27-late-2015.jpg) + case iMacRetina5K27InchLate2015 + /// Device is a [iMac (Retina 4K, 21.5-inch, Late 2015)](https://support.apple.com/kb/SP732) + /// + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/imac/imac-21-5-2015.jpg) + case iMacRetina4K215InchLate2015 + /// Device is a [iMac (21.5-inch, Late 2015)](https://support.apple.com/kb/SP733) + /// + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/imac/imac-21-5-2015.jpg) + case iMac215InchLate2015 + /// Device is a [iMac (Retina 5K, 27-inch, Mid 2015)](https://support.apple.com/kb/SP718) or [iMac (Retina 5K, 27-inch, Late 2014)](https://support.apple.com/kb/SP707) + /// + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/imac/imac-27-late-2015.jpg) + case iMacRetina5K27InchMid2015 + /// Device is a [iMac (21.5-inch, Mid 2014)](https://support.apple.com/kb/SP701) + /// + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/imac/imac-27-2014.jpg) + case iMac215InchMid2014 + /// Device is a [iMac (27-inch, Late 2013)](https://support.apple.com/kb/SP688) + /// + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/imac/imac-27-2013.jpg) + case iMac27InchLate2013 + /// Device is a [iMac (21.5-inch, Late 2013)](https://support.apple.com/kb/SP687) + /// + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/imac/imac-27-2013.jpg) + case iMac215InchLate2013 + /// Device is a [iMac (21.5-inch, Late 2012)](https://support.apple.com/kb/SP665) + /// + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/imac/imac-27-2012.jpg) + case iMac215InchLate2012 + /// Device is a [iMac (27-inch, Mid 2011)](https://support.apple.com/kb/SP689) + /// + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/imac/imac-27-2011.jpg) + case iMac27InchMid2011 + /// Device is a [iMac (21.5-inch, Mid 2011)](https://support.apple.com/kb/SP623) + /// + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/imac/imac-27-2011.jpg) + case iMac215InchMid2011 + /// Device is a [iMac (27-inch, Mid 2010)](https://support.apple.com/kb/SP695) + /// + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/imac/imac-27-2010.jpg) + case iMac27InchMid2010 + /// Device is a [iMac (21.5-inch, Mid 2010)](https://support.apple.com/kb/SP588) + /// + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/imac/imac-27-2010.jpg) + case iMac215InchMid2010 + /// Device is a [Mac Pro (2019)](https://support.apple.com/kb/SP797) + /// + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macpro/id-mac-pro-2019.jpg) + case macPro2019 + /// Device is a [Mac Pro (Late 2013)](https://support.apple.com/kb/SP697) + /// + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macpro/id-mac-pro-2013.jpg) + case macProLate2013 + /// Device is a [Mac Pro (Mid 2012)](https://support.apple.com/kb/SP652) + /// + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macpro/id-mac-pro-2009-2012.jpg) + case macProMid2012 + /// Device is a [Mac Pro (Early 2009)](https://support.apple.com/kb/SP506) + /// + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macpro/id-mac-pro-2009-2012.jpg) + case macProEarly2009 + /// Device is a [MacBook (Retina, 12-inch, 2017)](https://support.apple.com/kb/SP757) /// - /// ![Image](https://support.apple.com/library/APPLE/APPLECARE_ALLGEOS/SP826/sp826-apple-watch-series6-580_2x.png) - case appleWatchSeries6_40mm - /// Device is an [Apple Watch Series 6](https://support.apple.com/kb/SP826) + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbook/macbook-2017-device.jpg) + case macBookRetina12Inch2017 + /// Device is a [MacBook (Retina, 12-inch, Early 2016)](https://support.apple.com/kb/SP741) /// - /// ![Image](https://support.apple.com/library/APPLE/APPLECARE_ALLGEOS/SP826/sp826-apple-watch-series6-580_2x.png) - case appleWatchSeries6_44mm - /// Device is an [Apple Watch SE](https://support.apple.com/kb/SP827) + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbook/macbook-2016-device.jpg) + case macBookRetina12InchEarly2016 + /// Device is a [MacBook (Retina, 12-inch, Early 2015)](https://support.apple.com/kb/SP712) /// - /// ![Image](https://support.apple.com/library/APPLE/APPLECARE_ALLGEOS/SP827/sp827-apple-watch-se-580_2x.png) - case appleWatchSE_40mm - /// Device is an [Apple Watch SE](https://support.apple.com/kb/SP827) + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbook/macbook-2015-device.jpg) + case macBookRetina12InchEarly2015 + /// Device is a [MacBook (13-inch, Mid 2010)](https://support.apple.com/kb/SP584) /// - /// ![Image](https://support.apple.com/library/APPLE/APPLECARE_ALLGEOS/SP827/sp827-apple-watch-se-580_2x.png) - case appleWatchSE_44mm + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbook/macbook-late-2009-2010-device.jpg) + case macBook13InchMid2010 + /// Device is a [MacBook (13-inch, Late 2009)](https://support.apple.com/kb/SP579) + /// + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbook/macbook-late-2009-2010-device.jpg) + case macBook13InchLate2009 + /// Device is a [MacBook Air (Retina, 13-inch, 2019)](https://support.apple.com/kb/SP798) + /// + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbookair/macbook-air-2018-device.jpg) + case macBookAirRetina13Inch2019 + /// Device is a [MacBook Air (Retina, 13-inch, 2018)](https://support.apple.com/kb/SP783) + /// + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbookair/macbook-air-2018-device.jpg) + case macBookAirRetina13Inch2018 + /// Device is a [MacBook Air (13-inch, 2017)](https://support.apple.com/kb/SP753) + /// + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbookair/macbook-air-2017-device.jpg) + case macBookAir13Inch2017 + /// Device is a [MacBook Air (13-inch, Early 2015)](https://support.apple.com/kb/SP714) + /// + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbookair/macbook-air-2015-13in-device.jpg) + case macBookAir13InchEarly2015 + /// Device is a [MacBook Air (11-inch, Early 2015)](https://support.apple.com/kb/SP713) + /// + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbookair/macbook-air-2015-11in-device.jpg) + case macBookAir11InchEarly2015 + /// Device is a [MacBook Air (13-inch, Early 2014)](https://support.apple.com/kb/SP700) or [MacBook Air (13-inch, Mid 2013)](https://support.apple.com/kb/SP678) + /// + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbookair/macbook-air-2013-2014-13in-device.jpg) + case macBookAir13InchEarly2014 + /// Device is a [MacBook Air (11-inch, Early 2014)](https://support.apple.com/kb/SP699) or [MacBook Air (11-inch, Mid 2013)](https://support.apple.com/kb/SP677) + /// + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbookair/macbook-air-2013-2014-11in-device.jpg) + case macBookAir11InchEarly2014 + /// Device is a [MacBook Air (13-inch, Mid 2012)](https://support.apple.com/kb/SP670) + /// + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbookair/macbook-air-2012-13in-device.jpg) + case macBookAir13InchMid2012 + /// Device is a [MacBook Air (11-inch, Mid 2012)](https://support.apple.com/kb/SP650) + /// + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbookair/macbook-air-2012-11in-device.jpg) + case macBookAir11InchMid2012 + /// Device is a [MacBook Air (13-inch, Mid 2011)](https://support.apple.com/kb/SP683) + /// + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbookair/macbook-air-2011-13in-device.jpg) + case macBookAir13InchMid2011 + /// Device is a [MacBook Air (11-inch, Mid 2011)](https://support.apple.com/kb/SP631) + /// + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbookair/macbook-air-2011-11in-device.jpg) + case macBookAir11InchMid2011 + /// Device is a [MacBook Air (13-inch, Late 2010)](https://support.apple.com/kb/SP618) + /// + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbookair/macbook-air-2009-2010-13in-device.jpg) + case macBookAir13InchLate2010 + /// Device is a [MacBook Air (11-inch, Late 2010)](https://support.apple.com/kb/SP617) + /// + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbookair/macbook-air-2010-11in-device.jpg) + case macBookAir11InchLate2010 + /// Device is a [MacBook Air (Mid 2009)](https://support.apple.com/kb/SP548) + /// + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbookair/macbook-air-2009-2010-13in-device.jpg) + case macBookAirMid2009 + /// Device is a [MacBook Pro (16-inch, 2019)](https://support.apple.com/kb/SP809) + /// + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbookpro/macbook-pro-16in-2019.jpg) + case macBookPro16Inch2019 + /// Device is a [MacBook Pro (13-inch, 2019, Two Thunderbolt 3 ports)](https://support.apple.com/kb/SP799) + /// + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbookpro/macbook-pro-2018-13in-device.jpg) + case macBookPro13Inch2019TwoThunderbolt3Ports + /// Device is a [MacBook Pro (15-inch, 2019)](https://support.apple.com/kb/SP794) + /// + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbookpro/macbook-pro-2018-15in-device.jpg) + case macBookPro15Inch2019 + /// Device is a [MacBook Pro (13-inch, 2019, Four Thunderbolt 3 ports)](https://support.apple.com/kb/SP795) or [MacBook Pro (13-inch, 2018, Four Thunderbolt 3 ports)](https://support.apple.com/kb/SP775) + /// + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbookpro/macbook-pro-2018-13in-device.jpg) + case macBookPro13Inch2019FourThunderbolt3Ports + /// Device is a [MacBook Pro (15-inch, 2018)](https://support.apple.com/kb/SP776) + /// + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbookpro/macbook-pro-2018-15in-device.jpg) + case macBookPro15Inch2018 + /// Device is a [MacBook Pro (15-inch, 2017)](https://support.apple.com/kb/SP756) + /// + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbookpro/macbook-pro-2017-15in-device.jpg) + case macBookPro15Inch2017 + /// Device is a [MacBook Pro (13-inch, 2017, Four Thunderbolt 3 ports)](https://support.apple.com/kb/SP755) + /// + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbookpro/macbook-pro-2017-13in-device.jpg) + case macBookPro13Inch2017FourThunderbolt3Ports + /// Device is a [MacBook Pro (13-inch, 2017, Two Thunderbolt 3 ports)](https://support.apple.com/kb/SP754) + /// + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbookpro/macbook-pro-2017-13in-device-2thunderbolt-3ports.jpg) + case macBookPro13Inch2017TwoThunderbolt3Ports + /// Device is a [MacBook Pro (15-inch, 2016)](https://support.apple.com/kb/SP749) + /// + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbookpro/macbook-pro-2016-15in-device.jpg) + case macBookPro15Inch2016 + /// Device is a [MacBook Pro (13-inch, 2016, Four Thunderbolt 3 ports)](https://support.apple.com/kb/SP748) + /// + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbookpro/macbook-pro-2016-13in-device.jpg) + case macBookPro13Inch2016FourThunderbolt3Ports + /// Device is a [MacBook Pro (13-inch, 2016, Two Thunderbolt 3 ports)](https://support.apple.com/kb/SP747) + /// + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbookpro/macbook-pro-2016-13in-device.jpg) + case macBookPro13Inch2016TwoThunderbolt3Ports + /// Device is a [MacBook Pro (Retina, 15-inch, Mid 2015)](https://support.apple.com/kb/SP719) + /// + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbookpro/macbook-pro-mid-2015-15in-device.jpg) + case macBookProRetina15InchMid2015 + /// Device is a [MacBook Pro (Retina, 13-inch, Early 2015)](https://support.apple.com/kb/SP715) + /// + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbookpro/macbook-pro-early-2015-13in-device.jpg) + case macBookProRetina13InchEarly2015 + /// Device is a [MacBook Pro (Retina, 15-inch, Mid 2014)](https://support.apple.com/kb/SP704) or [MacBook Pro (Retina, 15-inch, Late 2013)](https://support.apple.com/kb/SP690) + /// + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbookpro/macbook-pro-mid-2014-15in-device.jpg) + case macBookProRetina15InchMid2014 + /// Device is a [MacBook Pro (Retina, 13-inch, Mid 2014)](https://support.apple.com/kb/SP703) or [MacBook Pro (Retina, 13-inch, Late 2013)](https://support.apple.com/kb/SP691) + /// + /// ![Image](https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbookpro/macbook-pro-mid-2014-13in-device.jpg) + case macBookProRetina13InchMid2014 + /// Device is an [iMac Pro](https://support.apple.com/kb/SP771) + /// + /// ![Image](https://support.apple.com/library/APPLE/APPLECARE_ALLGEOS/SP771/SP771-imac-pro-2017.png) + case iMacPro2017 #endif /// Device is [Simulator](https://developer.apple.com/library/ios/documentation/IDEs/Conceptual/iOS_Simulator_Guide/Introduction/Introduction.html) @@ -369,6 +576,12 @@ public enum Device { /// Gets the identifier from the system, such as "iPhone7,1". public static var identifier: String = { + #if os(macOS) + let identifier = try? sysctlData(for: [CTL_HW, HW_MODEL]).withUnsafeBufferPointer { dataPointer -> String? in + dataPointer.baseAddress.flatMap { String(validatingUTF8: $0) } + } + return identifier ?? "" + #else var systemInfo = utsname() uname(&systemInfo) let mirror = Mirror(reflecting: systemInfo.machine) @@ -378,6 +591,7 @@ public enum Device { return identifier + String(UnicodeScalar(UInt8(value))) } return identifier + #endif }() /// Maps an identifier to a Device. If the identifier can not be mapped to an existing device, `UnknownDevice(identifier)` is returned. @@ -412,11 +626,6 @@ public enum Device { case "iPhone12,1": return iPhone11 case "iPhone12,3": return iPhone11Pro case "iPhone12,5": return iPhone11ProMax - case "iPhone12,8": return iPhoneSE2 - case "iPhone13,2": return iPhone12 - case "iPhone13,1": return iPhone12Mini - case "iPhone13,3": return iPhone12Pro - case "iPhone13,4": return iPhone12ProMax case "iPad2,1", "iPad2,2", "iPad2,3", "iPad2,4": return iPad2 case "iPad3,1", "iPad3,2", "iPad3,3": return iPad3 case "iPad3,4", "iPad3,5", "iPad3,6": return iPad4 @@ -426,8 +635,6 @@ public enum Device { case "iPad7,5", "iPad7,6": return iPad6 case "iPad11,3", "iPad11,4": return iPadAir3 case "iPad7,11", "iPad7,12": return iPad7 - case "iPad11,6", "iPad11,7": return iPad8 - case "iPad13,1", "iPad13,2": return iPadAir4 case "iPad2,5", "iPad2,6", "iPad2,7": return iPadMini case "iPad4,4", "iPad4,5", "iPad4,6": return iPadMini2 case "iPad4,7", "iPad4,8", "iPad4,9": return iPadMini3 @@ -444,7 +651,7 @@ public enum Device { case "iPad13,4", "iPad13,5", "iPad13,6", "iPad13,7": return iPadPro11Inch3 case "iPad13,8", "iPad13,9", "iPad13,10", "iPad13,11": return iPadPro12Inch5 case "AudioAccessory1,1": return homePod - case "i386", "x86_64", "arm64": return simulator(mapToDevice(identifier: ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"] ?? "iOS")) + case "i386", "x86_64": return simulator(mapToDevice(identifier: ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"] ?? "iOS")) default: return unknown(identifier) } #elseif os(tvOS) @@ -469,11 +676,73 @@ public enum Device { case "Watch4,2", "Watch4,4": return appleWatchSeries4_44mm case "Watch5,1", "Watch5,3": return appleWatchSeries5_40mm case "Watch5,2", "Watch5,4": return appleWatchSeries5_44mm - case "Watch6,1", "Watch6,3": return appleWatchSeries6_40mm - case "Watch6,2", "Watch6,4": return appleWatchSeries6_44mm - case "Watch5,9", "Watch5,11": return appleWatchSE_40mm - case "Watch5,10", "Watch5,12": return appleWatchSE_44mm - case "i386", "x86_64", "arm64": return simulator(mapToDevice(identifier: ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"] ?? "watchOS")) + case "i386", "x86_64": return simulator(mapToDevice(identifier: ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"] ?? "watchOS")) + default: return unknown(identifier) + } + #elseif os(macOS) + switch identifier { + case "Macmini8,1": return macMini2018 + case "Macmini7,1": return macMiniLate2014 + case "Macmini6,1", "Macmini6,2": return macMiniLate2012 + case "Macmini5,1", "Macmini5,2": return macMiniMid2011 + case "Macmini4,1": return macMiniMid2010 + case "Macmini3,1": return macMini2009 + case "iMac19,1": return iMacRetina5K27Inch2019 + case "iMac19,2": return iMacRetina4K215Inch2019 + case "iMac18,3": return iMacRetina5K27Inch2017 + case "iMac18,2": return iMacRetina4K215Inch2017 + case "iMac18,1": return iMac215Inch2017 + case "iMac17,1": return iMacRetina5K27InchLate2015 + case "iMac16,2": return iMacRetina4K215InchLate2015 + case "iMac16,1": return iMac215InchLate2015 + case "iMac15,1": return iMacRetina5K27InchMid2015 + case "iMac14,4": return iMac215InchMid2014 + case "iMac14,2": return iMac27InchLate2013 + case "iMac14,1": return iMac215InchLate2013 + case "iMac13,1": return iMac215InchLate2012 + case "iMac12,2": return iMac27InchMid2011 + case "iMac12,1": return iMac215InchMid2011 + case "iMac11,3": return iMac27InchMid2010 + case "iMac11,2": return iMac215InchMid2010 + case "MacPro7,1": return macPro2019 + case "MacPro6,1": return macProLate2013 + case "MacPro5,1": return macProMid2012 + case "MacPro4,1": return macProEarly2009 + case "MacBook10,1": return macBookRetina12Inch2017 + case "MacBook9,1": return macBookRetina12InchEarly2016 + case "MacBook8,1": return macBookRetina12InchEarly2015 + case "MacBook7,1": return macBook13InchMid2010 + case "MacBook6,1": return macBook13InchLate2009 + case "MacBookAir8,2": return macBookAirRetina13Inch2019 + case "MacBookAir8,1": return macBookAirRetina13Inch2018 + case "MacBookAir7,3": return macBookAir13Inch2017 + case "MacBookAir7,2": return macBookAir13InchEarly2015 + case "MacBookAir7,1": return macBookAir11InchEarly2015 + case "MacBookAir6,2": return macBookAir13InchEarly2014 + case "MacBookAir6,1": return macBookAir11InchEarly2014 + case "MacBookAir5,2": return macBookAir13InchMid2012 + case "MacBookAir5,1": return macBookAir11InchMid2012 + case "MacBookAir4,2": return macBookAir13InchMid2011 + case "MacBookAir4,1": return macBookAir11InchMid2011 + case "MacBookAir3,2": return macBookAir13InchLate2010 + case "MacBookAir3,1": return macBookAir11InchLate2010 + case "MacBookAir2,1": return macBookAirMid2009 + case "MacBookPro16,1": return macBookPro16Inch2019 + case "MacBookPro15,4": return macBookPro13Inch2019TwoThunderbolt3Ports + case "MacBookPro15,3": return macBookPro15Inch2019 + case "MacBookPro15,2": return macBookPro13Inch2019FourThunderbolt3Ports + case "MacBookPro15,1": return macBookPro15Inch2018 + case "MacBookPro14,3": return macBookPro15Inch2017 + case "MacBookPro14,2": return macBookPro13Inch2017FourThunderbolt3Ports + case "MacBookPro14,1": return macBookPro13Inch2017TwoThunderbolt3Ports + case "MacBookPro13,3": return macBookPro15Inch2016 + case "MacBookPro13,2": return macBookPro13Inch2016FourThunderbolt3Ports + case "MacBookPro13,1": return macBookPro13Inch2016TwoThunderbolt3Ports + case "MacBookPro11,4": return macBookProRetina15InchMid2015 + case "MacBookPro12,1": return macBookProRetina13InchEarly2015 + case "MacBookPro11,2": return macBookProRetina15InchMid2014 + case "MacBookPro11,1": return macBookProRetina13InchMid2014 + case "iMacPro1,1": return iMacPro2017 default: return unknown(identifier) } #endif @@ -523,11 +792,6 @@ public enum Device { case .iPhone11: return 6.1 case .iPhone11Pro: return 5.8 case .iPhone11ProMax: return 6.5 - case .iPhoneSE2: return 4.7 - case .iPhone12: return 6.1 - case .iPhone12Mini: return 5.4 - case .iPhone12Pro: return 6.1 - case .iPhone12ProMax: return 6.7 case .iPad2: return 9.7 case .iPad3: return 9.7 case .iPad4: return 9.7 @@ -537,8 +801,6 @@ public enum Device { case .iPad6: return 9.7 case .iPadAir3: return 10.5 case .iPad7: return 10.2 - case .iPad8: return 10.2 - case .iPadAir4: return 10.9 case .iPadMini: return 7.9 case .iPadMini2: return 7.9 case .iPadMini3: return 7.9 @@ -572,13 +834,11 @@ public enum Device { case .appleWatchSeries4_44mm: return 2.0 case .appleWatchSeries5_40mm: return 1.8 case .appleWatchSeries5_44mm: return 2.0 - case .appleWatchSeries6_40mm: return 1.8 - case .appleWatchSeries6_44mm: return 2.0 - case .appleWatchSE_40mm: return 1.8 - case .appleWatchSE_44mm: return 2.0 case .simulator(let model): return model.diagonal case .unknown: return -1 } + #elseif os(macOS) + return -1 #endif } #endif @@ -611,11 +871,6 @@ public enum Device { case .iPhone11: return (width: 9, height: 19.5) case .iPhone11Pro: return (width: 9, height: 19.5) case .iPhone11ProMax: return (width: 9, height: 19.5) - case .iPhoneSE2: return (width: 9, height: 16) - case .iPhone12: return (width: 9, height: 19.5) - case .iPhone12Mini: return (width: 9, height: 19.5) - case .iPhone12Pro: return (width: 9, height: 19.5) - case .iPhone12ProMax: return (width: 9, height: 19.5) case .iPad2: return (width: 3, height: 4) case .iPad3: return (width: 3, height: 4) case .iPad4: return (width: 3, height: 4) @@ -625,8 +880,6 @@ public enum Device { case .iPad6: return (width: 3, height: 4) case .iPadAir3: return (width: 3, height: 4) case .iPad7: return (width: 3, height: 4) - case .iPad8: return (width: 3, height: 4) - case .iPadAir4: return (width: 41, height: 59) case .iPadMini: return (width: 3, height: 4) case .iPadMini2: return (width: 3, height: 4) case .iPadMini3: return (width: 3, height: 4) @@ -660,15 +913,13 @@ public enum Device { case .appleWatchSeries4_44mm: return (width: 4, height: 5) case .appleWatchSeries5_40mm: return (width: 4, height: 5) case .appleWatchSeries5_44mm: return (width: 4, height: 5) - case .appleWatchSeries6_40mm: return (width: 4, height: 5) - case .appleWatchSeries6_44mm: return (width: 4, height: 5) - case .appleWatchSE_40mm: return (width: 4, height: 5) - case .appleWatchSE_44mm: return (width: 4, height: 5) case .simulator(let model): return model.screenRatio case .unknown: return (width: -1, height: -1) } #elseif os(tvOS) return (width: -1, height: -1) + #elseif os(macOS) + return (width: -1, height: -1) #endif } @@ -680,7 +931,7 @@ public enum Device { /// All iPhones public static var allPhones: [Device] { - return [.iPhone4, .iPhone4s, .iPhone5, .iPhone5c, .iPhone5s, .iPhone6, .iPhone6Plus, .iPhone6s, .iPhone6sPlus, .iPhone7, .iPhone7Plus, .iPhoneSE, .iPhone8, .iPhone8Plus, .iPhoneX, .iPhoneXS, .iPhoneXSMax, .iPhoneXR, .iPhone11, .iPhone11Pro, .iPhone11ProMax, .iPhoneSE2, .iPhone12, .iPhone12Mini, .iPhone12Pro, .iPhone12ProMax] + return [.iPhone4, .iPhone4s, .iPhone5, .iPhone5c, .iPhone5s, .iPhone6, .iPhone6Plus, .iPhone6s, .iPhone6sPlus, .iPhone7, .iPhone7Plus, .iPhoneSE, .iPhone8, .iPhone8Plus, .iPhoneX, .iPhoneXS, .iPhoneXSMax, .iPhoneXR, .iPhone11, .iPhone11Pro, .iPhone11ProMax] } /// All iPads @@ -689,14 +940,13 @@ public enum Device { } /// All X-Series Devices - @available(*, deprecated, renamed: "allDevicesWithSensorHousing") public static var allXSeriesDevices: [Device] { - return [.iPhoneX, .iPhoneXS, .iPhoneXSMax, .iPhoneXR, .iPhone11, .iPhone11Pro, .iPhone11ProMax, .iPhone12, .iPhone12Mini, .iPhone12Pro, .iPhone12ProMax] + return [.iPhoneX, .iPhoneXS, .iPhoneXSMax, .iPhoneXR, .iPhone11, .iPhone11Pro, .iPhone11ProMax] } - /// All Plus and Max-Sized Devices + /// All Plus-Sized Devices public static var allPlusSizedDevices: [Device] { - return [.iPhone6Plus, .iPhone6sPlus, .iPhone7Plus, .iPhone8Plus, .iPhoneXSMax, .iPhone11ProMax, .iPhone12ProMax] + return [.iPhone6Plus, .iPhone6sPlus, .iPhone7Plus, .iPhone8Plus, .iPhoneXSMax, .iPhone11ProMax] } /// All Pro Devices @@ -729,13 +979,12 @@ public enum Device { return allMiniDevices.map(Device.simulator) } - /// All simulator X series Devices - @available(*, deprecated, renamed: "allSimulatorDevicesWithSensorHousing") + /// All simulator Plus-Sized Devices public static var allSimulatorXSeriesDevices: [Device] { - return allDevicesWithSensorHousing.map(Device.simulator) + return allXSeriesDevices.map(Device.simulator) } - /// All simulator Plus and Max-Sized Devices + /// All simulator Plus-Sized Devices public static var allSimulatorPlusSizedDevices: [Device] { return allPlusSizedDevices.map(Device.simulator) } @@ -788,11 +1037,12 @@ public enum Device { /// All Touch ID Capable Devices public static var allTouchIDCapableDevices: [Device] { - return [.iPhone5s, .iPhone6, .iPhone6Plus, .iPhone6s, .iPhone6sPlus, .iPhone7, .iPhone7Plus, .iPhoneSE, .iPhone8, .iPhone8Plus, .iPhoneSE2, .iPadAir2, .iPad5, .iPad6, .iPadAir3, .iPad7, .iPad8, .iPadAir4, .iPadMini3, .iPadMini4, .iPadMini5, .iPadPro9Inch, .iPadPro12Inch, .iPadPro12Inch2, .iPadPro10Inch] + return [.iPhone5s, .iPhone6, .iPhone6Plus, .iPhone6s, .iPhone6sPlus, .iPhone7, .iPhone7Plus, .iPhoneSE, .iPhone8, .iPhone8Plus, .iPadAir2, .iPad5, .iPad6, .iPadAir3, .iPad7, .iPadMini3, .iPadMini4, .iPadMini5, .iPadPro9Inch, .iPadPro12Inch, .iPadPro12Inch2, .iPadPro10Inch] } /// All Face ID Capable Devices public static var allFaceIDCapableDevices: [Device] { + return [.iPhoneX, .iPhoneXS, .iPhoneXSMax, .iPhoneXR, .iPhone11, .iPhone11Pro, .iPhone11ProMax, .iPhone12, .iPhone12Mini, .iPhone12Pro, .iPhone12ProMax, .iPadPro11Inch, .iPadPro12Inch3, .iPadPro11Inch2, .iPadPro12Inch4, .iPadPro11Inch3, .iPadPro12Inch5] } @@ -803,12 +1053,12 @@ public enum Device { /// Returns whether or not the device has Touch ID public var isTouchIDCapable: Bool { - return isOneOf(Device.allTouchIDCapableDevices) || isOneOf(Device.allTouchIDCapableDevices.map(Device.simulator)) + return isOneOf(Device.allTouchIDCapableDevices) } /// Returns whether or not the device has Face ID public var isFaceIDCapable: Bool { - return isOneOf(Device.allFaceIDCapableDevices) || isOneOf(Device.allFaceIDCapableDevices.map(Device.simulator)) + return isOneOf(Device.allFaceIDCapableDevices) } /// Returns whether or not the device has any biometric sensor (i.e. Touch ID or Face ID) @@ -818,45 +1068,41 @@ public enum Device { /// All devices that feature a sensor housing in the screen public static var allDevicesWithSensorHousing: [Device] { - return [.iPhoneX, .iPhoneXS, .iPhoneXSMax, .iPhoneXR, .iPhone11, .iPhone11Pro, .iPhone11ProMax, .iPhone12, .iPhone12Mini, .iPhone12Pro, .iPhone12ProMax] - } - - /// All simulator devices that feature a sensor housing in the screen - public static var allSimulatorDevicesWithSensorHousing: [Device] { - return allDevicesWithSensorHousing.map(Device.simulator) + return [.iPhoneX, .iPhoneXS, .iPhoneXSMax, .iPhoneXR, .iPhone11, .iPhone11Pro, .iPhone11ProMax] } /// Returns whether or not the device has a sensor housing public var hasSensorHousing: Bool { - return isOneOf(Device.allDevicesWithSensorHousing) || isOneOf(Device.allDevicesWithSensorHousing.map(Device.simulator)) + return isOneOf(Device.allDevicesWithSensorHousing) } /// All devices that feature a screen with rounded corners. public static var allDevicesWithRoundedDisplayCorners: [Device] { + return [.iPhoneX, .iPhoneXS, .iPhoneXSMax, .iPhoneXR, .iPhone11, .iPhone11Pro, .iPhone11ProMax, .iPhone12, .iPhone12Mini, .iPhone12Pro, .iPhone12ProMax, .iPadAir4, .iPadPro11Inch, .iPadPro12Inch3, .iPadPro11Inch2, .iPadPro12Inch4, .iPadPro11Inch3, .iPadPro12Inch5] } /// Returns whether or not the device has a screen with rounded corners. public var hasRoundedDisplayCorners: Bool { - return isOneOf(Device.allDevicesWithRoundedDisplayCorners) || isOneOf(Device.allDevicesWithRoundedDisplayCorners.map(Device.simulator)) + return isOneOf(Device.allDevicesWithRoundedDisplayCorners) } /// All devices that have 3D Touch support. public static var allDevicesWith3dTouchSupport: [Device] { - return [.iPhone6s, .iPhone6sPlus, .iPhone7, .iPhone7Plus, .iPhone8, .iPhone8Plus, .iPhoneX, .iPhoneXS, .iPhoneXSMax] + return [.iPhone6s, .iPhone6sPlus, .iPhone7, .iPhone7Plus, .iPhoneSE, .iPhone8, .iPhone8Plus, .iPhoneX, .iPhoneXS, .iPhoneXSMax] } /// Returns whether or not the device has 3D Touch support. public var has3dTouchSupport: Bool { - return isOneOf(Device.allDevicesWith3dTouchSupport) || isOneOf(Device.allDevicesWith3dTouchSupport.map(Device.simulator)) + return isOneOf(Device.allDevicesWith3dTouchSupport) } /// All devices that support wireless charging. public static var allDevicesWithWirelessChargingSupport: [Device] { - return [.iPhone8, .iPhone8Plus, .iPhoneX, .iPhoneXS, .iPhoneXSMax, .iPhoneXR, .iPhone11, .iPhone11Pro, .iPhone11ProMax, .iPhoneSE2, .iPhone12, .iPhone12Mini, .iPhone12Pro, .iPhone12ProMax] + return [.iPhone8, .iPhone8Plus, .iPhoneX, .iPhoneXS, .iPhoneXSMax, .iPhoneXR, .iPhone11, .iPhone11Pro, .iPhone11ProMax] } - /// Returns whether or not the device supports wireless charging. + /// Returns whether or not the device supports wireless charging public var supportsWirelessCharging: Bool { return isOneOf(Device.allDevicesWithWirelessChargingSupport) || isOneOf(Device.allDevicesWithWirelessChargingSupport.map(Device.simulator)) } @@ -883,7 +1129,7 @@ public enum Device { #elseif os(watchOS) /// All Watches public static var allWatches: [Device] { - return [.appleWatchSeries0_38mm, .appleWatchSeries0_42mm, .appleWatchSeries1_38mm, .appleWatchSeries1_42mm, .appleWatchSeries2_38mm, .appleWatchSeries2_42mm, .appleWatchSeries3_38mm, .appleWatchSeries3_42mm, .appleWatchSeries4_40mm, .appleWatchSeries4_44mm, .appleWatchSeries5_40mm, .appleWatchSeries5_44mm, .appleWatchSeries6_40mm, .appleWatchSeries6_44mm, .appleWatchSE_40mm, .appleWatchSE_44mm] + return [.appleWatchSeries0_38mm, .appleWatchSeries0_42mm, .appleWatchSeries1_38mm, .appleWatchSeries1_42mm, .appleWatchSeries2_38mm, .appleWatchSeries2_42mm, .appleWatchSeries3_38mm, .appleWatchSeries3_42mm, .appleWatchSeries4_40mm, .appleWatchSeries4_44mm, .appleWatchSeries5_40mm, .appleWatchSeries5_44mm] } /// All simulator Watches @@ -898,8 +1144,69 @@ public enum Device { /// Returns whether or not the device has Force Touch support. public var hasForceTouchSupport: Bool { - return isOneOf(Device.allWatchesWithForceTouchSupport) || isOneOf(Device.allWatchesWithForceTouchSupport.map(Device.simulator)) + return isOneOf(Device.allWatchesWithForceTouchSupport) } + #elseif os(macOS) + /// All Macs + public static var allMacs: [Device] { + return [.macMini2018, .macMiniLate2014, .macMiniLate2012, .macMiniMid2011, .macMiniMid2010, .macMini2009, .iMacRetina5K27Inch2019, .iMacRetina4K215Inch2019, .iMacRetina5K27Inch2017, .iMacRetina4K215Inch2017, .iMac215Inch2017, .iMacRetina5K27InchLate2015, .iMacRetina4K215InchLate2015, .iMac215InchLate2015, .iMacRetina5K27InchMid2015, .iMac215InchMid2014, .iMac27InchLate2013, .iMac215InchLate2013, .iMac215InchLate2012, .iMac27InchMid2011, .iMac215InchMid2011, .iMac27InchMid2010, .iMac215InchMid2010, .macPro2019, .macProLate2013, .macProMid2012, .macProEarly2009, .macBookRetina12Inch2017, .macBookRetina12InchEarly2016, .macBookRetina12InchEarly2015, .macBook13InchMid2010, .macBook13InchLate2009, .macBookAirRetina13Inch2019, .macBookAirRetina13Inch2018, .macBookAir13Inch2017, .macBookAir13InchEarly2015, .macBookAir11InchEarly2015, .macBookAir13InchEarly2014, .macBookAir11InchEarly2014, .macBookAir13InchMid2012, .macBookAir11InchMid2012, .macBookAir13InchMid2011, .macBookAir11InchMid2011, .macBookAir13InchLate2010, .macBookAir11InchLate2010, .macBookAirMid2009, .macBookPro16Inch2019, .macBookPro13Inch2019TwoThunderbolt3Ports, .macBookPro15Inch2019, .macBookPro13Inch2019FourThunderbolt3Ports, .macBookPro15Inch2018, .macBookPro15Inch2017, .macBookPro13Inch2017FourThunderbolt3Ports, .macBookPro13Inch2017TwoThunderbolt3Ports, .macBookPro15Inch2016, .macBookPro13Inch2016FourThunderbolt3Ports, .macBookPro13Inch2016TwoThunderbolt3Ports, .macBookProRetina15InchMid2015, .macBookProRetina13InchEarly2015, .macBookProRetina15InchMid2014, .macBookProRetina13InchMid2014, .iMacPro2017] + } + + public static var allMacMinis: [Device] { + return [.macMini2018, .macMiniLate2014, .macMiniLate2012, .macMiniMid2011, .macMiniMid2010, .macMini2009] + } + + public static var allMacBookAirs: [Device] { + return [.macBookAirRetina13Inch2019, .macBookAirRetina13Inch2018, .macBookAir13Inch2017, .macBookAir13InchEarly2015, .macBookAir11InchEarly2015, .macBookAir13InchEarly2014, .macBookAir11InchEarly2014, .macBookAir13InchMid2012, .macBookAir11InchMid2012, .macBookAir13InchMid2011, .macBookAir11InchMid2011, .macBookAir13InchLate2010, .macBookAir11InchLate2010, .macBookAirMid2009] + } + + public static var allMacBooks: [Device] { + return [.macBookRetina12Inch2017, .macBookRetina12InchEarly2016, .macBookRetina12InchEarly2015, .macBook13InchMid2010, .macBook13InchLate2009] + } + + public static var allMacBookPros: [Device] { + return [.macBookPro16Inch2019, .macBookPro13Inch2019TwoThunderbolt3Ports, .macBookPro15Inch2019, .macBookPro13Inch2019FourThunderbolt3Ports, .macBookPro15Inch2018, .macBookPro15Inch2017, .macBookPro13Inch2017FourThunderbolt3Ports, .macBookPro13Inch2017TwoThunderbolt3Ports, .macBookPro15Inch2016, .macBookPro13Inch2016FourThunderbolt3Ports, .macBookPro13Inch2016TwoThunderbolt3Ports, .macBookProRetina15InchMid2015, .macBookProRetina13InchEarly2015, .macBookProRetina15InchMid2014, .macBookProRetina13InchMid2014] + } + + public static var allIMacs: [Device] { + return [.iMacRetina5K27Inch2019, .iMacRetina4K215Inch2019, .iMacRetina5K27Inch2017, .iMacRetina4K215Inch2017, .iMac215Inch2017, .iMacRetina5K27InchLate2015, .iMacRetina4K215InchLate2015, .iMac215InchLate2015, .iMacRetina5K27InchMid2015, .iMac215InchMid2014, .iMac27InchLate2013, .iMac215InchLate2013, .iMac215InchLate2012, .iMac27InchMid2011, .iMac215InchMid2011, .iMac27InchMid2010, .iMac215InchMid2010] + } + + public static var allIMacPros: [Device] { + return [.iMacPro2017] + } + + public static var allMacPros: [Device] { + return [.macPro2019, .macProLate2013, .macProMid2012, .macProEarly2009] + } + + public var isMacMini: Bool { + return isOneOf(Device.allMacMinis) + } + + public var isMacBookAir: Bool { + return isOneOf(Device.allMacBookAirs) + } + + public var isMacBook: Bool { + return isOneOf(Device.allMacBooks) + } + + public var isMacBookPro: Bool { + return isOneOf(Device.allMacBookPros) + } + + public var isIMac: Bool { + return isOneOf(Device.allIMacs) + } + + public var isIMacPro: Bool { + return isOneOf(Device.allIMacPros) + } + + public var isMacPro: Bool { + return isOneOf(Device.allMacPros) + } #endif /// All real devices (i.e. all devices except for all simulators) @@ -910,6 +1217,8 @@ public enum Device { return allTVs #elseif os(watchOS) return allWatches + #elseif os(macOS) + return allMacs #endif } @@ -951,8 +1260,6 @@ public enum Device { return devices.contains(self) } - // MARK: Current Device - /// Whether or not the current device is the current device. private var isCurrent: Bool { return self == Device.current @@ -963,6 +1270,8 @@ public enum Device { guard isCurrent else { return nil } #if os(watchOS) return WKInterfaceDevice.current().name + #elseif os(macOS) + return description #else return UIDevice.current.name #endif @@ -973,6 +1282,8 @@ public enum Device { guard isCurrent else { return nil } #if os(watchOS) return WKInterfaceDevice.current().systemName + #elseif os(macOS) + return "macOS" #else return UIDevice.current.systemName #endif @@ -983,6 +1294,8 @@ public enum Device { guard isCurrent else { return nil } #if os(watchOS) return WKInterfaceDevice.current().systemVersion + #elseif os(macOS) + return ProcessInfo.processInfo.operatingSystemVersionString #else return UIDevice.current.systemVersion #endif @@ -993,6 +1306,10 @@ public enum Device { guard isCurrent else { return nil } #if os(watchOS) return WKInterfaceDevice.current().model + #elseif os(macOS) + var set = CharacterSet.decimalDigits + set.insert(",") + return Device.identifier.components(separatedBy: set).joined() #else return UIDevice.current.model #endif @@ -1003,6 +1320,8 @@ public enum Device { guard isCurrent else { return nil } #if os(watchOS) return WKInterfaceDevice.current().localizedModel + #elseif os(macOS) + return model #else return UIDevice.current.localizedModel #endif @@ -1036,11 +1355,6 @@ public enum Device { case .iPhone11: return 326 case .iPhone11Pro: return 458 case .iPhone11ProMax: return 458 - case .iPhoneSE2: return 326 - case .iPhone12: return 460 - case .iPhone12Mini: return 476 - case .iPhone12Pro: return 460 - case .iPhone12ProMax: return 458 case .iPad2: return 132 case .iPad3: return 264 case .iPad4: return 264 @@ -1050,8 +1364,6 @@ public enum Device { case .iPad6: return 264 case .iPadAir3: return 264 case .iPad7: return 264 - case .iPad8: return 264 - case .iPadAir4: return 264 case .iPadMini: return 163 case .iPadMini2: return 326 case .iPadMini3: return 326 @@ -1085,15 +1397,13 @@ public enum Device { case .appleWatchSeries4_44mm: return 326 case .appleWatchSeries5_40mm: return 326 case .appleWatchSeries5_44mm: return 326 - case .appleWatchSeries6_40mm: return 326 - case .appleWatchSeries6_44mm: return 326 - case .appleWatchSE_40mm: return 326 - case .appleWatchSE_44mm: return 326 case .simulator(let model): return model.ppi case .unknown: return nil } #elseif os(tvOS) return nil + #elseif os(macOS) + return nil #endif } @@ -1120,7 +1430,7 @@ public enum Device { } } -// MARK: CustomStringConvertible +// MARK: - CustomStringConvertible extension Device: CustomStringConvertible { /// A textual representation of the device. @@ -1151,11 +1461,6 @@ extension Device: CustomStringConvertible { case .iPhone11: return "iPhone 11" case .iPhone11Pro: return "iPhone 11 Pro" case .iPhone11ProMax: return "iPhone 11 Pro Max" - case .iPhoneSE2: return "iPhone SE (2nd generation)" - case .iPhone12: return "iPhone 12" - case .iPhone12Mini: return "iPhone 12 mini" - case .iPhone12Pro: return "iPhone 12 Pro" - case .iPhone12ProMax: return "iPhone 12 Pro Max" case .iPad2: return "iPad 2" case .iPad3: return "iPad (3rd generation)" case .iPad4: return "iPad (4th generation)" @@ -1165,8 +1470,6 @@ extension Device: CustomStringConvertible { case .iPad6: return "iPad (6th generation)" case .iPadAir3: return "iPad Air (3rd generation)" case .iPad7: return "iPad (7th generation)" - case .iPad8: return "iPad (8th generation)" - case .iPadAir4: return "iPad Air (4th generation)" case .iPadMini: return "iPad Mini" case .iPadMini2: return "iPad Mini 2" case .iPadMini3: return "iPad Mini 3" @@ -1183,7 +1486,7 @@ extension Device: CustomStringConvertible { case .iPadPro11Inch3: return "iPad Pro (11-inch) (3rd generation)" case .iPadPro12Inch5: return "iPad Pro (12.9-inch) (5th generation)" case .homePod: return "HomePod" - case .simulator(let model): return "Simulator (\(model.description))" + case .simulator(let model): return "Simulator (\(model))" case .unknown(let identifier): return identifier } #elseif os(watchOS) @@ -1200,11 +1503,7 @@ extension Device: CustomStringConvertible { case .appleWatchSeries4_44mm: return "Apple Watch Series 4 44mm" case .appleWatchSeries5_40mm: return "Apple Watch Series 5 40mm" case .appleWatchSeries5_44mm: return "Apple Watch Series 5 44mm" - case .appleWatchSeries6_40mm: return "Apple Watch Series 6 40mm" - case .appleWatchSeries6_44mm: return "Apple Watch Series 6 44mm" - case .appleWatchSE_40mm: return "Apple Watch SE 40mm" - case .appleWatchSE_44mm: return "Apple Watch SE 44mm" - case .simulator(let model): return "Simulator (\(model.description))" + case .simulator(let model): return "Simulator (\(model))" case .unknown(let identifier): return identifier } #elseif os(tvOS) @@ -1284,7 +1583,7 @@ extension Device: CustomStringConvertible { case .simulator(let model): return "Simulator (\(model.safeDescription))" case .unknown(let identifier): return identifier } - #elseif os(watchOS) + #elseif os(macOS) switch self { case .appleWatchSeries0_38mm: return "Apple Watch (1st generation) 38mm" case .appleWatchSeries0_42mm: return "Apple Watch (1st generation) 42mm" @@ -1315,10 +1614,9 @@ extension Device: CustomStringConvertible { } #endif } - } -// MARK: Equatable +// MARK: - Equatable extension Device: Equatable { /// Compares two devices @@ -1333,7 +1631,7 @@ extension Device: Equatable { } -// MARK: Battery +// MARK: - Battery #if os(iOS) || os(watchOS) @available(iOS 8.0, watchOS 4.0, *) extension Device { @@ -1390,7 +1688,11 @@ extension Device { /// The user enabled Low Power mode public var lowPowerMode: Bool { - return ProcessInfo.processInfo.isLowPowerModeEnabled + if #available(iOS 9.0, *) { + return ProcessInfo.processInfo.isLowPowerModeEnabled + } else { + return false + } } /// Provides a textual representation of the battery state. @@ -1429,7 +1731,7 @@ extension Device { } #endif -// MARK: Device.Batterystate: Comparable +// MARK: - Device.Batterystate: Comparable #if os(iOS) || os(watchOS) @available(iOS 8.0, watchOS 4.0, *) extension Device.BatteryState: Comparable { @@ -1465,7 +1767,7 @@ extension Device.BatteryState: Comparable { #if os(iOS) extension Device { - // MARK: Orientation + // MARK: - Orientation /** This enum describes the state of the orientation. - Landscape: The device is in Landscape Orientation @@ -1487,7 +1789,7 @@ extension Device { #endif #if os(iOS) -// MARK: DiskSpace +// MARK: - DiskSpace extension Device { /// Return the root url @@ -1543,7 +1845,7 @@ extension Device { #endif #if os(iOS) -// MARK: Apple Pencil +// MARK: - Apple Pencil extension Device { /** @@ -1574,20 +1876,13 @@ extension Device { case .iPad6: return .firstGeneration case .iPadAir3: return .firstGeneration case .iPad7: return .firstGeneration - case .iPad8: return .firstGeneration case .iPadMini5: return .firstGeneration case .iPadPro9Inch: return .firstGeneration case .iPadPro12Inch: return .firstGeneration case .iPadPro12Inch2: return .firstGeneration case .iPadPro10Inch: return .firstGeneration - case .iPadAir4: return .secondGeneration case .iPadPro11Inch: return .secondGeneration case .iPadPro12Inch3: return .secondGeneration - case .iPadPro11Inch2: return .secondGeneration - case .iPadPro12Inch4: return .secondGeneration - case .iPadPro11Inch3: return .secondGeneration - case .iPadPro12Inch5: return .secondGeneration - case .simulator(let model): return model.applePencilSupport default: return [] } } @@ -1595,20 +1890,17 @@ extension Device { #endif #if os(iOS) -// MARK: Cameras +// MARK: - Cameras extension Device { - public enum CameraType { - @available(*, deprecated, renamed: "wide") + public enum CameraTypes { case normal - - case wide case telephoto case ultraWide } /// Returns an array of the types of cameras the device has - public var cameras: [CameraType] { + public var cameras: [CameraTypes] { switch self { case .iPodTouch5: return [.wide] case .iPodTouch6: return [.wide] @@ -1675,7 +1967,6 @@ extension Device { } /// All devices that feature a normal camera - @available(*, deprecated, renamed: "allDevicesWithWideCamera") public static var allDevicesWithNormalCamera: [Device] { return Device.allDevicesWithWideCamera } @@ -1687,7 +1978,7 @@ extension Device { /// All devices that feature a telephoto camera public static var allDevicesWithTelephotoCamera: [Device] { - return [.iPhone7Plus, .iPhone8Plus, .iPhoneX, .iPhoneXS, .iPhoneXSMax, .iPhone11Pro, .iPhone11ProMax, .iPhone12Pro, .iPhone12ProMax] + return [.iPhone7Plus, .iPhone8Plus, .iPhoneX, .iPhoneXS, .iPhoneXSMax, .iPhone11Pro, .iPhone11ProMax] } /// All devices that feature an ultra wide camera @@ -1701,14 +1992,8 @@ extension Device { } /// Returns whether or not the current device has a normal camera - @available(*, deprecated, renamed: "hasWideCamera") public var hasNormalCamera: Bool { - return self.hasWideCamera - } - - /// Returns whether or not the current device has a wide camera - public var hasWideCamera: Bool { - return self.cameras.contains(.wide) + return self.cameras.contains(.normal) } /// Returns whether or not the current device has a telephoto camera @@ -1723,3 +2008,25 @@ extension Device { } #endif + +#if os(macOS) +private func sysctlData(for keys: [Int32]) throws -> [Int8] { + return try keys.withUnsafeBufferPointer { keysPointer -> [Int8] in + // Get the data size + var requiredSize = 0 + var result = Darwin.sysctl(UnsafeMutablePointer(mutating: keysPointer.baseAddress), UInt32(keys.count), nil, &requiredSize, nil, 0) + if result != 0, let code = POSIXErrorCode(rawValue: errno) { + throw POSIXError(code) + } + // get info + let data = [Int8](repeating: 0, count: requiredSize) + result = data.withUnsafeBufferPointer { dataBuffer -> Int32 in + Darwin.sysctl(UnsafeMutablePointer(mutating: keysPointer.baseAddress), UInt32(keys.count), UnsafeMutableRawPointer(mutating: dataBuffer.baseAddress), &requiredSize, nil, 0) + } + if result != 0, let code = POSIXErrorCode(rawValue: errno) { + throw POSIXError(code) + } + return data + } +} +#endif diff --git a/Source/Device.swift.gyb b/Source/Device.swift.gyb index 969fe966..642e5b37 100644 --- a/Source/Device.swift.gyb +++ b/Source/Device.swift.gyb @@ -11,7 +11,7 @@ %{ class Device: - def __init__(self, caseName, comment, imageURL, identifiers, diagonal, screenRatio, description, safeDescription, ppi, isPlusFormFactor, isPadMiniFormFactor, isPro, isXSeries, hasTouchID, hasFaceID, hasSensorHousing, supportsWirelessCharging, hasRoundedDisplayCorners, applePencilSupport, hasForce3dTouchSupport, cameras, hasLidarSensor): + def __init__(self, caseName, comment, imageURL, identifiers, diagonal, screenRatio, description, ppi, isPlusFormFactor, isPadMiniFormFactor, isPro, isXSeries, hasTouchID, hasFaceID, hasSensorHousing, supportsWirelessCharging, hasRoundedDisplayCorners, applePencilSupport, hasForce3dTouchSupport, cameras): self.caseName = caseName self.comment = comment self.imageURL = imageURL @@ -19,7 +19,6 @@ class Device: self.diagonal = diagonal self.screenRatio = screenRatio self.description = description - self.safeDescription = safeDescription self.ppi = ppi self.isPlusFormFactor = isPlusFormFactor self.isPadMiniFormFactor = isPadMiniFormFactor @@ -33,7 +32,6 @@ class Device: self.applePencilSupport = applePencilSupport self.hasForce3dTouchSupport = hasForce3dTouchSupport self.cameras = cameras - self.hasLidarSensor = hasLidarSensor # iOS iPods = [ @@ -101,7 +99,7 @@ iPads = [ ] homePods = [ - Device("homePod", "Device is a [HomePod](https://support.apple.com/kb/SP773)", "https://support.apple.com/library/APPLE/APPLECARE_ALLGEOS/SP773/homepod_space_gray_large_2x.jpg", ["AudioAccessory1,1"], -1, (4, 5), "HomePod", "HomePod", -1, False, False, False, False, False, False, False, False, False, 0, False, 0, False), + Device("homePod", "Device is a [HomePod](https://support.apple.com/kb/SP773)", "https://support.apple.com/library/APPLE/APPLECARE_ALLGEOS/SP773/homepod_space_gray_large_2x.jpg", ["AudioAccessory1,1"], -1, (4, 5), "HomePod", -1, False, False, False, False, False, False, False, False, False, 0, False, 0), ] # tvOS tvs = [ @@ -116,110 +114,410 @@ watches = [ "appleWatchSeries0_38mm", "Device is an [Apple Watch (1st generation)](https://support.apple.com/kb/SP735)", "https://km.support.apple.com/resources/sites/APPLE/content/live/IMAGES/0/IM784/en_US/apple_watch_sport-240.png", - ["Watch1,1"], 1.5, (4,5), "Apple Watch (1st generation) 38mm", "Apple Watch (1st generation) 38mm", 290, False, False, False, False, False, False, False, True, False, 0, True, 0, False), + ["Watch1,1"], 1.5, (4,5), "Apple Watch (1st generation) 38mm", 290, False, False, False, False, False, False, False, True, False, 0, True, 0), Device( "appleWatchSeries0_42mm", "Device is an [Apple Watch (1st generation)](https://support.apple.com/kb/SP735)", "https://km.support.apple.com/resources/sites/APPLE/content/live/IMAGES/0/IM784/en_US/apple_watch_sport-240.png", - ["Watch1,2"], 1.6, (4,5), "Apple Watch (1st generation) 42mm", "Apple Watch (1st generation) 42mm", 303, False, False, False, False, False, False, False, True, False, 0, True, 0, False), + ["Watch1,2"], 1.6, (4,5), "Apple Watch (1st generation) 42mm", 303, False, False, False, False, False, False, False, True, False, 0, True, 0), Device( "appleWatchSeries1_38mm", "Device is an [Apple Watch Series 1](https://support.apple.com/kb/SP745)", "https://km.support.apple.com/resources/sites/APPLE/content/live/IMAGES/0/IM848/en_US/applewatch-series2-aluminum-temp-240.png", - ["Watch2,6"], 1.5, (4,5), "Apple Watch Series 1 38mm", "Apple Watch Series 1 38mm", 290, False, False, False, False, False, False, False, True, False, 0, True, 0, False), + ["Watch2,6"], 1.5, (4,5), "Apple Watch Series 1 38mm", 290, False, False, False, False, False, False, False, True, False, 0, True, 0), Device( "appleWatchSeries1_42mm", "Device is an [Apple Watch Series 1](https://support.apple.com/kb/SP745)", "https://km.support.apple.com/resources/sites/APPLE/content/live/IMAGES/0/IM848/en_US/applewatch-series2-aluminum-temp-240.png", - ["Watch2,7"], 1.6, (4,5), "Apple Watch Series 1 42mm", "Apple Watch Series 1 42mm", 303, False, False, False, False, False, False, False, True, False, 0, True, 0, False), + ["Watch2,7"], 1.6, (4,5), "Apple Watch Series 1 42mm", 303, False, False, False, False, False, False, False, True, False, 0, True, 0), Device( "appleWatchSeries2_38mm", "Device is an [Apple Watch Series 2](https://support.apple.com/kb/SP746)", "https://km.support.apple.com/resources/sites/APPLE/content/live/IMAGES/0/IM852/en_US/applewatch-series2-hermes-240.png", - ["Watch2,3"], 1.5, (4,5), "Apple Watch Series 2 38mm", "Apple Watch Series 2 38mm", 290, False, False, False, False, False, False, False, True, False, 0, True, 0, False), + ["Watch2,3"], 1.5, (4,5), "Apple Watch Series 2 38mm", 290, False, False, False, False, False, False, False, True, False, 0, True, 0), Device( "appleWatchSeries2_42mm", "Device is an [Apple Watch Series 2](https://support.apple.com/kb/SP746)", "https://km.support.apple.com/resources/sites/APPLE/content/live/IMAGES/0/IM852/en_US/applewatch-series2-hermes-240.png", - ["Watch2,4"], 1.6, (4,5), "Apple Watch Series 2 42mm", "Apple Watch Series 2 42mm", 303, False, False, False, False, False, False, False, True, False, 0, True, 0, False), + ["Watch2,4"], 1.6, (4,5), "Apple Watch Series 2 42mm", 303, False, False, False, False, False, False, False, True, False, 0, True, 0), Device( "appleWatchSeries3_38mm", "Device is an [Apple Watch Series 3](https://support.apple.com/kb/SP766)", "https://km.support.apple.com/resources/sites/APPLE/content/live/IMAGES/0/IM893/en_US/apple-watch-s3-nikeplus-240.png", - ["Watch3,1", "Watch3,3"], 1.5, (4,5), "Apple Watch Series 3 38mm", "Apple Watch Series 3 38mm", 290, False, False, False, False, False, False, False, True, False, 0, True, 0, False), + ["Watch3,1", "Watch3,3"], 1.5, (4,5), "Apple Watch Series 3 38mm", 290, False, False, False, False, False, False, False, True, False, 0, True, 0), Device( "appleWatchSeries3_42mm", "Device is an [Apple Watch Series 3](https://support.apple.com/kb/SP766)", "https://km.support.apple.com/resources/sites/APPLE/content/live/IMAGES/0/IM893/en_US/apple-watch-s3-nikeplus-240.png", - ["Watch3,2", "Watch3,4"], 1.6, (4,5), "Apple Watch Series 3 42mm", "Apple Watch Series 3 42mm", 303, False, False, False, False, False, False, False, True, False, 0, True, 0, False), + ["Watch3,2", "Watch3,4"], 1.6, (4,5), "Apple Watch Series 3 42mm", 303, False, False, False, False, False, False, False, True, False, 0, True, 0), Device( "appleWatchSeries4_40mm", "Device is an [Apple Watch Series 4](https://support.apple.com/kb/SP778)", "https://km.support.apple.com/resources/sites/APPLE/content/live/IMAGES/0/IM911/en_US/aw-series4-nike-240.png", - ["Watch4,1", "Watch4,3"], 1.8, (4,5), "Apple Watch Series 4 40mm", "Apple Watch Series 4 40mm", 326, False, False, False, False, False, False, False, True, False, 0, True, 0, False), + ["Watch4,1", "Watch4,3"], 1.8, (4,5), "Apple Watch Series 4 40mm", 326, False, False, False, False, False, False, False, True, False, 0, True, 0), Device( "appleWatchSeries4_44mm", "Device is an [Apple Watch Series 4](https://support.apple.com/kb/SP778)", "https://km.support.apple.com/resources/sites/APPLE/content/live/IMAGES/0/IM911/en_US/aw-series4-nike-240.png", - ["Watch4,2", "Watch4,4"], 2.0, (4,5), "Apple Watch Series 4 44mm", "Apple Watch Series 4 44mm", 326, False, False, False, False, False, False, False, True, False, 0, True, 0, False), + ["Watch4,2", "Watch4,4"], 2.0, (4,5), "Apple Watch Series 4 44mm", 326, False, False, False, False, False, False, False, True, False, 0, True, 0), Device( "appleWatchSeries5_40mm", "Device is an [Apple Watch Series 5](https://support.apple.com/kb/SP808)", "https://support.apple.com/library/APPLE/APPLECARE_ALLGEOS/SP808/sp808-apple-watch-series-5_2x.png", - ["Watch5,1", "Watch5,3"], 1.8, (4,5), "Apple Watch Series 5 40mm", "Apple Watch Series 5 40mm", 326, False, False, False, False, False, False, False, True, False, 0, True, 0, False), + ["Watch5,1", "Watch5,3"], 1.8, (4,5), "Apple Watch Series 5 40mm", 326, False, False, False, False, False, False, False, True, False, 0, True, 0), Device( "appleWatchSeries5_44mm", "Device is an [Apple Watch Series 5](https://support.apple.com/kb/SP808)", "https://support.apple.com/library/APPLE/APPLECARE_ALLGEOS/SP808/sp808-apple-watch-series-5_2x.png", - ["Watch5,2", "Watch5,4"], 2.0, (4,5), "Apple Watch Series 5 44mm", "Apple Watch Series 5 44mm", 326, False, False, False, False, False, False, False, True, False, 0, True, 0, False), - + ["Watch5,2", "Watch5,4"], 2.0, (4,5), "Apple Watch Series 5 44mm", 326, False, False, False, False, False, False, False, True, False, 0, True, 0) + ] +# macOS +## https://support.apple.com/specs/macmini, https://support.apple.com/en-us/HT201894 +macMinis = [ Device( - "appleWatchSeries6_40mm", - "Device is an [Apple Watch Series 6](https://support.apple.com/kb/SP826)", - "https://support.apple.com/library/APPLE/APPLECARE_ALLGEOS/SP826/sp826-apple-watch-series6-580_2x.png", - ["Watch6,1", "Watch6,3"], 1.8, (4,5), "Apple Watch Series 6 40mm", "Apple Watch Series 6 40mm", 326, False, False, False, False, False, False, False, True, False, 0, False, 0, False), - + "macMini2018", + "Device is a [Mac mini (2018)](https://support.apple.com/kb/SP782)", + "https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macmini/mac-mini-2018-space-gray.jpg", + ["Macmini8,1"], 0, (), "Mac mini (2018)", -1, False, False, False, False, False, False, False, False, False, 0, False, 0), Device( - "appleWatchSeries6_44mm", - "Device is an [Apple Watch Series 6](https://support.apple.com/kb/SP826)", - "https://support.apple.com/library/APPLE/APPLECARE_ALLGEOS/SP826/sp826-apple-watch-series6-580_2x.png", - ["Watch6,2", "Watch6,4"], 2.0, (4,5), "Apple Watch Series 6 44mm", "Apple Watch Series 6 44mm", 326, False, False, False, False, False, False, False, True, False, 0, False, 0, False), - + "macMiniLate2014", + "Device is a [Mac mini (Late 2014)](https://support.apple.com/kb/SP710)", + "https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macmini/mac-mini-2014.jpg", + ["Macmini7,1"], 0, (), "Mac mini (Late 2014)", -1, False, False, False, False, False, False, False, False, False, 0, False, 0), Device( - "appleWatchSE_40mm", - "Device is an [Apple Watch SE](https://support.apple.com/kb/SP827)", - "https://support.apple.com/library/APPLE/APPLECARE_ALLGEOS/SP827/sp827-apple-watch-se-580_2x.png", - ["Watch5,9", "Watch5,11"], 1.8, (4,5), "Apple Watch SE 40mm", "Apple Watch SE 40mm", 326, False, False, False, False, False, False, False, True, False, 0, False, 0, False), - + "macMiniLate2012", + "Device is a [Mac mini (Late 2012)](https://support.apple.com/kb/SP659)", + "https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macmini/mac-mini-2011-2012-2014-device.jpg", + ["Macmini6,1", "Macmini6,2"], 0, (), "Mac mini (Late 2012)", -1, False, False, False, False, False, False, False, False, False, 0, False, 0), Device( "appleWatchSE_44mm", "Device is an [Apple Watch SE](https://support.apple.com/kb/SP827)", "https://support.apple.com/library/APPLE/APPLECARE_ALLGEOS/SP827/sp827-apple-watch-se-580_2x.png", ["Watch5,10", "Watch5,12"], 2.0, (4,5), "Apple Watch SE 44mm", "Apple Watch SE 44mm", 326, False, False, False, False, False, False, False, True, False, 0, False, 0, False), ] +iMacs = [ + Device( + "iMacRetina5K27Inch2019", + "Device is a [iMac (Retina 5K, 27-inch, 2019)](https://support.apple.com/kb/SP790)", + "https://support.apple.com/library/content/dam/edam/applecare/images/en_US/imac/imac-27-2017.jpg", + ["iMac19,1"], 0, (), "iMac (Retina 5K, 27-inch, 2019)", -1, False, False, False, False, False, False, False, False, False, 0, False, 0), + Device( + "iMacRetina4K215Inch2019", + "Device is a [iMac (Retina 4K, 21.5-inch, 2019)](https://support.apple.com/kb/SP789)", + "https://support.apple.com/library/content/dam/edam/applecare/images/en_US/imac/imac-21-5-2017.jpg", + ["iMac19,2"], 0, (), "iMac (Retina 4K, 21.5-inch, 2019)", -1, False, False, False, False, False, False, False, False, False, 0, False, 0), + Device( + "iMacRetina5K27Inch2017", + "Device is a [iMac (Retina 5K, 27-inch, 2017)](https://support.apple.com/kb/SP760)", + "https://support.apple.com/library/content/dam/edam/applecare/images/en_US/imac/imac-27-2017.jpg", + ["iMac18,3"], 0, (), "iMac (Retina 5K, 27-inch, 2017)", -1, False, False, False, False, False, False, False, False, False, 0, False, 0), + Device( + "iMacRetina4K215Inch2017", + "Device is a [iMac (Retina 4K, 21.5-inch, 2017)](https://support.apple.com/kb/SP759)", + "https://support.apple.com/library/content/dam/edam/applecare/images/en_US/imac/imac-21-5-2017.jpg", + ["iMac18,2"], 0, (), "iMac (Retina 4K, 21.5-inch, 2017)", -1, False, False, False, False, False, False, False, False, False, 0, False, 0), + Device( + "iMac215Inch2017", + "Device is a [iMac (21.5-inch, 2017)](https://support.apple.com/kb/SP758)", + "https://support.apple.com/library/content/dam/edam/applecare/images/en_US/imac/imac-21-5-2017.jpg", + ["iMac18,1"], 0, (), "iMac (21.5-inch, 2017)", -1, False, False, False, False, False, False, False, False, False, 0, False, 0), + Device( + "iMacRetina5K27InchLate2015", + "Device is a [iMac (Retina 5K, 27-inch, Late 2015)](https://support.apple.com/kb/SP731)", + "https://support.apple.com/library/content/dam/edam/applecare/images/en_US/imac/imac-27-late-2015.jpg", + ["iMac17,1"], 0, (), "iMac (Retina 5K, 27-inch, Late 2015)", -1, False, False, False, False, False, False, False, False, False, 0, False, 0), + Device( + "iMacRetina4K215InchLate2015", + "Device is a [iMac (Retina 4K, 21.5-inch, Late 2015)](https://support.apple.com/kb/SP732)", + "https://support.apple.com/library/content/dam/edam/applecare/images/en_US/imac/imac-21-5-2015.jpg", + ["iMac16,2"], 0, (), "iMac (Retina 4K, 21.5-inch, Late 2015)", -1, False, False, False, False, False, False, False, False, False, 0, False, 0), + Device( + "iMac215InchLate2015", + "Device is a [iMac (21.5-inch, Late 2015)](https://support.apple.com/kb/SP733)", + "https://support.apple.com/library/content/dam/edam/applecare/images/en_US/imac/imac-21-5-2015.jpg", + ["iMac16,1"], 0, (), "iMac (21.5-inch, Late 2015)", -1, False, False, False, False, False, False, False, False, False, 0, False, 0), + Device( + "iMacRetina5K27InchMid2015", + "Device is a [iMac (Retina 5K, 27-inch, Mid 2015)](https://support.apple.com/kb/SP718) or [iMac (Retina 5K, 27-inch, Late 2014)](https://support.apple.com/kb/SP707)", + "https://support.apple.com/library/content/dam/edam/applecare/images/en_US/imac/imac-27-late-2015.jpg", + ["iMac15,1"], 0, (), "iMac (Retina 5K, 27-inch)", -1, False, False, False, False, False, False, False, False, False, 0, False, 0), + Device( + "iMac215InchMid2014", + "Device is a [iMac (21.5-inch, Mid 2014)](https://support.apple.com/kb/SP701)", + "https://support.apple.com/library/content/dam/edam/applecare/images/en_US/imac/imac-27-2014.jpg", + ["iMac14,4"], 0, (), "iMac (21.5-inch, Mid 2014)", -1, False, False, False, False, False, False, False, False, False, 0, False, 0), + Device( + "iMac27InchLate2013", + "Device is a [iMac (27-inch, Late 2013)](https://support.apple.com/kb/SP688)", + "https://support.apple.com/library/content/dam/edam/applecare/images/en_US/imac/imac-27-2013.jpg", + ["iMac14,2"], 0, (), "iMac (27-inch, Late 2013)", -1, False, False, False, False, False, False, False, False, False, 0, False, 0), + Device( + "iMac215InchLate2013", + "Device is a [iMac (21.5-inch, Late 2013)](https://support.apple.com/kb/SP687)", + "https://support.apple.com/library/content/dam/edam/applecare/images/en_US/imac/imac-27-2013.jpg", + ["iMac14,1"], 0, (), "iMac (21.5-inch, Late 2013)", -1, False, False, False, False, False, False, False, False, False, 0, False, 0), + Device( + "iMac215InchLate2012", + "Device is a [iMac (21.5-inch, Late 2012)](https://support.apple.com/kb/SP665)", + "https://support.apple.com/library/content/dam/edam/applecare/images/en_US/imac/imac-27-2012.jpg", + ["iMac13,1"], 0, (), "iMac (21.5-inch, Late 2012)", -1, False, False, False, False, False, False, False, False, False, 0, False, 0), + Device( + "iMac27InchMid2011", + "Device is a [iMac (27-inch, Mid 2011)](https://support.apple.com/kb/SP689)", + "https://support.apple.com/library/content/dam/edam/applecare/images/en_US/imac/imac-27-2011.jpg", + ["iMac12,2"], 0, (), "iMac (27-inch, Mid 2011)", -1, False, False, False, False, False, False, False, False, False, 0, False, 0), + Device( + "iMac215InchMid2011", + "Device is a [iMac (21.5-inch, Mid 2011)](https://support.apple.com/kb/SP623)", + "https://support.apple.com/library/content/dam/edam/applecare/images/en_US/imac/imac-27-2011.jpg", + ["iMac12,1"], 0, (), "iMac (21.5-inch, Mid 2011)", -1, False, False, False, False, False, False, False, False, False, 0, False, 0), + Device( + "iMac27InchMid2010", + "Device is a [iMac (27-inch, Mid 2010)](https://support.apple.com/kb/SP695)", + "https://support.apple.com/library/content/dam/edam/applecare/images/en_US/imac/imac-27-2010.jpg", + ["iMac11,3"], 0, (), "iMac (27-inch, Mid 2010)", -1, False, False, False, False, False, False, False, False, False, 0, False, 0), + Device( + "iMac215InchMid2010", + "Device is a [iMac (21.5-inch, Mid 2010)](https://support.apple.com/kb/SP588)", + "https://support.apple.com/library/content/dam/edam/applecare/images/en_US/imac/imac-27-2010.jpg", + ["iMac11,2"], 0, (), "iMac (21.5-inch, Mid 2010)", -1, False, False, False, False, False, False, False, False, False, 0, False, 0) +] +## https://support.apple.com/mac/mac-pro, https://support.apple.com/en-us/HT202888 +macPros = [ + Device( + "macPro2019", + "Device is a [Mac Pro (2019)](https://support.apple.com/kb/SP797)", + "https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macpro/id-mac-pro-2019.jpg", + ["MacPro7,1"], 0, (), "Mac Pro (2019)", -1, False, False, False, False, False, False, False, False, False, 0, False, 0), + Device( + "macProLate2013", + "Device is a [Mac Pro (Late 2013)](https://support.apple.com/kb/SP697)", + "https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macpro/id-mac-pro-2013.jpg", + ["MacPro6,1"], 0, (), "Mac Pro (Late 2013)", -1, False, False, False, False, False, False, False, False, False, 0, False, 0), + Device( + "macProMid2012", + "Device is a [Mac Pro (Mid 2012)](https://support.apple.com/kb/SP652)", + "https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macpro/id-mac-pro-2009-2012.jpg", + ["MacPro5,1"], 0, (), "Mac Pro (Mid 2010 to Mid 2012)", -1, False, False, False, False, False, False, False, False, False, 0, False, 0), + Device( + "macProEarly2009", + "Device is a [Mac Pro (Early 2009)](https://support.apple.com/kb/SP506)", + "https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macpro/id-mac-pro-2009-2012.jpg", + ["MacPro4,1"], 0, (), "Mac Pro (Early 2009)", -1, False, False, False, False, False, False, False, False, False, 0, False, 0) +] +## https://support.apple.com/mac/macbook, https://support.apple.com/en-us/HT201608 +macBooks = [ + Device( + "macBookRetina12Inch2017", + "Device is a [MacBook (Retina, 12-inch, 2017)](https://support.apple.com/kb/SP757)", + "https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbook/macbook-2017-device.jpg", + ["MacBook10,1"], 0, (), "MacBook (Retina, 12-inch, 2017)", -1, False, False, False, False, False, False, False, False, False, 0, False, 0), + Device( + "macBookRetina12InchEarly2016", + "Device is a [MacBook (Retina, 12-inch, Early 2016)](https://support.apple.com/kb/SP741)", + "https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbook/macbook-2016-device.jpg", + ["MacBook9,1"], 0, (), "MacBook (Retina, 12-inch, Early 2016)", -1, False, False, False, False, False, False, False, False, False, 0, False, 0), + Device( + "macBookRetina12InchEarly2015", + "Device is a [MacBook (Retina, 12-inch, Early 2015)](https://support.apple.com/kb/SP712)", + "https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbook/macbook-2015-device.jpg", + ["MacBook8,1"], 0, (), "MacBook (Retina, 12-inch, Early 2015)", -1, False, False, False, False, False, False, False, False, False, 0, False, 0), + Device( + "macBook13InchMid2010", + "Device is a [MacBook (13-inch, Mid 2010)](https://support.apple.com/kb/SP584)", + "https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbook/macbook-late-2009-2010-device.jpg", + ["MacBook7,1"], 0, (), "MacBook (13-inch, Mid 2010)", -1, False, False, False, False, False, False, False, False, False, 0, False, 0), + Device( + "macBook13InchLate2009", + "Device is a [MacBook (13-inch, Late 2009)](https://support.apple.com/kb/SP579)", + "https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbook/macbook-late-2009-2010-device.jpg", + ["MacBook6,1"], 0, (), "MacBook (13-inch, Late 2009)", -1, False, False, False, False, False, False, False, False, False, 0, False, 0) +] +## https://support.apple.com/mac/macbook-air, https://support.apple.com/en-us/HT201862 +macBookAirs = [ + Device( + "macBookAirRetina13Inch2019", + "Device is a [MacBook Air (Retina, 13-inch, 2019)](https://support.apple.com/kb/SP798)", + "https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbookair/macbook-air-2018-device.jpg", + ["MacBookAir8,2"], 0, (), "MacBook Air (Retina, 13-inch, 2019)", -1, False, False, False, False, False, False, False, False, False, 0, False, 0), + Device( + "macBookAirRetina13Inch2018", + "Device is a [MacBook Air (Retina, 13-inch, 2018)](https://support.apple.com/kb/SP783)", + "https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbookair/macbook-air-2018-device.jpg", + ["MacBookAir8,1"], 0, (), "MacBook Air (Retina, 13-inch, 2018)", -1, False, False, False, False, False, False, False, False, False, 0, False, 0), + Device( + "macBookAir13Inch2017", + "Device is a [MacBook Air (13-inch, 2017)](https://support.apple.com/kb/SP753)", + "https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbookair/macbook-air-2017-device.jpg", + ["MacBookAir7,3"], 0, (), "MacBook Air (13-inch, 2017)", -1, False, False, False, False, False, False, False, False, False, 0, False, 0), + Device( + "macBookAir13InchEarly2015", + "Device is a [MacBook Air (13-inch, Early 2015)](https://support.apple.com/kb/SP714)", + "https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbookair/macbook-air-2015-13in-device.jpg", + ["MacBookAir7,2"], 0, (), "MacBook Air (13-inch, Early 2015)", -1, False, False, False, False, False, False, False, False, False, 0, False, 0), + Device( + "macBookAir11InchEarly2015", + "Device is a [MacBook Air (11-inch, Early 2015)](https://support.apple.com/kb/SP713)", + "https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbookair/macbook-air-2015-11in-device.jpg", + ["MacBookAir7,1"], 0, (), "MacBook Air (11-inch, Early 2015)", -1, False, False, False, False, False, False, False, False, False, 0, False, 0), + Device( + "macBookAir13InchEarly2014", + "Device is a [MacBook Air (13-inch, Early 2014)](https://support.apple.com/kb/SP700) or [MacBook Air (13-inch, Mid 2013)](https://support.apple.com/kb/SP678)", + "https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbookair/macbook-air-2013-2014-13in-device.jpg", + ["MacBookAir6,2"], 0, (), "MacBook Air (13-inch, Early 2014)", -1, False, False, False, False, False, False, False, False, False, 0, False, 0), + Device( + "macBookAir11InchEarly2014", + "Device is a [MacBook Air (11-inch, Early 2014)](https://support.apple.com/kb/SP699) or [MacBook Air (11-inch, Mid 2013)](https://support.apple.com/kb/SP677)", + "https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbookair/macbook-air-2013-2014-11in-device.jpg", + ["MacBookAir6,1"], 0, (), "MacBook Air (11-inch, Early 2014)", -1, False, False, False, False, False, False, False, False, False, 0, False, 0), + Device( + "macBookAir13InchMid2012", + "Device is a [MacBook Air (13-inch, Mid 2012)](https://support.apple.com/kb/SP670)", + "https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbookair/macbook-air-2012-13in-device.jpg", + ["MacBookAir5,2"], 0, (), "MacBook Air (13-inch, Mid 2012)", -1, False, False, False, False, False, False, False, False, False, 0, False, 0), + Device( + "macBookAir11InchMid2012", + "Device is a [MacBook Air (11-inch, Mid 2012)](https://support.apple.com/kb/SP650)", + "https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbookair/macbook-air-2012-11in-device.jpg", + ["MacBookAir5,1"], 0, (), "MacBook Air (11-inch, Mid 2012)", -1, False, False, False, False, False, False, False, False, False, 0, False, 0), + Device( + "macBookAir13InchMid2011", + "Device is a [MacBook Air (13-inch, Mid 2011)](https://support.apple.com/kb/SP683)", + "https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbookair/macbook-air-2011-13in-device.jpg", + ["MacBookAir4,2"], 0, (), "MacBook Air (13-inch, Mid 2011)", -1, False, False, False, False, False, False, False, False, False, 0, False, 0), + Device( + "macBookAir11InchMid2011", + "Device is a [MacBook Air (11-inch, Mid 2011)](https://support.apple.com/kb/SP631)", + "https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbookair/macbook-air-2011-11in-device.jpg", + ["MacBookAir4,1"], 0, (), "MacBook Air (11-inch, Mid 2011)", -1, False, False, False, False, False, False, False, False, False, 0, False, 0), + Device( + "macBookAir13InchLate2010", + "Device is a [MacBook Air (13-inch, Late 2010)](https://support.apple.com/kb/SP618)", + "https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbookair/macbook-air-2009-2010-13in-device.jpg", + ["MacBookAir3,2"], 0, (), "MacBook Air (13-inch, Late 2010)", -1, False, False, False, False, False, False, False, False, False, 0, False, 0), + Device( + "macBookAir11InchLate2010", + "Device is a [MacBook Air (11-inch, Late 2010)](https://support.apple.com/kb/SP617)", + "https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbookair/macbook-air-2010-11in-device.jpg", + ["MacBookAir3,1"], 0, (), "MacBook Air (11-inch, Late 2010)", -1, False, False, False, False, False, False, False, False, False, 0, False, 0), + Device( + "macBookAirMid2009", + "Device is a [MacBook Air (Mid 2009)](https://support.apple.com/kb/SP548)", + "https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbookair/macbook-air-2009-2010-13in-device.jpg", + ["MacBookAir2,1"], 0, (), "MacBook Air (Mid 2009)", -1, False, False, False, False, False, False, False, False, False, 0, False, 0) +] +## https://support.apple.com/mac/macbook-pro, https://support.apple.com/en-us/HT201300 +macBookPros = [ + Device( + "macBookPro16Inch2019", + "Device is a [MacBook Pro (16-inch, 2019)](https://support.apple.com/kb/SP809)", + "https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbookpro/macbook-pro-16in-2019.jpg", + ["MacBookPro16,1"], 0, (), "MacBook Pro (16-inch, 2019)", -1, False, False, False, False, False, False, False, False, False, 0, False, 0), + Device( + "macBookPro13Inch2019TwoThunderbolt3Ports", + "Device is a [MacBook Pro (13-inch, 2019, Two Thunderbolt 3 ports)](https://support.apple.com/kb/SP799)", + "https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbookpro/macbook-pro-2018-13in-device.jpg", + ["MacBookPro15,4"], 0, (), "MacBook Pro (13-inch, 2019, Two Thunderbolt 3 ports)", -1, False, False, False, False, False, False, False, False, False, 0, False, 0), + Device( + "macBookPro15Inch2019", + "Device is a [MacBook Pro (15-inch, 2019)](https://support.apple.com/kb/SP794)", + "https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbookpro/macbook-pro-2018-15in-device.jpg", + ["MacBookPro15,3"], 0, (), "MacBook Pro (15-inch, 2019)", -1, False, False, False, False, False, False, False, False, False, 0, False, 0), + Device( + "macBookPro13Inch2019FourThunderbolt3Ports", + "Device is a [MacBook Pro (13-inch, 2019, Four Thunderbolt 3 ports)](https://support.apple.com/kb/SP795) or [MacBook Pro (13-inch, 2018, Four Thunderbolt 3 ports)](https://support.apple.com/kb/SP775)", + "https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbookpro/macbook-pro-2018-13in-device.jpg", + ["MacBookPro15,2"], 0, (), "MacBook Pro (13-inch, 2019, Four Thunderbolt 3 ports)", -1, False, False, False, False, False, False, False, False, False, 0, False, 0), + Device( + "macBookPro15Inch2018", + "Device is a [MacBook Pro (15-inch, 2018)](https://support.apple.com/kb/SP776)", + "https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbookpro/macbook-pro-2018-15in-device.jpg", + ["MacBookPro15,1"], 0, (), "MacBook Pro (15-inch, 2018)", -1, False, False, False, False, False, False, False, False, False, 0, False, 0), + Device( + "macBookPro15Inch2017", + "Device is a [MacBook Pro (15-inch, 2017)](https://support.apple.com/kb/SP756)", + "https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbookpro/macbook-pro-2017-15in-device.jpg", + ["MacBookPro14,3"], 0, (), "MacBook Pro (15-inch, 2017)", -1, False, False, False, False, False, False, False, False, False, 0, False, 0), + Device( + "macBookPro13Inch2017FourThunderbolt3Ports", + "Device is a [MacBook Pro (13-inch, 2017, Four Thunderbolt 3 ports)](https://support.apple.com/kb/SP755)", + "https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbookpro/macbook-pro-2017-13in-device.jpg", + ["MacBookPro14,2"], 0, (), "MacBook Pro (13-inch, 2017, Four Thunderbolt 3 ports)", -1, False, False, False, False, False, False, False, False, False, 0, False, 0), + Device( + "macBookPro13Inch2017TwoThunderbolt3Ports", + "Device is a [MacBook Pro (13-inch, 2017, Two Thunderbolt 3 ports)](https://support.apple.com/kb/SP754)", + "https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbookpro/macbook-pro-2017-13in-device-2thunderbolt-3ports.jpg", + ["MacBookPro14,1"], 0, (), "MacBook Pro (13-inch, 2017, Two Thunderbolt 3 ports)", -1, False, False, False, False, False, False, False, False, False, 0, False, 0), + Device( + "macBookPro15Inch2016", + "Device is a [MacBook Pro (15-inch, 2016)](https://support.apple.com/kb/SP749)", + "https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbookpro/macbook-pro-2016-15in-device.jpg", + ["MacBookPro13,3"], 0, (), "MacBook Pro (15-inch, 2016)", -1, False, False, False, False, False, False, False, False, False, 0, False, 0), + Device( + "macBookPro13Inch2016FourThunderbolt3Ports", + "Device is a [MacBook Pro (13-inch, 2016, Four Thunderbolt 3 ports)](https://support.apple.com/kb/SP748)", + "https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbookpro/macbook-pro-2016-13in-device.jpg", + ["MacBookPro13,2"], 0, (), "MacBook Pro (13-inch, 2016, Four Thunderbolt 3 ports)", -1, False, False, False, False, False, False, False, False, False, 0, False, 0), + Device( + "macBookPro13Inch2016TwoThunderbolt3Ports", + "Device is a [MacBook Pro (13-inch, 2016, Two Thunderbolt 3 ports)](https://support.apple.com/kb/SP747)", + "https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbookpro/macbook-pro-2016-13in-device.jpg", + ["MacBookPro13,1"], 0, (), "MacBook Pro (13-inch, 2016, Two Thunderbolt 3 ports)", -1, False, False, False, False, False, False, False, False, False, 0, False, 0), + Device( + "macBookProRetina15InchMid2015", + "Device is a [MacBook Pro (Retina, 15-inch, Mid 2015)](https://support.apple.com/kb/SP719)", + "https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbookpro/macbook-pro-mid-2015-15in-device.jpg", + ["MacBookPro11,4"], 0, (), "MacBook Pro (Retina, 15-inch, Mid 2015)", -1, False, False, False, False, False, False, False, False, False, 0, False, 0), + Device( + "macBookProRetina13InchEarly2015", + "Device is a [MacBook Pro (Retina, 13-inch, Early 2015)](https://support.apple.com/kb/SP715)", + "https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbookpro/macbook-pro-early-2015-13in-device.jpg", + ["MacBookPro12,1"], 0, (), "MacBook Pro (Retina, 13-inch, Early 2015)", -1, False, False, False, False, False, False, False, False, False, 0, False, 0), + Device( + "macBookProRetina15InchMid2014", + "Device is a [MacBook Pro (Retina, 15-inch, Mid 2014)](https://support.apple.com/kb/SP704) or [MacBook Pro (Retina, 15-inch, Late 2013)](https://support.apple.com/kb/SP690)", + "https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbookpro/macbook-pro-mid-2014-15in-device.jpg", + ["MacBookPro11,2"], 0, (), "MacBook Pro (Retina, 15-inch, Mid 2014)", -1, False, False, False, False, False, False, False, False, False, 0, False, 0), + Device( + "macBookProRetina13InchMid2014", + "Device is a [MacBook Pro (Retina, 13-inch, Mid 2014)](https://support.apple.com/kb/SP703) or [MacBook Pro (Retina, 13-inch, Late 2013)](https://support.apple.com/kb/SP691)", + "https://support.apple.com/library/content/dam/edam/applecare/images/en_US/macbookpro/macbook-pro-mid-2014-13in-device.jpg", + ["MacBookPro11,1"], 0, (), "MacBook Pro (Retina, 13-inch, Mid 2014)", -1, False, False, False, False, False, False, False, False, False, 0, False, 0) +] +## https://support.apple.com/mac/imac-pro +iMacPros = [ + Device( + "iMacPro2017", + "Device is an [iMac Pro](https://support.apple.com/kb/SP771)", + "https://support.apple.com/library/APPLE/APPLECARE_ALLGEOS/SP771/SP771-imac-pro-2017.png", + ["iMacPro1,1"], 0, (), "iMac Pro (2017)", -1, False, False, False, False, False, False, False, False, False, 0, False, 0) +] iOSDevices = iPods + iPhones + iPads + homePods tvOSDevices = tvs watchOSDevices = watches +macOSDevices = macMinis + iMacs + macPros + macBooks + macBookAirs + macBookPros + iMacPros }% #if os(watchOS) import WatchKit +#elseif os(macOS) +import AppKit #else import UIKit #endif -// MARK: Device +// MARK: - Device /// This enum is a value-type wrapper and extension of /// [`UIDevice`](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIDevice_Class/). @@ -271,6 +569,13 @@ public enum Device { /// /// ![Image](${device.imageURL}) case ${device.caseName} +% end + #elseif os(macOS) +% for device in macOSDevices: + /// ${device.comment} + /// + /// ![Image](${device.imageURL}) + case ${device.caseName} % end #endif @@ -291,6 +596,12 @@ public enum Device { /// Gets the identifier from the system, such as "iPhone7,1". public static var identifier: String = { + #if os(macOS) + let identifier = try? sysctlData(for: [CTL_HW, HW_MODEL]).withUnsafeBufferPointer { dataPointer -> String? in + dataPointer.baseAddress.flatMap { String(validatingUTF8: $0) } + } + return identifier ?? "" + #else var systemInfo = utsname() uname(&systemInfo) let mirror = Mirror(reflecting: systemInfo.machine) @@ -300,6 +611,7 @@ public enum Device { return identifier + String(UnicodeScalar(UInt8(value))) } return identifier + #endif }() /// Maps an identifier to a Device. If the identifier can not be mapped to an existing device, `UnknownDevice(identifier)` is returned. @@ -313,7 +625,7 @@ public enum Device { % for device in iOSDevices: case ${', '.join(list(map(lambda device: "\"" + device + "\"", device.identifiers)))}: return ${device.caseName} % end - case "i386", "x86_64", "arm64": return simulator(mapToDevice(identifier: ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"] ?? "iOS")) + case "i386", "x86_64": return simulator(mapToDevice(identifier: ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"] ?? "iOS")) default: return unknown(identifier) } #elseif os(tvOS) @@ -321,7 +633,7 @@ public enum Device { % for device in tvOSDevices: case ${', '.join(list(map(lambda device: "\"" + device + "\"", device.identifiers)))}: return ${device.caseName} % end - case "i386", "x86_64", "arm64": return simulator(mapToDevice(identifier: ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"] ?? "tvOS")) + case "i386", "x86_64": return simulator(mapToDevice(identifier: ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"] ?? "tvOS")) default: return unknown(identifier) } #elseif os(watchOS) @@ -329,7 +641,14 @@ public enum Device { % for device in watchOSDevices: case ${', '.join(list(map(lambda device: "\"" + device + "\"", device.identifiers)))}: return ${device.caseName} % end - case "i386", "x86_64", "arm64": return simulator(mapToDevice(identifier: ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"] ?? "watchOS")) + case "i386", "x86_64": return simulator(mapToDevice(identifier: ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"] ?? "watchOS")) + default: return unknown(identifier) + } + #elseif os(macOS) + switch identifier { + % for device in macOSDevices: + case ${', '.join(list(map(lambda device: "\"" + device + "\"", device.identifiers)))}: return ${device.caseName} + % end default: return unknown(identifier) } #endif @@ -369,6 +688,8 @@ public enum Device { case .simulator(let model): return model.diagonal case .unknown: return -1 } + #elseif os(macOS) + return -1 #endif } #endif @@ -393,6 +714,8 @@ public enum Device { } #elseif os(tvOS) return (width: -1, height: -1) + #elseif os(macOS) + return (width: -1, height: -1) #endif } @@ -413,12 +736,11 @@ public enum Device { } /// All X-Series Devices - @available(*, deprecated, renamed: "allDevicesWithSensorHousing") public static var allXSeriesDevices: [Device] { return [${', '.join(list(map(lambda device: "." + device.caseName, list(filter(lambda device: device.isXSeries == True, iOSDevices)))))}] } - /// All Plus and Max-Sized Devices + /// All Plus-Sized Devices public static var allPlusSizedDevices: [Device] { return [${', '.join(list(map(lambda device: "." + device.caseName, list(filter(lambda device: device.isPlusFormFactor == True, iOSDevices)))))}] } @@ -453,13 +775,12 @@ public enum Device { return allMiniDevices.map(Device.simulator) } - /// All simulator X series Devices - @available(*, deprecated, renamed: "allSimulatorDevicesWithSensorHousing") + /// All simulator Plus-Sized Devices public static var allSimulatorXSeriesDevices: [Device] { - return allDevicesWithSensorHousing.map(Device.simulator) + return allXSeriesDevices.map(Device.simulator) } - /// All simulator Plus and Max-Sized Devices + /// All simulator Plus-Sized Devices public static var allSimulatorPlusSizedDevices: [Device] { return allPlusSizedDevices.map(Device.simulator) } @@ -520,19 +841,14 @@ public enum Device { return [${', '.join(list(map(lambda device: "." + device.caseName, list(filter(lambda device: device.hasFaceID == True, iOSDevices)))))}] } - /// All Devices with Touch ID or Face ID - public static var allBiometricAuthenticationCapableDevices: [Device] { - return [${', '.join(list(map(lambda device: "." + device.caseName, list(filter(lambda device: device.hasTouchID == True or device.hasFaceID == True, iOSDevices)))))}] - } - /// Returns whether or not the device has Touch ID public var isTouchIDCapable: Bool { - return isOneOf(Device.allTouchIDCapableDevices) || isOneOf(Device.allTouchIDCapableDevices.map(Device.simulator)) + return isOneOf(Device.allTouchIDCapableDevices) } /// Returns whether or not the device has Face ID public var isFaceIDCapable: Bool { - return isOneOf(Device.allFaceIDCapableDevices) || isOneOf(Device.allFaceIDCapableDevices.map(Device.simulator)) + return isOneOf(Device.allFaceIDCapableDevices) } /// Returns whether or not the device has any biometric sensor (i.e. Touch ID or Face ID) @@ -545,14 +861,9 @@ public enum Device { return [${', '.join(list(map(lambda device: "." + device.caseName, list(filter(lambda device: device.hasSensorHousing == True, iOSDevices)))))}] } - /// All simulator devices that feature a sensor housing in the screen - public static var allSimulatorDevicesWithSensorHousing: [Device] { - return allDevicesWithSensorHousing.map(Device.simulator) - } - /// Returns whether or not the device has a sensor housing public var hasSensorHousing: Bool { - return isOneOf(Device.allDevicesWithSensorHousing) || isOneOf(Device.allDevicesWithSensorHousing.map(Device.simulator)) + return isOneOf(Device.allDevicesWithSensorHousing) } /// All devices that feature a screen with rounded corners. @@ -562,7 +873,7 @@ public enum Device { /// Returns whether or not the device has a screen with rounded corners. public var hasRoundedDisplayCorners: Bool { - return isOneOf(Device.allDevicesWithRoundedDisplayCorners) || isOneOf(Device.allDevicesWithRoundedDisplayCorners.map(Device.simulator)) + return isOneOf(Device.allDevicesWithRoundedDisplayCorners) } /// All devices that have 3D Touch support. @@ -572,7 +883,7 @@ public enum Device { /// Returns whether or not the device has 3D Touch support. public var has3dTouchSupport: Bool { - return isOneOf(Device.allDevicesWith3dTouchSupport) || isOneOf(Device.allDevicesWith3dTouchSupport.map(Device.simulator)) + return isOneOf(Device.allDevicesWith3dTouchSupport) } /// All devices that support wireless charging. @@ -580,19 +891,9 @@ public enum Device { return [${', '.join(list(map(lambda device: "." + device.caseName, list(filter(lambda device: device.supportsWirelessCharging == True, iOSDevices)))))}] } - /// Returns whether or not the device supports wireless charging. + /// Returns whether or not the device supports wireless charging public var supportsWirelessCharging: Bool { - return isOneOf(Device.allDevicesWithWirelessChargingSupport) || isOneOf(Device.allDevicesWithWirelessChargingSupport.map(Device.simulator)) - } - - /// All devices that have a LiDAR sensor. - public static var allDevicesWithALidarSensor: [Device] { - return [${', '.join(list(map(lambda device: "." + device.caseName, list(filter(lambda device: device.hasLidarSensor == True, iOSDevices)))))}] - } - - /// Returns whether or not the device has a LiDAR sensor. - public var hasLidarSensor: Bool { - return isOneOf(Device.allDevicesWithALidarSensor) || isOneOf(Device.allDevicesWithALidarSensor.map(Device.simulator)) + return isOneOf(Device.allDevicesWithWirelessChargingSupport) } #elseif os(tvOS) /// All TVs @@ -622,8 +923,69 @@ public enum Device { /// Returns whether or not the device has Force Touch support. public var hasForceTouchSupport: Bool { - return isOneOf(Device.allWatchesWithForceTouchSupport) || isOneOf(Device.allWatchesWithForceTouchSupport.map(Device.simulator)) + return isOneOf(Device.allWatchesWithForceTouchSupport) } + #elseif os(macOS) + /// All Macs + public static var allMacs: [Device] { + return [${', '.join(list(map(lambda device: "." + device.caseName, macOSDevices)))}] + } + + public static var allMacMinis: [Device] { + return [${', '.join(list(map(lambda device: "." + device.caseName, macMinis)))}] + } + + public static var allMacBookAirs: [Device] { + return [${', '.join(list(map(lambda device: "." + device.caseName, macBookAirs)))}] + } + + public static var allMacBooks: [Device] { + return [${', '.join(list(map(lambda device: "." + device.caseName, macBooks)))}] + } + + public static var allMacBookPros: [Device] { + return [${', '.join(list(map(lambda device: "." + device.caseName, macBookPros)))}] + } + + public static var allIMacs: [Device] { + return [${', '.join(list(map(lambda device: "." + device.caseName, iMacs)))}] + } + + public static var allIMacPros: [Device] { + return [${', '.join(list(map(lambda device: "." + device.caseName, iMacPros)))}] + } + + public static var allMacPros: [Device] { + return [${', '.join(list(map(lambda device: "." + device.caseName, macPros)))}] + } + + public var isMacMini: Bool { + return isOneOf(Device.allMacMinis) + } + + public var isMacBookAir: Bool { + return isOneOf(Device.allMacBookAirs) + } + + public var isMacBook: Bool { + return isOneOf(Device.allMacBooks) + } + + public var isMacBookPro: Bool { + return isOneOf(Device.allMacBookPros) + } + + public var isIMac: Bool { + return isOneOf(Device.allIMacs) + } + + public var isIMacPro: Bool { + return isOneOf(Device.allIMacPros) + } + + public var isMacPro: Bool { + return isOneOf(Device.allMacPros) + } #endif /// All real devices (i.e. all devices except for all simulators) @@ -634,6 +996,8 @@ public enum Device { return allTVs #elseif os(watchOS) return allWatches + #elseif os(macOS) + return allMacs #endif } @@ -675,8 +1039,6 @@ public enum Device { return devices.contains(self) } - // MARK: Current Device - /// Whether or not the current device is the current device. private var isCurrent: Bool { return self == Device.current @@ -687,6 +1049,8 @@ public enum Device { guard isCurrent else { return nil } #if os(watchOS) return WKInterfaceDevice.current().name + #elseif os(macOS) + return description #else return UIDevice.current.name #endif @@ -697,6 +1061,8 @@ public enum Device { guard isCurrent else { return nil } #if os(watchOS) return WKInterfaceDevice.current().systemName + #elseif os(macOS) + return "macOS" #else return UIDevice.current.systemName #endif @@ -707,6 +1073,8 @@ public enum Device { guard isCurrent else { return nil } #if os(watchOS) return WKInterfaceDevice.current().systemVersion + #elseif os(macOS) + return ProcessInfo.processInfo.operatingSystemVersionString #else return UIDevice.current.systemVersion #endif @@ -717,6 +1085,10 @@ public enum Device { guard isCurrent else { return nil } #if os(watchOS) return WKInterfaceDevice.current().model + #elseif os(macOS) + var set = CharacterSet.decimalDigits + set.insert(",") + return Device.identifier.components(separatedBy: set).joined() #else return UIDevice.current.model #endif @@ -727,6 +1099,8 @@ public enum Device { guard isCurrent else { return nil } #if os(watchOS) return WKInterfaceDevice.current().localizedModel + #elseif os(macOS) + return model #else return UIDevice.current.localizedModel #endif @@ -752,6 +1126,8 @@ public enum Device { } #elseif os(tvOS) return nil + #elseif os(macOS) + return nil #endif } @@ -778,7 +1154,7 @@ public enum Device { } } -// MARK: CustomStringConvertible +// MARK: - CustomStringConvertible extension Device: CustomStringConvertible { /// A textual representation of the device. @@ -788,7 +1164,7 @@ extension Device: CustomStringConvertible { % for device in iOSDevices: case .${device.caseName}: return "${device.description}" % end - case .simulator(let model): return "Simulator (\(model.description))" + case .simulator(let model): return "Simulator (\(model))" case .unknown(let identifier): return identifier } #elseif os(watchOS) @@ -796,7 +1172,7 @@ extension Device: CustomStringConvertible { % for device in watchOSDevices: case .${device.caseName}: return "${device.description}" % end - case .simulator(let model): return "Simulator (\(model.description))" + case .simulator(let model): return "Simulator (\(model))" case .unknown(let identifier): return identifier } #elseif os(tvOS) @@ -804,47 +1180,22 @@ extension Device: CustomStringConvertible { % for device in tvOSDevices: case .${device.caseName}: return "${device.description}" % end - case .simulator(let model): return "Simulator (\(model.description))" + case .simulator(let model): return "Simulator (\(model))" case .unknown(let identifier): return identifier } - #endif - } - - /// A safe version of `description`. - /// Example: - /// Device.iPhoneXR.description: iPhone Xʀ - /// Device.iPhoneXR.safeDescription: iPhone XR - public var safeDescription: String { - #if os(iOS) + #elseif os(macOS) switch self { - % for device in iOSDevices: - case .${device.caseName}: return "${device.safeDescription}" - % end - case .simulator(let model): return "Simulator (\(model.safeDescription))" - case .unknown(let identifier): return identifier - } - #elseif os(watchOS) - switch self { - % for device in watchOSDevices: - case .${device.caseName}: return "${device.safeDescription}" - % end - case .simulator(let model): return "Simulator (\(model.safeDescription))" - case .unknown(let identifier): return identifier - } - #elseif os(tvOS) - switch self { - % for device in tvOSDevices: - case .${device.caseName}: return "${device.safeDescription}" - % end - case .simulator(let model): return "Simulator (\(model.safeDescription))" +% for device in macOSDevices: + case .${device.caseName}: return "${device.description}" +% end + case .simulator(let model): return "Simulator (\(model))" case .unknown(let identifier): return identifier } #endif } - } -// MARK: Equatable +// MARK: - Equatable extension Device: Equatable { /// Compares two devices @@ -859,7 +1210,7 @@ extension Device: Equatable { } -// MARK: Battery +// MARK: - Battery #if os(iOS) || os(watchOS) @available(iOS 8.0, watchOS 4.0, *) extension Device { @@ -916,7 +1267,11 @@ extension Device { /// The user enabled Low Power mode public var lowPowerMode: Bool { - return ProcessInfo.processInfo.isLowPowerModeEnabled + if #available(iOS 9.0, *) { + return ProcessInfo.processInfo.isLowPowerModeEnabled + } else { + return false + } } /// Provides a textual representation of the battery state. @@ -955,7 +1310,7 @@ extension Device { } #endif -// MARK: Device.Batterystate: Comparable +// MARK: - Device.Batterystate: Comparable #if os(iOS) || os(watchOS) @available(iOS 8.0, watchOS 4.0, *) extension Device.BatteryState: Comparable { @@ -991,7 +1346,7 @@ extension Device.BatteryState: Comparable { #if os(iOS) extension Device { - // MARK: Orientation + // MARK: - Orientation /** This enum describes the state of the orientation. - Landscape: The device is in Landscape Orientation @@ -1013,7 +1368,7 @@ extension Device { #endif #if os(iOS) -// MARK: DiskSpace +// MARK: - DiskSpace extension Device { /// Return the root url @@ -1069,7 +1424,7 @@ extension Device { #endif #if os(iOS) -// MARK: Apple Pencil +// MARK: - Apple Pencil extension Device { /** @@ -1103,7 +1458,6 @@ extension Device { % for device in list(filter(lambda device: device.applePencilSupport == 2, iOSDevices)): case .${device.caseName}: return .secondGeneration % end - case .simulator(let model): return model.applePencilSupport default: return [] } } @@ -1111,23 +1465,20 @@ extension Device { #endif #if os(iOS) -// MARK: Cameras +// MARK: - Cameras extension Device { - public enum CameraType { - @available(*, deprecated, renamed: "wide") + public enum CameraTypes { case normal - - case wide case telephoto case ultraWide } /// Returns an array of the types of cameras the device has - public var cameras: [CameraType] { + public var cameras: [CameraTypes] { switch self { % for device in list(filter(lambda device: device.cameras == 1, iOSDevices)): - case .${device.caseName}: return [.wide] + case .${device.caseName}: return [.normal] % end % for device in list(filter(lambda device: device.cameras == 2, iOSDevices)): case .${device.caseName}: return [.telephoto] @@ -1136,16 +1487,13 @@ extension Device { case .${device.caseName}: return [.ultraWide] % end % for device in list(filter(lambda device: device.cameras == 12, iOSDevices)): - case .${device.caseName}: return [.wide, .telephoto] + case .${device.caseName}: return [.normal, .telephoto] % end % for device in list(filter(lambda device: device.cameras == 13, iOSDevices)): - case .${device.caseName}: return [.wide, .ultraWide] - % end - % for device in list(filter(lambda device: device.cameras == 23, iOSDevices)): - case .${device.caseName}: return [.telephoto, .ultraWide] + case .${device.caseName}: return [.normal, .ultraWide] % end % for device in list(filter(lambda device: device.cameras == 123, iOSDevices)): - case .${device.caseName}: return [.wide, .telephoto, .ultraWide] + case .${device.caseName}: return [.normal, .telephoto, .ultraWide] % end default: return [] } @@ -1157,13 +1505,7 @@ extension Device { } /// All devices that feature a normal camera - @available(*, deprecated, renamed: "allDevicesWithWideCamera") public static var allDevicesWithNormalCamera: [Device] { - return Device.allDevicesWithWideCamera - } - - /// All devices that feature a wide camera - public static var allDevicesWithWideCamera: [Device] { return [${', '.join(list(map(lambda device: "." + device.caseName, list(filter(lambda device: device.cameras == 1 or device.cameras == 12 or device.cameras == 13 or device.cameras == 123, iOSDevices)))))}] } @@ -1183,14 +1525,8 @@ extension Device { } /// Returns whether or not the current device has a normal camera - @available(*, deprecated, renamed: "hasWideCamera") public var hasNormalCamera: Bool { - return self.hasWideCamera - } - - /// Returns whether or not the current device has a wide camera - public var hasWideCamera: Bool { - return self.cameras.contains(.wide) + return self.cameras.contains(.normal) } /// Returns whether or not the current device has a telephoto camera @@ -1205,3 +1541,25 @@ extension Device { } #endif + +#if os(macOS) +private func sysctlData(for keys: [Int32]) throws -> [Int8] { + return try keys.withUnsafeBufferPointer { keysPointer -> [Int8] in + // Get the data size + var requiredSize = 0 + var result = Darwin.sysctl(UnsafeMutablePointer(mutating: keysPointer.baseAddress), UInt32(keys.count), nil, &requiredSize, nil, 0) + if result != 0, let code = POSIXErrorCode(rawValue: errno) { + throw POSIXError(code) + } + // get info + let data = [Int8](repeating: 0, count: requiredSize) + result = data.withUnsafeBufferPointer { dataBuffer -> Int32 in + Darwin.sysctl(UnsafeMutablePointer(mutating: keysPointer.baseAddress), UInt32(keys.count), UnsafeMutableRawPointer(mutating: dataBuffer.baseAddress), &requiredSize, nil, 0) + } + if result != 0, let code = POSIXErrorCode(rawValue: errno) { + throw POSIXError(code) + } + return data + } +} +#endif diff --git a/Tests/Tests.swift b/Tests/Tests.swift index 091864eb..a78e7017 100644 --- a/Tests/Tests.swift +++ b/Tests/Tests.swift @@ -16,6 +16,11 @@ class DeviceKitTests: XCTestCase { let device = Device.current + #if os(macOS) + func testDeviceIsKnown() { + XCTAssertTrue(device.isOneOf(Device.allMacs), "device: \(device)") + } + #else func testDeviceSimulator() { XCTAssertTrue(device.isOneOf(Device.allSimulators)) } @@ -27,6 +32,7 @@ class DeviceKitTests: XCTestCase { || device.description.contains("iPod") || device.description.contains("TV")) } + #endif // MARK: - iOS #if os(iOS) @@ -154,7 +160,6 @@ class DeviceKitTests: XCTestCase { XCTAssertTrue(Device.iPhone7.screenRatio == (width: 9, height: 16)) XCTAssertTrue(Device.iPhone7Plus.screenRatio == (width: 9, height: 16)) XCTAssertTrue(Device.iPhoneSE.screenRatio == (width: 9, height: 16)) - XCTAssertTrue(Device.iPhoneSE2.screenRatio == (width: 9, height: 16)) XCTAssertTrue(Device.iPhone8.screenRatio == (width: 9, height: 16)) XCTAssertTrue(Device.iPhone8Plus.screenRatio == (width: 9, height: 16)) XCTAssertTrue(Device.iPhoneX.screenRatio == (width: 9, height: 19.5)) @@ -276,17 +281,6 @@ class DeviceKitTests: XCTestCase { XCTAssertEqual(Device.unknown(uuid).description, uuid) } - func testSafeDescription() { - for device in Device.allRealDevices { - switch device { - case .iPhoneXR, .iPhoneXS, .iPhoneXSMax: - XCTAssertNotEqual(device.description, device.safeDescription) - default: - XCTAssertEqual(device.description, device.safeDescription) - } - } - } - func testIsPad() { Device.allPads.forEach { XCTAssertTrue($0.isPad) } } @@ -310,7 +304,6 @@ class DeviceKitTests: XCTestCase { assertEqualDeviceAndSimulator(device: Device.iPhone7, property: \Device.ppi, value: 326) assertEqualDeviceAndSimulator(device: Device.iPhone7Plus, property: \Device.ppi, value: 401) assertEqualDeviceAndSimulator(device: Device.iPhoneSE, property: \Device.ppi, value: 326) - assertEqualDeviceAndSimulator(device: Device.iPhoneSE2, property: \Device.ppi, value: 326) assertEqualDeviceAndSimulator(device: Device.iPhone8, property: \Device.ppi, value: 326) assertEqualDeviceAndSimulator(device: Device.iPhone8Plus, property: \Device.ppi, value: 401) assertEqualDeviceAndSimulator(device: Device.iPhoneX, property: \Device.ppi, value: 458) @@ -349,7 +342,7 @@ class DeviceKitTests: XCTestCase { } func testIsPlusSized() { - XCTAssertEqual(Device.allPlusSizedDevices, [.iPhone6Plus, .iPhone6sPlus, .iPhone7Plus, .iPhone8Plus, .iPhoneXSMax, .iPhone11ProMax, .iPhone12ProMax]) + XCTAssertEqual(Device.allPlusSizedDevices, [.iPhone6Plus, .iPhone6sPlus, .iPhone7Plus, .iPhone8Plus, .iPhoneXSMax, .iPhone11ProMax]) } func testIsPro() { @@ -400,25 +393,23 @@ class DeviceKitTests: XCTestCase { func testCameras() { for device in Device.allDevicesWithCamera { - XCTAssertTrue(device.cameras.contains(.wide) || device.cameras.contains(.telephoto) || device.cameras.contains(.ultraWide)) + XCTAssertTrue(device.cameras.contains(.normal) || device.cameras.contains(.telephoto)) XCTAssertTrue(device.hasCamera) - XCTAssertTrue(device.hasWideCamera || device.hasTelephotoCamera || device.hasUltraWideCamera) + XCTAssertTrue(device.hasNormalCamera || device.hasTelephotoCamera) } for device in Device.allPhones + Device.allPads + Device.allPods { if !Device.allDevicesWithCamera.contains(device) { - XCTAssertFalse(device.cameras.contains(.wide)) + XCTAssertFalse(device.cameras.contains(.normal)) XCTAssertFalse(device.cameras.contains(.telephoto)) - XCTAssertFalse(device.cameras.contains(.ultraWide)) XCTAssertFalse(device.hasCamera) - XCTAssertFalse(device.hasWideCamera) + XCTAssertFalse(device.hasNormalCamera) XCTAssertFalse(device.hasTelephotoCamera) - XCTAssertFalse(device.hasUltraWideCamera) } } - for device in Device.allDevicesWithWideCamera { - XCTAssertTrue(device.cameras.contains(.wide)) + for device in Device.allDevicesWithNormalCamera { + XCTAssertTrue(device.cameras.contains(.normal)) XCTAssertTrue(device.hasCamera) - XCTAssertTrue(device.hasWideCamera) + XCTAssertTrue(device.hasNormalCamera) } for device in Device.allDevicesWithTelephotoCamera { XCTAssertTrue(device.cameras.contains(.telephoto)) @@ -452,12 +443,6 @@ class DeviceKitTests: XCTestCase { XCTAssertEqual(Device.mapToDevice(identifier: "AppleTV6,2").description, "Apple TV 4K") } - func testSafeDescription() { - for device in Device.allRealDevices { - XCTAssertEqual(device.description, device.safeDescription) - } - } - /// Test that all the ppi values for applicable devices match the public information available at wikipedia. Test non-applicable devices return nil. func testPPI() { // Non-applicable devices: