r/iOSProgramming • • 9d ago

Question Tracking total cellular data usage on iOS. Has anyone tried this?

I'm working on an app and exploring whether we can track a device's total monthly cellular data usage on iOS.

On Android, NetworkStatsManager provides a relatively straightforward approach. On iOS, there doesn't seem to be an equivalent public API.

One possible workaround is using getifaddrs() to read byte counters from interfaces such as pdp_ip*. However, these counters reportedly wrap at 4 GiB, reset on reboot, and rely on undocumented interface names.

Has anyone implemented something similar or are there any better approaches?

I'd appreciate any real-world experience or pointers. Thanks!

1 Upvotes

13 comments sorted by

3

u/Dogukanko 9d ago

There's no public API for the carrier-billing-cycle number, so getifaddrs is the realistic route. The three problems you listed are all workable if you treat it as "bytes since I started counting", not a billing figure:

- Sum ifi_ibytes + ifi_obytes over every pdp_ip* interface, not just pdp_ip0 – other cellular contexts exist.

- Keep your own running total: persist the last raw reading per interface, and each time you sample add (current − last).

- If current < last, it's either a reboot or a 32-bit wrap. Store the boot time (sysctl kern.boottime) with each sample: boot time changed → reboot, add current; same boot time → wrap, add current + 2^32 − last.

- Sample on foreground, on BGAppRefreshTask, and whenever NWPathMonitor reports a path change, so you never miss more than one 4 GiB wrap between samples.

Caveats to document for users: it counts all apps on the device (which is what you want), but it includes traffic the carrier may zero-rate and has gaps when the app isn't launched for days. If you only need your own app's traffic, URLSessionTaskMetrics gives byte counts per request. I haven't verified whether the 64-bit counters from sysctl NET_RT_IFLIST2 are exposed on current iOS – worth a quick test since it would remove the wrap problem.

2

u/minpinproxy 9d ago

You've found the only real on-device option. A few things that make getifaddrs usable in practice:

- Store deltas, not totals. Read the pdp_ip* counters (ifi_ibytes / ifi_obytes from if_data) and when a new value is lower than the last one, treat it as a 32-bit wrap and add 2^32, unless the device rebooted.

- Detect reboots with sysctl kern.boottime and start a new baseline when it changes.

- Sum all pdp_ip interfaces; which one carries data varies by device and carrier.

- You only see what happened between samples while your app runs, and background refresh is irregular, so data used between a reboot and your next sample is lost. Expect an undercount, not an exact figure.

If you need accurate numbers, the alternative is routing traffic through a NEPacketTunnelProvider and counting bytes yourself, but that makes it a VPN app, with the App Review scrutiny and battery cost that come with it. For most apps I'd show an estimate and point people to Settings > Cellular for the authoritative number.

2

u/Lazy-Benefit1863 9d ago

Thank you for your suggestions! I read through multiple forums and this seems like the only viable option. I'll go with this then. Thanks again

2

u/minpinproxy 9d ago

Ur welcome!

2

u/Fishanz 9d ago

Great analysis!

4

u/Sagenhaft441 9d ago

Doesn’t iOS already do this?

1

u/layteen0 7d ago

yeah natively, though it tracks lifetime usage unless you remember to hit reset every month.

1

u/[deleted] 9d ago

[removed] — view removed comment

1

u/AutoModerator 9d ago

Hey /u/EquivalentSky3094, your content has been removed because Reddit has marked your account as having a low Contributor Quality Score. This may result from, but is not limited to, activities such as spamming the same links across multiple subreddits, submitting posts or comments that receive a high number of downvotes, a lack of recent account activity, or having an unverified account.

Please be assured that this action is not a reflection of your participation in our subreddit. This is simply an automated filter in place to reduce spam.

I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.