├── .gitignore ├── .swift-version ├── .swiftpm └── xcode │ └── package.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ └── IDEWorkspaceChecks.plist ├── LICENSE ├── Package.swift ├── README.md ├── Sources └── UIScreenExtension │ └── UIScreenExtension.swift ├── UIScreenExtension.podspec ├── UIScreenExtension.xcodeproj ├── project.pbxproj └── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ └── IDEWorkspaceChecks.plist └── UIScreenExtension ├── Info.plist ├── SimulatorDeviceInfoView.swift └── UIScreenExtension.h /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xccheckout 23 | *.xcscmblueprint 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | *.ipa 28 | *.dSYM.zip 29 | *.dSYM 30 | 31 | ## Playgrounds 32 | timeline.xctimeline 33 | playground.xcworkspace 34 | 35 | # Swift Package Manager 36 | # 37 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 38 | # Packages/ 39 | # Package.pins 40 | .build/ 41 | 42 | # CocoaPods 43 | # 44 | # We recommend against adding the Pods directory to your .gitignore. However 45 | # you should judge for yourself, the pros and cons are mentioned at: 46 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 47 | # 48 | # Pods/ 49 | 50 | # Carthage 51 | # 52 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 53 | # Carthage/Checkouts 54 | 55 | Carthage/Build 56 | 57 | # fastlane 58 | # 59 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 60 | # screenshots whenever they are needed. 61 | # For more information about the recommended setup visit: 62 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 63 | 64 | fastlane/report.xml 65 | fastlane/Preview.html 66 | fastlane/screenshots 67 | fastlane/test_output 68 | -------------------------------------------------------------------------------- /.swift-version: -------------------------------------------------------------------------------- 1 | 3.0 2 | -------------------------------------------------------------------------------- /.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.swiftpm/xcode/package.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Jens Schwarzer 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.2 2 | 3 | import PackageDescription 4 | 5 | let package = Package( 6 | name: "UIScreenExtension", 7 | platforms: [ 8 | .iOS(SupportedPlatform.IOSVersion.v9), 9 | ], 10 | products: [ 11 | .library( 12 | name: "UIScreenExtension", 13 | targets: ["UIScreenExtension"]), 14 | ], 15 | dependencies: [], 16 | targets: [ 17 | .target( 18 | name: "UIScreenExtension", 19 | dependencies: []), 20 | ] 21 | ) 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # UIScreenExtension 2 | 3 | This is an extension to UIScreen that provides information about the pixel density (or point density) of iPhones and iPads. For example this can be used to: 4 | 5 | * compute the dimension of the screen 6 | * draw a ruler; or 7 | * to show a proper ECG graph on the iPhone's screen. 8 | 9 | public extension UIScreen { 10 | 11 | /// The number of pixels per inch for this device 12 | public static let pixelsPerInch: CGFloat? 13 | 14 | /// The number of pixels per centimeter for this device 15 | public static let pixelsPerCentimeter: CGFloat? 16 | 17 | /// The number of points per inch for this device 18 | public static let pointsPerInch: CGFloat? 19 | 20 | /// The number of points per centimeter for this device 21 | public static let pointsPerCentimeter: CGFloat? 22 | 23 | /// The screen dimension in inches 24 | public static let dimensionInInches: CGSize? 25 | 26 | /// The screen dimension in centimeters 27 | public static let dimensionInCentimeters: CGSize? 28 | } 29 | 30 | The constants will be set to `.none` if the device is unknown. This can happen if Apple releases a new iPhone, so please remember to deal with this in your code. 31 | 32 | 33 | ## Installation and use 34 | 35 | The extension can be installed using Swift Package Manager or [Cocoapods](https://cocoapods.org/) by adding below line to your `Podfile`: 36 | 37 | pod 'UIScreenExtension', :git => 'https://github.com/marchv/UIScreenExtension' 38 | 39 | To use the extension in your code first import it by adding: 40 | 41 | import UIScreenExtension 42 | 43 | And then use it for example: 44 | 45 | if let pointsPerCentimeter = UIScreen.pointsPerCentimeter { 46 | // code 47 | } 48 | 49 | Or to compute the diagonal screen dimension: 50 | 51 | if let dimensionInInches = UIScreen.dimensionInInches { 52 | print(sqrt(pow(dimensionInInches.width, 2) + pow(dimensionInInches.height, 2))) // for example ~5.5 inches for iPhone 7 Plus 53 | } 54 | 55 | 56 | ## Support 57 | 58 | The extension supports all iPhones, iPods and iPads that are supported by iOS 9-14. 59 | 60 | 61 | ## Limitations 62 | 63 | Please note that iPhone only apps upscaled on iPads will not work properly! 64 | 65 | 66 | ## Improvements 67 | 68 | * Apple Watch support 69 | * Objective C support 70 | * Fetch information about new iPhone models from internet 71 | 72 | ## Author 73 | 74 | jens.schwarzer@marchv.com 75 | 76 | :) 77 | -------------------------------------------------------------------------------- /Sources/UIScreenExtension/UIScreenExtension.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIScreenExtension.swift 3 | // UIScreenExtension 4 | // 5 | // Created by Jens Schwarzer on 02/10/2017. 6 | // Copyright © 2017 marchv. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | internal extension UIDevice { 12 | 13 | // model identifiers can be found at https://www.theiphonewiki.com/wiki/Models 14 | static let modelIdentifier: String = { 15 | if let simulatorModelIdentifier = ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"] { return simulatorModelIdentifier } 16 | var sysinfo = utsname() 17 | uname(&sysinfo) // ignore return value 18 | return String(bytes: Data(bytes: &sysinfo.machine, count: Int(_SYS_NAMELEN)), encoding: .ascii)!.trimmingCharacters(in: .controlCharacters) 19 | }() 20 | 21 | } 22 | 23 | private func computeIfSome(optional: T?, computation: ((T) -> S)) -> S? { if let some = optional { return computation(some) } else { return .none } } 24 | 25 | @available(iOS 9.0, *) 26 | public extension UIScreen { 27 | 28 | /// The screen dimension in inches 29 | static let diagonalInInches: CGFloat? = { 30 | switch UIDevice.modelIdentifier { 31 | case "iPhone4,1": // iPhone 4S 32 | return 3.5 33 | 34 | case "iPhone5,1", "iPhone5,2": fallthrough // iPhone 5 35 | case "iPhone5,3", "iPhone5,4": fallthrough // iPhone 5C 36 | case "iPhone6,1", "iPhone6,2": fallthrough // iPhone 5S 37 | case "iPhone8,4": fallthrough // iPhone SE 38 | case "iPod5,1": fallthrough // iPod Touch 5th generation 39 | case "iPod7,1": fallthrough // iPod Touch 6th generation 40 | case "iPod9,1": // iPod Touch 7th generation 41 | return 4.0 42 | 43 | case "iPhone7,2": fallthrough // iPhone 6 44 | case "iPhone8,1": fallthrough // iPhone 6S 45 | case "iPhone9,1", "iPhone9,3": fallthrough // iPhone 7 46 | case "iPhone10,1", "iPhone10,4": fallthrough // iPhone 8 47 | case "iPhone12,8": fallthrough // iPhone SE 2nd generation 48 | case "iPhone14,6": // iPhone SE (3rd generation) 49 | return 4.7 50 | 51 | case "iPhone13,1": fallthrough // iPhone 12 Mini 52 | case "iPhone14,4": // iPhone 13 Mini 53 | return 5.4 54 | 55 | case "iPhone7,1": fallthrough // iPhone 6 Plus 56 | case "iPhone8,2": fallthrough // iPhone 6S Plus 57 | case "iPhone9,2", "iPhone9,4": fallthrough // iPhone 7 Plus 58 | case "iPhone10,2", "iPhone10,5": // iPhone 8 Plus 59 | return 5.5 60 | 61 | case "iPhone10,3", "iPhone10,6": fallthrough // iPhone X 62 | case "iPhone11,2": fallthrough // iPhone XS 63 | case "iPhone12,3": // iPhone 11 Pro 64 | return 5.8 65 | 66 | case "iPhone11,8": fallthrough // iPhone XR 67 | case "iPhone12,1": fallthrough // iPhone 11 68 | case "iPhone13,2": fallthrough // iPhone 12 69 | case "iPhone13,3": fallthrough // iPhone 12 Pro 70 | case "iPhone14,5": fallthrough // iPhone 13 71 | case "iPhone14,2": fallthrough // iPhone 13 Pro 72 | case "iPhone14,7": fallthrough // iPhone 14 73 | case "iPhone15,2": fallthrough // iPhone 14 Pro 74 | case "iPhone15,4": fallthrough // iPhone 15 75 | case "iPhone16,1": fallthrough // iPhone 15 Pro 76 | case "iPhone17,3": fallthrough // iPhone 16 77 | case "iPhone17,5": // iPhone 16e 78 | return 6.1 79 | 80 | case "iPhone17,1": // iPhone 16 Pro 81 | return 6.3 82 | 83 | case "iPhone17,2": // iPhone 16 Pro Max 84 | return 6.9 85 | 86 | case "iPhone11,4", "iPhone11,6": fallthrough // iPhone XS Max 87 | case "iPhone12,5": // iPhone 11 Pro Max 88 | return 6.5 89 | 90 | case "iPhone13,4": fallthrough // iPhone 12 Pro Max 91 | case "iPhone14,3": fallthrough // iPhone 13 Pro Max 92 | case "iPhone14,8": fallthrough // iPhone 14 Plus 93 | case "iPhone15,3": fallthrough // iPhone 14 Pro Max 94 | case "iPhone15,5": fallthrough // iPhone 15 Plus 95 | case "iPhone16,2": fallthrough // iPhone 15 Pro Max 96 | case "iPhone17,4": // iPhone 16 Plus 97 | return 6.7 98 | 99 | case "iPad2,5", "iPad2,6", "iPad2,7": fallthrough // iPad Mini 100 | case "iPad4,4", "iPad4,5", "iPad4,6": fallthrough // iPad Mini 2 101 | case "iPad4,7", "iPad4,8", "iPad4,9": fallthrough // iPad Mini 3 102 | case "iPad5,1", "iPad5,2": fallthrough // iPad Mini 4 103 | case "iPad11,1", "iPad11,2": fallthrough // iPad Mini 5 104 | case "iPad14,1", "iPad14,2": // iPad Mini 6 105 | return 7.9 106 | 107 | case "iPad2,1", "iPad2,2", "iPad2,3", "iPad2,4": fallthrough // iPad 2 108 | case "iPad3,1", "iPad3,2", "iPad3,3": fallthrough // iPad 3rd generation 109 | case "iPad3,4", "iPad3,5", "iPad3,6": fallthrough // iPad 4th generation 110 | case "iPad4,1", "iPad4,2", "iPad4,3": fallthrough // iPad Air 111 | case "iPad5,3", "iPad5,4": fallthrough // iPad Air 2 112 | case "iPad6,3", "iPad6,4": fallthrough // iPad Pro (9.7 inch) 113 | case "iPad6,11", "iPad6,12": fallthrough // iPad 5th generation 114 | case "iPad7,5", "iPad7,6": // iPad 6th generation 115 | return 9.7 116 | 117 | case "iPad7,11", "iPad7,12": fallthrough // iPad 7th generation 118 | case "iPad11,6", "iPad11,7": fallthrough // iPad 8th generation 119 | case "iPad12,1", "iPad12,2": // iPad 9th generation 120 | return 10.2 121 | 122 | case "iPad7,3", "iPad7,4": fallthrough // iPad Pro (10.5 inch) 123 | case "iPad11,3", "iPad11,4": // iPad Air (3rd generation) 124 | return 10.5 125 | 126 | case "iPad13,1", "iPad13,2": fallthrough // iPad Air (4th generation) 127 | case "iPad13,18", "iPad13,19": fallthrough // iPad 10th generation 128 | case "iPad13,16", "iPad13,17": // iPad Air (5th generation) 129 | return 10.9 130 | 131 | case "iPad8,1", "iPad8,2", "iPad8,3", "iPad8,4": fallthrough // iPad Pro (11 inch) 132 | case "iPad8,9", "iPad8,10": fallthrough // iPad Pro (11 inch, 2nd generation) 133 | case "iPad13,4", "iPad13,5", "iPad13,6", "iPad13,7": fallthrough // iPad Pro (11 inch, 3rd generation) 134 | case "iPad14,3", "iPad14,4": fallthrough // iPad Pro (11 inch, 4th generation) 135 | case "iPad14,8", "iPad14,9": fallthrough // iPad Air (11 inch, 6th generation) 136 | case "iPad16,3", "iPad16,4": fallthrough // iPad Pro (11 inch, 7th generation) 137 | case "iPad15,3", "iPad15,4": fallthrough // iPad Air (11 inch, 7th generation) 138 | case "iPad15,7", "iPad15,8": // iPad 11th generation 139 | return 11.0 140 | 141 | case "iPad14,10", "iPad14,11": fallthrough // iPad Air (13 inch, 6th generation) 142 | case "iPad16,5", "iPad16,6": fallthrough // iPad Pro (13 inch, 7th generation) 143 | case "iPad15,5", "iPad15,6": // iPad Air (13 inch, 7th generation) 144 | return 13.0 145 | 146 | case "iPad6,7", "iPad6,8": fallthrough // iPad Pro (12.9 inch) 147 | case "iPad7,1", "iPad7,2": fallthrough // iPad Pro (12.9 inch, 2nd generation) 148 | case "iPad8,5", "iPad8,6", "iPad8,7", "iPad8,8": fallthrough // iPad Pro (12.9 inch, 3rd generation) 149 | case "iPad8,11", "iPad8,12": fallthrough // iPad Pro (12.9 inch, 4th generation) 150 | case "iPad13,8", "iPad13,9", "iPad13,10", "iPad13,11": fallthrough // iPad Pro (12.9 inch, 5th generation) 151 | case "iPad14,5", "iPad14,6": // iPad Pro (12.9 inch, 6th generation) 152 | return 12.9 153 | 154 | default: // unknown model identifier 155 | return .none 156 | } 157 | }() 158 | 159 | /// The number of pixels per inch for this device 160 | static let pixelsPerInch: CGFloat? = computeIfSome(optional: dimensionInInches, computation: { main.nativeBounds.height / $0.height }) 161 | 162 | /// The number of pixels per centimeter for this device 163 | static let pixelsPerCentimeter: CGFloat? = computeIfSome(optional: pixelsPerInch, computation: { $0 / 2.54 }) 164 | 165 | /// The number of points per inch for this device 166 | static let pointsPerInch: CGFloat? = computeIfSome(optional: pixelsPerInch, computation: { $0 / main.nativeScale }) 167 | 168 | /// The number of points per centimeter for this device 169 | static let pointsPerCentimeter: CGFloat? = computeIfSome(optional: pixelsPerCentimeter, computation: { $0 / main.nativeScale }) 170 | 171 | /// The screen dimension in inches 172 | static let dimensionInInches: CGSize? = computeIfSome(optional: diagonalInInches, computation: { 173 | let ratio = main.nativeBounds.width / main.nativeBounds.height 174 | let height = $0 / sqrt(pow(ratio, 2) + 1) 175 | let width = ratio * height 176 | return CGSize(width: width, height: height) 177 | }) 178 | 179 | /// The screen dimension in centimeters 180 | static let dimensionInCentimeters: CGSize? = computeIfSome(optional: pixelsPerCentimeter, computation: { CGSize(width: main.nativeBounds.width / $0, height: main.nativeBounds.height / $0) }) 181 | 182 | } 183 | -------------------------------------------------------------------------------- /UIScreenExtension.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | 3 | s.name = "UIScreenExtension" 4 | s.version = "0.0.11" 5 | s.summary = "An extension to UIScreen that offers information about the pixel density (or point density) of iPhones and iPads." 6 | s.description = <<-DESC 7 | This extension offers information about the pixel/point density measured in either pixels/points per centimeter/inch (PPI/PPCM). 8 | This can for example be used to compute the screen dimension, draw a ruler or to show ECG graph on the iPhone's screen. 9 | DESC 10 | 11 | s.homepage = "https://github.com/marchv/UIScreenExtension" 12 | s.license = { :type => "MIT", :file => "LICENSE" } 13 | s.author = { "Jens Schwarzer" => "jens.schwarzer@marchv.com" } 14 | s.platform = :ios, "13.0" 15 | s.source = { :git => "https://github.com/marchv/UIScreenExtension.git", :tag => s.version } 16 | s.source_files = "UIScreenExtension", "UIScreenExtension/**/*.{h,swift}", "Sources/**/*.{h,swift}" 17 | end 18 | -------------------------------------------------------------------------------- /UIScreenExtension.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 48; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 134B30931F822DA60040885A /* UIScreenExtension.h in Headers */ = {isa = PBXBuildFile; fileRef = 134B30911F822DA60040885A /* UIScreenExtension.h */; settings = {ATTRIBUTES = (Public, ); }; }; 11 | 134B309A1F822DC20040885A /* UIScreenExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 134B30991F822DC20040885A /* UIScreenExtension.swift */; }; 12 | 139181181F8255A2009C354A /* README.md in Resources */ = {isa = PBXBuildFile; fileRef = 139181171F8255A2009C354A /* README.md */; }; 13 | 1391811A1F825CEA009C354A /* UIScreenExtension.podspec in Resources */ = {isa = PBXBuildFile; fileRef = 139181191F825CEA009C354A /* UIScreenExtension.podspec */; }; 14 | 9AA14A7B266B79A300ED55F2 /* SimulatorDeviceInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9AA14A7A266B79A300ED55F2 /* SimulatorDeviceInfoView.swift */; }; 15 | /* End PBXBuildFile section */ 16 | 17 | /* Begin PBXFileReference section */ 18 | 134B308E1F822DA60040885A /* UIScreenExtension.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = UIScreenExtension.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 19 | 134B30911F822DA60040885A /* UIScreenExtension.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UIScreenExtension.h; sourceTree = ""; }; 20 | 134B30921F822DA60040885A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 21 | 134B30991F822DC20040885A /* UIScreenExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = UIScreenExtension.swift; path = Sources/UIScreenExtension/UIScreenExtension.swift; sourceTree = SOURCE_ROOT; }; 22 | 139181171F8255A2009C354A /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; 23 | 139181191F825CEA009C354A /* UIScreenExtension.podspec */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = UIScreenExtension.podspec; sourceTree = ""; }; 24 | 9AA14A7A266B79A300ED55F2 /* SimulatorDeviceInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimulatorDeviceInfoView.swift; sourceTree = ""; }; 25 | /* End PBXFileReference section */ 26 | 27 | /* Begin PBXFrameworksBuildPhase section */ 28 | 134B308A1F822DA60040885A /* Frameworks */ = { 29 | isa = PBXFrameworksBuildPhase; 30 | buildActionMask = 2147483647; 31 | files = ( 32 | ); 33 | runOnlyForDeploymentPostprocessing = 0; 34 | }; 35 | /* End PBXFrameworksBuildPhase section */ 36 | 37 | /* Begin PBXGroup section */ 38 | 134B30841F822DA60040885A = { 39 | isa = PBXGroup; 40 | children = ( 41 | 139181171F8255A2009C354A /* README.md */, 42 | 139181191F825CEA009C354A /* UIScreenExtension.podspec */, 43 | 134B30901F822DA60040885A /* UIScreenExtension */, 44 | 134B308F1F822DA60040885A /* Products */, 45 | ); 46 | sourceTree = ""; 47 | }; 48 | 134B308F1F822DA60040885A /* Products */ = { 49 | isa = PBXGroup; 50 | children = ( 51 | 134B308E1F822DA60040885A /* UIScreenExtension.framework */, 52 | ); 53 | name = Products; 54 | sourceTree = ""; 55 | }; 56 | 134B30901F822DA60040885A /* UIScreenExtension */ = { 57 | isa = PBXGroup; 58 | children = ( 59 | 134B30911F822DA60040885A /* UIScreenExtension.h */, 60 | 134B30921F822DA60040885A /* Info.plist */, 61 | 134B30991F822DC20040885A /* UIScreenExtension.swift */, 62 | 9AA14A7A266B79A300ED55F2 /* SimulatorDeviceInfoView.swift */, 63 | ); 64 | path = UIScreenExtension; 65 | sourceTree = ""; 66 | }; 67 | /* End PBXGroup section */ 68 | 69 | /* Begin PBXHeadersBuildPhase section */ 70 | 134B308B1F822DA60040885A /* Headers */ = { 71 | isa = PBXHeadersBuildPhase; 72 | buildActionMask = 2147483647; 73 | files = ( 74 | 134B30931F822DA60040885A /* UIScreenExtension.h in Headers */, 75 | ); 76 | runOnlyForDeploymentPostprocessing = 0; 77 | }; 78 | /* End PBXHeadersBuildPhase section */ 79 | 80 | /* Begin PBXNativeTarget section */ 81 | 134B308D1F822DA60040885A /* UIScreenExtension */ = { 82 | isa = PBXNativeTarget; 83 | buildConfigurationList = 134B30961F822DA60040885A /* Build configuration list for PBXNativeTarget "UIScreenExtension" */; 84 | buildPhases = ( 85 | 134B30891F822DA60040885A /* Sources */, 86 | 134B308A1F822DA60040885A /* Frameworks */, 87 | 134B308B1F822DA60040885A /* Headers */, 88 | 134B308C1F822DA60040885A /* Resources */, 89 | ); 90 | buildRules = ( 91 | ); 92 | dependencies = ( 93 | ); 94 | name = UIScreenExtension; 95 | productName = UIScreenExtension; 96 | productReference = 134B308E1F822DA60040885A /* UIScreenExtension.framework */; 97 | productType = "com.apple.product-type.framework"; 98 | }; 99 | /* End PBXNativeTarget section */ 100 | 101 | /* Begin PBXProject section */ 102 | 134B30851F822DA60040885A /* Project object */ = { 103 | isa = PBXProject; 104 | attributes = { 105 | LastUpgradeCheck = 1000; 106 | ORGANIZATIONNAME = marchv; 107 | TargetAttributes = { 108 | 134B308D1F822DA60040885A = { 109 | CreatedOnToolsVersion = 9.0; 110 | LastSwiftMigration = 0900; 111 | ProvisioningStyle = Automatic; 112 | }; 113 | }; 114 | }; 115 | buildConfigurationList = 134B30881F822DA60040885A /* Build configuration list for PBXProject "UIScreenExtension" */; 116 | compatibilityVersion = "Xcode 8.0"; 117 | developmentRegion = en; 118 | hasScannedForEncodings = 0; 119 | knownRegions = ( 120 | en, 121 | ); 122 | mainGroup = 134B30841F822DA60040885A; 123 | productRefGroup = 134B308F1F822DA60040885A /* Products */; 124 | projectDirPath = ""; 125 | projectRoot = ""; 126 | targets = ( 127 | 134B308D1F822DA60040885A /* UIScreenExtension */, 128 | ); 129 | }; 130 | /* End PBXProject section */ 131 | 132 | /* Begin PBXResourcesBuildPhase section */ 133 | 134B308C1F822DA60040885A /* Resources */ = { 134 | isa = PBXResourcesBuildPhase; 135 | buildActionMask = 2147483647; 136 | files = ( 137 | 1391811A1F825CEA009C354A /* UIScreenExtension.podspec in Resources */, 138 | 139181181F8255A2009C354A /* README.md in Resources */, 139 | ); 140 | runOnlyForDeploymentPostprocessing = 0; 141 | }; 142 | /* End PBXResourcesBuildPhase section */ 143 | 144 | /* Begin PBXSourcesBuildPhase section */ 145 | 134B30891F822DA60040885A /* Sources */ = { 146 | isa = PBXSourcesBuildPhase; 147 | buildActionMask = 2147483647; 148 | files = ( 149 | 134B309A1F822DC20040885A /* UIScreenExtension.swift in Sources */, 150 | 9AA14A7B266B79A300ED55F2 /* SimulatorDeviceInfoView.swift in Sources */, 151 | ); 152 | runOnlyForDeploymentPostprocessing = 0; 153 | }; 154 | /* End PBXSourcesBuildPhase section */ 155 | 156 | /* Begin XCBuildConfiguration section */ 157 | 134B30941F822DA60040885A /* Debug */ = { 158 | isa = XCBuildConfiguration; 159 | buildSettings = { 160 | ALWAYS_SEARCH_USER_PATHS = NO; 161 | CLANG_ANALYZER_NONNULL = YES; 162 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 163 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 164 | CLANG_CXX_LIBRARY = "libc++"; 165 | CLANG_ENABLE_MODULES = YES; 166 | CLANG_ENABLE_OBJC_ARC = YES; 167 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 168 | CLANG_WARN_BOOL_CONVERSION = YES; 169 | CLANG_WARN_COMMA = YES; 170 | CLANG_WARN_CONSTANT_CONVERSION = YES; 171 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 172 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 173 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 174 | CLANG_WARN_EMPTY_BODY = YES; 175 | CLANG_WARN_ENUM_CONVERSION = YES; 176 | CLANG_WARN_INFINITE_RECURSION = YES; 177 | CLANG_WARN_INT_CONVERSION = YES; 178 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 179 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 180 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 181 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 182 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 183 | CLANG_WARN_STRICT_PROTOTYPES = YES; 184 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 185 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 186 | CLANG_WARN_UNREACHABLE_CODE = YES; 187 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 188 | CODE_SIGN_IDENTITY = "iPhone Developer"; 189 | COPY_PHASE_STRIP = NO; 190 | CURRENT_PROJECT_VERSION = 1; 191 | DEBUG_INFORMATION_FORMAT = dwarf; 192 | ENABLE_STRICT_OBJC_MSGSEND = YES; 193 | ENABLE_TESTABILITY = YES; 194 | GCC_C_LANGUAGE_STANDARD = gnu11; 195 | GCC_DYNAMIC_NO_PIC = NO; 196 | GCC_NO_COMMON_BLOCKS = YES; 197 | GCC_OPTIMIZATION_LEVEL = 0; 198 | GCC_PREPROCESSOR_DEFINITIONS = ( 199 | "DEBUG=1", 200 | "$(inherited)", 201 | ); 202 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 203 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 204 | GCC_WARN_UNDECLARED_SELECTOR = YES; 205 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 206 | GCC_WARN_UNUSED_FUNCTION = YES; 207 | GCC_WARN_UNUSED_VARIABLE = YES; 208 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 209 | MTL_ENABLE_DEBUG_INFO = YES; 210 | ONLY_ACTIVE_ARCH = YES; 211 | SDKROOT = iphoneos; 212 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 213 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 214 | VERSIONING_SYSTEM = "apple-generic"; 215 | VERSION_INFO_PREFIX = ""; 216 | }; 217 | name = Debug; 218 | }; 219 | 134B30951F822DA60040885A /* Release */ = { 220 | isa = XCBuildConfiguration; 221 | buildSettings = { 222 | ALWAYS_SEARCH_USER_PATHS = NO; 223 | CLANG_ANALYZER_NONNULL = YES; 224 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 225 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 226 | CLANG_CXX_LIBRARY = "libc++"; 227 | CLANG_ENABLE_MODULES = YES; 228 | CLANG_ENABLE_OBJC_ARC = YES; 229 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 230 | CLANG_WARN_BOOL_CONVERSION = YES; 231 | CLANG_WARN_COMMA = YES; 232 | CLANG_WARN_CONSTANT_CONVERSION = YES; 233 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 234 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 235 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 236 | CLANG_WARN_EMPTY_BODY = YES; 237 | CLANG_WARN_ENUM_CONVERSION = YES; 238 | CLANG_WARN_INFINITE_RECURSION = YES; 239 | CLANG_WARN_INT_CONVERSION = YES; 240 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 241 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 242 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 243 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 244 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 245 | CLANG_WARN_STRICT_PROTOTYPES = YES; 246 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 247 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 248 | CLANG_WARN_UNREACHABLE_CODE = YES; 249 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 250 | CODE_SIGN_IDENTITY = "iPhone Developer"; 251 | COPY_PHASE_STRIP = NO; 252 | CURRENT_PROJECT_VERSION = 1; 253 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 254 | ENABLE_NS_ASSERTIONS = NO; 255 | ENABLE_STRICT_OBJC_MSGSEND = YES; 256 | GCC_C_LANGUAGE_STANDARD = gnu11; 257 | GCC_NO_COMMON_BLOCKS = YES; 258 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 259 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 260 | GCC_WARN_UNDECLARED_SELECTOR = YES; 261 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 262 | GCC_WARN_UNUSED_FUNCTION = YES; 263 | GCC_WARN_UNUSED_VARIABLE = YES; 264 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 265 | MTL_ENABLE_DEBUG_INFO = NO; 266 | SDKROOT = iphoneos; 267 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 268 | VALIDATE_PRODUCT = YES; 269 | VERSIONING_SYSTEM = "apple-generic"; 270 | VERSION_INFO_PREFIX = ""; 271 | }; 272 | name = Release; 273 | }; 274 | 134B30971F822DA60040885A /* Debug */ = { 275 | isa = XCBuildConfiguration; 276 | buildSettings = { 277 | CLANG_ENABLE_MODULES = YES; 278 | CODE_SIGN_IDENTITY = ""; 279 | CODE_SIGN_STYLE = Automatic; 280 | DEFINES_MODULE = YES; 281 | DYLIB_COMPATIBILITY_VERSION = 1; 282 | DYLIB_CURRENT_VERSION = 1; 283 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 284 | INFOPLIST_FILE = UIScreenExtension/Info.plist; 285 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 286 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 287 | PRODUCT_BUNDLE_IDENTIFIER = com.marchv.UIScreenExtension; 288 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 289 | SKIP_INSTALL = YES; 290 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 291 | SWIFT_VERSION = 4.2; 292 | TARGETED_DEVICE_FAMILY = "1,2"; 293 | }; 294 | name = Debug; 295 | }; 296 | 134B30981F822DA60040885A /* Release */ = { 297 | isa = XCBuildConfiguration; 298 | buildSettings = { 299 | CLANG_ENABLE_MODULES = YES; 300 | CODE_SIGN_IDENTITY = ""; 301 | CODE_SIGN_STYLE = Automatic; 302 | DEFINES_MODULE = YES; 303 | DYLIB_COMPATIBILITY_VERSION = 1; 304 | DYLIB_CURRENT_VERSION = 1; 305 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 306 | INFOPLIST_FILE = UIScreenExtension/Info.plist; 307 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 308 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 309 | PRODUCT_BUNDLE_IDENTIFIER = com.marchv.UIScreenExtension; 310 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 311 | SKIP_INSTALL = YES; 312 | SWIFT_VERSION = 4.2; 313 | TARGETED_DEVICE_FAMILY = "1,2"; 314 | }; 315 | name = Release; 316 | }; 317 | /* End XCBuildConfiguration section */ 318 | 319 | /* Begin XCConfigurationList section */ 320 | 134B30881F822DA60040885A /* Build configuration list for PBXProject "UIScreenExtension" */ = { 321 | isa = XCConfigurationList; 322 | buildConfigurations = ( 323 | 134B30941F822DA60040885A /* Debug */, 324 | 134B30951F822DA60040885A /* Release */, 325 | ); 326 | defaultConfigurationIsVisible = 0; 327 | defaultConfigurationName = Release; 328 | }; 329 | 134B30961F822DA60040885A /* Build configuration list for PBXNativeTarget "UIScreenExtension" */ = { 330 | isa = XCConfigurationList; 331 | buildConfigurations = ( 332 | 134B30971F822DA60040885A /* Debug */, 333 | 134B30981F822DA60040885A /* Release */, 334 | ); 335 | defaultConfigurationIsVisible = 0; 336 | defaultConfigurationName = Release; 337 | }; 338 | /* End XCConfigurationList section */ 339 | }; 340 | rootObject = 134B30851F822DA60040885A /* Project object */; 341 | } 342 | -------------------------------------------------------------------------------- /UIScreenExtension.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /UIScreenExtension.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /UIScreenExtension/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | NSPrincipalClass 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /UIScreenExtension/SimulatorDeviceInfoView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SimulatorDeviceInfoView.swift 3 | // UIScreenExtension 4 | // 5 | // Created by Tristan Warner-Smith on 05/06/2021. 6 | // Copyright © 2021 marchv. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | 11 | struct SimulatorDeviceInfoView: View { 12 | 13 | @available(iOS 13.0, *) 14 | var body: some View { 15 | Text("Model identifier: ") + Text("\(UIDevice.modelIdentifier)").bold() 16 | } 17 | } 18 | 19 | struct SimulatorDeviceInfoView_Previews: PreviewProvider { 20 | @available(iOS 13.0, *) 21 | static var previews: some View { 22 | SimulatorDeviceInfoView() 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /UIScreenExtension/UIScreenExtension.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIScreenExtension.h 3 | // UIScreenExtension 4 | // 5 | // Created by Jens Schwarzer on 02/10/2017. 6 | // Copyright © 2017 marchv. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for UIScreenExtension. 12 | FOUNDATION_EXPORT double UIScreenExtensionVersionNumber; 13 | 14 | //! Project version string for UIScreenExtension. 15 | FOUNDATION_EXPORT const unsigned char UIScreenExtensionVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | --------------------------------------------------------------------------------