Roamkeeper: see what's left of your roaming allowance at a glance

Every time I travel, I end up doing the same thing: land, switch on roaming, and then spend the trip wondering how much of my data allowance is left. The carrier sends a text when I’ve used most of it, usually at the worst possible moment. So I built the app I wanted: Roamkeeper, an iPhone app that shows what’s left of your roaming allowance on your Home Screen and Lock Screen, without having to open anything.
How it works
You set up the package your carrier sold you once: the data, minutes and texts it includes, and the zone it covers, such as the EU. When you land, you start a trip. From then on Roamkeeper tracks what you use and shows what’s left on a widget.
- Home Screen widgets: a ring for one allowance, or a summary of all three.
- Lock Screen widgets: a ring, a line or a rectangle below the clock.
- Quick logging: log a text or a call straight from the widget, without unlocking your phone.
- Alerts: a notification at 50%, 20% and 5% remaining, and when an allowance runs out. You can pick your own thresholds.
- Monthly packages: if your allowance renews every month rather than every trip, all the trips in the same billing month share one pool, which is how carriers actually meter it.
The hard part: iOS won’t tell you you’re roaming
This was the most interesting problem. iOS has no public way for an app to ask “is this phone roaming?” or “what’s left on this carrier plan?”. The old carrier APIs were deprecated in iOS 16, and the ones that still exist are private, so using them would get the app rejected.
So Roamkeeper works with what iOS does allow, and is upfront about it:
- Data is measured, but it’s an estimate. The app reads how many bytes the iPhone has sent and received over cellular, using standard system APIs. It has to handle two tricky cases where the counter suddenly goes down: after a restart, when the counter starts again from zero, and when a 32-bit counter wraps around at about 4 GB. Roamkeeper tells them apart, so nothing gets double-counted or lost.
- You can always correct it. When your carrier texts you the real balance, tap Set balance and Roamkeeper carries on from there. For an exact figure, iOS itself shows Current Period Roaming in Settings › Mobile Service. Apps can’t read it, but you can type it in.
- Calls and texts are logged by hand, because iOS doesn’t let apps see them. The widget buttons make that a one-second job.
- Location is optional and off by default. Turn it on and Roamkeeper pauses counting while you’re in your home country. It only asks for “While Using the App”, and your location never leaves the phone.
Widgets that stay fresh without burning the battery
iOS gives each widget a daily budget of refreshes. Ask for updates too often and the budget runs out by lunchtime, leaving the widget stale until midnight. Roamkeeper asks for a refresh every 20 minutes during a trip, and none at all when there’s no trip running. Anything you do in the app updates the widgets instantly. The larger widgets also show how old the estimate is, using a label that updates itself without costing a refresh.
Private by design
There’s no account, no server and no analytics. Your trips and usage are stored on your iPhone and never leave it. The app has no third-party code in it at all.
A few details I’m proud of
- Five languages: English, Italian, French, German and Spanish, with proper plural rules and word order for each, rather than English sentences stitched together.
- Daily allowances reset at your local midnight, so crossing time zones behaves the way you’d expect.
- More than 100 automated tests cover the parts where a silent mistake would mean a wrong number: counter maths, restarts, time zones, alerts and monthly pools.
- The app icon is drawn in code: the same ring you see in the app, around a globe.
Built with
Swift, SwiftUI, SwiftData, WidgetKit and App Intents, for iOS 17 and later.
Roamkeeper is free, with every feature included. If you travel with an iPhone and have ever run out of roaming data halfway through a trip, it’s for you. I’d love to hear what you think: get in touch.
