Library / SDK
iziz/libPhoneNumber-iOS avatar
iziz/libPhoneNumber-iOS

iziz/libPhoneNumber-iOS: An iOS Port of Google's libphonenumber With a Swift Facade on Top

iOS port of Google's libphonenumber with Objective-C core, Swift facade, SwiftUI input, and CocoaPods/SPM support

2,382 stars483 forksObjective-CApache-2.0

At a glance

What is it?
The Objective-C core still does the parsing, formatting and validation work. The Swift modules wrap it in smaller, task-focused imports, and the SwiftUI input ships as a separate product rather than inside the parser.
Who is it for?
Adopt it if you are shipping an Apple-platform app that needs offline parsing, formatting, validation, geocoding or short-number handling and you want to pick only the modules you use. Skip it if you need a non-Apple target, or if you are pinned to Xcode versions older than the ones the current release supports; version 1.7.x covers iOS 12 but cannot be built with Xcode 27.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 7 days ago.
What is it written in?
Mainly Objective-C, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 2, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What iziz/libPhoneNumber-iOS Actually Solves

Phone number handling looks like string work until you try it. A number typed by a user carries no country, no format guarantee, and no indication of whether the digits are long enough to be real. Google's libphonenumber solved that problem for Java and other runtimes by shipping metadata tables and the parsing rules that go with them. This project is the Apple-platform port of that metadata and behaviour.

The audience is narrow and specific: iOS, macCatalyst, tvOS, watchOS, macOS and visionOS developers who need validation, formatting, geocoding or short-number handling to run on the device rather than against a server. The README frames the split clearly. Use the Objective-C API when you need source-compatible legacy integration. Use the Swift facade modules for value-oriented parsing, formatting, validation, geocoding, short-number support, or a SwiftUI phone input.

That dual-surface design is the interesting part. Most ports pick one API and force everyone through it. Here the Objective-C core is described as the source of truth for parsing, formatting, validation, geocoding and short-number behaviour, while the Swift modules are task-focused imports layered on top.

How the Objective-C Core and Swift Facades Fit Together

The repository layout shows the layering. The core lives in libPhoneNumber/, with shared internals in libPhoneNumberInternal/. Each optional capability has its own directory and its own metadata: libPhoneNumberGeocoding/ with libPhoneNumberGeocodingMetaData/, libPhoneNumberShortNumber/ with libPhoneNumberShortNumberInternal/, libPhoneNumberCarrier/ with libPhoneNumberCarrierMetaData/, and libPhoneNumberTimeZones/ with libPhoneNumberTimeZonesMetaData/. The Swift facades mirror those names with a Swift prefix: libPhoneNumberSwiftCore/, libPhoneNumberSwiftGeocoding/, libPhoneNumberSwiftShortNumber/, libPhoneNumberSwiftCarrier/, libPhoneNumberSwiftTimeZones/, plus libPhoneNumberSwiftUI/ and libPhoneNumberSwiftUIEnrichment/.

The consequence is that metadata is not one monolith. Geocoding, carrier and timezone data arrive as separate bundles, which is why the README says those modules are opt-in because they ship metadata bundles. If you only need validation, you do not pay for the geocoding tables.

The SwiftUI module is deliberately outside the umbrella. The README states that the SwiftUI module is intentionally separate from the umbrella module because it is UI-specific and requires SwiftUI runtime availability. The umbrella product, libPhoneNumberIOSSwift, is described as one non-UI import covering core, geocoding and short-number facades. That is a sensible boundary, and it is one of the few places where the project's packaging choices are explained rather than just listed.

Installing via Swift Package Manager and a First Parse

The README gives the package URL directly. Add the repository as a package dependency:

text
https://github.com/iziz/libPhoneNumber-iOS

Then select only the products the app needs. For most Swift apps the README recommends starting with the core facade:

swift
.product(name: "libPhoneNumberSwiftCore", package: "libPhoneNumber")

Optional modules are added the same way, for example libPhoneNumberSwiftGeocoding, libPhoneNumberSwiftShortNumber, libPhoneNumberSwiftCarrier, libPhoneNumberSwiftTimeZones, libPhoneNumberSwiftUI and libPhoneNumberSwiftUIEnrichment. If you want a single non-UI import that covers core, geocoding and short-number facades, use the umbrella instead:

swift
.product(name: "libPhoneNumberIOSSwift", package: "libPhoneNumber")

CocoaPods users have a parallel set of pod names. The core Objective-C API is pod 'libPhoneNumber-iOS', '~> 2.1', the Swift core facade is pod 'libPhoneNumber-iOS-SwiftCore', '~> 2.1', and the Swift umbrella is pod 'libPhoneNumber-iOS-Swift', '~> 2.1'. The README shows the umbrella import as:

swift
import libPhoneNumberIOSSwift

Objective-C-compatible products are also published under the plain names: libPhoneNumber, libPhoneNumberGeocoding, libPhoneNumberShortNumber, libPhoneNumberCarrier and libPhoneNumberTimeZones. Carthage is listed as compatible in the badges and the README begins a Carthage section, though the excerpt cuts off before the configuration is shown. The README does not document an example parse call, so check the demo app in libPhoneNumber-Demo/ and the test targets for the exact API surface before you write integration code.

The Metadata Bundle Is the Real Dependency

This library is only as good as the tables underneath it. The release notes tie each version to a Google metadata revision: 2.1.1 corresponds to metadata v9.0.40, and 2.1.0 to metadata v9.0.39. The README says metadata updates are tracked against Google libphonenumber with parity checks and review artifacts, and the generatedJSON/ directory at the repository root is consistent with a generated-data pipeline.

That has a practical cost. Updating the library is not just a version bump in your manifest; it changes the numbers your app considers valid, the formats it produces, and the geocoding and carrier results it returns. If your tests assert on formatted output for a specific region, a metadata bump can break them. The CHANGELOG.md is the file to read before upgrading, and the release notes are the place where the metadata revision is stated.

The upside is that the project does not invent its own notion of a valid number. It follows Google's, which means behaviour should line up with server-side validation done with libphonenumber elsewhere in your stack. That consistency is the main reason to choose this over a hand-rolled regex, and it is worth more than any feature list.

Carrier Lookup and Timezone Lookup Are Hints, Not Facts

Two of the optional modules come with caveats the README states outright, and they are worth repeating because they affect product decisions.

Carrier names are original-assignment hints and may be misleading in mobile-number-portable regions. The README points to a safe-display API for user-facing carrier labels. If you are building a screen that says "your carrier is X", the raw lookup is the wrong call in any market where number portability is normal. This is not a bug; it is a property of prefix-based lookup.

Timezone lookup has a different limitation. The README says it returns possible CLDR timezone IDs from prefix metadata, not the user's current location. That distinction matters if you were hoping to use it for scheduling or for anything that depends on where the device actually is. It is a set of candidates derived from the number's prefix, nothing more. Both modules are opt-in partly because they ship metadata bundles, so you are also trading app size for capability you may not need.

Platform Floors and the Xcode 27 Constraint

The requirements table sets minimums at iOS 15.0, macCatalyst 15.0, tvOS 15.0, watchOS 9.0, macOS 12.0 and visionOS 1.0. The README explains why those numbers and not lower ones: these are the lowest deployment targets Xcode 27 accepts. It also names the escape hatch. Version 1.7.x supports iOS 12, tvOS 12, watchOS 4 and macOS 10.13, but cannot be built with Xcode 27.

That is a clean, honest trade-off statement, and it is the single most useful paragraph in the README for anyone evaluating adoption. If you maintain an app that still supports iOS 12, the current line is not available to you at the deployment target you need, and staying on 1.7.x means staying off Xcode 27. There is no third option documented.

The toolchain requirements are equally specific. The Swift package requires Swift 6 tools and builds in the Swift 6 language mode, while the CocoaPods specs accept Swift 5.9 or 6.0. A team on an older Swift toolchain can still consume the pods, but not the package. That asymmetry is easy to miss when comparing the two install paths.

Compared With PhoneNumberKit

PhoneNumberKit is the obvious alternative for Apple developers, and the difference is architectural rather than cosmetic. PhoneNumberKit is a native Swift library: its parsing and formatting code is written in Swift, and its metadata is packaged for its own implementation. This project takes the opposite route. The Objective-C core is a port of Google's libphonenumber metadata and behaviour, and the Swift modules are facades over that core rather than a reimplementation.

What that buys you is fidelity to Google's rules and a metadata revision you can name per release, which matters if the same numbers are validated by a libphonenumber-based service on your backend. What it costs you is a mixed-language codebase: the source of truth is Objective-C, so debugging a parsing edge case means reading Objective-C, not Swift. The Swift facade is an interface, not a replacement engine.

If you are starting a greenfield Swift app with no server-side libphonenumber dependency and you want a single-language stack, PhoneNumberKit is the more direct fit. If metadata parity with Google's implementation is the requirement, this project is built around exactly that.

Licence, Maintenance and Upgrade Cost

The licence is Apache-2.0, the same family as Google's libphonenumber, which keeps the metadata and code redistribution terms consistent with the upstream project. Apache-2.0 includes a patent grant and requires that notices be preserved. That is a description of the licence text, not legal advice; if you ship a modified copy, have your own counsel look at the notice requirements.

The repository is not archived, and the last push was on 2026-09-25, with releases 2.1.1 and 2.1.0 landing on 2026-09-25 and 2026-09-17 respectively. The cadence of those releases tracks Google metadata revisions, which is the upgrade rhythm you should plan for. Budget for reading CHANGELOG.md and re-running your formatting assertions whenever the metadata revision changes, because that is the change that will move your test output. The README does not document a rollback procedure, so pin exact versions in your manifest if you need a predictable path back.

Editorial conclusion

Adopt it if you are shipping an Apple-platform app that needs offline parsing, formatting, validation, geocoding or short-number handling and you want to pick only the modules you use. Skip it if you need a non-Apple target, or if you are pinned to Xcode versions older than the ones the current release supports; version 1.7.x covers iOS 12 but cannot be built with Xcode 27. Before committing, verify the minimum deployment targets against your own project, check whether the module you want ships a metadata bundle, and read the safe-display note for carrier labels in mobile-number-portable regions.

Frequently asked questions

What is libPhoneNumber for iOS?

It is an Apple-platform port of Google's libphonenumber metadata and behaviour, with a stable Objective-C core and Swift-first facades for modern Swift apps. It covers parsing, formatting, validation, geocoding, short-number handling and a SwiftUI phone input.

Who maintains libPhoneNumber for iOS?

The repository is iziz/libPhoneNumber-iOS, and the README describes it as an Apple-platform port of Google's libphonenumber metadata and behaviour. The README does not name individual maintainers; the AUTHORS file at the repository root is the place to check.

What is libPhoneNumber for iOS?

It is the Apple-platform port of Google's libphonenumber, published as iziz/libPhoneNumber-iOS. The README describes a stable Objective-C core with Swift-first facade modules, installable through Swift Package Manager, CocoaPods and Carthage.

Official sources

  1. iziz/libPhoneNumber-iOS on GitHub
  2. License: Apache-2.0
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/iziz-libphonenumber-ios.svg)](https://hysenlabs.com/projects/iziz-libphonenumber-ios)