{"id":13340086,"url":"https://github.com/kudit/Device","last_synced_at":"2025-03-11T16:32:10.538Z","repository":{"id":226678484,"uuid":"761395799","full_name":"kudit/Device","owner":"kudit","description":"UIDevice-like replacement that works on all platforms with a consistent API.","archived":false,"fork":false,"pushed_at":"2024-10-18T18:36:56.000Z","size":18746,"stargazers_count":15,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-10-25T14:42:39.051Z","etag":null,"topics":["battery","battery-level","battery-state","device","device-family","device-information","identifier-mapping","ios","maccatalyst","macos","simulator","swift","swift-playgrounds","swiftpm","thermal-state","tvos","visionos","watchos"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kudit.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-02-21T19:41:54.000Z","updated_at":"2024-10-25T11:15:04.000Z","dependencies_parsed_at":"2024-03-21T02:45:16.721Z","dependency_job_id":"993becf8-da11-4f73-86cc-a577313a01ba","html_url":"https://github.com/kudit/Device","commit_stats":null,"previous_names":["kudit/device"],"tags_count":64,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kudit%2FDevice","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kudit%2FDevice/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kudit%2FDevice/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kudit%2FDevice/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kudit","download_url":"https://codeload.github.com/kudit/Device/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243070409,"owners_count":20231448,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["battery","battery-level","battery-state","device","device-family","device-information","identifier-mapping","ios","maccatalyst","macos","simulator","swift","swift-playgrounds","swiftpm","thermal-state","tvos","visionos","watchos"],"created_at":"2024-07-29T19:22:07.544Z","updated_at":"2025-03-11T16:32:05.487Z","avatar_url":"https://github.com/kudit.png","language":"Swift","funding_links":["http://paypal.me/kudit"],"categories":[],"sub_categories":[],"readme":"\u003cimg src=\"/Development/Resources/Assets.xcassets/AppIcon.appiconset/Icon.png\" height=\"128\"\u003e\n\n[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fkudit%2FDevice%2Fbadge%3Ftype%3Dplatforms)](https://swiftpackageindex.com/kudit/Device)\n\n# Device.swiftpm\nDevice is a value-type replacement for device information on all supported platforms (very similar to DeviceKit but designed to be easier to maintain).  Device definitions include clear initializers so anyone can add new devices and contribute to the project even on an iPad using Swift Playgrounds rather than requiring Xcode.  No need to memorize mapping schema or use additional build tools.\n\nThe primary goals are to be easily maintainable by multiple individuals, employ a consistent API that can be used across all platforms, and to be maintainable using Swift Playgrounds on iPad and macOS.  APIs are typically present even on platforms that don't support all features so that availability checks do not have to be performed in external code, and where irrelevant, code can simply return optionals.\n\nThis is actively maintained so if there is a feature request or change, we will strive to address within a week.\n\n\n## Features\n- Can develop and modify without Xcode using Swift Playgrounds on iPad!\n- Framework\n    - Clearly labeled device identification\n    - Device idiom detection\n    - Environmental detections:\n        - Simulator\n        - Playground\n        - Preview\n        - Designed for iPad\n        - macCataylst\n- Debugging\n    - Provides UI for quickly showing information about devices and batteries.\n- Device Information\n    - Identifier (ex: `Mac14,10`)\n    - Name (ex: `Ben's iPad` Note: only available on some devices.)\n    - Operating System (ex: `iPad OS 17.4`)\n    - Official Name (ex: `MacBook Pro (16-inch, 2023`)\n    - Image\n    - Color\n    - CPU (ex: `M2 Pro`)\n    - Cellular technology\n    - Thermal state\n    - Orientation\n    - Screen information\n        - Size\n        - Diagonal\n        - Pixels Per Inch (PPI)\n        - Ratio\n- Battery \u0026 Power Information\n    - Battery availability\n    - Battery state changes\n    - Battery level\n    - Low Power Mode\n    - Plugged in\n    - Battery View\n    - Battery Symbols\n    - Battery Coloring\n- User Hardware Settings\n    - Disable Idle Timer (set permanently or automatically when plugged in)\n    - Display Zoom\n    - Guided Access\n    - Screen Brightness (only available on iOS)\n    - Available Disk Space\n- Capabilities (with symbols for each)\n    - Model Attributes\n        - Pro\n        - Air\n        - mini\n        - Plus\n        - Max\n        - Mac form factor\n        -  Watch size\n    - Connections\n        - Headphone Jack\n        - 30-pin Connector\n        - Lightning Connector\n        - USB-C\n        - Thunderbolt\n    - Power\n        - Battery\n        - Wireless Charging\n        - MagSafe (MacBook and iPhone)\n    - Dislplay Features\n        - Force/3D Touch\n        - Rounded Corners\n        - Notch\n        - Dynamic Island\n    - Additional Features\n        - Ringer Switch\n        -  Pay\n        - NFC\n        - Action Button\n        -  Pencil Support\n    - Sensors\n        - Biometrics\n        - LIDAR\n        - Barometer\n        - Crash Detection\n        - Cameras\n\n\n## Requirements\n- iOS 11+ (15.2+ minimum required for Swift Playgrounds support)\n- macOS 10.5+ (UI only supported on macOS 12.0+)\n- macCatalyst 13.0+ (first version available)\n- tvOS 11.0+ (UI only supported on tvOS 15.0+, 17+ required for most SwiftUI features)\n- watchOS 4.0+ (UI only supported on watchOS 8.0+)\n- visionOS 1.0+\n- Theoretically should work with Linux, Windows, and Vapor, but haven't tested.  If you would like to help, please let us know.\n\n\n## Known Issues\nBuilt for macOS \"Designed for iPad\" returns an iPad profile instead of actual hardware profile.\nCustom Symbols likely won't work in macOS \u003c 13 or watchOS \u003c 7.\nLowPowerMode checks unavailable in macOS \u003c 12.\n*See CHANGELOG.md for more known issues and roadmap*\n\n\n## Installation\nInstall by adding this as a package dependency to your code.  This can be done in Xcode or Swift Playgrounds!\n\n### Swift Package Manager\n\n#### Swift 5+\nYou can try these examples in a Swift Playground by adding package: `https://github.com/kudit/Device`\n\nIf the repository is private, use the following link to import: `https://\u003cyour-PAT-string\u003e@github.com/kudit/Device.git`\n\nOr you can manually enter the following in the Package.swift file:\n```swift\ndependencies: [\n    .package(url: \"https://github.com/kudit/Device.git\", from: \"2.0.0\"),\n]\n```\n\n\n## Usage\nFirst make sure to import the framework:\n```swift\nimport Device\n```\n\nHere are some usage examples.\n\n### Get the version of Device that is imported.\n```swift\nlet version = Device.version\n```\n\n### Get the device You're Running On\n```swift\nlet device = await Device.current // await required if not on the main thread (@MainActor isolated)\n\nprint(device) // prints, for example, \"iPhone 6 Plus\"\n\nif device.has(.force3dTouch) {\n    // do something that needs force-touch.\n} else {\n    // fallback for devices that do not support this.\n}\n\nif device.is(.plus) || device.is(.max) {\n    // do something only available for \"Plus\" model devices.\n}\n\nif device.has(.battery) \u0026\u0026 device.has(.lidar) \u0026\u0026 device.has(.headphoneJack) {\n    // do something only if there is a battery, lidar, and a headphoneJack\n}\n```\nGet the full list of flags that can be queried for under the enum Capability in Hardware.swift.\n\n### Get the device idiom\n```swift\nlet device = Device.current\nif device.idiom == .pad {\n  // iPad\n} else if device.idiom == .phone {\n  // iPhone\n} else if device.idiom == .vision {\n  // Apple Vision device\n}\n```\n\n### Check if running in a Simulator\n```swift\nif Device.isSimulator {\n  // Running on one of the simulators\n  // Skip doing something irrelevant for Simulator\n} \n```\n\n### Check if running in a Preview\n```swift\nif Device.isPreview {\n  // Running in an XCode #Preview\n} \n```\n\n### Check if running in a Playground\n```swift\nif Device.isPlayground {\n  // Running in an XCode #Preview\n} \n```\n\n### Check if running on a physical device\n```swift\nif Device.isRealDevice {\n  // Running on physical hardware and not a simulator\n} \n```\n\n### Get the Current Battery State\n**Note:**\n\n\u003e When getting the current battery state, battery monitoring enabled will be temporarily set to true and then restored to whatever it was beforehand, so no need to manage monitoring separately.  If you need to be notified when the battery state or level changes, you can add a monitor that will call your code whenever the level changes.  However, typically this can just be dropped in as the DeviceBattery is an ObservableObject.\n\n```swift\n\n\nif let battery = Device.current.battery {\n    // do things that need the battery\n    if battery.currentState == .full || (battery.currentState == .charging \u0026\u0026 battery.currentLevel \u003e= 75) {\n        print(\"Your battery is happy! 😊\")\n    }\n    \n    // get the current battery level\n    if battery.currentLevel \u003e= 50 {\n        install_iOS()\n    } else {\n        showLowBatteryWarning()\n    }\n\n    if battery.lowPowerMode {\n        print(\"Low Power mode is enabled! 🔋\")\n    } else {\n        print(\"Low Power mode is disabled! 😊\")\n    }\n\n    // add monitor to do something whenever battery level changes (like updating UI)\n    battery.addMonitor {\n        localBatteryLevel = battery.currentLevel\n        localBatteryState = battery.currentState\n    }\n} else {\n    // handle behaviour on devices without a battery\n}\n```\n\n### Get the Current Battery Level\n```swift\nif let level = Device.current.battery?.currentLevel, level \u003e= 50 {\n  install_iOS()\n} else {\n  showError()\n}\n```\n\n### Check if a Guided Access session is currently active\n```swift\nif Device.current.isGuidedAccessSessionActive {\n  print(\"Guided Access session is currently active\")\n} else {\n  print(\"No Guided Access session is currently active\")\n}\n```\n\n### Get Screen Brightness\n```swift\nif Device.current.screenBrightness \u003e 50 {\n  print(\"Take care of your eyes!\")\n}\n```\n\n### Get Available Disk Space\n```swift\nif Device.current.volumeAvailableCapacityForOpportunisticUsage ?? 0 \u003e Int64(1_000_000) {\n  // download that nice-to-have huge file\n}\n\nif Device.current.volumeAvailableCapacityForImportantUsage ?? 0 \u003e Int64(1_000) {\n  // download that file you really need\n}\n```\n\n### Disabling the Idle Timer\n```swift\nDevice.current.isIdleTimerDisabled = true // must be run on the main actor\n\n// Disable automatically when plugged in.  Only call this once (probably during init).\nDevice.current.disableIdleTimerWhenPluggedIn()\n```\n\n### Displaying a BatteryView\n```swift\n// BatteryView() will default to a view with a live updating battery indicator.\nBatteryView()\n// you can have a larger one by changing the font size\nBatteryView(fontSize: 80)\n```\n\nAll these tests can be demonstrated using previews or by running the app executable that is bundled in the Development folder of the module.\n\n## Source of Information\nSome information has been sourced from the following:\n- https://www.theiphonewiki.com/wiki/Models\n- https://www.everymac.com\n- https://github.com/devicekit/DeviceKit\n\n## Contributing\nIf you have the need for a specific feature that you want implemented or if you experienced a bug, please open an issue.\nIf you extended the functionality yourself and want others to use it too, please submit a pull request.\n\n\n## Donations\nThis was a lot of work.  If you find this useful particularly if you use this in a commercial product, please consider making a donation to http://paypal.me/kudit\n\n\n## License\nFeel free to use this in projects, however, please include a link back to this project and credit somewhere in the app.  Example Markdown and string interpolation for the version:\n```swift\nText(\"Open Source projects used include [Device](https://github.com/kudit/Device) v\\(Device.version)\n```\n\n\n## Contributors\nThe complete list of people who contributed to this project is available [here](https://github.com/kudit/Device/graphs/contributors).\nA big thanks to everyone who has contributed! 🙏\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkudit%2FDevice","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkudit%2FDevice","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkudit%2FDevice/lists"}