DEV Community

Cover image for I wrote my own MTP engine in Swift because moving files off an Android phone shouldn't need Electron
sameh
sameh

Posted on

I wrote my own MTP engine in Swift because moving files off an Android phone shouldn't need Electron


Google's Android File Transfer for Mac is dead. The community replacement most people reach for, OpenMTP, is an Electron app — which always felt wrong to me for a utility whose whole job is shoving bytes over a cable as fast as possible.

So I wrote Android Rapid Transfer: a native file-transfer app for macOS, with a Linux build too, and its own MTP engine written from scratch in Swift. It's open source under the MIT license.

Why MTP is the hard part

MTP (Media Transfer Protocol) is the thing that makes phone-to-computer copies weird. Only one program can hold the phone at a time. Phones hide their files until you unlock them and tap "Allow". Some cables only charge. The protocol itself is chatty, so naive implementations crawl on folders with thousands of files.

The engine — MTPKit, with shared core logic in ARTCore — handles all of that: device detection and session management, bulk folder listings, and large transfers streamed in big USB reads and writes so throughput stays up. The UI only draws what's on screen, so a folder with 2,000 items lays out in about 50 milliseconds.

The Mac app

SwiftUI, dual-pane: your Mac's folders on one side, the phone's storage on the other, with Finder-style breadcrumbs and keyboard navigation. Copy either way with one click, drag between panes or straight from Finder, or queue files from several folders and paste them where they belong.

A few details I'm proud of:

  • Stop means stop. It takes effect immediately, even mid-file, and never leaves half-written files on either side. Interrupted copies can be resumed.
  • Live progress you can trust — files done, bytes, speed, time left, in the window, the Dock, and a notification when it finishes in the background.
  • Copy by date range — pick a range, get just those photos and videos, with a live preview while the phone is scanned.
  • It names the culprit. When another app has grabbed the phone (Google Drive, Dropbox, Samsung Smart Switch...), the connection screen tells you which one, because MTP only allows one at a time.

No analytics, no accounts, no telemetry. The only network call it makes on its own is the Sparkle update check, which you can turn off.

The Linux app

Same core and engine, native GTK4/libadwaita interface. It talks to the phone through the kernel's USB interface — no libusb, no libmtp, no FUSE mount — and notices plug/unplug through udev. When GNOME Files has the phone open, there's a "Release the Phone" button instead of a cryptic error. Ships as .deb, .rpm, AppImage, and tarball.

The numbers

Measured on one phone (Xiaomi REDMI Note 15 5G) over USB — single-device numbers, not a benchmark suite, your mileage will vary with phone, cable, and port (many phones only do USB 2.0 speeds regardless):

  • 200 MB file to the phone: ~38 MB/s · to the Mac: ~42 MB/s
  • Folder of 50 files to the phone: 1.9 s
  • Full phone scan (208 folders, 2,052 files): 2.2 s

There's a 42-second demo video in the README: first launch to finished copies.

What's next

Notarized builds, a Homebrew cask, and — the part I can't do alone — device-compatibility reports. If you still tether an Android phone to a Mac (or a Linux box), I'd genuinely like to know your transfer speeds and whether your device is detected.

Repo: https://github.com/sameh0/android-rapid-transfer

Top comments (0)