iOS port from libphonenumber (Google's phone number handling library)

Overview

CocoaPods CocoaPods Travis Coveralls Carthage compatible

libPhoneNumber for iOS

  • NBPhoneNumberUtil
  • NBAsYouTypeFormatter

ARC only

Update Log

https://github.com/iziz/libPhoneNumber-iOS/wiki/Update-Log

Issue

You can check phone number validation using below link. https://rawgit.com/googlei18n/libphonenumber/master/javascript/i18n/phonenumbers/demo-compiled.html

Please report, if the above results are different from this iOS library. Otherwise, please create issue to following link below to request additional telephone numbers formatting rule. https://github.com/google/libphonenumber/issues

Metadata in this library was generated from that. so, you should change it first. :)

Install

Using CocoaPods

source 'https://github.com/CocoaPods/Specs.git'
pod 'libPhoneNumber-iOS', '~> 0.8'
Installing libPhoneNumber Geocoding Features
pod 'libPhoneNumberGeocoding', :git => 'https://github.com/CocoaPods/Specs.git'

Using 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 libPhoneNumber into your Xcode project using Carthage, specify it in your Cartfile:

github "iziz/libPhoneNumber-iOS"

And set the Embedded Content Contains Swift to "Yes" in your build settings.

Setting up manually

Add source files to your projects from libPhoneNumber - Add "CoreTelephony.framework"

See sample test code from

[libPhoneNumber-iOS/libPhoneNumberTests/ ... Test.m] (https://github.com/iziz/libPhoneNumber-iOS/tree/master/libPhoneNumberTests)

Usage - NBPhoneNumberUtil

 NBPhoneNumberUtil *phoneUtil = [NBPhoneNumberUtil sharedInstance];
 NSError *anError = nil;
 NBPhoneNumber *myNumber = [phoneUtil parse:@"6766077303"
                              defaultRegion:@"AT" error:&anError];
 if (anError == nil) {
     NSLog(@"isValidPhoneNumber ? [%@]", [phoneUtil isValidNumber:myNumber] ? @"YES":@"NO");

     // E164          : +436766077303
     NSLog(@"E164          : %@", [phoneUtil format:myNumber
                                       numberFormat:NBEPhoneNumberFormatE164
                                              error:&anError]);
     // INTERNATIONAL : +43 676 6077303
     NSLog(@"INTERNATIONAL : %@", [phoneUtil format:myNumber
                                       numberFormat:NBEPhoneNumberFormatINTERNATIONAL
                                              error:&anError]);
     // NATIONAL      : 0676 6077303
     NSLog(@"NATIONAL      : %@", [phoneUtil format:myNumber
                                       numberFormat:NBEPhoneNumberFormatNATIONAL
                                              error:&anError]);
     // RFC3966       : tel:+43-676-6077303
     NSLog(@"RFC3966       : %@", [phoneUtil format:myNumber
                                       numberFormat:NBEPhoneNumberFormatRFC3966
                                              error:&anError]);
 } else {
     NSLog(@"Error : %@", [anError localizedDescription]);
 }

 NSLog (@"extractCountryCode [%@]", [phoneUtil extractCountryCode:@"823213123123" nationalNumber:nil]);

 NSString *nationalNumber = nil;
 NSNumber *countryCode = [phoneUtil extractCountryCode:@"823213123123" nationalNumber:&nationalNumber];

 NSLog (@"extractCountryCode [%@] [%@]", countryCode, nationalNumber);
Output
2014-07-06 12:39:37.240 libPhoneNumberTest[1581:60b] isValidPhoneNumber ? [YES]
2014-07-06 12:39:37.242 libPhoneNumberTest[1581:60b] E164          : +436766077303
2014-07-06 12:39:37.243 libPhoneNumberTest[1581:60b] INTERNATIONAL : +43 676 6077303
2014-07-06 12:39:37.243 libPhoneNumberTest[1581:60b] NATIONAL      : 0676 6077303
2014-07-06 12:39:37.244 libPhoneNumberTest[1581:60b] RFC3966       : tel:+43-676-6077303
2014-07-06 12:39:37.244 libPhoneNumberTest[1581:60b] extractCountryCode [82]
2014-07-06 12:39:37.245 libPhoneNumberTest[1581:60b] extractCountryCode [82] [3213123123]

with Swift

Case (1) with Framework
import libPhoneNumberiOS
Case (2) with Bridging-Header
// Manually added
#import "NBPhoneNumberUtil.h"
#import "NBPhoneNumber.h"

// CocoaPods (check your library path)
#import "libPhoneNumber_iOS/NBPhoneNumberUtil.h"
#import "libPhoneNumber_iOS/NBPhoneNumber.h"

// add more if you want...
Case (3) with CocoaPods

import libPhoneNumber_iOS

- in swift class file
2.x
override func viewDidLoad() {
    super.viewDidLoad()

    guard let phoneUtil = NBPhoneNumberUtil.sharedInstance() else {
        return
    }

    do {
        let phoneNumber: NBPhoneNumber = try phoneUtil.parse("01065431234", defaultRegion: "KR")
        let formattedString: String = try phoneUtil.format(phoneNumber, numberFormat: .E164)

        NSLog("[%@]", formattedString)
    }
    catch let error as NSError {
        print(error.localizedDescription)
    }
}

Usage - NBAsYouTypeFormatter

 NBAsYouTypeFormatter *f = [[NBAsYouTypeFormatter alloc] initWithRegionCode:@"US"];
    NSLog(@"%@", [f inputDigit:@"6"]); // "6"
    NSLog(@"%@", [f inputDigit:@"5"]); // "65"
    NSLog(@"%@", [f inputDigit:@"0"]); // "650"
    NSLog(@"%@", [f inputDigit:@"2"]); // "650 2"
    NSLog(@"%@", [f inputDigit:@"5"]); // "650 25"
    NSLog(@"%@", [f inputDigit:@"3"]); // "650 253"

    // Note this is how a US local number (without area code) should be formatted.
    NSLog(@"%@", [f inputDigit:@"2"]); // "650 2532"
    NSLog(@"%@", [f inputDigit:@"2"]); // "650 253 22"
    NSLog(@"%@", [f inputDigit:@"2"]); // "650 253 222"
    NSLog(@"%@", [f inputDigit:@"2"]); // "650 253 2222"
    // Can remove last digit
    NSLog(@"%@", [f removeLastDigit]); // "650 253 222"

    NSLog(@"%@", [f inputString:@"16502532222"]); // 1 650 253 2222

libPhoneNumberGeocoding

For more information on libPhoneNumberGeocoding and its usage, please visit libPhoneNumberGeocoding for more information.

libPhoneNumberShortNumber

For more information on libPhoneNumberShortNumber and its usage, please visit libPhoneNumberShortNumber for more information.

Visit libphonenumber for more information or mail ([email protected])
Comments
  • Move to using compressed JSON for Metadata

    Move to using compressed JSON for Metadata

    This reduces the compiled size of the library by 75% and gets rid of a lot of support infrastructure. Instead of doing a pile of codegen the creates a class per country code, this uses the actual JSON as the backing metadata. It is imported into the application as compressed JSON. Overall this reduces the compiled binary size of libPhoneNumberiOS from 2.9 MB (ARM64/Arm7 compiled for profiling) down to 732k. It also makes updating the library significantly easier as it should only take updating the json file (and fixing any tests).

    Sorry for the large patch, but it was difficult to break up into smaller pieces given the amount of change. All tests pass. If you accept this, we may want to consider dropping the iOS MetadataGenerator app as it basically doesn't do anything anymore, and we can just pull any of its tests into the test bundle.

    opened by dmaclach 47
  • Version 0.8.10 appears to be broken

    Version 0.8.10 appears to be broken

    Looking at the CI results, it appears that 0.8.10 doesn't compile.

    https://github.com/iziz/libPhoneNumber-iOS/compare/0.8.8...0.8.10

    When CocoaPods picked up the latest version this broke our build.

    opened by rowillia 10
  • Crash when using from multiple threads

    Crash when using from multiple threads

    I'm using libPhoneNumber (installed version 0.8.5 from CocoaPods) from multiple threads. Each thread creates its own instance of NBPhoneNumberUtil. Now I'm seeing a rare crash where one thread is in the middle of a NBPhoneNumberUtil operation. The other has just finished it and is crashing in the release/teardown of NBPhoneNumberUtil. At least that's how it looks like.

    This is my thread with the NBPhoneNumberUtil operation in progress:

    0   libsystem_platform.dylib             0x00000001947092f8 _platform_memmove + 168
    1   libicucore.A.dylib                   0x00000001939094c4 utext_openCharacterIterator + 2644
    2   libicucore.A.dylib                   0x0000000193908f9c utext_openCharacterIterator + 1324
    3   libicucore.A.dylib                   0x00000001939084e8 utext_clone + 28
    4   libicucore.A.dylib                   0x00000001939bcba4 icu::RegexMatcher::reset(UText*) + 60
    5   libicucore.A.dylib                   0x00000001939fd6e8 uregex_setText + 196
    6   Foundation                           0x00000001835323e0 -[NSRegularExpression(NSMatching) enumerateMatchesInString:options:range:usingBlock:] + 1884
    7   Foundation                           0x0000000183531c3c -[NSRegularExpression(NSMatching) firstMatchInString:options:range:] + 140
    8   WhereToKit                           0x00000001005e6360 -[NBPhoneNumberUtil matchesEntirely:string:] (NBPhoneNumberUtil.m:3850)
    9   WhereToKit                           0x00000001005e0c28 -[NBPhoneNumberUtil isNumberMatchingDesc:numberDesc:] (NBPhoneNumberUtil.m:2255)
    10  WhereToKit                           0x00000001005e0628 -[NBPhoneNumberUtil getNumberTypeHelper:metadata:] (NBPhoneNumberUtil.m:2146)
    11  WhereToKit                           0x00000001005e0e90 -[NBPhoneNumberUtil isValidNumberForRegion:regionCode:] (NBPhoneNumberUtil.m:2322)
    12  WhereToKit                           0x00000 001005e0ca4 -[NBPhoneNumberUtil isValidNumber:] (NBPhoneNumberUtil.m:2273)
    

    This is the crashing thread where I just finished using NBPhoneNumberUtil:

    Thread 20 Crashed:
    0   libobjc.A.dylib                      0x0000000193eebf04 objc_destructInstance + 40
    1   libobjc.A.dylib                      0x0000000193eebf90 object_dispose + 24
    2   libobjc.A.dylib                      0x0000000193ef8e28 objc_object::sidetable_release(bool) + 224
    3   WhereToKit                           0x00000001003c2724 -[NSString(Additions) isValidPhoneNumberCountryCode:] (NSString+Additions.m:142)
    

    Here's the general crash information:

    Exception Type:  SIGSEGV
    Exception Codes: SEGV_ACCERR at 0x1a50093358c
    Crashed Thread:  20
    
    Application Specific Information:
    Selector name found in current argument registers: dealloc
    

    Is the use of libPhoneNumber from multiple threads not supported? The recent refactoring of moving away from the singleton suggested to me that it's fine to use it from multiple threads as long as the NBPhoneNumberUtil objects are not shared.

    opened by futuretap 10
  • Declared init method in header file to allow instantiation without using the singleton.

    Declared init method in header file to allow instantiation without using the singleton.

    Singletons are believed by many people to be a bad pattern. Currently there is no way to instantiate an instance of NBPhoneNumberUtil without using the singleton sharedInstance class method because the init method is not declared in the header file. I cannot see any reason not to have this method public - it does not prevent anyone from using the shared instances and allows those of us who do not wish to do so to use the init method.

    opened by Rupert-RR 10
  • Fix xcode analysis warnings

    Fix xcode analysis warnings

    • Using NSNumber* as boolean might be confusing. Making the test to nil explicit is clearer.
    • Protect against regionCode == nil by reversing the order of the comparison.
    opened by jeroentrappers 9
  • Library has severe memory allocation issues

    Library has severe memory allocation issues

    This library has memory allocation issues, it will continue to consume more and more memory if you give it lots of phone numbers. If you process a list of phone numbers of 30K you will see it allocate 450MBs of memory on an iPhone 5S, and due to the singleton, then never release it. The situation only gets worse if you alloc, then init the library without the singleton. The library is obviously storing something in an NSMutableArray or NSMutableString, and never deletes them. It's a very useful library, but if your processing a large number of iPhone AddressBook contacts it will crash your application when it processes a large number of phone numbers.

    opened by pmurphyjam 9
  • what is the correct import statement for bridging header in swift project using cocoapods

    what is the correct import statement for bridging header in swift project using cocoapods

    I'm trying to use libPhoneNumber-iOS/NBPhoneNumber in a swift project and I'm getting a file not found error in the bridging header.

    I'm using this import statement in the bridging header file

    #import <libPhoneNumber-iOS/NBPhoneNumber.h>

    Should I be using a different import statement?

    opened by mypark 8
  • Deprecation of singleton

    Deprecation of singleton

    I'm wondering why you deprecated the sharedInstance… methods. Didn't it make sense to use the shared instance for caching purposes? Should I really create a new instance for each phone number check?

    Would be great if you could elaborate on the reasoning and how we should change our code when using the lib.

    opened by futuretap 8
  • isValidNumber is failing some valid numbers.

    isValidNumber is failing some valid numbers.

    "(366) 522-8999" parsed with "US" and "+84 74 883313" parsed with "ZZ" both fail isValidNumber:

    Changing the area code to something like "(818) 522-8999" for the first one passes.

    "+84 74 883313" is a valid number for Vietnam - from wikipedia: Area codes starting with 7[edit] With effect from 5 October 2008, all telephone numbers in this area have 7 digits. 74 – Trà Vinh Province http://en.wikipedia.org/wiki/Telephone_numbers_in_Vietnam

    Debugging a little it looks like the problem is somewhere in this returning nil NSString *regionCode = [self getRegionCodeForNumber:number];

    I'm guessing this has something to do with metadata rules?

    Depend on libphonenumber (Google) 
    opened by jrapoport 8
  • Changing classes names

    Changing classes names

    Hi @iziz, i'm trying to include libPhoneNumber inside a framework i'm helping to build. To avoid crashes, when another app is using this framework and also includes your library, i'm changing the class names by adding a prefix. The problem is that when I change the classes names the library is not formatting anymore. Have any clue why ?

    opened by vrunoa 7
  • isViablePhoneNumber returns true for number that cannot be parsed

    isViablePhoneNumber returns true for number that cannot be parsed

    I am parsing the numbers in the user's contact list, and the following number causes the parse function to crash:

    "927636539 nytt- (old)533021236"

    In order to prevent crashes like this, I run isViablePhoneNumber on every number before attempting a parse. This works for many "numbers" that are in fact things like user account names or other text strings, but for the above number, it does return true, even though supplying that number to the parse function causes it to crash.

    opened by larsekman 7
  • Missing version tags

    Missing version tags

    The last published version is 1.0.2, whereas v 1.0.4 shipped 16 months ago. Ideally, there'd also be a tag for 1.0.5 pinned at 243e3cb19245fd77492289f2c7360b1560598519

    opened by lickel 0
  • The library doesn't support US number from new area code 572 in Oklahoma

    The library doesn't support US number from new area code 572 in Oklahoma

    Describe the bug The library doesn't support US number from new area code 572 in Oklahoma To Reproduce Steps to reproduce the behavior: the number is 5724475334 [phoneUtil isValidNumberForRegion:recipientNumberUS regionCode:@"US"] Expected behavior Should say the number is valid

    opened by dani2906 0
  • Update phone number definitions to latest from libPhoneNumber

    Update phone number definitions to latest from libPhoneNumber

    This updates the phone number rules for 01431cabced345d079f8bb19c1649420cc3647be of (google/libphonenumber)[https://github.com/google/libphonenumber]. Additionally I have added a section on how to update the definitions to make this easier in the future.

    opened by threema-jarem 0
  • how to handle errors

    how to handle errors

    i have problem showing different errors like:

    • phone number is too short or something like this
    • phone number is too long or something like this

    currently i can get notified abt the number not being a valid for the region or not a valid number using isValid method but what if i wanted to know some more specific errors? any help?

    opened by benjimkh 0
  • Phone number validation is not validating for Kuwait in iOS

    Phone number validation is not validating for Kuwait in iOS

    I am trying to validate a Phone number of Kuwait country it is always returning false for this series but in android it working returning true, which is correct. Is there any other way to solve this.

           guard let phoneUtil = NBPhoneNumberUtil.sharedInstance() else {
                   return
             }
    
            do {
                let phoneNumber: NBPhoneNumber = try phoneUtil.parse("41442429", defaultRegion: "KW")
                print("IsValidPhoneNumber ==> \(phoneUtil.isValidNumber(phoneNumber) ? "YES": "NO")")
                
            }
            catch let error as NSError {
                print(error.localizedDescription)
            }
    
    opened by Ashok07k 1
  • Invalid Number Issue for Valid Number

    Invalid Number Issue for Valid Number

    I am using libPhonenumber-iOS 0.9.15 version. I have tried following valid number but it still shows invalid. Country code: +254 (Kenya) Number: 114200391

    opened by NosherKhalid 0
Releases(1.0.2)
Owner
iziz
Just for FUN!
iziz
A library for formatting strings on iOS and macOS

Sprinter Introduction What? Why? How? Usage Installation Integration Localization Thread Safety Advanced Usage Introduction What? Sprinter is a librar

Nick Lockwood 168 Feb 6, 2022
SZMentionsSwift is a lightweight mentions library for iOS.

SZMentionsSwift is a lightweight mentions library for iOS. This library was built to assist with the adding, removing and editing of a mention within a textview.

Steven Zweier 122 Dec 12, 2022
BonMot is a Swift attributed string library

BonMot (pronounced Bon Mo, French for good word) is a Swift attributed string library. It abstracts away the complexities of the iOS, macOS, tvOS, and

Rightpoint 3.4k Dec 30, 2022
Croc is a swift emoji string parsing library

Croc is a library for parsing emojis on iOS. It provides a simple and lightweight interface for detecting, generating, categorizing and managing emoji characters, making emoji-powered features an easy task for developers.

Joe Kalash 127 Nov 20, 2022
SwiftVerbalExpressions is a Swift library that helps to construct difficult regular expressions

SwiftVerbalExpressions Swift Regular Expressions made easy SwiftVerbalExpressions is a Swift library that helps to construct difficult regular express

null 582 Jun 29, 2022
🌭 Mustard is a Swift library for tokenizing strings when splitting by whitespace doesn't cut it.

Mustard ?? Mustard is a Swift library for tokenizing strings when splitting by whitespace doesn't cut it. Quick start using character sets Foundation

Mathew Sanders 695 Nov 11, 2022
Swift markdown library

Markdown ![Swift version](https://img.shields.io/badge/Swift-2.1 | 2.2-blue.svg) ![GitHub license](https://img.shields.io/badge/license-LGPL v3-green.

Crossroad Labs 79 Oct 9, 2022
A simple library for building attributed strings, for a more civilized age.

Veneer A simple library for building attributed strings, for a more civilized age. Veneer was created to make creating attributed strings easier to re

Wess Cope 26 Dec 27, 2022
Lightweight library to set an Image as text background. Written in swift.

![](https://img.shields.io/badge/Swift 2-compatible-4BC51D.svg?style=flat-square) Simple and light weight UIView that animate text with an image. Demo

Lucas Ortis 552 Sep 9, 2022
A simple library that provides standard Unicode emoji support across all platforms

Twitter Emoji (Twemoji) A simple library that provides standard Unicode emoji support across all platforms. Twemoji v13.1 adheres to the Unicode 13.0

Twitter 15k Jan 8, 2023
User input masking library repo.

Migration Guide: v.6 This update brings breaking changes. Namely, the autocomplete flag is now a part of the CaretGravity enum, thus the Mask::apply c

red_mad_robot 548 Dec 20, 2022
A Cross-Platform String and Regular Expression Library written in Swift.

Guitar ?? A Cross-Platform String and Regular Expression Library written in Swift. About This library seeks to add common string manipulation function

Arthur Ariel Sabintsev 659 Dec 27, 2022
A lightweight fuzzy-search library, with zero dependencies

Fuse What is Fuse? Fuse is a super lightweight library which provides a simple way to do fuzzy searching. Usage Example 1 let fuse = Fuse() let result

Kiro Risk 864 Dec 29, 2022
Swift emoji string parsing library

Croc is a library for parsing emojis on iOS. It provides a simple and lightweight interface for detecting, generating, categorizing and managing emoji

Joe Kalash 125 Sep 27, 2021
Fully open source text editor for iOS written in Swift.

Edhita Fully open source text editor for iOS written in Swift. http://edhita.bornneet.com/ What Edhita means? Edhita (Romaji) == エディタ (Katakana) == Ed

Tatsuya Tobioka 1.2k Jan 1, 2023
Notepad - A fully themeable iOS markdown editor with live syntax highlighting.

Notepad is just like any other UITextView, but you need to use the convenience initializer in order to use the themes. To create a new theme, copy one of the existing themes and edit the JSON.

Rudd Fawcett 802 Dec 31, 2022
An NSPredicate DSL for iOS, OSX, tvOS, & watchOS. Inspired by SnapKit and lovingly written in Swift.

PrediKit A Swift NSPredicate DSL for iOS & OS X inspired by SnapKit, lovingly written in Swift, and created by that weird dude at KrakenDev. If you're

Hector Matos 542 Sep 24, 2022
Texstyle allows you to format iOS attributed strings easily.

Texstyle allows you to format attributed strings easily. Features Applying attributes with strong typing and autocompletion Cache for attributes Subst

Rosberry 79 Sep 9, 2022
A standalone, flexible API that provides a full-featured rich text editor for iOS applications.

Twitter Text Editor A standalone, flexible API that provides a full featured rich text editor for iOS applications. This provides a robust text attrib

Twitter 2.8k Dec 29, 2022