Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support iOS, watchOS, tvOS #3

Merged
merged 5 commits into from
Jul 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions .github/workflows/json_format.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ name: JSON formatting checker
on:
push:
paths:
- "mac-device-identifiers*.json"
- "*-device-identifiers*.json"
pull_request:
paths:
- "mac-device-identifiers*.json"
- "*-device-identifiers*.json"

jobs:
format:
Expand All @@ -23,14 +23,17 @@ jobs:

- name: Format JSON files
run: |
npx jsonlint -i ios-device-identifiers.json
npx jsonlint -i tvos-device-identifiers.json
npx jsonlint -i watchos-device-identifiers.json
npx jsonlint -i mac-device-identifiers.json
npx jsonlint -i mac-device-identifiers-unique.json
- name: Check JSON files have changed
run: |
git diff --exit-code --quiet mac-device-identifiers*.json
git diff --exit-code --quiet *-device-identifiers*.json
- name: Check JSON length is same
- name: Check mac-device-identifiers.json is unique
run: |
length1=`cat mac-device-identifiers.json | jq length`
length2=`cat mac-device-identifiers-unique.json | jq length`
Expand Down
36 changes: 36 additions & 0 deletions .github/workflows/xcode-scrapper.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: Scrap from Xcode

on:
workflow_dispatch:
schedule:
- cron: '0 0 * * 1' # Every Monday at 00:00 UTC

jobs:
scrap:
runs-on: macos-latest

steps:
- name: Check out Git repository
uses: actions/checkout@v3

- name: Install Deno
uses: denoland/setup-deno@v1
with:
deno-version: v1.x

- name: Run scrape-from-xcode.ts
run: |
deno run --allow-run --allow-write scripts/scrape-from-xcode.ts

- name: Get current date
id: date
run: |
echo "DATE=$(date +'%Y-%m-%d')" >> $GITHUB_OUTPUT
echo "MONTH_YEAR=$(date +'%b %Y')" >> $GITHUB_OUTPUT

- name: Create Pull Request
uses: peter-evans/create-pull-request@v4
with:
title: "[${{ steps.date.outputs.MONTH_YEAR }}] Update apple device identifiers"
commit-message: "[${{ steps.date.outputs.DATE }}] Update apple device identifiers"
branch: scrapping-xcode
28 changes: 20 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,31 @@
# mac-device-identifiers
A json file for mapping macOS device identifiers to some human readable equivalent.
# apple-device-identifiers

A json file for mapping iOS, iPadOS, tvOS, watchOS, and macOS device identifiers to some human readable equivalent.

## Genrerate JSON file

```shell
$ deno run --allow-net --allow-write scripts/scrape-from-apple.ts
$ deno run --allow-read --allow-write scripts/migrate-json.ts
# iOS, iPadOS, tvOS, watchOS
deno run --allow-run --allow-write scripts/scrape-from-xcode.ts

# macOS
deno run --allow-net --allow-write scripts/scrape-from-apple.ts
deno run --allow-read --allow-write scripts/migrate-json.ts
```

## Source
## References (iOS, iPadOS, tvOS, watchOS)

- [Identify your iPhone model](https://support.apple.com/en-us/HT201296)
- [Identify your iPad model](https://support.apple.com/en-us/HT201471)
- [Identify your iPod model](https://support.apple.com/en-us/HT204217)
- [Identify your Apple Watch](https://support.apple.com/en-us/HT204507)
- [Identify your Apple TV model](https://support.apple.com/en-us/HT200008)

## Sources (macOS)

- [Identify your MacBook model](https://support.apple.com/en-us/HT201608)
- [Identify your MacBook Air model](https://support.apple.com/en-us/HT201862)
- [Identify your MacBook Pro model](https://support.apple.com/en-us/HT201300)
- [Identify your iMac model](https://support.apple.com/en-us/HT201634)
- [Identify your Mac mini model](https://support.apple.com/en-us/HT201894)
- [Identify your Mac Pro model](https://support.apple.com/en-us/HT202888)

## See also
- [fieldnotescommunities/ios-device-identifiers](https://github.com/fieldnotescommunities/ios-device-identifiers)
148 changes: 148 additions & 0 deletions ios-device-identifiers.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
{
"arm64": "iPhone Simulator",
"i386": "iPhone Simulator",
"iPad1,1": "iPad",
"iPad1,2": "iPad",
"iPad2,1": "iPad 2",
"iPad2,2": "iPad 2",
"iPad2,3": "iPad 2",
"iPad2,4": "iPad 2",
"iPad2,5": "iPad mini",
"iPad2,6": "iPad mini",
"iPad2,7": "iPad mini",
"iPad3,1": "iPad (3rd generation)",
"iPad3,2": "iPad (3rd generation)",
"iPad3,3": "iPad (3rd generation)",
"iPad3,4": "iPad (4th generation)",
"iPad3,5": "iPad (4th generation)",
"iPad3,6": "iPad (4th generation)",
"iPad4,1": "iPad Air",
"iPad4,2": "iPad Air",
"iPad4,3": "iPad Air",
"iPad4,4": "iPad mini 2",
"iPad4,5": "iPad mini 2",
"iPad4,6": "iPad mini 2",
"iPad4,7": "iPad mini 3",
"iPad4,8": "iPad mini 3",
"iPad4,9": "iPad mini 3",
"iPad5,1": "iPad mini 4",
"iPad5,2": "iPad mini 4",
"iPad5,3": "iPad Air 2",
"iPad5,4": "iPad Air 2",
"iPad6,3": "iPad Pro (9.7-inch)",
"iPad6,4": "iPad Pro (9.7-inch)",
"iPad6,7": "iPad Pro (12.9-inch)",
"iPad6,8": "iPad Pro (12.9-inch)",
"iPad6,11": "iPad (5th generation)",
"iPad6,12": "iPad (5th generation)",
"iPad7,1": "iPad Pro (12.9-inch) (2nd generation)",
"iPad7,2": "iPad Pro (12.9-inch) (2nd generation)",
"iPad7,3": "iPad Pro (10.5-inch)",
"iPad7,4": "iPad Pro (10.5-inch)",
"iPad7,5": "iPad (6th generation)",
"iPad7,6": "iPad (6th generation)",
"iPad7,11": "iPad (7th generation)",
"iPad7,12": "iPad (7th generation)",
"iPad8,1": "iPad Pro (11-inch)",
"iPad8,2": "iPad Pro (11-inch)",
"iPad8,3": "iPad Pro (11-inch)",
"iPad8,4": "iPad Pro (11-inch)",
"iPad8,5": "iPad Pro (12.9-inch) (3rd generation)",
"iPad8,6": "iPad Pro (12.9-inch) (3rd generation)",
"iPad8,7": "iPad Pro (12.9-inch) (3rd generation)",
"iPad8,8": "iPad Pro (12.9-inch) (3rd generation)",
"iPad8,9": "iPad Pro (11-inch) (2nd generation)",
"iPad8,10": "iPad Pro (11-inch) (2nd generation)",
"iPad8,11": "iPad Pro (12.9-inch) (4th generation)",
"iPad8,12": "iPad Pro (12.9-inch) (4th generation)",
"iPad11,1": "iPad mini (5th generation)",
"iPad11,2": "iPad mini (5th generation)",
"iPad11,3": "iPad Air (3rd generation)",
"iPad11,4": "iPad Air (3rd generation)",
"iPad11,6": "iPad (8th generation)",
"iPad11,7": "iPad (8th generation)",
"iPad12,1": "iPad (9th generation)",
"iPad12,2": "iPad (9th generation)",
"iPad13,1": "iPad Air (4th generation)",
"iPad13,2": "iPad Air (4th generation)",
"iPad13,4": "iPad Pro (11-inch) (3rd generation)",
"iPad13,5": "iPad Pro (11-inch) (3rd generation)",
"iPad13,6": "iPad Pro (11-inch) (3rd generation)",
"iPad13,7": "iPad Pro (11-inch) (3rd generation)",
"iPad13,8": "iPad Pro (12.9-inch) (5th generation)",
"iPad13,9": "iPad Pro (12.9-inch) (5th generation)",
"iPad13,10": "iPad Pro (12.9-inch) (5th generation)",
"iPad13,11": "iPad Pro (12.9-inch) (5th generation)",
"iPad13,16": "iPad Air (5th generation)",
"iPad13,17": "iPad Air (5th generation)",
"iPad13,18": "iPad (10th generation)",
"iPad13,19": "iPad (10th generation)",
"iPad14,1": "iPad mini (6th generation)",
"iPad14,2": "iPad mini (6th generation)",
"iPad14,3-A": "iPad Pro (11-inch) (4th generation)",
"iPad14,3-B": "iPad Pro (11-inch) (4th generation)",
"iPad14,4-A": "iPad Pro (11-inch) (4th generation)",
"iPad14,4-B": "iPad Pro (11-inch) (4th generation)",
"iPad14,5-A": "iPad Pro (12.9-inch) (6th generation)",
"iPad14,5-B": "iPad Pro (12.9-inch) (6th generation)",
"iPad14,6-A": "iPad Pro (12.9-inch) (6th generation)",
"iPad14,6-B": "iPad Pro (12.9-inch) (6th generation)",
"iPhone1,1": "iPhone",
"iPhone1,2": "iPhone 3G",
"iPhone2,1": "iPhone 3GS",
"iPhone3,1": "iPhone 4",
"iPhone3,2": "iPhone 4",
"iPhone3,3": "iPhone 4",
"iPhone4,1": "iPhone 4s",
"iPhone5,1": "iPhone 5",
"iPhone5,2": "iPhone 5",
"iPhone5,3": "iPhone 5c",
"iPhone5,4": "iPhone 5c",
"iPhone6,1": "iPhone 5s",
"iPhone6,2": "iPhone 5s",
"iPhone7,1": "iPhone 6 Plus",
"iPhone7,2": "iPhone 6",
"iPhone8,1": "iPhone 6s",
"iPhone8,2": "iPhone 6s Plus",
"iPhone8,4": "iPhone SE (1st generation)",
"iPhone9,1": "iPhone 7",
"iPhone9,2": "iPhone 7 Plus",
"iPhone9,3": "iPhone 7",
"iPhone9,4": "iPhone 7 Plus",
"iPhone10,1": "iPhone 8",
"iPhone10,2": "iPhone 8 Plus",
"iPhone10,3": "iPhone X",
"iPhone10,4": "iPhone 8",
"iPhone10,5": "iPhone 8 Plus",
"iPhone10,6": "iPhone X",
"iPhone11,2": "iPhone XS",
"iPhone11,4": "iPhone XS Max",
"iPhone11,6": "iPhone XS Max",
"iPhone11,8": "iPhone XR",
"iPhone12,1": "iPhone 11",
"iPhone12,3": "iPhone 11 Pro",
"iPhone12,5": "iPhone 11 Pro Max",
"iPhone12,8": "iPhone SE (2nd generation)",
"iPhone13,1": "iPhone 12 mini",
"iPhone13,2": "iPhone 12",
"iPhone13,3": "iPhone 12 Pro",
"iPhone13,4": "iPhone 12 Pro Max",
"iPhone14,2": "iPhone 13 Pro",
"iPhone14,3": "iPhone 13 Pro Max",
"iPhone14,4": "iPhone 13 mini",
"iPhone14,5": "iPhone 13",
"iPhone14,6": "iPhone SE (3rd generation)",
"iPhone14,7": "iPhone 14",
"iPhone14,8": "iPhone 14 Plus",
"iPhone15,2": "iPhone 14 Pro",
"iPhone15,3": "iPhone 14 Pro Max",
"iPod1,1": "iPod touch",
"iPod2,1": "iPod touch (2nd generation)",
"iPod3,1": "iPod touch (3rd generation)",
"iPod4,1": "iPod touch (4th generation)",
"iPod5,1": "iPod touch (5th generation)",
"iPod7,1": "iPod touch (6th generation)",
"iPod9,1": "iPod touch (7th generation)",
"MacFamily20,1": "Mac",
"x86_64": "iPhone Simulator"
}
35 changes: 35 additions & 0 deletions scripts/scrape-from-xcode.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/bin/bash

# Scrape device_traits.db from Xcode to get a list of all device types

# Usage: ./scrape-from-xcode.sh <platform>
# Example: ./scrape-from-xcode.sh iPhoneOS

# Requires jq: https://stedolan.github.io/jq/
# Requires sqlite3: https://www.sqlite.org/index.html
# Tested with Xcode 14.3.1

# Platform: iPhoneOS | AppleTVOS | WatchOS
PLATFORM=$1

if [ -z "$PLATFORM" ]; then
echo "Usage: $0 <platform>"
exit 1
fi

if [ "$PLATFORM" != "iPhoneOS" ] && [ "$PLATFORM" != "AppleTVOS" ] && [ "$PLATFORM" != "WatchOS" ]; then
echo "Error: Invalid platform: $PLATFORM"
exit 1
fi

DB_FILE="/Applications/Xcode.app/Contents/Developer/Platforms/$PLATFORM.platform/usr/standalone/device_traits.db"

if [ ! -f "$DB_FILE" ]; then
echo "Error: $DB_FILE not found"
exit 1
fi

QUERY="SELECT ProductType as key, ProductDescription as value FROM Devices"

json=$(sqlite3 "$DB_FILE" "$QUERY" -json | jq -r 'map({(.key): .value}) | add')
echo "$json"
39 changes: 39 additions & 0 deletions scripts/scrape-from-xcode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
async function scrapeFromXcode(platform: string) {
const process = Deno.run({ cmd: ["bash", "-c", `scripts/scrape-from-xcode.sh ${platform}`], stdout: "piped" });
const output = await process.output().then((o) => new TextDecoder().decode(o));
const obj = JSON.parse(output);
return obj as { [key: string]: string };
}

const collator = new Intl.Collator(undefined, { numeric: true, sensitivity: "base" });
function naturalSort(dict: { [key: string]: string }) {
const sortedKeys = [...Object.keys(dict)].sort((a, b) => collator.compare(a, b));
const sortedDict = {} as { [key: string]: string };
sortedKeys.forEach((key) => (sortedDict[key] = dict[key]));
return sortedDict;
}

async function generateJsonFile(platform: { name: string; file: string }) {
console.log(`Generating ${platform.file}...`);
const dict = await scrapeFromXcode(platform.name);

console.log(`Merging with previous ${platform.file}...`);
const old = await Deno.readTextFile(platform.file)
.catch(() => "{}")
.then((s) => JSON.parse(s) as { [key: string]: string });
const merged = { ...dict, ...old };
const sorted = naturalSort(merged);

console.log(`Writing ${platform.file}...`);
const json = JSON.stringify(sorted, null, 2);
await Deno.writeTextFile(platform.file, json);
}

const platforms = [
{ name: "iPhoneOS", file: "ios-device-identifiers.json" },
{ name: "WatchOS", file: "watchos-device-identifiers.json" },
{ name: "AppleTVOS", file: "tvos-device-identifiers.json" },
];
await Promise.all(platforms.map((p) => generateJsonFile(p)));

console.log("Done!");
10 changes: 10 additions & 0 deletions tvos-device-identifiers.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"AppleTV1,1": "Apple TV (1st generation)",
"AppleTV2,1": "Apple TV (2nd generation)",
"AppleTV3,1": "Apple TV (3rd generation)",
"AppleTV3,2": "Apple TV (3rd generation)",
"AppleTV5,3": "Apple TV HD",
"AppleTV6,2": "Apple TV 4K (1st generation)",
"AppleTV11,1": "Apple TV 4K (2nd generation)",
"AppleTV14,1": "Apple TV 4K (3rd generation)"
}
41 changes: 41 additions & 0 deletions watchos-device-identifiers.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"Watch1,1": "Apple Watch (1st generation)",
"Watch1,2": "Apple Watch (1st generation)",
"Watch2,3": "Apple Watch Series 2",
"Watch2,4": "Apple Watch Series 2",
"Watch2,6": "Apple Watch Series 1",
"Watch2,7": "Apple Watch Series 1",
"Watch3,1": "Apple Watch Series 3 (GPS + Cellular)",
"Watch3,2": "Apple Watch Series 3 (GPS + Cellular)",
"Watch3,3": "Apple Watch Series 3 (GPS)",
"Watch3,4": "Apple Watch Series 3 (GPS)",
"Watch4,1": "Apple Watch Series 4 (GPS)",
"Watch4,2": "Apple Watch Series 4 (GPS)",
"Watch4,3": "Apple Watch Series 4 (GPS + Cellular)",
"Watch4,4": "Apple Watch Series 4 (GPS + Cellular)",
"Watch5,1": "Apple Watch Series 5 (GPS)",
"Watch5,2": "Apple Watch Series 5 (GPS)",
"Watch5,3": "Apple Watch Series 5 (GPS + Cellular)",
"Watch5,4": "Apple Watch Series 5 (GPS + Cellular)",
"Watch5,9": "Apple Watch SE (GPS)",
"Watch5,10": "Apple Watch SE (GPS)",
"Watch5,11": "Apple Watch SE (GPS + Cellular)",
"Watch5,12": "Apple Watch SE (GPS + Cellular)",
"Watch6,1": "Apple Watch Series 6 (GPS)",
"Watch6,2": "Apple Watch Series 6 (GPS)",
"Watch6,3": "Apple Watch Series 6 (GPS + Cellular)",
"Watch6,4": "Apple Watch Series 6 (GPS + Cellular)",
"Watch6,6": "Apple Watch Series 7 (GPS)",
"Watch6,7": "Apple Watch Series 7 (GPS)",
"Watch6,8": "Apple Watch Series 7 (GPS + Cellular)",
"Watch6,9": "Apple Watch Series 7 (GPS + Cellular)",
"Watch6,10": "Apple Watch SE (GPS)",
"Watch6,11": "Apple Watch SE (GPS)",
"Watch6,12": "Apple Watch SE (GPS + Cellular)",
"Watch6,13": "Apple Watch SE (GPS + Cellular)",
"Watch6,14": "Apple Watch Series 8 (GPS)",
"Watch6,15": "Apple Watch Series 8 (GPS)",
"Watch6,16": "Apple Watch Series 8 (GPS + Cellular)",
"Watch6,17": "Apple Watch Series 8 (GPS + Cellular)",
"Watch6,18": "Apple Watch Ultra"
}