Skip to content

Instantly share code, notes, and snippets.

@henrik242
Last active April 19, 2025 20:26
Show Gist options
  • Save henrik242/1da3a252ca66fb7d17bca5509a67937f to your computer and use it in GitHub Desktop.
Save henrik242/1da3a252ca66fb7d17bca5509a67937f to your computer and use it in GitHub Desktop.
Read AirTag data from the FindMy.app cache and convert to GPX
#!/usr/bin/env bash
#
# Reads AirTag data from the FindMy.app cache and converts it to a daily GPX file
#
# Rsyncs the data to a web accessible folder that can be displayed with e.g.
# https://gist.github.com/henrik242/84ad80dd2170385fe819df1d40224cc4
#
# This should typically be run as a cron job
#
set -o pipefail -o nounset -o errexit
export PATH=/usr/local/bin:$PATH
DATADIR=/tmp/airtag-data
TODAY=$(date +%d)
mkdir -p $DATADIR
DATA=$DATADIR/airtagdata-$TODAY.txt
GPX=$DATADIR/airtagdata-$TODAY.gpx
TAGNAME=Foobar
if [[ $(uname -s) == "Darwin" ]]; then
TOMORROW=$(date -v +1d +%d)
else
TOMORROW=$(date --date="tomorrow" +%d)
fi
rm -f $DATADIR/airtagdata-$TOMORROW.gpx
jq -r '.[] | select(.name == "'$TAGNAME'") | .location | "\(.latitude) \(.longitude) \(.altitude) \(.timeStamp/1000 | todate)"' \
$HOME/Library/Caches/com.apple.findmy.fmipcore/Items.data >> $DATA
START='<?xml version="1.0" encoding="UTF-8"?>
<gpx xmlns="http://www.topografix.com/GPX/1/1" xmlns:mytracks="http://mytracks.stichling.info/myTracksGPX/1/0" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" creator="myTracks" version="1.1" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd">
<trk>
<name>'$TAGNAME'</name>
<extensions>
<mytracks:color red="0.000000" green="0.000000" blue="1.000000" alpha="1.000000" />
<mytracks:area showArea="no" areaDistance="0.000000" />
<mytracks:directionArrows showDirectionArrows="yes" />
<mytracks:sync syncPhotosOniPhone="no" />
<mytracks:timezone offset="120" />
</extensions>
<trkseg>'
END=' </trkseg>
</trk>
</gpx>'
echo $START > $GPX
function elems() {
LAT=$1
LON=$2
ELE=$3
TS=$4
}
cat $DATA | while read line; do
elems $line
echo '<trkpt lat="'$LAT'" lon="'$LON'">
<ele>'$ELE'</ele>
<time>'$TS'</time>
</trkpt>' >> $GPX
done
echo $END >> $GPX
cp $GPX $DATADIR/airtagdata.gpx
rsync -a --exclude='*.txt' $DATADIR example.com:public_html/airtag/
@wilkyconsultants
Copy link

The best recommendation is to buy a cheap Mac that supports macOS Sonoma 14.3.1 (minimum models: MacBook Air 2018, MacBook Pro 2018, Mac mini 2018, iMac 2019, or newer). Install macOS Sonoma 14.3.1, the last version before Apple started encrypting Find My cache files. This allows you to read AirTag and shared item locations directly from:

~/Library/Caches/com.apple.findmy.fmipcore/Items.data
~/Library/Caches/com.apple.findmy.fmipcore/Devices.data

With this setup, you can still extract the data in plain format using available scripts. In newer macOS versions, reading this data is practically impossible due to the encryption implemented by Apple.

I am using a Mac Mini 2012 with Sonoma 14.3.1 for my data collection along with a bunch of VMs running Monterey. Sonoma is better as it can access shared tags as well but Monterey is a good fall back since it can run in a small Macos VM under windows. With a 16 GB memory on a windows box you can run 5 VMs with no issues getting you 5 x 32 tags = 160 on 1 box!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment