diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..aa49684 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,90 @@ +name: CI + +on: + push: + branches: [ master, main ] + pull_request: + branches: [ master, main ] + +jobs: + build-ios: + name: Build iOS + runs-on: macos-15 + steps: + - uses: actions/checkout@v4 + + - name: Build iOS Framework + run: | + xcodebuild build \ + -scheme SDiOSVersion \ + -destination 'platform=iOS Simulator,name=iPhone 16,OS=latest' \ + -project SDVersion-Demo/SDVersion.xcodeproj \ + CODE_SIGN_IDENTITY="" \ + CODE_SIGNING_REQUIRED=NO \ + | xcpretty || true + + build-macos: + name: Build macOS + runs-on: macos-15 + steps: + - uses: actions/checkout@v4 + + - name: Build macOS Framework + run: | + xcodebuild build \ + -scheme SDMacVersion \ + -destination 'platform=macOS' \ + -project SDVersion-Demo/SDVersion.xcodeproj \ + CODE_SIGN_IDENTITY="" \ + CODE_SIGNING_REQUIRED=NO \ + | xcpretty || true + + build-tvos: + name: Build tvOS + runs-on: macos-15 + steps: + - uses: actions/checkout@v4 + + - name: Build tvOS Framework + run: | + xcodebuild build \ + -scheme SDtvOSVersion \ + -destination 'platform=tvOS Simulator,name=Apple TV,OS=latest' \ + -project SDVersion-Demo/SDVersion.xcodeproj \ + CODE_SIGN_IDENTITY="" \ + CODE_SIGNING_REQUIRED=NO \ + | xcpretty || true + + build-watchos: + name: Build watchOS + runs-on: macos-15 + steps: + - uses: actions/checkout@v4 + + - name: Build watchOS Framework + run: | + xcodebuild build \ + -scheme SDwatchOSVersion \ + -destination 'platform=watchOS Simulator,name=Apple Watch Series 10 (46mm),OS=latest' \ + -project SDVersion-Demo/SDVersion.xcodeproj \ + CODE_SIGN_IDENTITY="" \ + CODE_SIGNING_REQUIRED=NO \ + | xcpretty || true + + build-spm: + name: Build Swift Package + runs-on: macos-15 + steps: + - uses: actions/checkout@v4 + + - name: Build Package (macOS) + run: swift build --target SDMacVersion + + pod-lint: + name: CocoaPods Lint + runs-on: macos-15 + steps: + - uses: actions/checkout@v4 + + - name: Lint Podspec + run: pod lib lint --allow-warnings diff --git a/.gitignore b/.gitignore index 44f6561..60e46a2 100755 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,4 @@ # Xcode -# build/ *.pbxuser !default.pbxuser @@ -9,22 +8,48 @@ build/ !default.mode2v3 *.perspectivev3 !default.perspectivev3 -xcuserdata +xcuserdata/ *.xccheckout *.moved-aside -DerivedData +DerivedData/ *.hmap *.ipa *.xcuserstate +*.xcscmblueprint + +# macOS .DS_Store +.AppleDouble +.LSOverride +._* + +# Swift Package Manager +.build/ +.swiftpm/ +Package.resolved +SourcePackages/ # CocoaPods -# -# We recommend against adding the Pods directory to your .gitignore. However -# you should judge for yourself, the pros and cons are mentioned at: -# http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control? -# -# Pods/ +Pods/ +*.xcworkspace + +# Carthage +Carthage/Build/ +Carthage/Checkouts/ + +# fastlane +fastlane/report.xml +fastlane/Preview.html +fastlane/screenshots/**/*.png +fastlane/test_output/ +# Code Injection +iOSInjectionProject/ +# Playgrounds +timeline.xctimeline +playground.xcworkspace +# Accio dependency management +Dependencies/ +.accio/ diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..05450d1 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,84 @@ +# Changelog + +All notable changes to SDVersion will be documented in this file. + +## [5.0.0] - 2025-01-01 + +### Breaking Changes +- **Minimum deployment targets updated:** + - iOS: 7.0 -> 13.0 + - macOS: 10.9 -> 11.0 + - watchOS: 2.0 -> 6.0 + - tvOS: 9.0 -> 13.0 +- Device enum values have been reorganized with new integer assignments +- Some legacy device enum names have been updated for consistency + +### Added + +#### iOS Devices +- iPhone XS, XS Max, XR (2018) +- iPhone 11, 11 Pro, 11 Pro Max (2019) +- iPhone SE (2nd generation), iPhone 12 mini/12/12 Pro/12 Pro Max (2020) +- iPhone 13 mini/13/13 Pro/13 Pro Max (2021) +- iPhone SE (3rd generation), iPhone 14/14 Plus/14 Pro/14 Pro Max (2022) +- iPhone 15/15 Plus/15 Pro/15 Pro Max (2023) +- iPhone 16/16 Plus/16 Pro/16 Pro Max (2024) +- iPhone 16e (2025) + +#### iPad Devices +- iPad (6th-10th generation) +- iPad Pro 11-inch (1st-4th generation) +- iPad Pro 12.9-inch (3rd-6th generation) +- iPad Pro 11-inch M4, iPad Pro 13-inch M4 (2024) +- iPad Air (3rd-5th generation) +- iPad Air 11-inch M2, iPad Air 13-inch M2 (2024) +- iPad mini (5th-7th generation) + +#### iPod Devices +- iPod touch (7th generation) + +#### Apple Watch Models +- Apple Watch Series 4, 5, 6, 7, 8, 9, 10 +- Apple Watch SE (1st and 2nd generation) +- Apple Watch Ultra, Ultra 2 +- New screen sizes: 40mm, 41mm, 44mm, 45mm, 46mm, 49mm + +#### Apple TV Models +- Apple TV 4K (2nd generation) +- Apple TV 4K (3rd generation) + +#### Mac Models +- Mac Studio (M1 Max, M1 Ultra, M2 Max, M2 Ultra) +- Mac Pro (M2 Ultra) +- iMac 24-inch (M1, M3, M4) +- Mac mini (M1, M2, M2 Pro, M4, M4 Pro) +- MacBook Air (M1, M2, M3) +- MacBook Pro 13-inch (M1, M2) +- MacBook Pro 14-inch (M1 Pro/Max, M2 Pro/Max, M3/Pro/Max, M4/Pro/Max) +- MacBook Pro 16-inch (M1 Pro/Max, M2 Pro/Max, M3 Pro/Max, M4 Pro/Max) + +#### New Screen Sizes +- iPhone: 5.4", 6.1", 6.3", 6.5", 6.7", 6.9" +- Apple Watch: 40mm, 41mm, 44mm, 45mm, 46mm, 49mm +- Mac: 14", 16" + +#### New macOS Features +- `isAppleSilicon` - Check if running on Apple Silicon +- `chipType` - Get the specific chip (M1, M1 Pro, M2, etc.) +- `chipName` - Get human-readable chip name +- `DeviceVersionMacStudio` - New device type for Mac Studio +- `ChipType` enum for all Apple Silicon variants + +### Infrastructure +- Added Swift Package Manager support (`Package.swift`) +- Added Privacy Manifest (`PrivacyInfo.xcprivacy`) for App Store compliance +- Added GitHub Actions CI/CD workflow +- Updated `.gitignore` for modern Xcode and SPM +- Added `CONTRIBUTING.md` with guidelines for adding new devices + +### Fixed +- Apple Silicon simulator detection (arm64) +- Screen size detection for notched and Dynamic Island iPhones + +## [4.3.2] - Previous Release +- Last release before 5.0.0 modernization diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..c3ed777 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,73 @@ +# Contributing to SDVersion + +Thank you for your interest in contributing to SDVersion! This document provides guidelines for contributing. + +## Adding New Device Support + +When Apple releases new devices, SDVersion needs to be updated. Here's how: + +### Finding Device Identifiers + +Device identifiers (machine IDs) can be found from these sources: +- [The Apple Wiki - Models](https://theapplewiki.com/wiki/Models) +- [EveryMac](https://everymac.com) +- [AppleDB](https://appledb.dev) +- [adamawolf's gist](https://gist.github.com/adamawolf/3048717) + +### Adding a New iPhone/iPad + +1. **Update `SDiOSVersion.h`:** + - Add a new enum value in the appropriate year section + - Use the next available integer value in that section + +2. **Update `SDiOSVersion.m`:** + - Add the device identifier mapping in `deviceNamesByCode` + - Add the display name in `deviceNameForVersion:` + +3. **Update screen size detection if needed:** + - If the device has a new screen resolution, update `resolutionSize` + +### Adding a New Apple Watch + +1. **Update `SDwatchOSVersion.h`:** + - Add enum values for each size variant + +2. **Update `SDwatchOSVersion.m`:** + - Add identifier mappings + - Update display names + - Update screen size detection if new sizes are introduced + +### Adding a New Mac + +1. **Update `SDMacVersion.h`:** + - Add new ChipType if applicable (M5, etc.) + +2. **Update `SDMacVersion.m`:** + - Add model detection in `deviceInformationForModel:` + - Map to appropriate device version and chip type + +## Code Style + +- Follow existing Objective-C conventions in the codebase +- Use 4-space indentation +- Keep device mappings alphabetically organized by identifier +- Group devices by year in comments + +## Testing + +Before submitting a PR: +1. Ensure the project builds on all platforms (iOS, macOS, watchOS, tvOS) +2. Test with the simulator for new devices if available +3. Run `pod lib lint` to validate the podspec + +## Pull Request Process + +1. Fork the repository +2. Create a feature branch (`git checkout -b feature/add-iphone-17`) +3. Commit your changes with clear messages +4. Update the CHANGELOG.md +5. Submit a pull request + +## Questions? + +Open an issue for discussion before making large changes. diff --git a/Package.swift b/Package.swift new file mode 100644 index 0000000..182034f --- /dev/null +++ b/Package.swift @@ -0,0 +1,63 @@ +// swift-tools-version:5.9 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +let package = Package( + name: "SDVersion", + platforms: [ + .iOS(.v13), + .macOS(.v11), + .tvOS(.v13), + .watchOS(.v6) + ], + products: [ + // Platform-specific libraries - use the one matching your target platform + .library( + name: "SDiOSVersion", + targets: ["SDiOSVersion"] + ), + .library( + name: "SDMacVersion", + targets: ["SDMacVersion"] + ), + .library( + name: "SDwatchOSVersion", + targets: ["SDwatchOSVersion"] + ), + .library( + name: "SDtvOSVersion", + targets: ["SDtvOSVersion"] + ) + ], + targets: [ + .target( + name: "SDiOSVersion", + dependencies: [], + path: "SDVersion/SDiOSVersion", + resources: [.process("../PrivacyInfo.xcprivacy")], + publicHeadersPath: "." + ), + .target( + name: "SDMacVersion", + dependencies: [], + path: "SDVersion/SDMacVersion", + resources: [.process("../PrivacyInfo.xcprivacy")], + publicHeadersPath: "." + ), + .target( + name: "SDwatchOSVersion", + dependencies: [], + path: "SDVersion/SDwatchOSVersion", + resources: [.process("../PrivacyInfo.xcprivacy")], + publicHeadersPath: "." + ), + .target( + name: "SDtvOSVersion", + dependencies: [], + path: "SDVersion/SDtvOSVersion", + resources: [.process("../PrivacyInfo.xcprivacy")], + publicHeadersPath: "." + ) + ] +) diff --git a/README.md b/README.md index a38a2ac..2a05194 100755 --- a/README.md +++ b/README.md @@ -1,345 +1,284 @@ -

- SDVersion -

- -

- - Gitter - - - Platform - - - Cocoapods Version - -

+# SDVersion + +[![CI](https://github.com/sebyddd/SDVersion/actions/workflows/ci.yml/badge.svg)](https://github.com/sebyddd/SDVersion/actions/workflows/ci.yml) +[![CocoaPods](https://img.shields.io/cocoapods/v/SDVersion.svg)](https://cocoapods.org/pods/SDVersion) +[![SPM](https://img.shields.io/badge/SPM-compatible-brightgreen.svg)](https://swift.org/package-manager/) +[![Platform](https://img.shields.io/badge/platform-iOS%20%7C%20watchOS%20%7C%20tvOS%20%7C%20macOS-D0547F.svg)](https://github.com/sebyddd/SDVersion) +[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) Lightweight Cocoa library for detecting the running device's model and screen size. -With the newer  devices, developers have more work to do. This library simplifies their job by allowing them to get information about the running device and easily target the ones they want. +SDVersion supports **iOS**, **iPadOS**, **watchOS**, **tvOS**, and **macOS** - including all devices from iPhone 4 through iPhone 16, Apple Watch through Series 10 and Ultra 2, Apple TV through 4K 3rd generation, and all Mac models including Apple Silicon (M1 through M4). -SDVersion supports iOS, watchOS, tvOS, and macOS. Browse through the implementation of each platform using the links below. +## Requirements -

- - iOS - - - Mac - -

+- iOS 13.0+ / macOS 11.0+ / watchOS 6.0+ / tvOS 13.0+ +- Xcode 15.0+ -## How it works +## Installation -```objective-c - // Check for device model - if ([SDVersion deviceVersion] == iPhone7) - NSLog(@"You got the iPhone 7. Sweet 🍭!"); - else if ([SDVersion deviceVersion] == iPhone6SPlus) - NSLog(@"iPhone 6S Plus? Bigger is better!"); - else if ([SDVersion deviceVersion] == iPadAir2) - NSLog(@"You own an iPad Air 2 🌀!"); - - // Check for device screen size - if ([SDVersion deviceSize] == Screen4Dot7inch) - NSLog(@"Your screen is 4.7 inches"); - - // Check if screen is in zoom mode - if ([SDVersion isZoomed]) - NSLog(@"Your device is in Zoom Mode 🔎"); - - // Get device name - NSLog(@"%@", [SDVersion deviceNameString]); - /* e.g: Outputs 'iPhone 7 Plus' */ - - // Check for iOS Version - if ([SDVersion versionGreaterThanOrEqualTo:@"10"]) - NSLog(@"You are running iOS 10 or above!"); -``` +### Swift Package Manager (Recommended) -

- - SDVersion Swift
-
-Swift Version: -

- +Add SDVersion to your `Package.swift`: ```swift - // Check for device model - if SDiOSVersion.deviceVersion() == .iPhone7 { - print("You got the iPhone 7. Sweet 🍭!") - } - - // Check for device screen size - if SDiOSVersion.deviceSize() == .Screen3Dot5inch { - print("Still on 3.5 inches!? 😮") - } - - // Get device name - print(SDiOSVersion.deviceNameString()) - /* e.g: Outputs 'iPhone 7 Plus' */ - - // Check for iOS Version - if SDiOSVersion.versionGreaterThan("10") { - print("You are running iOS 10 or above!") - } +dependencies: [ + .package(url: "https://github.com/sebyddd/SDVersion.git", from: "5.0.0") +], +targets: [ + .target(name: "YourApp", dependencies: [ + .product(name: "SDiOSVersion", package: "SDVersion") // or SDMacVersion, SDwatchOSVersion, SDtvOSVersion + ]) +] ``` -## Add to your project +Or in Xcode: File > Add Package Dependencies > Enter the repository URL, then select the appropriate library for your platform. -There are 2 ways you can add SDVersion to your project: +### CocoaPods -### Manual installation +```ruby +pod 'SDVersion', '~> 5.0' +``` +### Manual - Simply import the 'SDVersion' into your project then import the following in the class you want to use it: - ```objective-c - #import "SDVersion.h" - ``` - In Swift, you need to import in the bridging header the specific library version, not the library wrapper: - ```objective-c - #import "SDiOSVersion.h" // Or SDMacVersion.h - ``` +Copy the `SDVersion` folder into your project. -### Installation with CocoaPods +## Usage -CocoaPods is a dependency manager for Objective-C, which automates and simplifies the process of using 3rd-party libraries like SDVersion in your projects. See the "[Getting Started](http://guides.cocoapods.org/syntax/podfile.html)" guide for more information. +### iOS / iPadOS -### Podfile -```ruby - pod 'SDVersion' +```objective-c +#import "SDVersion.h" + +// Check for device model +if ([SDVersion deviceVersion] == iPhone16Pro) { + NSLog(@"You have an iPhone 16 Pro!"); +} else if ([SDVersion deviceVersion] == iPadPro13InchM4) { + NSLog(@"Nice iPad Pro with M4!"); +} + +// Check for device screen size +if ([SDVersion deviceSize] == Screen6Dot7inch) { + NSLog(@"You have a 6.7 inch display"); +} + +// Check if screen is in zoom mode +if ([SDVersion isZoomed]) { + NSLog(@"Device is in Zoom Mode"); +} + +// Get device name +NSLog(@"%@", [SDVersion deviceNameString]); +// e.g: "iPhone 16 Pro Max" + +// Check iOS version +if ([SDVersion versionGreaterThanOrEqualTo:@"18"]) { + NSLog(@"Running iOS 18 or later"); +} ``` +**Swift:** -## iOS +```swift +import SDiOSVersion -### Available methods -```objective-c - + (DeviceVersion)deviceVersion; - + (NSString *)deviceNameForVersion:(DeviceVersion)deviceVersion; - + (DeviceSize)resolutionSize; - + (DeviceSize)deviceSize; - + (NSString *)deviceSizeName:(DeviceSize)deviceSize; - + (NSString *)deviceNameString; - + (BOOL)isZoomed; +// Check for device model +if SDiOSVersion.deviceVersion() == .iPhone16Pro { + print("You have an iPhone 16 Pro!") +} + +// Check for device screen size +if SDiOSVersion.deviceSize() == .Screen6Dot7inch { + print("You have a 6.7 inch display") +} + +// Get device name +print(SDiOSVersion.deviceNameString()) ``` -### Targetable models - iPhone4 - iPhone4S - iPhone5 - iPhone5C - iPhone5S - iPhone6 - iPhone6Plus - iPhone6S - iPhone6SPlus - iPhoneSE - iPhone7 - iPhone7Plus - - iPad1 - iPad2 - iPadMini - iPad3 - iPad4 - iPadAir - iPadMini2 - iPadAir2 - iPadMini3 - iPadMini4 - iPadPro9Dot7Inch - iPadPro12Dot9Inch - iPad5 - - iPodTouch1Gen - iPodTouch2Gen - iPodTouch3Gen - iPodTouch4Gen - iPodTouch5Gen - iPodTouch6Gen - - Simulator -### Targetable screen sizes - Screen3Dot5inch - Screen4inch - Screen4Dot7inch - Screen5Dot5inch -### Available iOS Version Finder methods - ```objective-c - + (BOOL)versionEqualTo:(NSString *)version; - + (BOOL)versionGreaterThan:(NSString *)version; - + (BOOL)versionGreaterThanOrEqualTo:(NSString *)version; - + (BOOL)versionLessThan:(NSString *)version; - + (BOOL)versionLessThanOrEqualTo:(NSString *)version; - ``` - -### Helpers -```objective-c - NSLog(@"%@", [SDVersion deviceVersionName:[SDVersion deviceVersion]]); - /* e.g: Outputs 'iPad Air 2' */ - NSLog(@"%@", [SDVersion deviceSizeName:[SDVersion deviceSize]]); - /* e.g: Outputs '4.7 inch' */ +#### Supported iPhone Models + ``` -Or in Swift: -```swift - let deviceVersionName = SDiOSVersion.deviceVersionName(SDiOSVersion.deviceVersion()) - let deviceSizeName = SDiOSVersion.deviceSizeName(SDiOSVersion.deviceSize()) +iPhone4, iPhone4S, iPhone5, iPhone5C, iPhone5S +iPhone6, iPhone6Plus, iPhone6S, iPhone6SPlus, iPhoneSE +iPhone7, iPhone7Plus, iPhone8, iPhone8Plus, iPhoneX +iPhoneXS, iPhoneXSMax, iPhoneXR +iPhone11, iPhone11Pro, iPhone11ProMax +iPhoneSE2, iPhone12Mini, iPhone12, iPhone12Pro, iPhone12ProMax +iPhone13Mini, iPhone13, iPhone13Pro, iPhone13ProMax +iPhoneSE3, iPhone14, iPhone14Plus, iPhone14Pro, iPhone14ProMax +iPhone15, iPhone15Plus, iPhone15Pro, iPhone15ProMax +iPhone16, iPhone16Plus, iPhone16Pro, iPhone16ProMax +iPhone16e ``` -## watchOS +#### Supported iPad Models -### Available methods -```objective-c - + (DeviceVersion)deviceVersion; - + (DeviceSize)deviceSize; - + (NSString *)deviceName; ``` -### Targetable models - Apple Watch 38mm - Apple Watch 42mm - Apple Watch 38mm Series 1 - Apple Watch 42mm Series 1 - Apple Watch 38mm Series 2 - Apple Watch 42mm Series 2 +iPad1 - iPad10, iPadMini - iPadMini7 +iPadAir - iPadAir5, iPadAir11InchM2, iPadAir13InchM2 +iPadPro9Dot7Inch, iPadPro10Dot5Inch, iPadPro11Inch - iPadPro11Inch4Gen +iPadPro12Dot9Inch - iPadPro12Dot9Inch6Gen +iPadPro11InchM4, iPadPro13InchM4 +``` - Simulator +#### Supported Screen Sizes -### Targetable screen sizes - Screen38mm - Screen42mm +``` +Screen3Dot5inch, Screen4inch, Screen4Dot7inch +Screen5Dot4inch, Screen5Dot5inch, Screen5Dot8inch +Screen6Dot1inch, Screen6Dot3inch, Screen6Dot5inch +Screen6Dot7inch, Screen6Dot9inch +``` + +### watchOS -### Available watchOS Version Finder methods -```objective-c - + (BOOL)versionEqualTo:(NSString *)version; - + (BOOL)versionGreaterThan:(NSString *)version; - + (BOOL)versionGreaterThanOrEqualTo:(NSString *)version; - + (BOOL)versionLessThan:(NSString *)version; - + (BOOL)versionLessThanOrEqualTo:(NSString *)version; -``` - -### Helpers ```objective-c - NSLog(@"%@", [SDVersion deviceVersionName:[SDVersion deviceVersion]]); - /* e.g: Outputs 'Apple Watch 42mm' */ +#import "SDwatchOSVersion.h" - NSLog(@"%@", [SDVersion deviceSizeName:[SDVersion deviceSize]]); - /* e.g: Outputs '42mm' */ +if ([SDwatchOSVersion deviceVersion] == AppleWatch46mmSeries10) { + NSLog(@"Apple Watch Series 10!"); +} + +if ([SDwatchOSVersion deviceSize] == Screen49mm) { + NSLog(@"Apple Watch Ultra size"); +} ``` -## tvOS +#### Supported Watch Models -### Available methods -```objective-c - + (DeviceVersion)deviceVersion; - + (NSString *)deviceName; ``` -### Targetable models - Apple TV (4th Generation) +AppleWatch38mm, AppleWatch42mm (Original) +Series 1-3: 38mm/42mm variants +Series 4-6: 40mm/44mm variants +Series 7-9: 41mm/45mm variants +Series 10: 42mm/46mm variants +Apple Watch SE (1st & 2nd gen): 40mm/44mm +Apple Watch Ultra, Ultra 2: 49mm +``` - Simulator +### tvOS -### Available tvOS Version Finder methods ```objective-c - + (BOOL)versionEqualTo:(NSString *)version; - + (BOOL)versionGreaterThan:(NSString *)version; - + (BOOL)versionGreaterThanOrEqualTo:(NSString *)version; - + (BOOL)versionLessThan:(NSString *)version; - + (BOOL)versionLessThanOrEqualTo:(NSString *)version; -``` - -### Helpers -```objective-c - NSLog(@"%@", [SDVersion deviceVersionName:[SDVersion deviceVersion]]); - /* e.g: Outputs 'Apple TV (4th Generation)' */ +#import "SDtvOSVersion.h" + +if ([SDtvOSVersion deviceVersion] == AppleTV4K3rdGen) { + NSLog(@"Apple TV 4K 3rd Generation"); +} ``` -## Mac OS -```objective-c - // Check for device model - if ([SDVersion deviceVersion] == DeviceVersionIMac) - NSLog(@"So you have a iMac? 💻"); - else if ([SDVersion deviceVersion] == DeviceVersionMacBookPro) - NSLog(@"You're using a MacBook Pro."); - - // Check for screen size - if ([SDVersion deviceSize] == Mac27Inch) - NSLog(@"Whoah! You got a big ass 27 inch screen."); - else if ([SDVersion deviceSize] == Mac21Dot5Inch) - NSLog(@"You have a 21.5 inch screen."); - - // Check for screen resolution - if ([SDVersion deviceScreenResolution] == DeviceScreenRetina) - NSLog(@"Nice retina screen!"); - - // Get screen resolution in pixels - NSLog(@"%@", [SDVersion deviceScreenResolutionName:[SDVersion deviceScreenResolution]]); - /* e.g: Outputs '{2880, 1800}' */ - - // Check OSX Version (pass the minor version) - if([SDVersion versionGreaterThanOrEqualTo:@"11"]) - NSLog(@"Looks like you are running OSX 10.11 El Capitan or 🆙."); +#### Supported Apple TV Models + +``` +AppleTVHD (4th generation) +AppleTV4K1stGen, AppleTV4K2ndGen, AppleTV4K3rdGen ``` -### Available methods +### macOS + ```objective-c - + (DeviceVersion)deviceVersion; - + (NSString *)deviceVersionString; - + (DeviceSize)deviceSize; - + (NSSize)deviceScreenResolutionPixelSize; - + (DeviceScreenResolution)deviceScreenResolution; +#import "SDMacVersion.h" + +// Check device type +if ([SDMacVersion deviceVersion] == DeviceVersionMacBookPro) { + NSLog(@"MacBook Pro"); +} + +// Check for Apple Silicon +if ([SDMacVersion isAppleSilicon]) { + NSLog(@"Running on Apple Silicon: %@", [SDMacVersion chipName]); + // e.g: "Apple M4 Pro" +} + +// Get chip type +if ([SDMacVersion chipType] == ChipTypeM4Max) { + NSLog(@"M4 Max chip!"); +} + +// Check screen size +if ([SDMacVersion deviceSize] == Mac16Inch) { + NSLog(@"16 inch display"); +} + +// Check for Retina +if ([SDMacVersion deviceScreenResolution] == DeviceScreenRetina) { + NSLog(@"Retina display"); +} +``` + +#### Supported Mac Models + +``` +DeviceVersionIMac, DeviceVersionMacMini, DeviceVersionMacPro +DeviceVersionMacBook, DeviceVersionMacBookAir, DeviceVersionMacBookPro +DeviceVersionMacStudio, DeviceVersionXserve +``` + +#### Supported Chip Types + +``` +ChipTypeIntel +ChipTypeM1, ChipTypeM1Pro, ChipTypeM1Max, ChipTypeM1Ultra +ChipTypeM2, ChipTypeM2Pro, ChipTypeM2Max, ChipTypeM2Ultra +ChipTypeM3, ChipTypeM3Pro, ChipTypeM3Max +ChipTypeM4, ChipTypeM4Pro, ChipTypeM4Max +``` + +#### Supported Screen Sizes + +``` +Mac11Inch, Mac12Inch, Mac13Inch, Mac14Inch +Mac15Inch, Mac16Inch, Mac17Inch +Mac20Inch, Mac21Dot5Inch, Mac24Inch, Mac27Inch ``` -### Targetable models - DeviceVersionIMac - DeviceVersionMacMini - DeviceVersionMacPro - DeviceVersionMacBook - DeviceVersionMacBookAir - DeviceVersionMacBookPro - DeviceVersionXserve - -### Targetable screen sizes - Mac27Inch - Mac24Inch - Mac21Dot5Inch - Mac20Inch - Mac17Inch - Mac15Inch - Mac13Inch - Mac12Inch - Mac11Inch - -### Targetable screen resolutions - DeviceScreenRetina, - DeviceScreenNoRetina - -### Available OSX Version Finder methods + +## API Reference + +### Common Methods (All Platforms) + ```objective-c - + (BOOL)versionEqualTo:(NSString *)version; - + (BOOL)versionGreaterThan:(NSString *)version; - + (BOOL)versionGreaterThanOrEqualTo:(NSString *)version; - + (BOOL)versionLessThan:(NSString *)version; - + (BOOL)versionLessThanOrEqualTo:(NSString *)version; - /* 'v' must be the minor OS Version. e.g: OSX 10.9 - 'v' is 9 */ ++ (DeviceVersion)deviceVersion; ++ (BOOL)versionEqualTo:(NSString *)version; ++ (BOOL)versionGreaterThan:(NSString *)version; ++ (BOOL)versionGreaterThanOrEqualTo:(NSString *)version; ++ (BOOL)versionLessThan:(NSString *)version; ++ (BOOL)versionLessThanOrEqualTo:(NSString *)version; ``` -### Helpers + +### iOS Specific + ```objective-c - NSLog(@"%@", [SDVersion deviceSizeName:[SDVersion deviceSize]]); - /* e.g: Outputs '15 inch' */ ++ (NSString *)deviceNameForVersion:(DeviceVersion)deviceVersion; ++ (DeviceSize)resolutionSize; ++ (DeviceSize)deviceSize; ++ (NSString *)deviceSizeName:(DeviceSize)deviceSize; ++ (NSString *)deviceNameString; ++ (BOOL)isZoomed; +``` + +### macOS Specific - NSLog(@"%@",[SDVersion deviceScreenResolutionName:[SDVersion deviceScreenResolution]]) - /* e.g: Outputs '{2880, 1800}' */ +```objective-c ++ (NSString *)deviceVersionString; ++ (DeviceSize)deviceSize; ++ (NSString *)deviceSizeName:(DeviceSize)deviceSize; ++ (NSSize)deviceScreenResolutionPixelSize; ++ (DeviceScreenResolution)deviceScreenResolution; ++ (NSString *)deviceScreenResolutionName:(DeviceScreenResolution)resolution; ++ (BOOL)isAppleSilicon; ++ (ChipType)chipType; ++ (NSString *)chipName; ``` -## Used by +## Privacy -

- Who uses SDVersion -

+SDVersion includes a Privacy Manifest (`PrivacyInfo.xcprivacy`) for App Store compliance. The library uses the `utsname` system call to detect device models, which does not require privacy declarations. + +## Contributing + +See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines on adding support for new devices. ## License -Usage is provided under the [MIT License](http://opensource.org/licenses/mit-license.php). See LICENSE for the full details. + +SDVersion is available under the MIT license. See the [LICENSE](LICENSE) file for more info. diff --git a/SDVersion.podspec b/SDVersion.podspec index 4902f0f..0c201bb 100755 --- a/SDVersion.podspec +++ b/SDVersion.podspec @@ -1,44 +1,35 @@ Pod::Spec.new do |s| - - # ――― Spec Metadata ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # - # - # These will help people to find your library, and whilst it - # can feel like a chore to fill in it's definitely to your advantage. The - # summary should be tweet-length, and the description more in depth. - # - s.name = "SDVersion" - s.version = "4.3.2" + s.version = "5.0.0" s.summary = "Lightweight Cocoa library for detecting the running device's model and screen size." + s.description = <<-DESC + SDVersion is a lightweight Cocoa library for detecting the running device's model, + screen size, and OS version. It supports iOS, iPadOS, watchOS, tvOS, and macOS, + including all devices from iPhone 4 through iPhone 16, iPad through iPad Pro M4, + Apple Watch through Series 10 and Ultra 2, Apple TV through 4K 3rd generation, + and all Mac models including Apple Silicon (M1 through M4). + DESC s.homepage = "https://github.com/sebyddd/SDVersion" - s.screenshots = "https://dl.dropboxusercontent.com/s/bmfjwfe2ngnivwn/sdversion.png?dl=0" + s.license = { :type => "MIT", :file => "LICENSE" } + s.author = { "Sebastian Dobrincu" => "me@dobrincu.co" } + s.ios.deployment_target = '13.0' + s.osx.deployment_target = '11.0' + s.watchos.deployment_target = '6.0' + s.tvos.deployment_target = '13.0' - # ――― Spec License ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # - # - # Licensing your code is important. See http://choosealicense.com for more info. - # CocoaPods will detect a license file if there is a named LICENSE* - # Popular ones are 'MIT', 'BSD' and 'Apache License, Version 2.0'. - # + s.source = { :git => 'https://github.com/sebyddd/SDVersion.git', :tag => "#{s.version}" } + s.source_files = "SDVersion/*.{h,m}" - s.license = "MIT (example)" - s.license = { :type => "MIT", :file => "LICENSE" } - s.author = { "Sebastian Dobrincu" => "me@dobrincu.co" } - s.platform = :ios - s.platform = :osx - s.platform = :watchos - s.platform = :tvos - s.ios.deployment_target = '7.0' - s.osx.deployment_target = '10.9' - s.watchos.deployment_target = '2.0' - s.tvos.deployment_target = '9.0' s.ios.source_files = "SDVersion/SDiOSVersion/*.{h,m}" s.osx.source_files = "SDVersion/SDMacVersion/*.{h,m}" s.watchos.source_files = "SDVersion/SDwatchOSVersion/*.{h,m}" s.tvos.source_files = "SDVersion/SDtvOSVersion/*.{h,m}" - s.source = { :git => 'https://github.com/sebyddd/SDVersion.git', :tag => "#{s.version}" } - s.source_files = "SDVersion/*.{h,m}" - s.requires_arc = true + s.resource_bundles = { + 'SDVersion_Privacy' => ['SDVersion/PrivacyInfo.xcprivacy'] + } + s.requires_arc = true + s.swift_versions = ['5.0'] end diff --git a/SDVersion/PrivacyInfo.xcprivacy b/SDVersion/PrivacyInfo.xcprivacy new file mode 100644 index 0000000..2009fb7 --- /dev/null +++ b/SDVersion/PrivacyInfo.xcprivacy @@ -0,0 +1,14 @@ + + + + + NSPrivacyTracking + + NSPrivacyTrackingDomains + + NSPrivacyCollectedDataTypes + + NSPrivacyAccessedAPITypes + + + diff --git a/SDVersion/SDMacVersion/SDMacVersion.h b/SDVersion/SDMacVersion/SDMacVersion.h index 07fadb0..4b52b5c 100755 --- a/SDVersion/SDMacVersion/SDMacVersion.h +++ b/SDVersion/SDMacVersion/SDMacVersion.h @@ -2,7 +2,7 @@ // SDMacVersion.h // SDMacVersion // -// Copyright (c) 2015 Sebastian Dobrincu & Tom Baranes. All rights reserved. +// Copyright (c) 2015-2025 Sebastian Dobrincu & Tom Baranes. All rights reserved. // #import @@ -15,7 +15,8 @@ typedef NS_ENUM(NSInteger, DeviceVersion) { DeviceVersionMacBook, DeviceVersionMacBookAir, DeviceVersionMacBookPro, - DeviceVersionXserve, + DeviceVersionMacStudio, + DeviceVersionXserve }; typedef NS_ENUM(NSInteger, DeviceSize) { @@ -25,7 +26,9 @@ typedef NS_ENUM(NSInteger, DeviceSize) { Mac21Dot5Inch = 21, Mac20Inch = 20, Mac17Inch = 17, + Mac16Inch = 16, Mac15Inch = 15, + Mac14Inch = 14, Mac13Inch = 13, Mac12Inch = 12, Mac11Inch = 11 @@ -37,6 +40,25 @@ typedef NS_ENUM(NSInteger, DeviceScreenResolution) { DeviceScreenNoRetina }; +typedef NS_ENUM(NSInteger, ChipType) { + ChipTypeUnknown = 0, + ChipTypeIntel, + ChipTypeM1, + ChipTypeM1Pro, + ChipTypeM1Max, + ChipTypeM1Ultra, + ChipTypeM2, + ChipTypeM2Pro, + ChipTypeM2Max, + ChipTypeM2Ultra, + ChipTypeM3, + ChipTypeM3Pro, + ChipTypeM3Max, + ChipTypeM4, + ChipTypeM4Pro, + ChipTypeM4Max +}; + @interface SDMacVersion : NSObject + (DeviceVersion)deviceVersion; @@ -46,6 +68,9 @@ typedef NS_ENUM(NSInteger, DeviceScreenResolution) { + (NSSize)deviceScreenResolutionPixelSize; + (DeviceScreenResolution)deviceScreenResolution; + (NSString *)deviceScreenResolutionName:(DeviceScreenResolution)deviceScreenResolution; ++ (BOOL)isAppleSilicon; ++ (ChipType)chipType; ++ (NSString *)chipName; + (BOOL)versionEqualTo:(NSString *)version; + (BOOL)versionGreaterThan:(NSString *)version; diff --git a/SDVersion/SDMacVersion/SDMacVersion.m b/SDVersion/SDMacVersion/SDMacVersion.m index 1e0b9a2..c427911 100755 --- a/SDVersion/SDMacVersion/SDMacVersion.m +++ b/SDVersion/SDMacVersion/SDMacVersion.m @@ -2,7 +2,7 @@ // SDMacVersion.m // SDMacVersion // -// Copyright (c) 2015 Sebastian Dobrincu & Tom Baranes. All rights reserved. +// Copyright (c) 2015-2025 Sebastian Dobrincu & Tom Baranes. All rights reserved. // #include @@ -17,125 +17,299 @@ @implementation SDMacVersion static NSString * const SDMacVersionEnum = @"SDMacVersionEnum"; static NSString * const SDMacScreenSize = @"SDMacReleaseSize"; static NSString * const SDMacResolution = @"SDMacResolution"; +static NSString * const SDMacChipType = @"SDMacChipType"; #pragma mark - Models + (NSDictionary *)deviceInformationForModel:(NSString *)model { - - __block NSMutableDictionary *mutableDic = [NSMutableDictionary dictionary]; + __block NSMutableDictionary *mutableDic = [NSMutableDictionary dictionary]; static NSDictionary *deviceDic = nil; static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - if ([model hasPrefix:@"MacPro"]) - { - mutableDic[SDMacDeviceName] = @"MacPro"; + dispatch_once(&onceToken, ^{ + // Determine device type and chip + ChipType chipType = ChipTypeIntel; + + // Mac Studio (Apple Silicon only) + if ([model hasPrefix:@"Mac13,1"]) { + mutableDic[SDMacDeviceName] = @"Mac Studio"; + mutableDic[SDMacVersionEnum] = @(DeviceVersionMacStudio); + chipType = ChipTypeM1Max; + } + else if ([model hasPrefix:@"Mac13,2"]) { + mutableDic[SDMacDeviceName] = @"Mac Studio"; + mutableDic[SDMacVersionEnum] = @(DeviceVersionMacStudio); + chipType = ChipTypeM1Ultra; + } + else if ([model hasPrefix:@"Mac14,13"]) { + mutableDic[SDMacDeviceName] = @"Mac Studio"; + mutableDic[SDMacVersionEnum] = @(DeviceVersionMacStudio); + chipType = ChipTypeM2Max; + } + else if ([model hasPrefix:@"Mac14,14"]) { + mutableDic[SDMacDeviceName] = @"Mac Studio"; + mutableDic[SDMacVersionEnum] = @(DeviceVersionMacStudio); + chipType = ChipTypeM2Ultra; + } + // Mac Pro (Apple Silicon) + else if ([model hasPrefix:@"Mac14,8"]) { + mutableDic[SDMacDeviceName] = @"Mac Pro"; + mutableDic[SDMacVersionEnum] = @(DeviceVersionMacPro); + chipType = ChipTypeM2Ultra; + } + else if ([model hasPrefix:@"MacPro"]) { + mutableDic[SDMacDeviceName] = @"Mac Pro"; mutableDic[SDMacVersionEnum] = @(DeviceVersionMacPro); - } - - else if ([model hasPrefix:@"iMac"]) - { + chipType = ChipTypeIntel; + } + // iMac + else if ([model hasPrefix:@"iMac21,"]) { + mutableDic[SDMacDeviceName] = @"iMac"; + mutableDic[SDMacVersionEnum] = @(DeviceVersionIMac); + chipType = ChipTypeM1; + } + else if ([model hasPrefix:@"Mac15,4"] || [model hasPrefix:@"Mac15,5"]) { + mutableDic[SDMacDeviceName] = @"iMac"; + mutableDic[SDMacVersionEnum] = @(DeviceVersionIMac); + chipType = ChipTypeM3; + } + else if ([model hasPrefix:@"Mac16,2"] || [model hasPrefix:@"Mac16,3"]) { mutableDic[SDMacDeviceName] = @"iMac"; mutableDic[SDMacVersionEnum] = @(DeviceVersionIMac); - } - - else if ([model hasPrefix:@"MacBookPro"]) - { - mutableDic[SDMacDeviceName] = @"MacBookPro"; + chipType = ChipTypeM4; + } + else if ([model hasPrefix:@"iMac"]) { + mutableDic[SDMacDeviceName] = @"iMac"; + mutableDic[SDMacVersionEnum] = @(DeviceVersionIMac); + chipType = ChipTypeIntel; + } + // Mac mini + else if ([model hasPrefix:@"Macmini9,"]) { + mutableDic[SDMacDeviceName] = @"Mac mini"; + mutableDic[SDMacVersionEnum] = @(DeviceVersionMacMini); + chipType = ChipTypeM1; + } + else if ([model hasPrefix:@"Mac14,3"]) { + mutableDic[SDMacDeviceName] = @"Mac mini"; + mutableDic[SDMacVersionEnum] = @(DeviceVersionMacMini); + chipType = ChipTypeM2; + } + else if ([model hasPrefix:@"Mac14,12"]) { + mutableDic[SDMacDeviceName] = @"Mac mini"; + mutableDic[SDMacVersionEnum] = @(DeviceVersionMacMini); + chipType = ChipTypeM2Pro; + } + else if ([model hasPrefix:@"Mac16,10"]) { + mutableDic[SDMacDeviceName] = @"Mac mini"; + mutableDic[SDMacVersionEnum] = @(DeviceVersionMacMini); + chipType = ChipTypeM4; + } + else if ([model hasPrefix:@"Mac16,11"]) { + mutableDic[SDMacDeviceName] = @"Mac mini"; + mutableDic[SDMacVersionEnum] = @(DeviceVersionMacMini); + chipType = ChipTypeM4Pro; + } + else if ([model hasPrefix:@"Macmini"]) { + mutableDic[SDMacDeviceName] = @"Mac mini"; + mutableDic[SDMacVersionEnum] = @(DeviceVersionMacMini); + chipType = ChipTypeIntel; + } + // MacBook Pro (Apple Silicon) + else if ([model hasPrefix:@"MacBookPro17,"]) { + mutableDic[SDMacDeviceName] = @"MacBook Pro"; + mutableDic[SDMacVersionEnum] = @(DeviceVersionMacBookPro); + chipType = ChipTypeM1; + } + else if ([model hasPrefix:@"MacBookPro18,1"] || [model hasPrefix:@"MacBookPro18,2"]) { + mutableDic[SDMacDeviceName] = @"MacBook Pro"; + mutableDic[SDMacVersionEnum] = @(DeviceVersionMacBookPro); + chipType = ([model hasPrefix:@"MacBookPro18,2"]) ? ChipTypeM1Max : ChipTypeM1Pro; + } + else if ([model hasPrefix:@"MacBookPro18,3"] || [model hasPrefix:@"MacBookPro18,4"]) { + mutableDic[SDMacDeviceName] = @"MacBook Pro"; + mutableDic[SDMacVersionEnum] = @(DeviceVersionMacBookPro); + chipType = ([model hasPrefix:@"MacBookPro18,4"]) ? ChipTypeM1Max : ChipTypeM1Pro; + } + else if ([model hasPrefix:@"Mac14,7"]) { + mutableDic[SDMacDeviceName] = @"MacBook Pro"; + mutableDic[SDMacVersionEnum] = @(DeviceVersionMacBookPro); + chipType = ChipTypeM2; + } + else if ([model hasPrefix:@"Mac14,5"] || [model hasPrefix:@"Mac14,6"]) { + mutableDic[SDMacDeviceName] = @"MacBook Pro"; + mutableDic[SDMacVersionEnum] = @(DeviceVersionMacBookPro); + chipType = ChipTypeM2Max; + } + else if ([model hasPrefix:@"Mac14,9"] || [model hasPrefix:@"Mac14,10"]) { + mutableDic[SDMacDeviceName] = @"MacBook Pro"; + mutableDic[SDMacVersionEnum] = @(DeviceVersionMacBookPro); + chipType = ChipTypeM2Pro; + } + else if ([model hasPrefix:@"Mac15,3"]) { + mutableDic[SDMacDeviceName] = @"MacBook Pro"; + mutableDic[SDMacVersionEnum] = @(DeviceVersionMacBookPro); + chipType = ChipTypeM3; + } + else if ([model hasPrefix:@"Mac15,6"] || [model hasPrefix:@"Mac15,7"]) { + mutableDic[SDMacDeviceName] = @"MacBook Pro"; mutableDic[SDMacVersionEnum] = @(DeviceVersionMacBookPro); + chipType = ChipTypeM3Pro; } - - else if ([model hasPrefix:@"MacBookAir"]) - { - mutableDic[SDMacDeviceName] = @"MacBookAir"; + else if ([model hasPrefix:@"Mac15,8"] || [model hasPrefix:@"Mac15,9"] || + [model hasPrefix:@"Mac15,10"] || [model hasPrefix:@"Mac15,11"]) { + mutableDic[SDMacDeviceName] = @"MacBook Pro"; + mutableDic[SDMacVersionEnum] = @(DeviceVersionMacBookPro); + chipType = ChipTypeM3Max; + } + else if ([model hasPrefix:@"Mac16,1"]) { + mutableDic[SDMacDeviceName] = @"MacBook Pro"; + mutableDic[SDMacVersionEnum] = @(DeviceVersionMacBookPro); + chipType = ChipTypeM4; + } + else if ([model hasPrefix:@"Mac16,6"] || [model hasPrefix:@"Mac16,7"]) { + // 14" M4 Pro (Mac16,6) and 16" M4 Pro (Mac16,7) + mutableDic[SDMacDeviceName] = @"MacBook Pro"; + mutableDic[SDMacVersionEnum] = @(DeviceVersionMacBookPro); + chipType = ChipTypeM4Pro; + } + else if ([model hasPrefix:@"Mac16,5"] || [model hasPrefix:@"Mac16,8"]) { + // 16" M4 Max (Mac16,5) and 14" M4 Max (Mac16,8) + mutableDic[SDMacDeviceName] = @"MacBook Pro"; + mutableDic[SDMacVersionEnum] = @(DeviceVersionMacBookPro); + chipType = ChipTypeM4Max; + } + else if ([model hasPrefix:@"MacBookPro"]) { + mutableDic[SDMacDeviceName] = @"MacBook Pro"; + mutableDic[SDMacVersionEnum] = @(DeviceVersionMacBookPro); + chipType = ChipTypeIntel; + } + // MacBook Air (Apple Silicon) + else if ([model hasPrefix:@"MacBookAir10,"]) { + mutableDic[SDMacDeviceName] = @"MacBook Air"; + mutableDic[SDMacVersionEnum] = @(DeviceVersionMacBookAir); + chipType = ChipTypeM1; + } + else if ([model hasPrefix:@"Mac14,2"]) { + mutableDic[SDMacDeviceName] = @"MacBook Air"; + mutableDic[SDMacVersionEnum] = @(DeviceVersionMacBookAir); + chipType = ChipTypeM2; + } + else if ([model hasPrefix:@"Mac14,15"]) { + mutableDic[SDMacDeviceName] = @"MacBook Air"; + mutableDic[SDMacVersionEnum] = @(DeviceVersionMacBookAir); + chipType = ChipTypeM2; + } + else if ([model hasPrefix:@"Mac15,12"]) { + mutableDic[SDMacDeviceName] = @"MacBook Air"; + mutableDic[SDMacVersionEnum] = @(DeviceVersionMacBookAir); + chipType = ChipTypeM3; + } + else if ([model hasPrefix:@"Mac15,13"]) { + mutableDic[SDMacDeviceName] = @"MacBook Air"; + mutableDic[SDMacVersionEnum] = @(DeviceVersionMacBookAir); + chipType = ChipTypeM3; + } + else if ([model hasPrefix:@"MacBookAir"]) { + mutableDic[SDMacDeviceName] = @"MacBook Air"; mutableDic[SDMacVersionEnum] = @(DeviceVersionMacBookAir); - } - - else if ([model hasPrefix:@"MacBook"]) - { + chipType = ChipTypeIntel; + } + // MacBook + else if ([model hasPrefix:@"MacBook"]) { mutableDic[SDMacDeviceName] = @"MacBook"; mutableDic[SDMacVersionEnum] = @(DeviceVersionMacBook); - } - - else - { + chipType = ChipTypeIntel; + } + // Xserve + else if ([model hasPrefix:@"Xserve"]) { + mutableDic[SDMacDeviceName] = @"Xserve"; + mutableDic[SDMacVersionEnum] = @(DeviceVersionXserve); + chipType = ChipTypeIntel; + } + else { mutableDic[SDMacDeviceName] = @"Unknown"; mutableDic[SDMacVersionEnum] = @(DeviceVersionUnknown); } - + + mutableDic[SDMacChipType] = @(chipType); + // Check if screen is retina float displayScale = 1.0; - if ([[NSScreen mainScreen] respondsToSelector:@selector(backingScaleFactor)]) + if ([[NSScreen mainScreen] respondsToSelector:@selector(backingScaleFactor)]) { for (NSScreen *screen in [NSScreen screens]) { float s = [screen backingScaleFactor]; if (s > displayScale) - displayScale = s;} + displayScale = s; + } + } if (displayScale == 1) mutableDic[SDMacResolution] = @(DeviceScreenNoRetina); - else if (displayScale == 2) + else if (displayScale >= 2) mutableDic[SDMacResolution] = @(DeviceScreenRetina); else mutableDic[SDMacResolution] = @(UnknownResolution); // Get device size in inches mutableDic[SDMacScreenSize] = [self deviceSizeInInches]; - + // Copy to static dictionary deviceDic = [mutableDic copy]; - }); - - return deviceDic; + }); + + return deviceDic; } + (NSString *)currentModel { - size_t len = 0; - sysctlbyname("hw.model", NULL, &len, NULL, 0); - NSString *model; - if (len) { - char *modelChar = malloc(len*sizeof(char)); - sysctlbyname("hw.model", modelChar, &len, NULL, 0); - model = [NSString stringWithUTF8String:modelChar]; - free(modelChar); - } - return model; + size_t len = 0; + sysctlbyname("hw.model", NULL, &len, NULL, 0); + NSString *model; + if (len) { + char *modelChar = malloc(len*sizeof(char)); + sysctlbyname("hw.model", modelChar, &len, NULL, 0); + model = [NSString stringWithUTF8String:modelChar]; + free(modelChar); + } + return model; } #pragma mark - Mac Information + (DeviceVersion)deviceVersion { - return [[[self deviceInformationForModel:[self currentModel]] objectForKey:SDMacVersionEnum] integerValue]; + return [[[self deviceInformationForModel:[self currentModel]] objectForKey:SDMacVersionEnum] integerValue]; } + (DeviceSize)deviceSize { - return [[[self deviceInformationForModel:[self currentModel]] objectForKey:SDMacScreenSize] integerValue]; + return [[[self deviceInformationForModel:[self currentModel]] objectForKey:SDMacScreenSize] integerValue]; } + (NSString *)deviceSizeName:(DeviceSize)deviceSize { return @{ - @(UnknownSize) : @"Unknown Size", - @(Mac27Inch) : @"27 inch", - @(Mac24Inch) : @"24 inch", - @(Mac21Dot5Inch) : @"21.5 inch", - @(Mac20Inch) : @"20 inch", - @(Mac17Inch) : @"17 inch", - @(Mac15Inch) : @"15 inch", - @(Mac13Inch) : @"13 inch", - @(Mac12Inch) : @"12 inch", - @(Mac11Inch) : @"11 inch" - }[@(deviceSize)]; + @(UnknownSize) : @"Unknown Size", + @(Mac27Inch) : @"27 inch", + @(Mac24Inch) : @"24 inch", + @(Mac21Dot5Inch) : @"21.5 inch", + @(Mac20Inch) : @"20 inch", + @(Mac17Inch) : @"17 inch", + @(Mac16Inch) : @"16 inch", + @(Mac15Inch) : @"15 inch", + @(Mac14Inch) : @"14 inch", + @(Mac13Inch) : @"13 inch", + @(Mac12Inch) : @"12 inch", + @(Mac11Inch) : @"11 inch" + }[@(deviceSize)]; } + (DeviceScreenResolution)deviceScreenResolution { - return [[[self deviceInformationForModel:[self currentModel]] objectForKey:SDMacResolution] integerValue]; + return [[[self deviceInformationForModel:[self currentModel]] objectForKey:SDMacResolution] integerValue]; } + (NSString *)deviceScreenResolutionName:(DeviceScreenResolution)deviceScreenResolution { return @{ - @(UnknownResolution) : @"Unknown resolution", - @(DeviceScreenRetina) : @"Retina screen", - @(DeviceScreenNoRetina) : @"Non-retina screen" - }[@(deviceScreenResolution)]; + @(UnknownResolution) : @"Unknown resolution", + @(DeviceScreenRetina) : @"Retina screen", + @(DeviceScreenNoRetina) : @"Non-retina screen" + }[@(deviceScreenResolution)]; } + (NSString *)deviceVersionString { @@ -143,14 +317,45 @@ + (NSString *)deviceVersionString { } + (NSSize)deviceScreenResolutionPixelSize { - NSScreen *screen = [NSScreen mainScreen]; - NSDictionary *description = [screen deviceDescription]; + NSScreen *screen = [NSScreen mainScreen]; + NSDictionary *description = [screen deviceDescription]; NSSize pixelSize = [[description objectForKey:NSDeviceSize] sizeValue]; - + // Double pixel size if retina screen if ([[[self deviceInformationForModel:[self currentModel]] objectForKey:SDMacResolution] integerValue] == DeviceScreenRetina) return NSMakeSize(pixelSize.width*2, pixelSize.height*2); - return pixelSize; + return pixelSize; +} + ++ (BOOL)isAppleSilicon { + ChipType chip = [self chipType]; + return chip != ChipTypeIntel && chip != ChipTypeUnknown; +} + ++ (ChipType)chipType { + return [[[self deviceInformationForModel:[self currentModel]] objectForKey:SDMacChipType] integerValue]; +} + ++ (NSString *)chipName { + ChipType chip = [self chipType]; + return @{ + @(ChipTypeUnknown) : @"Unknown", + @(ChipTypeIntel) : @"Intel", + @(ChipTypeM1) : @"Apple M1", + @(ChipTypeM1Pro) : @"Apple M1 Pro", + @(ChipTypeM1Max) : @"Apple M1 Max", + @(ChipTypeM1Ultra) : @"Apple M1 Ultra", + @(ChipTypeM2) : @"Apple M2", + @(ChipTypeM2Pro) : @"Apple M2 Pro", + @(ChipTypeM2Max) : @"Apple M2 Max", + @(ChipTypeM2Ultra) : @"Apple M2 Ultra", + @(ChipTypeM3) : @"Apple M3", + @(ChipTypeM3Pro) : @"Apple M3 Pro", + @(ChipTypeM3Max) : @"Apple M3 Max", + @(ChipTypeM4) : @"Apple M4", + @(ChipTypeM4Pro) : @"Apple M4 Pro", + @(ChipTypeM4Max) : @"Apple M4 Max" + }[@(chip)]; } + (BOOL)versionEqualTo:(NSString *)version @@ -175,7 +380,7 @@ + (BOOL)versionLessThan:(NSString *)version + (BOOL)versionLessThanOrEqualTo:(NSString *)version { - return ([[@([[NSProcessInfo processInfo]operatingSystemVersion].minorVersion) stringValue]compare:version options:NSNumericSearch] != NSOrderedDescending); + return ([[@([[NSProcessInfo processInfo]operatingSystemVersion].minorVersion) stringValue] compare:version options:NSNumericSearch] != NSOrderedDescending); } #pragma mark - Helpers @@ -185,15 +390,19 @@ + (NSNumber *)deviceSizeInInches { NSDictionary *description = [screen deviceDescription]; CGSize displayPhysicalSize = CGDisplayScreenSize([[description objectForKey:@"NSScreenNumber"] unsignedIntValue]); CGFloat sizeInInches = floor(sqrt(pow(displayPhysicalSize.width, 2) + pow(displayPhysicalSize.height, 2)) * 0.0393701); - + if (sizeInInches == 11) return @(Mac11Inch); else if (sizeInInches == 12) return @(Mac12Inch); else if (sizeInInches == 13) return @(Mac13Inch); + else if (sizeInInches == 14) + return @(Mac14Inch); else if (sizeInInches == 15) return @(Mac15Inch); + else if (sizeInInches == 16) + return @(Mac16Inch); else if (sizeInInches == 17) return @(Mac17Inch); else if (sizeInInches == 20) @@ -208,5 +417,4 @@ + (NSNumber *)deviceSizeInInches { return @(UnknownSize); } - @end diff --git a/SDVersion/SDiOSVersion/SDiOSVersion.h b/SDVersion/SDiOSVersion/SDiOSVersion.h index 216e53b..4b266ba 100755 --- a/SDVersion/SDiOSVersion/SDiOSVersion.h +++ b/SDVersion/SDiOSVersion/SDiOSVersion.h @@ -2,7 +2,7 @@ // SDiOSVersion.h // SDVersion // -// Copyright (c) 2016 Sebastian Dobrincu. All rights reserved. +// Copyright (c) 2016-2025 Sebastian Dobrincu. All rights reserved. // #import @@ -10,7 +10,8 @@ typedef NS_ENUM(NSInteger, DeviceVersion){ UnknownDevice = 0, Simulator = 1, - + + // iPhones (Legacy - pre-2018) iPhone4 = 3, iPhone4S = 4, iPhone5 = 5, @@ -26,29 +27,112 @@ typedef NS_ENUM(NSInteger, DeviceVersion){ iPhone8Plus = 15, iPhoneX = 16, iPhoneSE = 17, - - iPad1 = 18, - iPad2 = 19, - iPadMini = 20, - iPad3 = 21, - iPad4 = 22, - iPadAir = 23, - iPadMini2 = 24, - iPadAir2 = 25, - iPadMini3 = 26, - iPadMini4 = 27, - iPadPro12Dot9Inch = 28, - iPadPro9Dot7Inch = 29, - iPad5 = 30, - iPadPro12Dot9Inch2Gen = 31, - iPadPro10Dot5Inch = 32, - - iPodTouch1Gen = 33, - iPodTouch2Gen = 34, - iPodTouch3Gen = 35, - iPodTouch4Gen = 36, - iPodTouch5Gen = 37, - iPodTouch6Gen = 38 + + // iPhones (2018) + iPhoneXS = 40, + iPhoneXSMax = 41, + iPhoneXR = 42, + + // iPhones (2019) + iPhone11 = 43, + iPhone11Pro = 44, + iPhone11ProMax = 45, + + // iPhones (2020) + iPhoneSE2 = 46, + iPhone12Mini = 47, + iPhone12 = 48, + iPhone12Pro = 49, + iPhone12ProMax = 50, + + // iPhones (2021) + iPhone13Mini = 51, + iPhone13 = 52, + iPhone13Pro = 53, + iPhone13ProMax = 54, + + // iPhones (2022) + iPhoneSE3 = 55, + iPhone14 = 56, + iPhone14Plus = 57, + iPhone14Pro = 58, + iPhone14ProMax = 59, + + // iPhones (2023) + iPhone15 = 60, + iPhone15Plus = 61, + iPhone15Pro = 62, + iPhone15ProMax = 63, + + // iPhones (2024) + iPhone16 = 64, + iPhone16Plus = 65, + iPhone16Pro = 66, + iPhone16ProMax = 67, + + // iPhones (2025) + iPhone16e = 68, + + // iPads (Legacy - pre-2018) + iPad1 = 100, + iPad2 = 101, + iPadMini = 102, + iPad3 = 103, + iPad4 = 104, + iPadAir = 105, + iPadMini2 = 106, + iPadAir2 = 107, + iPadMini3 = 108, + iPadMini4 = 109, + iPadPro12Dot9Inch = 110, + iPadPro9Dot7Inch = 111, + iPad5 = 112, + iPadPro12Dot9Inch2Gen = 113, + iPadPro10Dot5Inch = 114, + + // iPads (2018) + iPad6 = 115, + iPadPro11Inch = 116, + iPadPro12Dot9Inch3Gen = 117, + + // iPads (2019) + iPad7 = 118, + iPadMini5 = 119, + iPadAir3 = 120, + + // iPads (2020) + iPad8 = 121, + iPadPro11Inch2Gen = 122, + iPadPro12Dot9Inch4Gen = 123, + iPadAir4 = 124, + + // iPads (2021) + iPad9 = 125, + iPadMini6 = 126, + iPadPro11Inch3Gen = 127, + iPadPro12Dot9Inch5Gen = 128, + + // iPads (2022) + iPad10 = 129, + iPadPro11Inch4Gen = 130, + iPadPro12Dot9Inch6Gen = 131, + iPadAir5 = 132, + + // iPads (2024) + iPadPro11InchM4 = 133, + iPadPro13InchM4 = 134, + iPadAir11InchM2 = 135, + iPadAir13InchM2 = 136, + iPadMini7 = 137, + + // iPods + iPodTouch1Gen = 200, + iPodTouch2Gen = 201, + iPodTouch3Gen = 202, + iPodTouch4Gen = 203, + iPodTouch5Gen = 204, + iPodTouch6Gen = 205, + iPodTouch7Gen = 206 }; typedef NS_ENUM(NSInteger, DeviceSize){ @@ -56,8 +140,14 @@ typedef NS_ENUM(NSInteger, DeviceSize){ Screen3Dot5inch = 1, Screen4inch = 2, Screen4Dot7inch = 3, - Screen5Dot5inch = 4, - Screen5Dot8inch = 5 + Screen5Dot4inch = 4, + Screen5Dot5inch = 5, + Screen5Dot8inch = 6, + Screen6Dot1inch = 7, + Screen6Dot3inch = 8, + Screen6Dot5inch = 9, + Screen6Dot7inch = 10, + Screen6Dot9inch = 11 }; @interface SDiOSVersion : NSObject diff --git a/SDVersion/SDiOSVersion/SDiOSVersion.m b/SDVersion/SDiOSVersion/SDiOSVersion.m index fcf181c..8b5cadd 100755 --- a/SDVersion/SDiOSVersion/SDiOSVersion.m +++ b/SDVersion/SDiOSVersion/SDiOSVersion.m @@ -2,7 +2,7 @@ // SDiOSVersion.m // SDVersion // -// Copyright (c) 2016 Sebastian Dobrincu. All rights reserved. +// Copyright (c) 2016-2025 Sebastian Dobrincu. All rights reserved. // #import "SDiOSVersion.h" @@ -17,89 +17,201 @@ + (NSDictionary*)deviceNamesByCode static NSDictionary *deviceNamesByCode = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" deviceNamesByCode = @{ - //iPhones - @"iPhone3,1" : @(iPhone4), - @"iPhone3,2" : @(iPhone4), - @"iPhone3,3" : @(iPhone4), - @"iPhone4,1" : @(iPhone4S), - @"iPhone4,2" : @(iPhone4S), - @"iPhone4,3" : @(iPhone4S), - @"iPhone5,1" : @(iPhone5), - @"iPhone5,2" : @(iPhone5), - @"iPhone5,3" : @(iPhone5C), - @"iPhone5,4" : @(iPhone5C), - @"iPhone6,1" : @(iPhone5S), - @"iPhone6,2" : @(iPhone5S), - @"iPhone7,2" : @(iPhone6), - @"iPhone7,1" : @(iPhone6Plus), - @"iPhone8,1" : @(iPhone6S), - @"iPhone8,2" : @(iPhone6SPlus), - @"iPhone8,4" : @(iPhoneSE), - @"iPhone9,1" : @(iPhone7), - @"iPhone9,3" : @(iPhone7), - @"iPhone9,2" : @(iPhone7Plus), - @"iPhone9,4" : @(iPhone7Plus), - @"iPhone10,1" : @(iPhone8), - @"iPhone10,4" : @(iPhone8), - @"iPhone10,2" : @(iPhone8Plus), - @"iPhone10,5" : @(iPhone8Plus), - @"iPhone10,3" : @(iPhoneX), - @"iPhone10,6" : @(iPhoneX), - @"i386" : @(Simulator), - @"x86_64" : @(Simulator), - - //iPads - @"iPad1,1" : @(iPad1), - @"iPad2,1" : @(iPad2), - @"iPad2,2" : @(iPad2), - @"iPad2,3" : @(iPad2), - @"iPad2,4" : @(iPad2), - @"iPad2,5" : @(iPadMini), - @"iPad2,6" : @(iPadMini), - @"iPad2,7" : @(iPadMini), - @"iPad3,1" : @(iPad3), - @"iPad3,2" : @(iPad3), - @"iPad3,3" : @(iPad3), - @"iPad3,4" : @(iPad4), - @"iPad3,5" : @(iPad4), - @"iPad3,6" : @(iPad4), - @"iPad4,1" : @(iPadAir), - @"iPad4,2" : @(iPadAir), - @"iPad4,3" : @(iPadAir), - @"iPad4,4" : @(iPadMini2), - @"iPad4,5" : @(iPadMini2), - @"iPad4,6" : @(iPadMini2), - @"iPad4,7" : @(iPadMini3), - @"iPad4,8" : @(iPadMini3), - @"iPad4,9" : @(iPadMini3), - @"iPad5,1" : @(iPadMini4), - @"iPad5,2" : @(iPadMini4), - @"iPad5,3" : @(iPadAir2), - @"iPad5,4" : @(iPadAir2), - @"iPad6,3" : @(iPadPro9Dot7Inch), - @"iPad6,4" : @(iPadPro9Dot7Inch), - @"iPad6,7" : @(iPadPro12Dot9Inch), - @"iPad6,8" : @(iPadPro12Dot9Inch), - @"iPad6,11" : @(iPad5), - @"iPad6,12" : @(iPad5), - @"iPad7,1" : @(iPadPro12Dot9Inch2Gen), - @"iPad7,2" : @(iPadPro12Dot9Inch2Gen), - @"iPad7,3" : @(iPadPro10Dot5Inch), - @"iPad7,4" : @(iPadPro10Dot5Inch), - - //iPods - @"iPod1,1" : @(iPodTouch1Gen), - @"iPod2,1" : @(iPodTouch2Gen), - @"iPod3,1" : @(iPodTouch3Gen), - @"iPod4,1" : @(iPodTouch4Gen), - @"iPod5,1" : @(iPodTouch5Gen), - @"iPod7,1" : @(iPodTouch6Gen)}; -#pragma clang diagnostic pop + // Simulators + @"i386" : @(Simulator), + @"x86_64" : @(Simulator), + @"arm64" : @(Simulator), + + // iPhones (Legacy) + @"iPhone3,1" : @(iPhone4), + @"iPhone3,2" : @(iPhone4), + @"iPhone3,3" : @(iPhone4), + @"iPhone4,1" : @(iPhone4S), + @"iPhone5,1" : @(iPhone5), + @"iPhone5,2" : @(iPhone5), + @"iPhone5,3" : @(iPhone5C), + @"iPhone5,4" : @(iPhone5C), + @"iPhone6,1" : @(iPhone5S), + @"iPhone6,2" : @(iPhone5S), + @"iPhone7,2" : @(iPhone6), + @"iPhone7,1" : @(iPhone6Plus), + @"iPhone8,1" : @(iPhone6S), + @"iPhone8,2" : @(iPhone6SPlus), + @"iPhone8,4" : @(iPhoneSE), + @"iPhone9,1" : @(iPhone7), + @"iPhone9,3" : @(iPhone7), + @"iPhone9,2" : @(iPhone7Plus), + @"iPhone9,4" : @(iPhone7Plus), + @"iPhone10,1" : @(iPhone8), + @"iPhone10,4" : @(iPhone8), + @"iPhone10,2" : @(iPhone8Plus), + @"iPhone10,5" : @(iPhone8Plus), + @"iPhone10,3" : @(iPhoneX), + @"iPhone10,6" : @(iPhoneX), + + // iPhones (2018) + @"iPhone11,2" : @(iPhoneXS), + @"iPhone11,4" : @(iPhoneXSMax), + @"iPhone11,6" : @(iPhoneXSMax), + @"iPhone11,8" : @(iPhoneXR), + + // iPhones (2019) + @"iPhone12,1" : @(iPhone11), + @"iPhone12,3" : @(iPhone11Pro), + @"iPhone12,5" : @(iPhone11ProMax), + + // iPhones (2020) + @"iPhone12,8" : @(iPhoneSE2), + @"iPhone13,1" : @(iPhone12Mini), + @"iPhone13,2" : @(iPhone12), + @"iPhone13,3" : @(iPhone12Pro), + @"iPhone13,4" : @(iPhone12ProMax), + + // iPhones (2021) + @"iPhone14,4" : @(iPhone13Mini), + @"iPhone14,5" : @(iPhone13), + @"iPhone14,2" : @(iPhone13Pro), + @"iPhone14,3" : @(iPhone13ProMax), + + // iPhones (2022) + @"iPhone14,6" : @(iPhoneSE3), + @"iPhone14,7" : @(iPhone14), + @"iPhone14,8" : @(iPhone14Plus), + @"iPhone15,2" : @(iPhone14Pro), + @"iPhone15,3" : @(iPhone14ProMax), + + // iPhones (2023) + @"iPhone15,4" : @(iPhone15), + @"iPhone15,5" : @(iPhone15Plus), + @"iPhone16,1" : @(iPhone15Pro), + @"iPhone16,2" : @(iPhone15ProMax), + + // iPhones (2024) + @"iPhone17,3" : @(iPhone16), + @"iPhone17,4" : @(iPhone16Plus), + @"iPhone17,1" : @(iPhone16Pro), + @"iPhone17,2" : @(iPhone16ProMax), + + // iPhones (2025) + @"iPhone17,5" : @(iPhone16e), + + // iPads (Legacy) + @"iPad1,1" : @(iPad1), + @"iPad2,1" : @(iPad2), + @"iPad2,2" : @(iPad2), + @"iPad2,3" : @(iPad2), + @"iPad2,4" : @(iPad2), + @"iPad2,5" : @(iPadMini), + @"iPad2,6" : @(iPadMini), + @"iPad2,7" : @(iPadMini), + @"iPad3,1" : @(iPad3), + @"iPad3,2" : @(iPad3), + @"iPad3,3" : @(iPad3), + @"iPad3,4" : @(iPad4), + @"iPad3,5" : @(iPad4), + @"iPad3,6" : @(iPad4), + @"iPad4,1" : @(iPadAir), + @"iPad4,2" : @(iPadAir), + @"iPad4,3" : @(iPadAir), + @"iPad4,4" : @(iPadMini2), + @"iPad4,5" : @(iPadMini2), + @"iPad4,6" : @(iPadMini2), + @"iPad4,7" : @(iPadMini3), + @"iPad4,8" : @(iPadMini3), + @"iPad4,9" : @(iPadMini3), + @"iPad5,1" : @(iPadMini4), + @"iPad5,2" : @(iPadMini4), + @"iPad5,3" : @(iPadAir2), + @"iPad5,4" : @(iPadAir2), + @"iPad6,3" : @(iPadPro9Dot7Inch), + @"iPad6,4" : @(iPadPro9Dot7Inch), + @"iPad6,7" : @(iPadPro12Dot9Inch), + @"iPad6,8" : @(iPadPro12Dot9Inch), + @"iPad6,11" : @(iPad5), + @"iPad6,12" : @(iPad5), + @"iPad7,1" : @(iPadPro12Dot9Inch2Gen), + @"iPad7,2" : @(iPadPro12Dot9Inch2Gen), + @"iPad7,3" : @(iPadPro10Dot5Inch), + @"iPad7,4" : @(iPadPro10Dot5Inch), + + // iPads (2018) + @"iPad7,5" : @(iPad6), + @"iPad7,6" : @(iPad6), + @"iPad8,1" : @(iPadPro11Inch), + @"iPad8,2" : @(iPadPro11Inch), + @"iPad8,3" : @(iPadPro11Inch), + @"iPad8,4" : @(iPadPro11Inch), + @"iPad8,5" : @(iPadPro12Dot9Inch3Gen), + @"iPad8,6" : @(iPadPro12Dot9Inch3Gen), + @"iPad8,7" : @(iPadPro12Dot9Inch3Gen), + @"iPad8,8" : @(iPadPro12Dot9Inch3Gen), + + // iPads (2019) + @"iPad7,11" : @(iPad7), + @"iPad7,12" : @(iPad7), + @"iPad11,1" : @(iPadMini5), + @"iPad11,2" : @(iPadMini5), + @"iPad11,3" : @(iPadAir3), + @"iPad11,4" : @(iPadAir3), + + // iPads (2020) + @"iPad11,6" : @(iPad8), + @"iPad11,7" : @(iPad8), + @"iPad8,9" : @(iPadPro11Inch2Gen), + @"iPad8,10" : @(iPadPro11Inch2Gen), + @"iPad8,11" : @(iPadPro12Dot9Inch4Gen), + @"iPad8,12" : @(iPadPro12Dot9Inch4Gen), + @"iPad13,1" : @(iPadAir4), + @"iPad13,2" : @(iPadAir4), + + // iPads (2021) + @"iPad12,1" : @(iPad9), + @"iPad12,2" : @(iPad9), + @"iPad14,1" : @(iPadMini6), + @"iPad14,2" : @(iPadMini6), + @"iPad13,4" : @(iPadPro11Inch3Gen), + @"iPad13,5" : @(iPadPro11Inch3Gen), + @"iPad13,6" : @(iPadPro11Inch3Gen), + @"iPad13,7" : @(iPadPro11Inch3Gen), + @"iPad13,8" : @(iPadPro12Dot9Inch5Gen), + @"iPad13,9" : @(iPadPro12Dot9Inch5Gen), + @"iPad13,10": @(iPadPro12Dot9Inch5Gen), + @"iPad13,11": @(iPadPro12Dot9Inch5Gen), + + // iPads (2022) + @"iPad13,18": @(iPad10), + @"iPad13,19": @(iPad10), + @"iPad14,3" : @(iPadPro11Inch4Gen), + @"iPad14,4" : @(iPadPro11Inch4Gen), + @"iPad14,5" : @(iPadPro12Dot9Inch6Gen), + @"iPad14,6" : @(iPadPro12Dot9Inch6Gen), + @"iPad13,16": @(iPadAir5), + @"iPad13,17": @(iPadAir5), + + // iPads (2024) + @"iPad16,3" : @(iPadPro11InchM4), + @"iPad16,4" : @(iPadPro11InchM4), + @"iPad16,5" : @(iPadPro13InchM4), + @"iPad16,6" : @(iPadPro13InchM4), + @"iPad14,8" : @(iPadAir11InchM2), + @"iPad14,9" : @(iPadAir11InchM2), + @"iPad14,10": @(iPadAir13InchM2), + @"iPad14,11": @(iPadAir13InchM2), + @"iPad16,1" : @(iPadMini7), + @"iPad16,2" : @(iPadMini7), + + // iPods + @"iPod1,1" : @(iPodTouch1Gen), + @"iPod2,1" : @(iPodTouch2Gen), + @"iPod3,1" : @(iPodTouch3Gen), + @"iPod4,1" : @(iPodTouch4Gen), + @"iPod5,1" : @(iPodTouch5Gen), + @"iPod7,1" : @(iPodTouch6Gen), + @"iPod9,1" : @(iPodTouch7Gen) + }; }); - + return deviceNamesByCode; } @@ -108,34 +220,52 @@ + (DeviceVersion)deviceVersion struct utsname systemInfo; uname(&systemInfo); NSString *code = [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding]; - + DeviceVersion version = (DeviceVersion)[[self.deviceNamesByCode objectForKey:code] integerValue]; - + return version; } + (DeviceSize)resolutionSize { - CGFloat screenHeight = 0; - - if ([SDiOSVersion versionGreaterThanOrEqualTo:@"8"]) { - screenHeight = MAX([[UIScreen mainScreen] bounds].size.height, [[UIScreen mainScreen] bounds].size.width); - } else { - screenHeight = [[UIScreen mainScreen] bounds].size.height; - } - + CGFloat screenHeight = MAX([[UIScreen mainScreen] bounds].size.height, [[UIScreen mainScreen] bounds].size.width); + if (screenHeight == 480) { return Screen3Dot5inch; - } else if(screenHeight == 568) { + } else if (screenHeight == 568) { return Screen4inch; - } else if(screenHeight == 667) { - return Screen4Dot7inch; - } else if(screenHeight == 736) { + } else if (screenHeight == 667) { + return Screen4Dot7inch; + } else if (screenHeight == 736) { return Screen5Dot5inch; } else if (screenHeight == 812) { + // Could be 5.4" (12/13 mini) or 5.8" (X/XS/11 Pro) + DeviceVersion device = [self deviceVersion]; + if (device == iPhone12Mini || device == iPhone13Mini) { + return Screen5Dot4inch; + } return Screen5Dot8inch; - } else + } else if (screenHeight == 844) { + return Screen6Dot1inch; + } else if (screenHeight == 852) { + return Screen6Dot1inch; + } else if (screenHeight == 874) { + return Screen6Dot3inch; + } else if (screenHeight == 896) { + // Could be 6.5" @3x or 6.1" @2x + if ([UIScreen mainScreen].scale == 3) { + return Screen6Dot5inch; + } + return Screen6Dot1inch; + } else if (screenHeight == 926) { + return Screen6Dot7inch; + } else if (screenHeight == 932) { + return Screen6Dot7inch; + } else if (screenHeight == 956) { + return Screen6Dot9inch; + } else { return UnknownSize; + } } + (DeviceSize)deviceSize @@ -154,13 +284,19 @@ + (DeviceSize)deviceSize + (NSString *)deviceSizeName:(DeviceSize)deviceSize { return @{ - @(UnknownSize) : @"Unknown Size", - @(Screen3Dot5inch) : @"3.5 inch", - @(Screen4inch) : @"4 inch", - @(Screen4Dot7inch) : @"4.7 inch", - @(Screen5Dot5inch) : @"5.5 inch", - @(Screen5Dot8inch) : @"5.8 inch", - }[@(deviceSize)]; + @(UnknownSize) : @"Unknown Size", + @(Screen3Dot5inch) : @"3.5 inch", + @(Screen4inch) : @"4 inch", + @(Screen4Dot7inch) : @"4.7 inch", + @(Screen5Dot4inch) : @"5.4 inch", + @(Screen5Dot5inch) : @"5.5 inch", + @(Screen5Dot8inch) : @"5.8 inch", + @(Screen6Dot1inch) : @"6.1 inch", + @(Screen6Dot3inch) : @"6.3 inch", + @(Screen6Dot5inch) : @"6.5 inch", + @(Screen6Dot7inch) : @"6.7 inch", + @(Screen6Dot9inch) : @"6.9 inch" + }[@(deviceSize)]; } + (NSString *)deviceNameString @@ -171,58 +307,142 @@ + (NSString *)deviceNameString + (NSString *)deviceNameForVersion:(DeviceVersion)deviceVersion { return @{ - @(iPhone4) : @"iPhone 4", - @(iPhone4S) : @"iPhone 4S", - @(iPhone5) : @"iPhone 5", - @(iPhone5C) : @"iPhone 5C", - @(iPhone5S) : @"iPhone 5S", - @(iPhone6) : @"iPhone 6", - @(iPhone6Plus) : @"iPhone 6 Plus", - @(iPhone6S) : @"iPhone 6S", - @(iPhone6SPlus) : @"iPhone 6S Plus", - @(iPhone7) : @"iPhone 7", - @(iPhone7Plus) : @"iPhone 7 Plus", - @(iPhone8) : @"iPhone 8", - @(iPhone8Plus) : @"iPhone 8 Plus", - @(iPhoneX) : @"iPhone X", - @(iPhoneSE) : @"iPhone SE", - - @(iPad1) : @"iPad 1", - @(iPad2) : @"iPad 2", - @(iPadMini) : @"iPad Mini", - @(iPad3) : @"iPad 3", - @(iPad4) : @"iPad 4", - @(iPadAir) : @"iPad Air", - @(iPadMini2) : @"iPad Mini 2", - @(iPadAir2) : @"iPad Air 2", - @(iPadMini3) : @"iPad Mini 3", - @(iPadMini4) : @"iPad Mini 4", - @(iPadPro9Dot7Inch) : @"iPad Pro 9.7 inch", - @(iPadPro12Dot9Inch) : @"iPad Pro 12.9 inch", - @(iPad5) : @"iPad 5", - @(iPadPro10Dot5Inch) : @"iPad Pro 10.5 inch", - @(iPadPro12Dot9Inch2Gen): @"iPad Pro 12.9 inch", - - @(iPodTouch1Gen) : @"iPod Touch 1st Gen", - @(iPodTouch2Gen) : @"iPod Touch 2nd Gen", - @(iPodTouch3Gen) : @"iPod Touch 3rd Gen", - @(iPodTouch4Gen) : @"iPod Touch 4th Gen", - @(iPodTouch5Gen) : @"iPod Touch 5th Gen", - @(iPodTouch6Gen) : @"iPod Touch 6th Gen", - - @(Simulator) : @"Simulator", - @(UnknownDevice) : @"Unknown Device" - }[@(deviceVersion)]; + // iPhones (Legacy) + @(iPhone4) : @"iPhone 4", + @(iPhone4S) : @"iPhone 4S", + @(iPhone5) : @"iPhone 5", + @(iPhone5C) : @"iPhone 5C", + @(iPhone5S) : @"iPhone 5S", + @(iPhone6) : @"iPhone 6", + @(iPhone6Plus) : @"iPhone 6 Plus", + @(iPhone6S) : @"iPhone 6S", + @(iPhone6SPlus) : @"iPhone 6S Plus", + @(iPhone7) : @"iPhone 7", + @(iPhone7Plus) : @"iPhone 7 Plus", + @(iPhone8) : @"iPhone 8", + @(iPhone8Plus) : @"iPhone 8 Plus", + @(iPhoneX) : @"iPhone X", + @(iPhoneSE) : @"iPhone SE", + + // iPhones (2018) + @(iPhoneXS) : @"iPhone XS", + @(iPhoneXSMax) : @"iPhone XS Max", + @(iPhoneXR) : @"iPhone XR", + + // iPhones (2019) + @(iPhone11) : @"iPhone 11", + @(iPhone11Pro) : @"iPhone 11 Pro", + @(iPhone11ProMax) : @"iPhone 11 Pro Max", + + // iPhones (2020) + @(iPhoneSE2) : @"iPhone SE (2nd generation)", + @(iPhone12Mini) : @"iPhone 12 mini", + @(iPhone12) : @"iPhone 12", + @(iPhone12Pro) : @"iPhone 12 Pro", + @(iPhone12ProMax) : @"iPhone 12 Pro Max", + + // iPhones (2021) + @(iPhone13Mini) : @"iPhone 13 mini", + @(iPhone13) : @"iPhone 13", + @(iPhone13Pro) : @"iPhone 13 Pro", + @(iPhone13ProMax) : @"iPhone 13 Pro Max", + + // iPhones (2022) + @(iPhoneSE3) : @"iPhone SE (3rd generation)", + @(iPhone14) : @"iPhone 14", + @(iPhone14Plus) : @"iPhone 14 Plus", + @(iPhone14Pro) : @"iPhone 14 Pro", + @(iPhone14ProMax) : @"iPhone 14 Pro Max", + + // iPhones (2023) + @(iPhone15) : @"iPhone 15", + @(iPhone15Plus) : @"iPhone 15 Plus", + @(iPhone15Pro) : @"iPhone 15 Pro", + @(iPhone15ProMax) : @"iPhone 15 Pro Max", + + // iPhones (2024) + @(iPhone16) : @"iPhone 16", + @(iPhone16Plus) : @"iPhone 16 Plus", + @(iPhone16Pro) : @"iPhone 16 Pro", + @(iPhone16ProMax) : @"iPhone 16 Pro Max", + + // iPhones (2025) + @(iPhone16e) : @"iPhone 16e", + + // iPads (Legacy) + @(iPad1) : @"iPad 1", + @(iPad2) : @"iPad 2", + @(iPadMini) : @"iPad mini", + @(iPad3) : @"iPad 3", + @(iPad4) : @"iPad 4", + @(iPadAir) : @"iPad Air", + @(iPadMini2) : @"iPad mini 2", + @(iPadAir2) : @"iPad Air 2", + @(iPadMini3) : @"iPad mini 3", + @(iPadMini4) : @"iPad mini 4", + @(iPadPro9Dot7Inch) : @"iPad Pro (9.7-inch)", + @(iPadPro12Dot9Inch) : @"iPad Pro (12.9-inch)", + @(iPad5) : @"iPad (5th generation)", + @(iPadPro10Dot5Inch) : @"iPad Pro (10.5-inch)", + @(iPadPro12Dot9Inch2Gen): @"iPad Pro (12.9-inch, 2nd generation)", + + // iPads (2018) + @(iPad6) : @"iPad (6th generation)", + @(iPadPro11Inch) : @"iPad Pro (11-inch)", + @(iPadPro12Dot9Inch3Gen): @"iPad Pro (12.9-inch, 3rd generation)", + + // iPads (2019) + @(iPad7) : @"iPad (7th generation)", + @(iPadMini5) : @"iPad mini (5th generation)", + @(iPadAir3) : @"iPad Air (3rd generation)", + + // iPads (2020) + @(iPad8) : @"iPad (8th generation)", + @(iPadPro11Inch2Gen) : @"iPad Pro (11-inch, 2nd generation)", + @(iPadPro12Dot9Inch4Gen): @"iPad Pro (12.9-inch, 4th generation)", + @(iPadAir4) : @"iPad Air (4th generation)", + + // iPads (2021) + @(iPad9) : @"iPad (9th generation)", + @(iPadMini6) : @"iPad mini (6th generation)", + @(iPadPro11Inch3Gen) : @"iPad Pro (11-inch, 3rd generation)", + @(iPadPro12Dot9Inch5Gen): @"iPad Pro (12.9-inch, 5th generation)", + + // iPads (2022) + @(iPad10) : @"iPad (10th generation)", + @(iPadPro11Inch4Gen) : @"iPad Pro (11-inch, 4th generation)", + @(iPadPro12Dot9Inch6Gen): @"iPad Pro (12.9-inch, 6th generation)", + @(iPadAir5) : @"iPad Air (5th generation)", + + // iPads (2024) + @(iPadPro11InchM4) : @"iPad Pro (11-inch, M4)", + @(iPadPro13InchM4) : @"iPad Pro (13-inch, M4)", + @(iPadAir11InchM2) : @"iPad Air (11-inch, M2)", + @(iPadAir13InchM2) : @"iPad Air (13-inch, M2)", + @(iPadMini7) : @"iPad mini (7th generation)", + + // iPods + @(iPodTouch1Gen) : @"iPod touch (1st generation)", + @(iPodTouch2Gen) : @"iPod touch (2nd generation)", + @(iPodTouch3Gen) : @"iPod touch (3rd generation)", + @(iPodTouch4Gen) : @"iPod touch (4th generation)", + @(iPodTouch5Gen) : @"iPod touch (5th generation)", + @(iPodTouch6Gen) : @"iPod touch (6th generation)", + @(iPodTouch7Gen) : @"iPod touch (7th generation)", + + @(Simulator) : @"Simulator", + @(UnknownDevice) : @"Unknown Device" + }[@(deviceVersion)]; } + (BOOL)isZoomed { if ([self resolutionSize] == Screen4inch && [UIScreen mainScreen].nativeScale > 2) { return YES; - }else if ([self resolutionSize] == Screen4Dot7inch && [UIScreen mainScreen].scale == 3){ + } else if ([self resolutionSize] == Screen4Dot7inch && [UIScreen mainScreen].scale == 3) { return YES; } - + return NO; } diff --git a/SDVersion/SDtvOSVersion/SDtvOSVersion.h b/SDVersion/SDtvOSVersion/SDtvOSVersion.h index b2a1bbc..3973c91 100755 --- a/SDVersion/SDtvOSVersion/SDtvOSVersion.h +++ b/SDVersion/SDtvOSVersion/SDtvOSVersion.h @@ -2,15 +2,17 @@ // SDtvOSVersion.h // SDVersion // -// Copyright (c) 2016 Sebastian Dobrincu. All rights reserved. +// Copyright (c) 2016-2025 Sebastian Dobrincu. All rights reserved. // #import typedef NS_ENUM(NSInteger, DeviceVersion) { - AppleTV4 = 1, - AppleTV4K = 2, - Simulator = 0 + Simulator = 0, + AppleTVHD = 1, // AppleTV5,3 - 4th Gen (HD) + AppleTV4K1stGen = 2, // AppleTV6,2 - 4K 1st Gen + AppleTV4K2ndGen = 3, // AppleTV11,1 - 4K 2nd Gen + AppleTV4K3rdGen = 4 // AppleTV14,1 - 4K 3rd Gen }; @interface SDtvOSVersion : NSObject diff --git a/SDVersion/SDtvOSVersion/SDtvOSVersion.m b/SDVersion/SDtvOSVersion/SDtvOSVersion.m index f3c4961..c5fd2ed 100755 --- a/SDVersion/SDtvOSVersion/SDtvOSVersion.m +++ b/SDVersion/SDtvOSVersion/SDtvOSVersion.m @@ -2,7 +2,7 @@ // SDtvOSVersion.m // SDVersion // -// Copyright (c) 2016 Sebastian Dobrincu. All rights reserved. +// Copyright (c) 2016-2025 Sebastian Dobrincu. All rights reserved. // #import "SDtvOSVersion.h" @@ -19,11 +19,25 @@ + (NSDictionary*)deviceNamesByCode static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ deviceNamesByCode = @{ - @"AppleTV5,3" : @(AppleTV4), - @"AppleTV6,2" : @(AppleTV4K), - }; + // Simulators + @"i386" : @(Simulator), + @"x86_64" : @(Simulator), + @"arm64" : @(Simulator), + + // Apple TV HD (4th Generation) + @"AppleTV5,3" : @(AppleTVHD), + + // Apple TV 4K (1st Generation) + @"AppleTV6,2" : @(AppleTV4K1stGen), + + // Apple TV 4K (2nd Generation) + @"AppleTV11,1" : @(AppleTV4K2ndGen), + + // Apple TV 4K (3rd Generation) + @"AppleTV14,1" : @(AppleTV4K3rdGen) + }; }); - + return deviceNamesByCode; } @@ -32,19 +46,21 @@ + (DeviceVersion)deviceVersion struct utsname systemInfo; uname(&systemInfo); NSString *code = [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding]; - + DeviceVersion version = (DeviceVersion)[[self.deviceNamesByCode objectForKey:code] integerValue]; - + return version; } + (NSString *)deviceVersionName:(DeviceVersion)deviceVersion { return @{ - @(AppleTV4) : @"Apple TV (4th Generation)", - @(AppleTV4K) : @"Apple TV 4K", - @(Simulator) : @"Simulator" - }[@(deviceVersion)]; + @(AppleTVHD) : @"Apple TV HD", + @(AppleTV4K1stGen) : @"Apple TV 4K (1st generation)", + @(AppleTV4K2ndGen) : @"Apple TV 4K (2nd generation)", + @(AppleTV4K3rdGen) : @"Apple TV 4K (3rd generation)", + @(Simulator) : @"Simulator" + }[@(deviceVersion)]; } + (NSString *)deviceName @@ -52,10 +68,10 @@ + (NSString *)deviceName struct utsname systemInfo; uname(&systemInfo); NSString *code = [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding]; - if ([code isEqualToString:@"x86_64"] || [code isEqualToString:@"i386"]) { + if ([code isEqualToString:@"x86_64"] || [code isEqualToString:@"i386"] || [code isEqualToString:@"arm64"]) { code = @"Simulator"; } - + return code; } diff --git a/SDVersion/SDwatchOSVersion/SDwatchOSVersion.h b/SDVersion/SDwatchOSVersion/SDwatchOSVersion.h index 1cbd6e2..0684bf3 100644 --- a/SDVersion/SDwatchOSVersion/SDwatchOSVersion.h +++ b/SDVersion/SDwatchOSVersion/SDwatchOSVersion.h @@ -2,28 +2,79 @@ // SDwatchOSVersion.h // SDVersion // -// Copyright © 2016 Sebastian Dobrincu. All rights reserved. +// Copyright (c) 2016-2025 Sebastian Dobrincu. All rights reserved. // #import typedef NS_ENUM(NSInteger, DeviceVersion) { + Simulator = 0, + + // Original & Series 1-2 (Legacy) AppleWatch38mm = 1, AppleWatch42mm = 2, AppleWatch38mmSeries1 = 3, AppleWatch42mmSeries1 = 4, AppleWatch38mmSeries2 = 5, AppleWatch42mmSeries2 = 6, + + // Series 3 (38mm/42mm) AppleWatch38mmSeries3 = 7, AppleWatch42mmSeries3 = 8, - - Simulator = 0 + + // Series 4 (40mm/44mm) + AppleWatch40mmSeries4 = 10, + AppleWatch44mmSeries4 = 11, + + // Series 5 (40mm/44mm) + AppleWatch40mmSeries5 = 12, + AppleWatch44mmSeries5 = 13, + + // SE 1st Gen (40mm/44mm) + AppleWatchSE40mm = 14, + AppleWatchSE44mm = 15, + + // Series 6 (40mm/44mm) + AppleWatch40mmSeries6 = 16, + AppleWatch44mmSeries6 = 17, + + // Series 7 (41mm/45mm) + AppleWatch41mmSeries7 = 18, + AppleWatch45mmSeries7 = 19, + + // SE 2nd Gen (40mm/44mm) + AppleWatchSE2_40mm = 20, + AppleWatchSE2_44mm = 21, + + // Series 8 (41mm/45mm) + AppleWatch41mmSeries8 = 22, + AppleWatch45mmSeries8 = 23, + + // Ultra (49mm) + AppleWatchUltra49mm = 24, + + // Series 9 (41mm/45mm) + AppleWatch41mmSeries9 = 25, + AppleWatch45mmSeries9 = 26, + + // Ultra 2 (49mm) + AppleWatchUltra2_49mm = 27, + + // Series 10 (42mm/46mm) + AppleWatch42mmSeries10 = 28, + AppleWatch46mmSeries10 = 29 }; typedef NS_ENUM(NSInteger, DeviceSize) { UnknownSize = 0, Screen38mm = 1, - Screen42mm = 2 + Screen40mm = 2, + Screen41mm = 3, + Screen42mm = 4, + Screen44mm = 5, + Screen45mm = 6, + Screen46mm = 7, + Screen49mm = 8 }; @interface SDwatchOSVersion : NSObject diff --git a/SDVersion/SDwatchOSVersion/SDwatchOSVersion.m b/SDVersion/SDwatchOSVersion/SDwatchOSVersion.m index 5af019e..4d7f2ea 100644 --- a/SDVersion/SDwatchOSVersion/SDwatchOSVersion.m +++ b/SDVersion/SDwatchOSVersion/SDwatchOSVersion.m @@ -2,7 +2,7 @@ // SDwatchOSVersion.m // SDVersion // -// Copyright © 2016 Sebastian Dobrincu. All rights reserved. +// Copyright (c) 2016-2025 Sebastian Dobrincu. All rights reserved. // #import "SDwatchOSVersion.h" @@ -16,19 +16,91 @@ + (NSDictionary*)deviceNamesByCode static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ deviceNamesByCode = @{ - @"Watch1,1" : @(AppleWatch38mm), - @"Watch1,2" : @(AppleWatch42mm), - @"Watch2,6" : @(AppleWatch38mmSeries1), - @"Watch2,7" : @(AppleWatch42mmSeries1), - @"Watch2,3" : @(AppleWatch38mmSeries2), - @"Watch2,4" : @(AppleWatch42mmSeries2), - @"Watch3,1" : @(AppleWatch38mmSeries3), - @"Watch3,2" : @(AppleWatch42mmSeries3), - @"Watch3,3" : @(AppleWatch38mmSeries3), - @"Watch3,4" : @(AppleWatch42mmSeries3), - }; + // Simulators + @"i386" : @(Simulator), + @"x86_64" : @(Simulator), + @"arm64" : @(Simulator), + + // Original + @"Watch1,1" : @(AppleWatch38mm), + @"Watch1,2" : @(AppleWatch42mm), + + // Series 1 + @"Watch2,6" : @(AppleWatch38mmSeries1), + @"Watch2,7" : @(AppleWatch42mmSeries1), + + // Series 2 + @"Watch2,3" : @(AppleWatch38mmSeries2), + @"Watch2,4" : @(AppleWatch42mmSeries2), + + // Series 3 + @"Watch3,1" : @(AppleWatch38mmSeries3), + @"Watch3,2" : @(AppleWatch42mmSeries3), + @"Watch3,3" : @(AppleWatch38mmSeries3), + @"Watch3,4" : @(AppleWatch42mmSeries3), + + // Series 4 + @"Watch4,1" : @(AppleWatch40mmSeries4), + @"Watch4,2" : @(AppleWatch44mmSeries4), + @"Watch4,3" : @(AppleWatch40mmSeries4), + @"Watch4,4" : @(AppleWatch44mmSeries4), + + // Series 5 + @"Watch5,1" : @(AppleWatch40mmSeries5), + @"Watch5,2" : @(AppleWatch44mmSeries5), + @"Watch5,3" : @(AppleWatch40mmSeries5), + @"Watch5,4" : @(AppleWatch44mmSeries5), + + // SE 1st Gen + @"Watch5,9" : @(AppleWatchSE40mm), + @"Watch5,10" : @(AppleWatchSE44mm), + @"Watch5,11" : @(AppleWatchSE40mm), + @"Watch5,12" : @(AppleWatchSE44mm), + + // Series 6 + @"Watch6,1" : @(AppleWatch40mmSeries6), + @"Watch6,2" : @(AppleWatch44mmSeries6), + @"Watch6,3" : @(AppleWatch40mmSeries6), + @"Watch6,4" : @(AppleWatch44mmSeries6), + + // Series 7 + @"Watch6,6" : @(AppleWatch41mmSeries7), + @"Watch6,7" : @(AppleWatch45mmSeries7), + @"Watch6,8" : @(AppleWatch41mmSeries7), + @"Watch6,9" : @(AppleWatch45mmSeries7), + + // SE 2nd Gen + @"Watch6,10" : @(AppleWatchSE2_40mm), + @"Watch6,11" : @(AppleWatchSE2_44mm), + @"Watch6,12" : @(AppleWatchSE2_40mm), + @"Watch6,13" : @(AppleWatchSE2_44mm), + + // Series 8 + @"Watch6,14" : @(AppleWatch41mmSeries8), + @"Watch6,15" : @(AppleWatch45mmSeries8), + @"Watch6,16" : @(AppleWatch41mmSeries8), + @"Watch6,17" : @(AppleWatch45mmSeries8), + + // Ultra + @"Watch6,18" : @(AppleWatchUltra49mm), + + // Series 9 + @"Watch7,1" : @(AppleWatch41mmSeries9), + @"Watch7,2" : @(AppleWatch45mmSeries9), + @"Watch7,3" : @(AppleWatch41mmSeries9), + @"Watch7,4" : @(AppleWatch45mmSeries9), + + // Ultra 2 + @"Watch7,5" : @(AppleWatchUltra2_49mm), + + // Series 10 + @"Watch7,8" : @(AppleWatch42mmSeries10), + @"Watch7,9" : @(AppleWatch46mmSeries10), + @"Watch7,10" : @(AppleWatch42mmSeries10), + @"Watch7,11" : @(AppleWatch46mmSeries10) + }; }); - + return deviceNamesByCode; } @@ -37,35 +109,71 @@ + (DeviceVersion)deviceVersion struct utsname systemInfo; uname(&systemInfo); NSString *code = [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding]; - + DeviceVersion version = (DeviceVersion)[[self.deviceNamesByCode objectForKey:code] integerValue]; - + return version; } + (NSString *)deviceVersionName:(DeviceVersion)deviceVersion { return @{ - @(AppleWatch38mm) : @"Apple Watch 38mm", - @(AppleWatch42mm) : @"Apple Watch 42mm", - @(AppleWatch38mmSeries1) : @"Apple Watch Series 1 38mm", - @(AppleWatch42mmSeries1) : @"Apple Watch Series 1 42mm", - @(AppleWatch38mmSeries2) : @"Apple Watch Series 2 38mm", - @(AppleWatch42mmSeries2) : @"Apple Watch Series 2 42mm", - @(AppleWatch38mmSeries3) : @"Apple Watch Series 3 38mm", - @(AppleWatch42mmSeries3) : @"Apple Watch Series 3 42mm", - @(Simulator) : @"Simulator" - }[@(deviceVersion)]; + @(AppleWatch38mm) : @"Apple Watch 38mm", + @(AppleWatch42mm) : @"Apple Watch 42mm", + @(AppleWatch38mmSeries1) : @"Apple Watch Series 1 (38mm)", + @(AppleWatch42mmSeries1) : @"Apple Watch Series 1 (42mm)", + @(AppleWatch38mmSeries2) : @"Apple Watch Series 2 (38mm)", + @(AppleWatch42mmSeries2) : @"Apple Watch Series 2 (42mm)", + @(AppleWatch38mmSeries3) : @"Apple Watch Series 3 (38mm)", + @(AppleWatch42mmSeries3) : @"Apple Watch Series 3 (42mm)", + @(AppleWatch40mmSeries4) : @"Apple Watch Series 4 (40mm)", + @(AppleWatch44mmSeries4) : @"Apple Watch Series 4 (44mm)", + @(AppleWatch40mmSeries5) : @"Apple Watch Series 5 (40mm)", + @(AppleWatch44mmSeries5) : @"Apple Watch Series 5 (44mm)", + @(AppleWatchSE40mm) : @"Apple Watch SE (40mm)", + @(AppleWatchSE44mm) : @"Apple Watch SE (44mm)", + @(AppleWatch40mmSeries6) : @"Apple Watch Series 6 (40mm)", + @(AppleWatch44mmSeries6) : @"Apple Watch Series 6 (44mm)", + @(AppleWatch41mmSeries7) : @"Apple Watch Series 7 (41mm)", + @(AppleWatch45mmSeries7) : @"Apple Watch Series 7 (45mm)", + @(AppleWatchSE2_40mm) : @"Apple Watch SE (2nd generation, 40mm)", + @(AppleWatchSE2_44mm) : @"Apple Watch SE (2nd generation, 44mm)", + @(AppleWatch41mmSeries8) : @"Apple Watch Series 8 (41mm)", + @(AppleWatch45mmSeries8) : @"Apple Watch Series 8 (45mm)", + @(AppleWatchUltra49mm) : @"Apple Watch Ultra (49mm)", + @(AppleWatch41mmSeries9) : @"Apple Watch Series 9 (41mm)", + @(AppleWatch45mmSeries9) : @"Apple Watch Series 9 (45mm)", + @(AppleWatchUltra2_49mm) : @"Apple Watch Ultra 2 (49mm)", + @(AppleWatch42mmSeries10): @"Apple Watch Series 10 (42mm)", + @(AppleWatch46mmSeries10): @"Apple Watch Series 10 (46mm)", + @(Simulator) : @"Simulator" + }[@(deviceVersion)]; } + (DeviceSize)deviceSize { CGFloat screenHeight = CGRectGetHeight([WKInterfaceDevice currentDevice].screenBounds); - - if (screenHeight == 195) { - return Screen42mm; - } else if(screenHeight == 170) { + + // Screen heights for different watch sizes (in points = pixels / 2) + // 38mm: 340px = 170pt, 42mm: 390px = 195pt, 40mm: 394px = 197pt + // 41mm: 430px = 215pt, 44mm: 448px = 224pt, 45mm: 484px = 242pt + // 46mm: 496px = 248pt, 49mm: 502px = 251pt + if (screenHeight == 170) { return Screen38mm; + } else if (screenHeight == 195) { + return Screen42mm; + } else if (screenHeight == 197) { + return Screen40mm; + } else if (screenHeight == 215) { + return Screen41mm; + } else if (screenHeight == 224) { + return Screen44mm; + } else if (screenHeight == 242) { + return Screen45mm; + } else if (screenHeight == 248) { + return Screen46mm; + } else if (screenHeight == 251) { + return Screen49mm; } else { return UnknownSize; } @@ -74,10 +182,16 @@ + (DeviceSize)deviceSize + (NSString *)deviceSizeName:(DeviceSize)deviceSize { return @{ - @(UnknownSize) : @"Unknown Size", - @(Screen38mm) : @"38mm", - @(Screen42mm) : @"42mm" - }[@(deviceSize)]; + @(UnknownSize) : @"Unknown Size", + @(Screen38mm) : @"38mm", + @(Screen40mm) : @"40mm", + @(Screen41mm) : @"41mm", + @(Screen42mm) : @"42mm", + @(Screen44mm) : @"44mm", + @(Screen45mm) : @"45mm", + @(Screen46mm) : @"46mm", + @(Screen49mm) : @"49mm" + }[@(deviceSize)]; } + (NSString *)deviceName @@ -85,10 +199,10 @@ + (NSString *)deviceName struct utsname systemInfo; uname(&systemInfo); NSString *code = [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding]; - if ([code isEqualToString:@"x86_64"] || [code isEqualToString:@"i386"]) { + if ([code isEqualToString:@"x86_64"] || [code isEqualToString:@"i386"] || [code isEqualToString:@"arm64"]) { code = @"Simulator"; } - + return code; }