PhoneNumberKit
A Swift framework for parsing, formatting and validating international phone numbers. Inspired by Google's libphonenumber.
Top Related Projects
Google's common Java, C++ and JavaScript library for parsing, formatting, and validating international phone numbers.
iOS port from libphonenumber (Google's phone number handling library)
A simpler (and smaller) rewrite of Google Android's libphonenumber library in javascript
PHP version of Google's phone number handling library
Quick Overview
PhoneNumberKit is a Swift framework for parsing, formatting, and validating international phone numbers. It provides a robust and efficient way to handle phone numbers in iOS and macOS applications, following the Google libphonenumber library's standards.
Pros
- Easy to use and integrate into Swift projects
- Supports parsing, formatting, and validation of international phone numbers
- Includes metadata for phone number formats from various countries
- Offers both synchronous and asynchronous parsing options
Cons
- Limited to Swift and Apple platforms (iOS, macOS)
- Requires regular updates to keep phone number metadata current
- May increase app size due to included metadata
- Performance might be affected when parsing large numbers of phone numbers
Code Examples
- Parsing a phone number:
import PhoneNumberKit
let phoneNumberKit = PhoneNumberKit()
do {
let phoneNumber = try phoneNumberKit.parse("+1 (415) 555-3695")
print(phoneNumber.countryCode) // 1
print(phoneNumber.nationalNumber) // 4155553695
} catch {
print("Invalid phone number")
}
- Formatting a phone number:
import PhoneNumberKit
let phoneNumberKit = PhoneNumberKit()
if let phoneNumber = try? phoneNumberKit.parse("+1 (415) 555-3695") {
let formattedNumber = phoneNumberKit.format(phoneNumber, toType: .international)
print(formattedNumber) // +1 415-555-3695
}
- Validating a phone number:
import PhoneNumberKit
let phoneNumberKit = PhoneNumberKit()
let isValid = phoneNumberKit.isValidPhoneNumber("+1 (415) 555-3695")
print(isValid) // true
Getting Started
To use PhoneNumberKit in your Swift project:
- Add PhoneNumberKit to your project using Swift Package Manager, CocoaPods, or Carthage.
- Import the framework in your Swift file:
import PhoneNumberKit
- Create an instance of PhoneNumberKit:
let phoneNumberKit = PhoneNumberKit()
- Use the various methods provided by PhoneNumberKit to parse, format, or validate phone numbers as shown in the code examples above.
Competitor Comparisons
Google's common Java, C++ and JavaScript library for parsing, formatting, and validating international phone numbers.
Pros of libphonenumber
- More comprehensive and mature library with support for a wider range of phone number formats and countries
- Regularly updated with new phone number metadata and formatting rules
- Offers additional features like time zone lookup based on phone numbers
Cons of libphonenumber
- Larger library size, which may impact app size and performance
- More complex setup and integration process, especially for mobile platforms
- Steeper learning curve due to its extensive API and features
Code Comparison
PhoneNumberKit:
let phoneNumber = try PhoneNumber(numberString: "+1 (408) 867-5309")
print(phoneNumber.nationalNumber) // 4088675309
print(phoneNumber.countryCode) // 1
libphonenumber:
PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
PhoneNumber number = phoneUtil.parse("+1 (408) 867-5309", "US");
System.out.println(number.getNationalNumber()); // 4088675309
System.out.println(number.getCountryCode()); // 1
Both libraries offer similar basic functionality for parsing and formatting phone numbers. PhoneNumberKit provides a more Swift-friendly API, while libphonenumber offers a more extensive set of features and language support. The choice between the two depends on the specific requirements of your project, such as platform, language preferences, and the need for advanced phone number handling capabilities.
iOS port from libphonenumber (Google's phone number handling library)
Pros of libPhoneNumber-iOS
- More comprehensive and accurate phone number parsing, based on Google's libphonenumber
- Supports a wider range of phone number formats and international standards
- Larger community and more frequent updates
Cons of libPhoneNumber-iOS
- Larger library size and potentially higher memory footprint
- More complex setup and integration process
- Steeper learning curve for developers
Code Comparison
libPhoneNumber-iOS:
let phoneUtil = NBPhoneNumberUtil()
do {
let phoneNumber = try phoneUtil.parse("202-555-0123", defaultRegion: "US")
let formattedNumber = try phoneUtil.format(phoneNumber, numberFormat: .E164)
print(formattedNumber) // Output: +12025550123
} catch {
print("Error parsing phone number")
}
PhoneNumberKit:
let phoneNumberKit = PhoneNumberKit()
do {
let phoneNumber = try phoneNumberKit.parse("202-555-0123", withRegion: "US")
let formattedNumber = phoneNumberKit.format(phoneNumber, toType: .e164)
print(formattedNumber) // Output: +12025550123
} catch {
print("Error parsing phone number")
}
Both libraries offer similar functionality for parsing and formatting phone numbers, but libPhoneNumber-iOS provides more advanced features and international support at the cost of increased complexity. PhoneNumberKit offers a simpler API and easier integration, making it suitable for projects with less demanding phone number handling requirements.
A simpler (and smaller) rewrite of Google Android's libphonenumber library in javascript
Pros of libphonenumber-js
- Written in JavaScript, making it more suitable for web and Node.js projects
- Smaller bundle size, which can lead to faster load times in web applications
- Supports both CommonJS and ES6 module systems, offering flexibility in integration
Cons of libphonenumber-js
- Less comprehensive validation and formatting options compared to PhoneNumberKit
- May require more manual configuration for certain use cases
- Limited support for phone number metadata updates
Code Comparison
PhoneNumberKit:
let phoneNumber = try PhoneNumber(numberString: "+1 (408) 867-5309")
let formattedNumber = phoneNumber.formatInternational() // +1 408-867-5309
libphonenumber-js:
import { parsePhoneNumber } from 'libphonenumber-js'
const phoneNumber = parsePhoneNumber('+1 (408) 867-5309')
const formattedNumber = phoneNumber.formatInternational() // +1 408 867 5309
Both libraries offer similar basic functionality for parsing and formatting phone numbers. PhoneNumberKit provides a more Swift-oriented API, while libphonenumber-js offers a JavaScript-friendly interface. The choice between them largely depends on the target platform and specific project requirements.
PHP version of Google's phone number handling library
Pros of libphonenumber-for-php
- More comprehensive phone number parsing and validation, based on Google's libphonenumber
- Supports a wider range of countries and phone number formats
- Regular updates to keep pace with changes in global phone number systems
Cons of libphonenumber-for-php
- Larger library size and potentially higher resource usage
- May be more complex to integrate and use for simple phone number tasks
- Primarily designed for PHP, limiting its use in other environments
Code Comparison
PhoneNumberKit (Swift):
let phoneNumber = try PhoneNumber(numberString: "+1 555 123 4567")
let formattedNumber = phoneNumber.nationalNumber
libphonenumber-for-php (PHP):
$phoneUtil = \libphonenumber\PhoneNumberUtil::getInstance();
$phoneNumber = $phoneUtil->parse("+1 555 123 4567", "US");
$formattedNumber = $phoneUtil->format($phoneNumber, \libphonenumber\PhoneNumberFormat::NATIONAL);
Both libraries offer phone number parsing and formatting capabilities, but libphonenumber-for-php provides more extensive functionality at the cost of increased complexity. PhoneNumberKit is more lightweight and Swift-specific, making it easier to integrate into iOS projects. The choice between the two depends on the specific requirements of the project, such as the need for comprehensive international support versus a simpler, more focused solution for mobile app development.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
PhoneNumberKit
Swift 5.3 framework for parsing, formatting and validating international phone numbers. Inspired by Google's libphonenumber.
Features
Features | |
---|---|
:phone: | Validate, normalize and extract the elements of any phone number string. |
:100: | Simple Swift syntax and a lightweight readable codebase. |
:checkered_flag: | Fast. 1000 parses -> ~0.4 seconds. |
:books: | Best-in-class metadata from Google's libPhoneNumber project. |
:trophy: | Fully tested to match the accuracy of Google's JavaScript implementation of libPhoneNumber. |
:iphone: | Built for iOS. Automatically grabs the default region code from the phone. |
ð | Editable (!) AsYouType formatter for UITextField. |
:us: | Convert country codes to country names and vice versa |
Usage
Import PhoneNumberKit at the top of the Swift file that will interact with a phone number.
import PhoneNumberKit
All of your interactions with PhoneNumberKit happen through a PhoneNumberUtility object. The first step you should take is to allocate one.
A PhoneNumberUtility instance is relatively expensive to allocate (it parses the metadata and keeps it in memory for the object's lifecycle), you should try and make sure PhoneNumberUtility is allocated once and deallocated when no longer needed.
let phoneNumberUtility = PhoneNumberUtility()
To parse a string, use the parse function. The region code is automatically computed but can be overridden if needed. PhoneNumberKit automatically does a hard type validation to ensure that the object created is valid, this can be quite costly performance-wise and can be turned off if needed.
do {
let phoneNumber = try phoneNumberUtility.parse("+33 6 89 017383")
let phoneNumberCustomDefaultRegion = try phoneNumberUtility.parse("+44 20 7031 3000", withRegion: "GB", ignoreType: true)
}
catch {
print("Generic parser error")
}
If you need to parse and validate a large amount of numbers at once, PhoneNumberKit has a special, lightning fast array parsing function. The default region code is automatically computed but can be overridden if needed. Here you can also ignore hard type validation if it is not necessary. Invalid numbers are ignored in the resulting array.
let rawNumberArray = ["0291 12345678", "+49 291 12345678", "04134 1234", "09123 12345"]
let phoneNumbers = phoneNumberUtility.parse(rawNumberArray)
let phoneNumbersCustomDefaultRegion = phoneNumberUtility.parse(rawNumberArray, withRegion: "DE", ignoreType: true)
PhoneNumber objects are immutable Swift structs with the following properties:
phoneNumber.numberString
phoneNumber.countryCode
phoneNumber.nationalNumber
phoneNumber.numberExtension
phoneNumber.type // e.g Mobile or Fixed
Formatting a PhoneNumber object into a string is also very easy
phoneNumberUtility.format(phoneNumber, toType: .e164) // +61236618300
phoneNumberUtility.format(phoneNumber, toType: .international) // +61 2 3661 8300
phoneNumberUtility.format(phoneNumber, toType: .national) // (02) 3661 8300
PhoneNumberTextField
To use the AsYouTypeFormatter, just replace your UITextField with a PhoneNumberTextField (if you are using Interface Builder make sure the module field is set to PhoneNumberKit).
You can customize your TextField UI in the following ways
withFlag
will display the country code for thecurrentRegion
. TheflagButton
is displayed in theleftView
of the text field with it's size set based off your text size.withExamplePlaceholder
usesattributedPlaceholder
to show an example number for thecurrentRegion
. In addition whenwithPrefix
is set, the country code's prefix will automatically be inserted and removed when editing changes.
PhoneNumberTextField automatically formats phone numbers and gives the user full editing capabilities. If you want to customize you can use the PartialFormatter directly. The default region code is automatically computed but can be overridden if needed (see the example given below).
class MyGBTextField: PhoneNumberTextField {
override var defaultRegion: String {
get {
return "GB"
}
set {} // exists for backward compatibility
}
}
let textField = PhoneNumberTextField()
PartialFormatter().formatPartial("+336895555") // +33 6 89 55 55
You can also query countries for a dialing code or the dialing code for a given country
phoneNumberUtility.countries(withCode: 33)
phoneNumberUtility.countryCode(for: "FR")
Customize Country Picker
You can customize colors and fonts on the Country Picker View Controller by overriding the property "withDefaultPickerUIOptions"
let options = CountryCodePickerOptions(
backgroundColor: UIColor.systemGroupedBackground
separatorColor: UIColor.opaqueSeparator
textLabelColor: UIColor.label
textLabelFont: .preferredFont(forTextStyle: .callout)
detailTextLabelColor: UIColor.secondaryLabel
detailTextLabelFont: .preferredFont(forTextStyle: .body)
tintColor: UIView().tintColor
cellBackgroundColor: UIColor.secondarySystemGroupedBackground
cellBackgroundColorSelection: UIColor.tertiarySystemGroupedBackground
)
textField.withDefaultPickerUIOptions = options
Or you can change it directly:
textField.withDefaultPickerUIOptions.backgroundColor = .red
Please refer to CountryCodePickerOptions
for more information about usage and how it affects the view.
Need more customization?
You can access the metadata powering PhoneNumberKit yourself, this enables you to program any behaviours as they may be implemented in PhoneNumberKit itself. It does mean you are exposed to the less polished interface of the underlying file format. If you program something you find useful please push it upstream!
phoneNumberUtility.metadata(for: "AU")?.mobile?.exampleNumber // 412345678
[Preferred] Setting up with Swift Package Manager
The Swift Package Manager is now the preferred tool for distributing PhoneNumberKit.
From Xcode 11+ :
- Select File > Swift Packages > Add Package Dependency. Enter
https://github.com/marmelroy/PhoneNumberKit.git
in the "Choose Package Repository" dialog. - In the next page, specify the version resolving rule as "Up to Next Major" from "3.7.0".
- After Xcode checked out the source and resolving the version, you can choose the "PhoneNumberKit" library and add it to your app target.
For more info, read Adding Package Dependencies to Your App from Apple.
Alternatively, you can also add PhoneNumberKit to your Package.swift
file:
dependencies: [
.package(url: "https://github.com/marmelroy/PhoneNumberKit", from: "3.7.0")
]
Setting up with Carthage
Carthage is a decentralized dependency manager that automates the process of adding frameworks to your Cocoa application.
You can install Carthage with Homebrew using the following command:
$ brew update
$ brew install carthage
To integrate PhoneNumberKit into your Xcode project using Carthage, specify it in your Cartfile
:
github "marmelroy/PhoneNumberKit"
Setting up with CocoaPods
pod 'PhoneNumberKit', '~> 3.7'
Top Related Projects
Google's common Java, C++ and JavaScript library for parsing, formatting, and validating international phone numbers.
iOS port from libphonenumber (Google's phone number handling library)
A simpler (and smaller) rewrite of Google Android's libphonenumber library in javascript
PHP version of Google's phone number handling library
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot