Compare commits
241 Commits
master
...
signal-mas
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
60482f7c03 | ||
|
|
830f8ce343 | ||
|
|
31d6aa948b | ||
|
|
982d77b437 | ||
|
|
91a2b72ecc | ||
|
|
5713a9db2c | ||
|
|
8b650eb023 | ||
|
|
47fb623a24 | ||
|
|
4cb452732b | ||
|
|
8813d13421 | ||
|
|
9f186c55df | ||
|
|
3220b40271 | ||
|
|
34c09794a4 | ||
|
|
f88bfbcc39 | ||
|
|
8666250d9e | ||
|
|
5078b0a6b1 | ||
|
|
8327e0d626 | ||
|
|
f9428f5425 | ||
|
|
33add44e56 | ||
|
|
7cc8c5370a | ||
|
|
7bb8bc73b5 | ||
|
|
fc302f606c | ||
|
|
237c22f309 | ||
|
|
fed56662c2 | ||
|
|
d4b92a473a | ||
|
|
f470e8a8ad | ||
|
|
1b7eb59099 | ||
|
|
a6f5cb0a2a | ||
|
|
10eb9ea448 | ||
|
|
a1ae914a87 | ||
|
|
dee72f9015 | ||
|
|
2bf05f1ef3 | ||
|
|
879586a987 | ||
|
|
c808da6676 | ||
|
|
4f14f1fa25 | ||
|
|
9d408d2843 | ||
|
|
c33c5d30a7 | ||
|
|
335d142287 | ||
|
|
6ba88d2d0a | ||
|
|
d72f2a803a | ||
|
|
f3c21f689d | ||
|
|
7904e66219 | ||
|
|
fd75124c4c | ||
|
|
bd7a11cbed | ||
|
|
a8c177f374 | ||
|
|
331403e3a2 | ||
|
|
56c81db3bb | ||
|
|
8b6f552682 | ||
|
|
4d2ce9aa39 | ||
|
|
58c86cfd30 | ||
|
|
4c4341c5b8 | ||
|
|
12927fe928 | ||
|
|
facc36cf4e | ||
|
|
243e3cb192 | ||
|
|
f6172055a6 | ||
|
|
c119db518a | ||
|
|
833658f242 | ||
|
|
4bee1edc3f | ||
|
|
ec1d830224 | ||
|
|
ac9b26fcfb | ||
|
|
01f4051864 | ||
|
|
df2fe450fc | ||
|
|
ac13d49a22 | ||
|
|
d7f378e14c | ||
|
|
d83733eaed | ||
|
|
ba5933c773 | ||
|
|
5e34f52808 | ||
|
|
a3d6e16956 | ||
|
|
78c8e2d177 | ||
|
|
7c8dab0db6 | ||
|
|
9e30e12883 | ||
|
|
2ed5732e05 | ||
|
|
18017aaff2 | ||
|
|
cdea5ab9a3 | ||
|
|
ef3c28c571 | ||
|
|
066a22a274 | ||
|
|
56ccb8e93d | ||
|
|
ad37ab41b0 | ||
|
|
c10c2f8919 | ||
|
|
1f27c0b6a0 | ||
|
|
de0f30998f | ||
|
|
992dec604f | ||
|
|
868139c9d9 | ||
|
|
0630296103 | ||
|
|
6de587fea6 | ||
|
|
20f8b4057e | ||
|
|
597cb8f977 | ||
|
|
2af42e97bf | ||
|
|
25e0a26273 | ||
|
|
235577546c | ||
|
|
54eeaf5822 | ||
|
|
d745bc2644 | ||
|
|
7ce982f2ac | ||
|
|
db5bc2bb1c | ||
|
|
6533339994 | ||
|
|
4377b21c87 | ||
|
|
7928a3e84b | ||
|
|
1d3441e9cd | ||
|
|
2f299e6093 | ||
|
|
4278e9f5c4 | ||
|
|
2e38f8beb3 | ||
|
|
8efc8d1b75 | ||
|
|
b56a06823b | ||
|
|
15210dddf1 | ||
|
|
d9364c24e3 | ||
|
|
7379b3ddb4 | ||
|
|
f3de9f98d9 | ||
|
|
449bc39a06 | ||
|
|
7f45d50d41 | ||
|
|
39681d7d00 | ||
|
|
a7a8b695a1 | ||
|
|
1d8a3b15b6 | ||
|
|
b88e57b3fb | ||
|
|
5d3b2409d6 | ||
|
|
a91b7de910 | ||
|
|
fa19a95f99 | ||
|
|
e7bedc47e2 | ||
|
|
772c50bb50 | ||
|
|
ea8723f87c | ||
|
|
6190dccdc2 | ||
|
|
47f03d7147 | ||
|
|
2231dba64f | ||
|
|
37f3d36cf4 | ||
|
|
d27172ea1f | ||
|
|
be50f56222 | ||
|
|
055d400569 | ||
|
|
baff89a966 | ||
|
|
9553d5143b | ||
|
|
d90147997a | ||
|
|
19c1939041 | ||
|
|
6f3e4b5ea2 | ||
|
|
ffee2417d7 | ||
|
|
416d6118a5 | ||
|
|
8eb8eb697a | ||
|
|
2ca30cf30c | ||
|
|
514d8563ab | ||
|
|
7b40b86cb6 | ||
|
|
ed43840290 | ||
|
|
aef716bc52 | ||
|
|
42f89cb1aa | ||
|
|
8ec1291b94 | ||
|
|
3380a2d779 | ||
|
|
af2df05f0c | ||
|
|
6d0d68b5c2 | ||
|
|
0c960720ce | ||
|
|
5f07a4ba10 | ||
|
|
deae5a1cba | ||
|
|
679fde1513 | ||
|
|
fbeab7c437 | ||
|
|
831926af74 | ||
|
|
4bc6883e04 | ||
|
|
ea3471b99b | ||
|
|
5727ea2296 | ||
|
|
13a3ffd3b6 | ||
|
|
ac96f3eb9d | ||
|
|
42da3048b5 | ||
|
|
c2f3f87e70 | ||
|
|
1290162b93 | ||
|
|
42a4086afe | ||
|
|
912eb46df9 | ||
|
|
9454228921 | ||
|
|
79c51ecc2f | ||
|
|
7e99bf8306 | ||
|
|
40ed463acf | ||
|
|
ddbb99f5d1 | ||
|
|
f1e7555dd2 | ||
|
|
7510f52b50 | ||
|
|
48f452b6d1 | ||
|
|
d966f86b74 | ||
|
|
a5641e22d6 | ||
|
|
2372fbedf9 | ||
|
|
d2d155cd6c | ||
|
|
0a524fb57f | ||
|
|
e3ae846845 | ||
|
|
ac6d8c2ff1 | ||
|
|
f22f2c0d3a | ||
|
|
415d879ecd | ||
|
|
f9402775d8 | ||
|
|
0db8cf77e8 | ||
|
|
17e3ec0a78 | ||
|
|
9702cb8396 | ||
|
|
5e013a021a | ||
|
|
f0fdd1649c | ||
|
|
707bfe41c8 | ||
|
|
ff855a4d16 | ||
|
|
d4bc3dda1f | ||
|
|
da60192150 | ||
|
|
91fc938b52 | ||
|
|
7db69e7dec | ||
|
|
529b75b242 | ||
|
|
cce141bced | ||
|
|
ee6133a1b0 | ||
|
|
c9714330e7 | ||
|
|
1e9c5c1336 | ||
|
|
bf8d708996 | ||
|
|
977e2a22be | ||
|
|
ceca8cf344 | ||
|
|
579804c9bb | ||
|
|
6b1205c040 | ||
|
|
5a2c22d53e | ||
|
|
b6be0b4093 | ||
|
|
6dcd392724 | ||
|
|
cfed14243d | ||
|
|
a5a35543d9 | ||
|
|
1ffae1ba54 | ||
|
|
e8b81e6301 | ||
|
|
20d30bf0ae | ||
|
|
2821128eb5 | ||
|
|
31ec850e83 | ||
|
|
c702bb49f4 | ||
|
|
4d410fd903 | ||
|
|
827cf73e80 | ||
|
|
93ac0ddc28 | ||
|
|
5600f12380 | ||
|
|
82c49a5726 | ||
|
|
364287ff34 | ||
|
|
9c22e23f9f | ||
|
|
6862e83f2b | ||
|
|
e598f745ab | ||
|
|
ea5e535a3a | ||
|
|
f7fcccbeaa | ||
|
|
6942861e95 | ||
|
|
05442282bc | ||
|
|
229398ed6f | ||
|
|
4058f1db82 | ||
|
|
b0f09a7866 | ||
|
|
e4eb1af383 | ||
|
|
83be9bf3b4 | ||
|
|
33eee5211e | ||
|
|
05f22d7646 | ||
|
|
9084ab4f3d | ||
|
|
ab29186e23 | ||
|
|
380b591453 | ||
|
|
cf46926c66 | ||
|
|
153d092f1a | ||
|
|
55b715a8c7 | ||
|
|
01c0b2a062 | ||
|
|
1c272e4ac0 | ||
|
|
717a0b03f3 | ||
|
|
f29cbb9704 | ||
|
|
6530ccb730 |
@ -1 +0,0 @@
|
||||
service_name: travis-ci
|
||||
12
.slather.yml
12
.slather.yml
@ -1,12 +0,0 @@
|
||||
ci_service: travis_ci
|
||||
coverage_service: coveralls
|
||||
xcodeproj: libPhoneNumber.xcodeproj
|
||||
ignore:
|
||||
- libPhoneNumber/AppDelegate.m
|
||||
- libPhoneNumber/main.m
|
||||
- libPhoneNumber/NBPhoneMetaDataGenerator.m
|
||||
- libPhoneNumber/NBPhoneMetaData.m
|
||||
- libPhoneNumber/NBPhoneNumberDesc.m
|
||||
- libPhoneNumber/NBMetadataHelper.m
|
||||
- libPhoneNumber/NBNumberFormat.m
|
||||
- libPhoneNumber/NBPhoneNumber.m
|
||||
11
.travis.yml
11
.travis.yml
@ -1,11 +0,0 @@
|
||||
language: objective-c
|
||||
|
||||
before_install:
|
||||
- gem install slather -N
|
||||
|
||||
script:
|
||||
- xcodebuild -project libPhoneNumber.xcodeproj -scheme libPhoneNumberiOSTests clean
|
||||
- xcodebuild -project libPhoneNumber.xcodeproj -scheme libPhoneNumberiOSTests -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO GCC_INSTRUMENT_PROGRAM_FLOW_ARCS=YES build-for-testing
|
||||
- xctool -project libPhoneNumber.xcodeproj -scheme libPhoneNumberiOSTests run-tests -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO GCC_INSTRUMENT_PROGRAM_FLOW_ARCS=YES GCC_GENERATE_TEST_COVERAGE_FILES=YES
|
||||
|
||||
after_success: slather
|
||||
3
Makefile
Normal file
3
Makefile
Normal file
@ -0,0 +1,3 @@
|
||||
.PHONY: metadata
|
||||
metadata:
|
||||
swift run --package-path MetadataArchiver -c release MetadataArchiver ${LIBPHONENUMBER}
|
||||
8
MetadataArchiver/.gitignore
vendored
Normal file
8
MetadataArchiver/.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
.DS_Store
|
||||
/.build
|
||||
/Packages
|
||||
xcuserdata/
|
||||
DerivedData/
|
||||
.swiftpm/configuration/registries.json
|
||||
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
|
||||
.netrc
|
||||
9
MetadataArchiver/Package.swift
Normal file
9
MetadataArchiver/Package.swift
Normal file
@ -0,0 +1,9 @@
|
||||
// swift-tools-version: 6.0
|
||||
|
||||
import PackageDescription
|
||||
|
||||
let package = Package(
|
||||
name: "MetadataArchiver",
|
||||
platforms: [.macOS(.v15)],
|
||||
targets: [.executableTarget(name: "MetadataArchiver")]
|
||||
)
|
||||
64
MetadataArchiver/Sources/main.swift
Normal file
64
MetadataArchiver/Sources/main.swift
Normal file
@ -0,0 +1,64 @@
|
||||
import Foundation
|
||||
import JavaScriptCore
|
||||
|
||||
func printErr(_ value: String) {
|
||||
try! FileHandle.standardError.write(contentsOf: Data(value.utf8) + Data("\n".utf8))
|
||||
}
|
||||
|
||||
if CommandLine.arguments.count < 2 {
|
||||
printErr("You must specify a path to libphonenumber.")
|
||||
exit(1)
|
||||
}
|
||||
let libPhoneNumberPath = CommandLine.arguments[1]
|
||||
let libPhoneNumberURL = URL(filePath: libPhoneNumberPath, relativeTo: URL.currentDirectory())
|
||||
|
||||
let outputUrl = URL(filePath: "libPhoneNumber/NBPhoneNumberMetaData.plist", relativeTo: URL.currentDirectory())
|
||||
// Dump JSON as well to make diffs easier to review.
|
||||
let jsonOutputUrl = URL(filePath: "libPhoneNumber/NBPhoneNumberMetaData.json", relativeTo: URL.currentDirectory())
|
||||
|
||||
func archiveObject(_ object: Any) -> Data {
|
||||
class Deduplicator: NSObject, NSKeyedArchiverDelegate {
|
||||
var objects: Set<NSObject> = []
|
||||
|
||||
func archiver(_ archiver: NSKeyedArchiver, willEncode object: Any) -> Any? {
|
||||
guard let nsObject = object as? NSObject else {
|
||||
return object
|
||||
}
|
||||
return objects.insert(nsObject).memberAfterInsert
|
||||
}
|
||||
}
|
||||
|
||||
let coder = NSKeyedArchiver(requiringSecureCoding: false)
|
||||
let delegate = Deduplicator()
|
||||
coder.delegate = delegate
|
||||
coder.encode(object, forKey: NSKeyedArchiveRootObjectKey)
|
||||
_ = delegate
|
||||
return coder.encodedData
|
||||
}
|
||||
|
||||
func parseMetadata3() throws {
|
||||
let context = JSContext()!
|
||||
context.exceptionHandler = { _, exception in
|
||||
printErr("\(exception!)")
|
||||
exit(1)
|
||||
}
|
||||
context.evaluateScript("""
|
||||
var goog = {"provide": function() {}};
|
||||
var i18n = {"phonenumbers": {"metadata": {}}};
|
||||
""")
|
||||
let metadataFileUrl = libPhoneNumberURL.appending(path: "javascript/i18n/phonenumbers/metadata.js")
|
||||
let metadataContent = String(data: try Data(contentsOf: metadataFileUrl), encoding: .utf8)!
|
||||
context.evaluateScript(metadataContent)
|
||||
let metadataEncoded = context.evaluateScript("JSON.stringify(i18n.phonenumbers.metadata)").toString()!
|
||||
let metadataObject = try JSONSerialization.jsonObject(with: Data(metadataEncoded.utf8))
|
||||
try JSONSerialization.data(withJSONObject: metadataObject, options: [.sortedKeys, .prettyPrinted]).write(to: jsonOutputUrl)
|
||||
try archiveObject(metadataObject).write(to: outputUrl)
|
||||
}
|
||||
|
||||
do {
|
||||
try parseMetadata3()
|
||||
} catch {
|
||||
printErr("\(error)")
|
||||
exit(1)
|
||||
}
|
||||
|
||||
181
README.md
Executable file → Normal file
181
README.md
Executable file → Normal file
@ -1,174 +1,17 @@
|
||||
[](http://cocoapods.org/?q=libPhoneNumber-iOS)
|
||||
[](http://cocoapods.org/?q=libPhoneNumber-iOS)
|
||||
[](https://travis-ci.org/iziz/libPhoneNumber-iOS)
|
||||
[](https://coveralls.io/github/iziz/libPhoneNumber-iOS?branch=master)
|
||||
[](https://github.com/Carthage/Carthage)
|
||||
# Signal's fork of [libPhoneNumber-iOS][]
|
||||
|
||||
# **libPhoneNumber for iOS**
|
||||
This is Signal's fork of libPhoneNumber-iOS, which is an Objective-C port of [Google's libphonenumber][libphonenumber].
|
||||
|
||||
- NBPhoneNumberUtil
|
||||
- NBAsYouTypeFormatter
|
||||
- NBTextField.swift (Swift 3)
|
||||
## How to update metadata from libphonenumber
|
||||
|
||||
> ARC only, or add the **"-fobjc-arc"** flag for non-ARC
|
||||
If you want the latest metadata from libphonenumber...
|
||||
|
||||
## Update Log
|
||||
[https://github.com/iziz/libPhoneNumber-iOS/wiki/Update-Log](https://github.com/iziz/libPhoneNumber-iOS/wiki/Update-Log)
|
||||
1. Clone this fork.
|
||||
1. Check out the version of [libphonenumber][] (not libPhoneNumber-iOS) that you want to pull metadata from. Remember this `<path>`.
|
||||
1. From the project root, run `LIBPHONENUMBER=<path> make metadata`. Use the `<path>` you remembered in the prior step.
|
||||
1. Commit the changes to the `signal-master` branch and push the changes.
|
||||
1. Update the dependency in the [Signal iOS project][signal-ios] as normal (using `bundle exec pod update libPhoneNumber-iOS`).
|
||||
|
||||
|
||||
## 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](http://cocoapods.org/?q=libPhoneNumber-iOS)
|
||||
```
|
||||
source 'https://github.com/CocoaPods/Specs.git'
|
||||
pod 'libPhoneNumber-iOS', '~> 0.8'
|
||||
```
|
||||
|
||||
#### Using [Carthage](https://github.com/Carthage/Carthage)
|
||||
|
||||
Carthage is a decentralized dependency manager that automates the process of adding frameworks to your Cocoa application.
|
||||
|
||||
You can install Carthage with [Homebrew](http://brew.sh/) using the following command:
|
||||
|
||||
```bash
|
||||
$ brew update
|
||||
$ brew install carthage
|
||||
```
|
||||
|
||||
To integrate libPhoneNumber into your Xcode project using Carthage, specify it in your `Cartfile`:
|
||||
|
||||
```ogdl
|
||||
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**
|
||||
```obj-c
|
||||
NBPhoneNumberUtil *phoneUtil = [[NBPhoneNumberUtil alloc] init];
|
||||
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
|
||||
```obj-c
|
||||
// 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
|
||||
```swift
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
let phoneUtil = NBPhoneNumberUtil()
|
||||
|
||||
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**
|
||||
```obj-c
|
||||
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
|
||||
```
|
||||
|
||||
##### Visit [libphonenumber](https://github.com/google/libphonenumber) for more information or mail (zen.isis@gmail.com)
|
||||
[libPhoneNumber-iOS]: https://github.com/iziz/libPhoneNumber-iOS
|
||||
[libphonenumber]: https://github.com/google/libphonenumber
|
||||
[signal-ios]: https://github.com/signalapp/Signal-iOS
|
||||
|
||||
@ -1,46 +0,0 @@
|
||||
//
|
||||
// AppDelegate.swift
|
||||
// libPhoneNumber-SwiftDemo
|
||||
//
|
||||
// Created by tabby on 2015. 11. 8..
|
||||
// Copyright © 2015년 ohtalk.me. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
@UIApplicationMain
|
||||
class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
|
||||
var window: UIWindow?
|
||||
|
||||
|
||||
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
|
||||
// Override point for customization after application launch.
|
||||
return true
|
||||
}
|
||||
|
||||
func applicationWillResignActive(_ application: UIApplication) {
|
||||
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
|
||||
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
|
||||
}
|
||||
|
||||
func applicationDidEnterBackground(_ application: UIApplication) {
|
||||
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
|
||||
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
|
||||
}
|
||||
|
||||
func applicationWillEnterForeground(_ application: UIApplication) {
|
||||
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
|
||||
}
|
||||
|
||||
func applicationDidBecomeActive(_ application: UIApplication) {
|
||||
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
|
||||
}
|
||||
|
||||
func applicationWillTerminate(_ application: UIApplication) {
|
||||
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -1,31 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11542" systemVersion="16B2555" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
|
||||
<device id="retina4_7" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11524"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--View Controller-->
|
||||
<scene sceneID="EHf-IW-A2E">
|
||||
<objects>
|
||||
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
|
||||
<layoutGuides>
|
||||
<viewControllerLayoutGuide type="top" id="Llm-lL-Icb"/>
|
||||
<viewControllerLayoutGuide type="bottom" id="xb3-aO-Qok"/>
|
||||
</layoutGuides>
|
||||
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</view>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="53" y="375"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
</document>
|
||||
@ -1,30 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11542" systemVersion="16B2555" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
|
||||
<device id="retina4_7" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11524"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--View Controller-->
|
||||
<scene sceneID="tne-QT-ifu">
|
||||
<objects>
|
||||
<viewController id="BYZ-38-t0r" customClass="ViewController" customModule="libPhoneNumberSampleSwift" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<layoutGuides>
|
||||
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
|
||||
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
|
||||
</layoutGuides>
|
||||
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</view>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
</scene>
|
||||
</scenes>
|
||||
</document>
|
||||
@ -1,46 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>libPhoneNumberSampleSwift</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIcons</key>
|
||||
<dict/>
|
||||
<key>CFBundleIcons~ipad</key>
|
||||
<dict/>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UIMainStoryboardFile</key>
|
||||
<string>Main</string>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array>
|
||||
<string>armv7</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
@ -1,36 +0,0 @@
|
||||
//
|
||||
// ViewController.swift
|
||||
// libPhoneNumber-SwiftDemo
|
||||
//
|
||||
// Created by tabby on 2015. 11. 8..
|
||||
// Copyright © 2015년 ohtalk.me. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import libPhoneNumberiOS
|
||||
|
||||
|
||||
class ViewController: UIViewController {
|
||||
let textField: UITextField = NBTextField()
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
view.backgroundColor = UIColor.black
|
||||
textField.backgroundColor = UIColor.white
|
||||
textField.frame.size.width = 200
|
||||
textField.frame.size.height = 25
|
||||
|
||||
view.addSubview(textField)
|
||||
}
|
||||
|
||||
override func viewWillLayoutSubviews() {
|
||||
super.viewWillLayoutSubviews()
|
||||
textField.center = self.view.center
|
||||
}
|
||||
|
||||
override func didReceiveMemoryWarning() {
|
||||
super.didReceiveMemoryWarning()
|
||||
// Dispose of any resources that can be recreated.
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
Pod::Spec.new do |s|
|
||||
s.name = "libPhoneNumber-iOS"
|
||||
s.version = "0.9.15"
|
||||
s.version = "1.2.0"
|
||||
s.summary = "iOS library for parsing, formatting, storing and validating international phone numbers from libphonenumber library."
|
||||
s.description = <<-DESC
|
||||
libPhoneNumber for iOS
|
||||
@ -10,13 +10,12 @@ DESC
|
||||
s.license = 'Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)'
|
||||
s.authors = { "iziz" => "zen.isis@gmail.com", "hyukhur" => "hyukhur@gmail.com" }
|
||||
s.source = { :git => "https://github.com/iziz/libPhoneNumber-iOS.git", :tag => s.version.to_s }
|
||||
s.libraries = 'z'
|
||||
s.ios.framework = 'CoreTelephony'
|
||||
s.ios.deployment_target = "6.0"
|
||||
s.osx.deployment_target = "10.9"
|
||||
s.watchos.deployment_target = "2.0"
|
||||
s.tvos.deployment_target = "9.0"
|
||||
s.ios.framework = 'Contacts'
|
||||
s.ios.deployment_target = "12.0"
|
||||
s.osx.deployment_target = "10.11"
|
||||
s.watchos.deployment_target = "4.0"
|
||||
s.tvos.deployment_target = "11.0"
|
||||
s.requires_arc = true
|
||||
s.private_header_files = 'libPhoneNumber/NBGeneratedPhoneNumberMetaData.h'
|
||||
s.source_files = 'libPhoneNumber/NBPhoneNumberDefines.{h,m}', 'libPhoneNumber/NBPhoneNumber.{h,m}', 'libPhoneNumber/NBNumberFormat.{h,m}', 'libPhoneNumber/NBPhoneNumberDesc.{h,m}', 'libPhoneNumber/NBPhoneMetaData.{h,m}', 'libPhoneNumber/NBPhoneNumberUtil.{h,m}', 'libPhoneNumber/NBMetadataHelper.{h,m}', 'libPhoneNumber/NBAsYouTypeFormatter.{h,m}', 'libPhoneNumber/NSArray+NBAdditions.{h,m}', 'libPhoneNumber/NBGeneratedPhoneNumberMetaData.h', 'libPhoneNumber/Internal/NBRegExMatcher.{h,m}', 'libPhoneNumber/Internal/NBRegularExpressionCache.{h,m}'
|
||||
s.resources = 'libPhoneNumber/NBPhoneNumberMetaData.plist'
|
||||
s.source_files = 'libPhoneNumber/NBPhoneNumberDefines.{h,m}', 'libPhoneNumber/NBPhoneNumber.{h,m}', 'libPhoneNumber/NBNumberFormat.{h,m}', 'libPhoneNumber/NBPhoneNumberDesc.{h,m}', 'libPhoneNumber/NBPhoneMetaData.{h,m}', 'libPhoneNumber/NBPhoneNumberUtil.{h,m}', 'libPhoneNumber/NBMetadataHelper.{h,m}', 'libPhoneNumber/NBAsYouTypeFormatter.{h,m}', 'libPhoneNumber/NSArray+NBAdditions.{h,m}', 'libPhoneNumber/Internal/NBRegExMatcher.{h,m}', 'libPhoneNumber/Internal/NBRegularExpressionCache.{h,m}'
|
||||
end
|
||||
|
||||
@ -1,28 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>libPhoneNumberiOS</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string></string>
|
||||
</dict>
|
||||
</plist>
|
||||
@ -1,83 +0,0 @@
|
||||
//
|
||||
// NBTextField.swift
|
||||
// libPhoneNumber
|
||||
//
|
||||
// Created by tabby on 2015. 11. 7..
|
||||
// Copyright © 2015년 ohtalk.me. All rights reserved.
|
||||
//
|
||||
|
||||
import libPhoneNumberiOS
|
||||
|
||||
|
||||
open class NBTextField: UITextField
|
||||
{
|
||||
// MARK: Options/Variables for phone number formatting
|
||||
|
||||
let phoneNumberUtility: NBPhoneNumberUtil = NBPhoneNumberUtil()
|
||||
var phoneNumberFormatter: NBAsYouTypeFormatter?
|
||||
|
||||
var shouldCheckValidationForInputText: Bool = true
|
||||
|
||||
var countryCode: String = "US" {//5 NSLocale.currentLocale().objectForKey(NSLocaleCountryCode) as! String {
|
||||
didSet {
|
||||
phoneNumberFormatter = NBAsYouTypeFormatter(regionCode: countryCode)
|
||||
numberTextDidChange()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: Initialization
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
registerForNotifications()
|
||||
phoneNumberFormatter = NBAsYouTypeFormatter(regionCode: countryCode)
|
||||
}
|
||||
deinit {
|
||||
NotificationCenter.default.removeObserver(self)
|
||||
}
|
||||
|
||||
required public init?(coder aDecoder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
|
||||
// MARK: UITextField input managing
|
||||
|
||||
override open func deleteBackward() {
|
||||
if text?.characters.last == " " {
|
||||
if let indexNumberWithWhiteSpace = text?.characters.index((text?.endIndex)!, offsetBy: -1) {
|
||||
text = text?.substring(to: indexNumberWithWhiteSpace)
|
||||
}
|
||||
return
|
||||
}
|
||||
super.deleteBackward()
|
||||
}
|
||||
|
||||
|
||||
// MARK: Notification for "UITextFieldTextDidChangeNotification"
|
||||
|
||||
fileprivate func registerForNotifications() {
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(NBTextField.numberTextDidChange), name: NSNotification.Name.UITextFieldTextDidChange, object: self)
|
||||
}
|
||||
|
||||
func numberTextDidChange() {
|
||||
let numbersOnly = phoneNumberUtility.normalize(text)
|
||||
text = phoneNumberFormatter!.inputStringAndRememberPosition(numbersOnly)
|
||||
|
||||
if phoneNumberFormatter!.isSuccessfulFormatting == false && shouldCheckValidationForInputText {
|
||||
shakeIt()
|
||||
}
|
||||
}
|
||||
|
||||
func shakeIt() {
|
||||
let offset = self.bounds.size.width / 30
|
||||
let animation = CABasicAnimation(keyPath: "position")
|
||||
animation.duration = 0.07
|
||||
animation.repeatCount = 2
|
||||
animation.autoreverses = true
|
||||
animation.fromValue = NSValue(cgPoint: CGPoint(x: self.center.x - offset, y: self.center.y))
|
||||
animation.toValue = NSValue(cgPoint: CGPoint(x: self.center.x + offset, y: self.center.y))
|
||||
self.layer.add(animation, forKey: "position")
|
||||
}
|
||||
}
|
||||
@ -1,33 +0,0 @@
|
||||
//
|
||||
// libPhoneNumber-iOS.h
|
||||
// libPhoneNumber-iOS
|
||||
//
|
||||
// Created by Roy Marmelstein on 04/08/2015.
|
||||
// Copyright (c) 2015 ohtalk.me. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
//! Project version number for libPhoneNumber-iOS.
|
||||
FOUNDATION_EXPORT double libPhoneNumber_iOSVersionNumber;
|
||||
|
||||
//! Project version string for libPhoneNumber-iOS.
|
||||
FOUNDATION_EXPORT const unsigned char libPhoneNumber_iOSVersionString[];
|
||||
|
||||
// In this header, you should import all the public headers of your framework
|
||||
// using statements like #import <libPhoneNumber_iOS/PublicHeader.h>
|
||||
|
||||
#import "NBPhoneNumberDefines.h"
|
||||
|
||||
// Features
|
||||
#import "NBAsYouTypeFormatter.h"
|
||||
#import "NBPhoneNumberUtil.h"
|
||||
|
||||
// Metadata
|
||||
#import "NBMetadataHelper.h"
|
||||
|
||||
// Model
|
||||
#import "NBNumberFormat.h"
|
||||
#import "NBPhoneMetaData.h"
|
||||
#import "NBPhoneNumber.h"
|
||||
#import "NBPhoneNumberDesc.h"
|
||||
@ -1,26 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2016 ohtalk.me. All rights reserved.</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string></string>
|
||||
</dict>
|
||||
</plist>
|
||||
@ -1,33 +0,0 @@
|
||||
//
|
||||
// libPhoneNumbermacOS.h
|
||||
// libPhoneNumbermacOS
|
||||
//
|
||||
// Created by Artem Starosvetskiy on 24/12/2016.
|
||||
// Copyright © 2016 ohtalk.me. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
//! Project version number for libPhoneNumbermacOS.
|
||||
FOUNDATION_EXPORT double libPhoneNumbermacOSVersionNumber;
|
||||
|
||||
//! Project version string for libPhoneNumbermacOS.
|
||||
FOUNDATION_EXPORT const unsigned char libPhoneNumbermacOSVersionString[];
|
||||
|
||||
// In this header, you should import all the public headers of your framework
|
||||
// using statements like #import <libPhoneNumbermacOS/PublicHeader.h>
|
||||
|
||||
#import "NBPhoneNumberDefines.h"
|
||||
|
||||
// Features
|
||||
#import "NBAsYouTypeFormatter.h"
|
||||
#import "NBPhoneNumberUtil.h"
|
||||
|
||||
// Metadata
|
||||
#import "NBMetadataHelper.h"
|
||||
|
||||
// Model
|
||||
#import "NBNumberFormat.h"
|
||||
#import "NBPhoneMetaData.h"
|
||||
#import "NBPhoneNumber.h"
|
||||
#import "NBPhoneNumberDesc.h"
|
||||
@ -1,26 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>libPhoneNumbertvOS</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string></string>
|
||||
</dict>
|
||||
</plist>
|
||||
@ -1,33 +0,0 @@
|
||||
//
|
||||
// libPhoneNumbertvOS.h
|
||||
// libPhoneNumbertvOS
|
||||
//
|
||||
// Created by Jeff Kelley on 11/16/16.
|
||||
// Copyright © 2016 ohtalk.me. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
//! Project version number for libPhoneNumber-tvOS.
|
||||
FOUNDATION_EXPORT double libPhoneNumber_tvOSVersionNumber;
|
||||
|
||||
//! Project version string for libPhoneNumber-tvOS.
|
||||
FOUNDATION_EXPORT const unsigned char libPhoneNumber_tvOSVersionString[];
|
||||
|
||||
// In this header, you should import all the public headers of your framework
|
||||
// using statements like #import <libPhoneNumber_tvOS/PublicHeader.h>
|
||||
|
||||
#import "NBPhoneNumberDefines.h"
|
||||
|
||||
// Features
|
||||
#import "NBAsYouTypeFormatter.h"
|
||||
#import "NBPhoneNumberUtil.h"
|
||||
|
||||
// Metadata
|
||||
#import "NBMetadataCore.h"
|
||||
|
||||
// Model
|
||||
#import "NBNumberFormat.h"
|
||||
#import "NBPhoneMetaData.h"
|
||||
#import "NBPhoneNumber.h"
|
||||
#import "NBPhoneNumberDesc.h"
|
||||
@ -1,26 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>libPhoneNumberwatchOS</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string></string>
|
||||
</dict>
|
||||
</plist>
|
||||
@ -1,33 +0,0 @@
|
||||
//
|
||||
// libPhoneNumber-watchOS.h
|
||||
// libPhoneNumber-watchOS
|
||||
//
|
||||
// Created by Jeff Kelley on 11/16/16.
|
||||
// Copyright © 2016 ohtalk.me. All rights reserved.
|
||||
//
|
||||
|
||||
#import <WatchKit/WatchKit.h>
|
||||
|
||||
//! Project version number for libPhoneNumber-watchOS.
|
||||
FOUNDATION_EXPORT double libPhoneNumber_watchOSVersionNumber;
|
||||
|
||||
//! Project version string for libPhoneNumber-watchOS.
|
||||
FOUNDATION_EXPORT const unsigned char libPhoneNumber_watchOSVersionString[];
|
||||
|
||||
// In this header, you should import all the public headers of your framework
|
||||
// using statements like #import <libPhoneNumber_watchOS/PublicHeader.h>
|
||||
|
||||
#import "NBPhoneNumberDefines.h"
|
||||
|
||||
// Features
|
||||
#import "NBAsYouTypeFormatter.h"
|
||||
#import "NBPhoneNumberUtil.h"
|
||||
|
||||
// Metadata
|
||||
#import "NBMetadataCore.h"
|
||||
|
||||
// Model
|
||||
#import "NBNumberFormat.h"
|
||||
#import "NBPhoneMetaData.h"
|
||||
#import "NBPhoneNumber.h"
|
||||
#import "NBPhoneNumberDesc.h"
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,7 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:libPhoneNumber.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</plist>
|
||||
@ -1,91 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0940"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "8B1FEF721EB7BE7C00FBDE87"
|
||||
BuildableName = "SwiftDemo.app"
|
||||
BlueprintName = "SwiftDemo"
|
||||
ReferencedContainer = "container:libPhoneNumber.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "8B1FEF721EB7BE7C00FBDE87"
|
||||
BuildableName = "SwiftDemo.app"
|
||||
BlueprintName = "SwiftDemo"
|
||||
ReferencedContainer = "container:libPhoneNumber.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "8B1FEF721EB7BE7C00FBDE87"
|
||||
BuildableName = "SwiftDemo.app"
|
||||
BlueprintName = "SwiftDemo"
|
||||
ReferencedContainer = "container:libPhoneNumber.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "8B1FEF721EB7BE7C00FBDE87"
|
||||
BuildableName = "SwiftDemo.app"
|
||||
BlueprintName = "SwiftDemo"
|
||||
ReferencedContainer = "container:libPhoneNumber.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
@ -1,99 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0940"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "34ACBB841B7122AC0064B3BD"
|
||||
BuildableName = "libPhoneNumberiOS.framework"
|
||||
BlueprintName = "libPhoneNumberiOS"
|
||||
ReferencedContainer = "container:libPhoneNumber.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
<TestableReference
|
||||
skipped = "NO">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "14B7A2921DE9B65D0051AED7"
|
||||
BuildableName = "libPhoneNumberiOSTests.xctest"
|
||||
BlueprintName = "libPhoneNumberiOSTests"
|
||||
ReferencedContainer = "container:libPhoneNumber.xcodeproj">
|
||||
</BuildableReference>
|
||||
</TestableReference>
|
||||
</Testables>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "34ACBB841B7122AC0064B3BD"
|
||||
BuildableName = "libPhoneNumberiOS.framework"
|
||||
BlueprintName = "libPhoneNumberiOS"
|
||||
ReferencedContainer = "container:libPhoneNumber.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "34ACBB841B7122AC0064B3BD"
|
||||
BuildableName = "libPhoneNumberiOS.framework"
|
||||
BlueprintName = "libPhoneNumberiOS"
|
||||
ReferencedContainer = "container:libPhoneNumber.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "34ACBB841B7122AC0064B3BD"
|
||||
BuildableName = "libPhoneNumberiOS.framework"
|
||||
BlueprintName = "libPhoneNumberiOS"
|
||||
ReferencedContainer = "container:libPhoneNumber.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
@ -1,99 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0940"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "14B7A2921DE9B65D0051AED7"
|
||||
BuildableName = "libPhoneNumberiOSTests.xctest"
|
||||
BlueprintName = "libPhoneNumberiOSTests"
|
||||
ReferencedContainer = "container:libPhoneNumber.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
<TestableReference
|
||||
skipped = "NO">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "14B7A2921DE9B65D0051AED7"
|
||||
BuildableName = "libPhoneNumberiOSTests.xctest"
|
||||
BlueprintName = "libPhoneNumberiOSTests"
|
||||
ReferencedContainer = "container:libPhoneNumber.xcodeproj">
|
||||
</BuildableReference>
|
||||
</TestableReference>
|
||||
</Testables>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "14B7A2921DE9B65D0051AED7"
|
||||
BuildableName = "libPhoneNumberiOSTests.xctest"
|
||||
BlueprintName = "libPhoneNumberiOSTests"
|
||||
ReferencedContainer = "container:libPhoneNumber.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "14B7A2921DE9B65D0051AED7"
|
||||
BuildableName = "libPhoneNumberiOSTests.xctest"
|
||||
BlueprintName = "libPhoneNumberiOSTests"
|
||||
ReferencedContainer = "container:libPhoneNumber.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "14B7A2921DE9B65D0051AED7"
|
||||
BuildableName = "libPhoneNumberiOSTests.xctest"
|
||||
BlueprintName = "libPhoneNumberiOSTests"
|
||||
ReferencedContainer = "container:libPhoneNumber.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
@ -1,80 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0940"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "7C72507B1E0EBE7D00F916ED"
|
||||
BuildableName = "libPhoneNumbermacOS.framework"
|
||||
BlueprintName = "libPhoneNumbermacOS"
|
||||
ReferencedContainer = "container:libPhoneNumber.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "7C72507B1E0EBE7D00F916ED"
|
||||
BuildableName = "libPhoneNumbermacOS.framework"
|
||||
BlueprintName = "libPhoneNumbermacOS"
|
||||
ReferencedContainer = "container:libPhoneNumber.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "7C72507B1E0EBE7D00F916ED"
|
||||
BuildableName = "libPhoneNumbermacOS.framework"
|
||||
BlueprintName = "libPhoneNumbermacOS"
|
||||
ReferencedContainer = "container:libPhoneNumber.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
@ -1,80 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0940"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "1F31D54C1DDD47B900257818"
|
||||
BuildableName = "libPhoneNumbertvOS.framework"
|
||||
BlueprintName = "libPhoneNumbertvOS"
|
||||
ReferencedContainer = "container:libPhoneNumber.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "1F31D54C1DDD47B900257818"
|
||||
BuildableName = "libPhoneNumbertvOS.framework"
|
||||
BlueprintName = "libPhoneNumbertvOS"
|
||||
ReferencedContainer = "container:libPhoneNumber.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "1F31D54C1DDD47B900257818"
|
||||
BuildableName = "libPhoneNumbertvOS.framework"
|
||||
BlueprintName = "libPhoneNumbertvOS"
|
||||
ReferencedContainer = "container:libPhoneNumber.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
@ -1,80 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0940"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "1F31D5291DDD46B100257818"
|
||||
BuildableName = "libPhoneNumberwatchOS.framework"
|
||||
BlueprintName = "libPhoneNumberwatchOS"
|
||||
ReferencedContainer = "container:libPhoneNumber.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "1F31D5291DDD46B100257818"
|
||||
BuildableName = "libPhoneNumberwatchOS.framework"
|
||||
BlueprintName = "libPhoneNumberwatchOS"
|
||||
ReferencedContainer = "container:libPhoneNumber.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "1F31D5291DDD46B100257818"
|
||||
BuildableName = "libPhoneNumberwatchOS.framework"
|
||||
BlueprintName = "libPhoneNumberwatchOS"
|
||||
ReferencedContainer = "container:libPhoneNumber.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
@ -1,95 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# GeneratePhoneNumberHeader.sh
|
||||
# libPhoneNumber
|
||||
#
|
||||
# Created by Dave MacLachlan on 2/7/17.
|
||||
# Copyright © 2017 Google Inc. All rights reserved.
|
||||
|
||||
# Takes the data sets in the PhoneNumberMetaData testing files and compresses them and then
|
||||
# writes them into a header that we can pull into our source. The compression reduces them from 300k
|
||||
# of data to 44k (per architecture). It would possibly be better to have this as a resource file
|
||||
# that is read in from disk (because then we only pay for the size once), but that would
|
||||
# dramatically change how this library is currently used by clients.
|
||||
#
|
||||
# The data set used is controlled by the value of the "TESTING" macro when the code is actually
|
||||
# compiled.
|
||||
|
||||
set -eu
|
||||
|
||||
cd "${BASH_SOURCE%/*}" || exit
|
||||
|
||||
TEMPDIR=$(mktemp -d)
|
||||
gzip -c "../libPhoneNumberTests/generatedJSON/PhoneNumberMetaDataForTesting.json" > "$TEMPDIR/PhoneNumberMetaDataForTesting.zip"
|
||||
gzip -c "../libPhoneNumberTests/generatedJSON/PhoneNumberMetaData.json" > "$TEMPDIR/PhoneNumberMetaData.zip"
|
||||
gzip -c "../libPhoneNumberTests/generatedJSON/ShortNumberMetaData.json" > "$TEMPDIR/ShortNumberMetaData.zip"
|
||||
|
||||
cat > "NBGeneratedPhoneNumberMetaData.h" <<'EOF'
|
||||
/*****
|
||||
* Data Generated from GeneratePhoneNumberHeader.sh
|
||||
* Off of PhoneNumberMetaDataForTesting.json, PhoneNumberMetaData.json, and ShortNumberMetaData.json
|
||||
*/
|
||||
|
||||
#include <zlib.h>
|
||||
|
||||
// z_const is not defined in some versions of zlib, so define it here
|
||||
// in case it has not been defined.
|
||||
#if defined(ZLIB_CONST) && !defined(z_const)
|
||||
# define z_const const
|
||||
#else
|
||||
# define z_const
|
||||
#endif
|
||||
|
||||
#if TESTING==1
|
||||
|
||||
z_const Bytef kPhoneNumberMetaData[] = {
|
||||
EOF
|
||||
|
||||
cat "$TEMPDIR/PhoneNumberMetaDataForTesting.zip" | xxd -i >> "NBGeneratedPhoneNumberMetaData.h"
|
||||
|
||||
cat >> "NBGeneratedPhoneNumberMetaData.h" <<'EOF'
|
||||
};
|
||||
z_const size_t kPhoneNumberMetaDataCompressedLength = sizeof(kPhoneNumberMetaData);
|
||||
EOF
|
||||
LIB_SIZE=$(stat -f%z "../libPhoneNumberTests/generatedJSON/PhoneNumberMetaDataForTesting.json")
|
||||
echo "z_const size_t kPhoneNumberMetaDataExpandedLength = $LIB_SIZE;" >> "NBGeneratedPhoneNumberMetaData.h"
|
||||
|
||||
cat >> "NBGeneratedPhoneNumberMetaData.h" <<'EOF'
|
||||
|
||||
#else // TESTING == 1
|
||||
|
||||
z_const Bytef kPhoneNumberMetaData[] = {
|
||||
EOF
|
||||
|
||||
cat "$TEMPDIR/PhoneNumberMetaData.zip" | xxd -i >> "NBGeneratedPhoneNumberMetaData.h"
|
||||
|
||||
cat >> "NBGeneratedPhoneNumberMetaData.h" <<'EOF'
|
||||
};
|
||||
z_const size_t kPhoneNumberMetaDataCompressedLength = sizeof(kPhoneNumberMetaData);
|
||||
EOF
|
||||
LIB_SIZE=$(stat -f%z "../libPhoneNumberTests/generatedJSON/PhoneNumberMetaData.json")
|
||||
echo "z_const size_t kPhoneNumberMetaDataExpandedLength = $LIB_SIZE;" >> "NBGeneratedPhoneNumberMetaData.h"
|
||||
echo "#endif // TESTING" >> "NBGeneratedPhoneNumberMetaData.h"
|
||||
|
||||
# ShortNumberMetadata
|
||||
cat >> "NBGeneratedPhoneNumberMetaData.h" <<'EOF'
|
||||
|
||||
#if SHORT_NUMBER_SUPPORT
|
||||
|
||||
z_const Bytef kShortNumberMetaData[] = {
|
||||
EOF
|
||||
|
||||
cat "$TEMPDIR/ShortNumberMetaData.zip" | xxd -i >> "NBGeneratedPhoneNumberMetaData.h"
|
||||
|
||||
cat >> "NBGeneratedPhoneNumberMetaData.h" <<'EOF'
|
||||
};
|
||||
z_const size_t kShortNumberMetaDataCompressedLength = sizeof(kShortNumberMetaData);
|
||||
EOF
|
||||
LIB_SIZE=$(stat -f%z "../libPhoneNumberTests/generatedJSON/ShortNumberMetaData.json")
|
||||
echo "z_const size_t kShortNumberMetaDataExpandedLength = $LIB_SIZE;" >> "NBGeneratedPhoneNumberMetaData.h"
|
||||
echo "#endif // SHORT_NUMBER_SUPPORT" >> "NBGeneratedPhoneNumberMetaData.h"
|
||||
|
||||
rm "$TEMPDIR/PhoneNumberMetaDataForTesting.zip"
|
||||
rm "$TEMPDIR/PhoneNumberMetaData.zip"
|
||||
rm "$TEMPDIR/ShortNumberMetaData.zip"
|
||||
rmdir "$TEMPDIR"
|
||||
@ -8,11 +8,12 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@class NBAsYouTypeFormatter;
|
||||
@class NBMetadataHelper;
|
||||
|
||||
@interface NBAsYouTypeFormatter : NSObject
|
||||
|
||||
- (instancetype)initWithRegionCode:(NSString *)regionCode;
|
||||
- (instancetype)initWithRegionCode:(NSString *)regionCode bundle:(NSBundle *)bundle;
|
||||
- (instancetype)initWithRegionCode:(NSString *)regionCode metadataHelper:(NBMetadataHelper *)helper;
|
||||
|
||||
- (NSString *)inputString:(NSString *)string;
|
||||
- (NSString *)inputStringAndRememberPosition:(NSString *)string;
|
||||
|
||||
@ -51,6 +51,7 @@ static const NSUInteger NBMinLeadingDigitsLength = 3;
|
||||
positionToRemember_;
|
||||
@property(nonatomic, strong, readwrite) NSMutableArray *possibleFormats_;
|
||||
@property(nonatomic, strong, readwrite) NBPhoneMetaData *currentMetaData_, *defaultMetaData_;
|
||||
@property(nonatomic, strong) NBMetadataHelper *metadataHelper;
|
||||
|
||||
@end
|
||||
|
||||
@ -134,7 +135,8 @@ static const NSUInteger NBMinLeadingDigitsLength = 3;
|
||||
* @private
|
||||
*/
|
||||
NSString *eligible_format =
|
||||
@"^[-x‐-―−ー--/ ()()[].\\[\\]/~⁓∼~]*(\\$\\d[-x‐-―−ー--/ "
|
||||
@"^[-x‐-―−ー--/ "
|
||||
@" ()()[].\\[\\]/~⁓∼~]*(\\$\\d[-x‐-―−ー--/ "
|
||||
@" ()()[].\\[\\]/~⁓∼~]*)+$";
|
||||
self.ELIGIBLE_FORMAT_PATTERN_ =
|
||||
[NSRegularExpression regularExpressionWithPattern:eligible_format options:0 error:&anError];
|
||||
@ -263,17 +265,19 @@ static const NSUInteger NBMinLeadingDigitsLength = 3;
|
||||
*/
|
||||
|
||||
- (instancetype)initWithRegionCode:(NSString *)regionCode {
|
||||
return [self initWithRegionCode:regionCode bundle:[NSBundle mainBundle]];
|
||||
return [self initWithRegionCode:regionCode metadataHelper:[[NBMetadataHelper alloc] init]];
|
||||
}
|
||||
|
||||
- (instancetype)initWithRegionCode:(NSString *)regionCode bundle:(NSBundle *)bundle {
|
||||
- (instancetype)initWithRegionCode:(NSString *)regionCode
|
||||
metadataHelper:(NBMetadataHelper *)helper {
|
||||
self = [self init];
|
||||
if (self) {
|
||||
/**
|
||||
* @private
|
||||
* @type {i18n.phonenumbers.PhoneNumberUtil}
|
||||
*/
|
||||
self.phoneUtil_ = [NBPhoneNumberUtil sharedInstance];
|
||||
self.metadataHelper = helper;
|
||||
self.phoneUtil_ = [[NBPhoneNumberUtil alloc] initWithMetadataHelper:helper];
|
||||
self.defaultCountry_ = regionCode;
|
||||
self.currentMetaData_ = [self getMetadataForRegion_:self.defaultCountry_];
|
||||
/**
|
||||
@ -295,7 +299,7 @@ static const NSUInteger NBMinLeadingDigitsLength = 3;
|
||||
* @private
|
||||
*/
|
||||
- (NBPhoneMetaData *)getMetadataForRegion_:(NSString *)regionCode {
|
||||
NBMetadataHelper *helper = [[NBMetadataHelper alloc] init];
|
||||
NBMetadataHelper *helper = self.metadataHelper;
|
||||
/** @type {number} */
|
||||
NSNumber *countryCallingCode = [self.phoneUtil_ getCountryCodeForRegion:regionCode];
|
||||
/** @type {string} */
|
||||
@ -418,8 +422,8 @@ static const NSUInteger NBMinLeadingDigitsLength = 3;
|
||||
|
||||
for (NSUInteger i = 0; i < possibleFormatsLength; ++i) {
|
||||
/** @type {i18n.phonenumbers.NumberFormat} */
|
||||
NBNumberFormat *format =
|
||||
[self.possibleFormats_ nb_safeObjectAtIndex:i class:[NBNumberFormat class]];
|
||||
NBNumberFormat *format = [self.possibleFormats_ nb_safeObjectAtIndex:i
|
||||
class:[NBNumberFormat class]];
|
||||
|
||||
if (format.leadingDigitsPatterns.count == 0) {
|
||||
// Keep everything that isn't restricted by leading digits.
|
||||
@ -516,8 +520,9 @@ static const NSUInteger NBMinLeadingDigitsLength = 3;
|
||||
withTemplate:numberFormat];
|
||||
|
||||
// Replaces each digit with character DIGIT_PLACEHOLDER
|
||||
template =
|
||||
[self.phoneUtil_ replaceStringByRegex:template regex:@"9" withTemplate:NBDigitPlaceHolder];
|
||||
template = [self.phoneUtil_ replaceStringByRegex:template
|
||||
regex:@"9"
|
||||
withTemplate:NBDigitPlaceHolder];
|
||||
return template;
|
||||
}
|
||||
|
||||
@ -646,8 +651,8 @@ static const NSUInteger NBMinLeadingDigitsLength = 3;
|
||||
if (!nextChar || nextChar.length <= 0) {
|
||||
return self.currentOutput_;
|
||||
}
|
||||
self.currentOutput_ =
|
||||
[self inputDigitWithOptionToRememberPosition_:nextChar rememberPosition:YES];
|
||||
self.currentOutput_ = [self inputDigitWithOptionToRememberPosition_:nextChar
|
||||
rememberPosition:YES];
|
||||
return self.currentOutput_;
|
||||
}
|
||||
|
||||
@ -677,8 +682,8 @@ static const NSUInteger NBMinLeadingDigitsLength = 3;
|
||||
self.ableToFormat_ = NO;
|
||||
self.inputHasFormatting_ = YES;
|
||||
} else {
|
||||
nextChar =
|
||||
[self normalizeAndAccrueDigitsAndPlusSign_:nextChar rememberPosition:rememberPosition];
|
||||
nextChar = [self normalizeAndAccrueDigitsAndPlusSign_:nextChar
|
||||
rememberPosition:rememberPosition];
|
||||
}
|
||||
|
||||
if (!self.ableToFormat_) {
|
||||
@ -770,8 +775,6 @@ static const NSUInteger NBMinLeadingDigitsLength = 3;
|
||||
return [self attemptToChooseFormattingPattern_];
|
||||
}
|
||||
}
|
||||
|
||||
_isSuccessfulFormatting = NO;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -807,10 +810,12 @@ static const NSUInteger NBMinLeadingDigitsLength = 3;
|
||||
NSString *prefixBeforeNationalNumberStr = [self.prefixBeforeNationalNumber_ copy];
|
||||
NSRange lastRange = [prefixBeforeNationalNumberStr rangeOfString:self.nationalPrefixExtracted_
|
||||
options:NSBackwardsSearch];
|
||||
/** @type {number} */
|
||||
NSUInteger indexOfPreviousNdd = lastRange.location;
|
||||
self.prefixBeforeNationalNumber_ = [[prefixBeforeNationalNumberStr
|
||||
substringWithRange:NSMakeRange(0, indexOfPreviousNdd)] mutableCopy];
|
||||
if (lastRange.length > 0) {
|
||||
/** @type {number} */
|
||||
NSUInteger indexOfPreviousNdd = lastRange.location;
|
||||
self.prefixBeforeNationalNumber_ = [[prefixBeforeNationalNumberStr
|
||||
substringWithRange:NSMakeRange(0, indexOfPreviousNdd)] mutableCopy];
|
||||
}
|
||||
}
|
||||
|
||||
return self.nationalPrefixExtracted_ != [self removeNationalPrefixFromNationalNumber_];
|
||||
@ -851,8 +856,8 @@ static const NSUInteger NBMinLeadingDigitsLength = 3;
|
||||
NSString *pattern = numberFormat.pattern;
|
||||
/** @type {RegExp} */
|
||||
NSString *patternRegExp = [NSString stringWithFormat:@"^(?:%@)$", pattern];
|
||||
BOOL isPatternRegExp =
|
||||
[[self.phoneUtil_ matchesByRegex:nationalNumber regex:patternRegExp] count] > 0;
|
||||
BOOL isPatternRegExp = [[self.phoneUtil_ matchesByRegex:nationalNumber
|
||||
regex:patternRegExp] count] > 0;
|
||||
if (isPatternRegExp) {
|
||||
if (numberFormat.nationalPrefixFormattingRule.length > 0) {
|
||||
NSArray *matches = [self.NATIONAL_PREFIX_SEPARATORS_PATTERN_
|
||||
@ -1026,8 +1031,8 @@ static const NSUInteger NBMinLeadingDigitsLength = 3;
|
||||
NSString *nationalPrefixForParsing =
|
||||
[NSString stringWithFormat:@"^(?:%@)", self.currentMetaData_.nationalPrefixForParsing];
|
||||
/** @type {Array.<string>} */
|
||||
NSArray *m =
|
||||
[self.phoneUtil_ matchedStringByRegex:nationalNumber regex:nationalPrefixForParsing];
|
||||
NSArray *m = [self.phoneUtil_ matchedStringByRegex:nationalNumber
|
||||
regex:nationalPrefixForParsing];
|
||||
NSString *firstString = [m nb_safeStringAtIndex:0];
|
||||
if (m != nil && firstString != nil && firstString.length > 0) {
|
||||
// When the national prefix is detected, we use international formatting
|
||||
@ -1111,7 +1116,7 @@ static const NSUInteger NBMinLeadingDigitsLength = 3;
|
||||
NSString *newRegionCode = [self.phoneUtil_ getRegionCodeForCountryCode:countryCode];
|
||||
|
||||
if ([NB_REGION_CODE_FOR_NON_GEO_ENTITY isEqualToString:newRegionCode]) {
|
||||
NBMetadataHelper *helper = [[NBMetadataHelper alloc] init];
|
||||
NBMetadataHelper *helper = self.metadataHelper;
|
||||
self.currentMetaData_ = [helper getMetadataForNonGeographicalRegion:countryCode];
|
||||
} else if (newRegionCode != self.defaultCountry_) {
|
||||
self.currentMetaData_ = [self getMetadataForRegion_:newRegionCode];
|
||||
@ -1175,8 +1180,8 @@ static const NSUInteger NBMinLeadingDigitsLength = 3;
|
||||
|
||||
if ([self.phoneUtil_ stringPositionByRegex:subedString regex:NBDigitPlaceHolder] >= 0) {
|
||||
/** @type {number} */
|
||||
int digitPatternStart =
|
||||
[self.phoneUtil_ stringPositionByRegex:formattingTemplate regex:NBDigitPlaceHolder];
|
||||
int digitPatternStart = [self.phoneUtil_ stringPositionByRegex:formattingTemplate
|
||||
regex:NBDigitPlaceHolder];
|
||||
|
||||
/** @type {string} */
|
||||
NSRange tempRange = [formattingTemplate rangeOfString:NBDigitPlaceHolder];
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -15,27 +15,15 @@
|
||||
|
||||
+ (BOOL)hasValue:(NSString *)string;
|
||||
|
||||
+ (NSDictionary *)CCode2CNMap;
|
||||
- (instancetype)init;
|
||||
|
||||
- (NSArray *)getAllMetadata;
|
||||
- (NSArray *)regionCodeFromCountryCode:(NSNumber *)countryCodeNumber;
|
||||
- (NSString *)countryCodeFromRegionCode:(NSString *)regionCode;
|
||||
|
||||
- (NBPhoneMetaData *)getMetadataForNonGeographicalRegion:(NSNumber *)countryCallingCode;
|
||||
- (NBPhoneMetaData *)getMetadataForRegion:(NSString *)regionCode;
|
||||
|
||||
+ (NSArray *)regionCodeFromCountryCode:(NSNumber *)countryCodeNumber;
|
||||
+ (NSString *)countryCodeFromRegionCode:(NSString *)regionCode;
|
||||
|
||||
#if SHORT_NUMBER_SUPPORT
|
||||
|
||||
/**
|
||||
* Returns the short number metadata for the given region code or {@code nil} if the region
|
||||
* code is invalid or unknown.
|
||||
*
|
||||
* @param regionCode regionCode
|
||||
* @return {i18n.phonenumbers.PhoneMetadata}
|
||||
*/
|
||||
- (NBPhoneMetaData *)shortNumberMetadataForRegion:(NSString *)regionCode;
|
||||
|
||||
#endif // SHORT_NUMBER_SUPPORT
|
||||
- (NSDictionary *)countryCodeToCountryNumberDictionary;
|
||||
- (NSArray *)getAllMetadata;
|
||||
|
||||
@end
|
||||
|
||||
@ -7,19 +7,13 @@
|
||||
//
|
||||
|
||||
#import "NBMetadataHelper.h"
|
||||
#import "NBGeneratedPhoneNumberMetaData.h"
|
||||
#import "NBPhoneMetaData.h"
|
||||
|
||||
@interface NBMetadataHelper ()
|
||||
|
||||
// Cached metadata
|
||||
@property (nonatomic, strong) NSCache<NSString *, NBPhoneMetaData *> *metadataCache;
|
||||
|
||||
#if SHORT_NUMBER_SUPPORT
|
||||
|
||||
@property (nonatomic, strong) NSCache<NSString *, NBPhoneMetaData *> *shortNumberMetadataCache;
|
||||
|
||||
#endif //SHORT_NUMBER_SUPPORT
|
||||
@property(nonatomic, strong) NSCache<NSString *, NBPhoneMetaData *> *metadataCache;
|
||||
@property(nonatomic, strong) NSCache<NSString *, id> *metadataMapCache;
|
||||
|
||||
@end
|
||||
|
||||
@ -35,16 +29,22 @@ static NSString *StringByTrimming(NSString *aString) {
|
||||
return [aString stringByTrimmingCharactersInSet:whitespaceCharSet];
|
||||
}
|
||||
|
||||
@implementation NBMetadataHelper
|
||||
@implementation NBMetadataHelper {
|
||||
@private
|
||||
NSDictionary *_phoneNumberDataDictionary;
|
||||
NSDictionary *_countryCodeToCountryNumberDictionary;
|
||||
}
|
||||
|
||||
- (instancetype)init {
|
||||
self = [super init];
|
||||
|
||||
if (self != nil) {
|
||||
_metadataCache = [[NSCache alloc] init];
|
||||
#if SHORT_NUMBER_SUPPORT
|
||||
_shortNumberMetadataCache = [[NSCache alloc] init];
|
||||
#endif //SHORT_NUMBER_SUPPORT
|
||||
_metadataMapCache = [[NSCache alloc] init];
|
||||
_phoneNumberDataDictionary = [[self class] phoneNumberDataMap];
|
||||
[self countryCodeToCountryNumberDictionary];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@ -55,35 +55,42 @@ static NSString *StringByTrimming(NSString *aString) {
|
||||
Ref. site (countrycode.org)
|
||||
*/
|
||||
+ (NSDictionary *)phoneNumberDataMap {
|
||||
static NSDictionary *phoneNumberDataDictionary;
|
||||
static NSDictionary *result;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
phoneNumberDataDictionary =
|
||||
[self jsonObjectFromZippedDataWithBytes:kPhoneNumberMetaData
|
||||
compressedLength:kPhoneNumberMetaDataCompressedLength
|
||||
expandedLength:kPhoneNumberMetaDataExpandedLength];
|
||||
@autoreleasepool {
|
||||
NSString *path = [[NSBundle bundleForClass:NBMetadataHelper.class] pathForResource:@"NBPhoneNumberMetaData" ofType:@"plist"];
|
||||
NSData *fileContent = [NSData dataWithContentsOfFile:path];
|
||||
if (fileContent != nil) {
|
||||
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingFromData:fileContent error:NULL];
|
||||
unarchiver.requiresSecureCoding = YES;
|
||||
NSSet *allowedClasses = [NSSet setWithArray:@[NSArray.class, NSDictionary.class, NSNull.class, NSString.class, NSNumber.class]];
|
||||
result = (NSDictionary *)[unarchiver decodeObjectOfClasses:allowedClasses forKey:NSKeyedArchiveRootObjectKey];
|
||||
}
|
||||
NSAssert(result != nil, @"NBPhoneNumberMetaData.plist missing or corrupt");
|
||||
}
|
||||
});
|
||||
return phoneNumberDataDictionary;
|
||||
return result;
|
||||
}
|
||||
|
||||
+ (NSDictionary *)CCode2CNMap {
|
||||
static NSMutableDictionary *mapCCode2CN;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
NSDictionary *countryCodeToRegionCodeMap = [self CN2CCodeMap];
|
||||
mapCCode2CN = [[NSMutableDictionary alloc] init];
|
||||
- (NSDictionary *)countryCodeToCountryNumberDictionary {
|
||||
if (_countryCodeToCountryNumberDictionary == nil) {
|
||||
NSDictionary *countryCodeToRegionCodeMap = [self countryCodeToRegionCodeDictionary];
|
||||
NSMutableDictionary *map = [[NSMutableDictionary alloc] init];
|
||||
for (NSString *countryCode in countryCodeToRegionCodeMap) {
|
||||
NSArray *regionCodes = countryCodeToRegionCodeMap[countryCode];
|
||||
for (NSString *regionCode in regionCodes) {
|
||||
mapCCode2CN[regionCode] = countryCode;
|
||||
map[regionCode] = countryCode;
|
||||
}
|
||||
}
|
||||
});
|
||||
return mapCCode2CN;
|
||||
_countryCodeToCountryNumberDictionary = [map copy];
|
||||
}
|
||||
|
||||
return _countryCodeToCountryNumberDictionary;
|
||||
}
|
||||
|
||||
+ (NSDictionary *)CN2CCodeMap {
|
||||
return [self phoneNumberDataMap][@"countryCodeToRegionCodeMap"];
|
||||
- (NSDictionary *)countryCodeToRegionCodeDictionary {
|
||||
return _phoneNumberDataDictionary[@"countryCodeToRegionCodeMap"];
|
||||
}
|
||||
|
||||
- (NSArray *)getAllMetadata {
|
||||
@ -91,18 +98,18 @@ static NSString *StringByTrimming(NSString *aString) {
|
||||
NSMutableArray *resultMetadata = [[NSMutableArray alloc] initWithCapacity:countryCodes.count];
|
||||
|
||||
for (NSString *countryCode in countryCodes) {
|
||||
id countryDictionaryInstance =
|
||||
[NSDictionary dictionaryWithObject:countryCode forKey:NSLocaleCountryCode];
|
||||
id countryDictionaryInstance = [NSDictionary dictionaryWithObject:countryCode
|
||||
forKey:NSLocaleCountryCode];
|
||||
NSString *identifier = [NSLocale localeIdentifierFromComponents:countryDictionaryInstance];
|
||||
NSString *country =
|
||||
[[NSLocale currentLocale] displayNameForKey:NSLocaleIdentifier value:identifier];
|
||||
NSString *country = [[NSLocale currentLocale] displayNameForKey:NSLocaleIdentifier
|
||||
value:identifier];
|
||||
|
||||
NSMutableDictionary *countryMeta = [[NSMutableDictionary alloc] init];
|
||||
if (country) {
|
||||
[countryMeta setObject:country forKey:@"name"];
|
||||
} else {
|
||||
NSString *systemCountry =
|
||||
[[NSLocale systemLocale] displayNameForKey:NSLocaleIdentifier value:identifier];
|
||||
NSString *systemCountry = [[NSLocale systemLocale] displayNameForKey:NSLocaleIdentifier
|
||||
value:identifier];
|
||||
if (systemCountry) {
|
||||
[countryMeta setObject:systemCountry forKey:@"name"];
|
||||
}
|
||||
@ -123,8 +130,8 @@ static NSString *StringByTrimming(NSString *aString) {
|
||||
return resultMetadata;
|
||||
}
|
||||
|
||||
+ (NSArray *)regionCodeFromCountryCode:(NSNumber *)countryCodeNumber {
|
||||
NSArray *res = [self CN2CCodeMap][[countryCodeNumber stringValue]];
|
||||
- (NSArray *)regionCodeFromCountryCode:(NSNumber *)countryCodeNumber {
|
||||
NSArray *res = [self countryCodeToRegionCodeDictionary][[countryCodeNumber stringValue]];
|
||||
if ([res isKindOfClass:[NSArray class]] && [res count] > 0) {
|
||||
return res;
|
||||
}
|
||||
@ -132,8 +139,8 @@ static NSString *StringByTrimming(NSString *aString) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
+ (NSString *)countryCodeFromRegionCode:(NSString *)regionCode {
|
||||
return [self CCode2CNMap][regionCode];
|
||||
- (NSString *)countryCodeFromRegionCode:(NSString *)regionCode {
|
||||
return [self countryCodeToCountryNumberDictionary][regionCode];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -156,7 +163,7 @@ static NSString *StringByTrimming(NSString *aString) {
|
||||
return cachedMetadata;
|
||||
}
|
||||
|
||||
NSDictionary *dict = [[self class] phoneNumberDataMap][@"countryToMetadata"];
|
||||
NSDictionary *dict = _phoneNumberDataDictionary[@"countryToMetadata"];
|
||||
NSArray *entry = dict[regionCode];
|
||||
if (entry) {
|
||||
NBPhoneMetaData *metadata = [[NBPhoneMetaData alloc] initWithEntry:entry];
|
||||
@ -182,86 +189,4 @@ static NSString *StringByTrimming(NSString *aString) {
|
||||
return string.length != 0;
|
||||
}
|
||||
|
||||
#if SHORT_NUMBER_SUPPORT
|
||||
|
||||
+ (NSDictionary *)shortNumberDataMap {
|
||||
static NSDictionary *shortNumberDataDictionary;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
shortNumberDataDictionary =
|
||||
[self jsonObjectFromZippedDataWithBytes:kShortNumberMetaData
|
||||
compressedLength:kShortNumberMetaDataCompressedLength
|
||||
expandedLength:kShortNumberMetaDataExpandedLength];
|
||||
});
|
||||
return shortNumberDataDictionary;
|
||||
}
|
||||
|
||||
- (NBPhoneMetaData *)shortNumberMetadataForRegion:(NSString *)regionCode
|
||||
{
|
||||
regionCode = StringByTrimming(regionCode);
|
||||
if (regionCode.length == 0) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
regionCode = [regionCode uppercaseString];
|
||||
|
||||
NBPhoneMetaData *cachedMetadata = [_shortNumberMetadataCache objectForKey:regionCode];
|
||||
if (cachedMetadata != nil) {
|
||||
return cachedMetadata;
|
||||
}
|
||||
|
||||
NSDictionary *dict = [[self class] shortNumberDataMap][@"countryToMetadata"];
|
||||
NSArray *entry = dict[regionCode];
|
||||
if (entry) {
|
||||
NBPhoneMetaData *metadata = [[NBPhoneMetaData alloc] initWithEntry:entry];
|
||||
[_shortNumberMetadataCache setObject:metadata forKey:regionCode];
|
||||
return metadata;
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
#endif // SHORT_NUMBER_SUPPORT
|
||||
|
||||
|
||||
/**
|
||||
* Expand gzipped data into a JSON object.
|
||||
|
||||
* @param bytes Array<Bytef> of zipped data.
|
||||
* @param compressedLength Length of the compressed bytes.
|
||||
* @param expandedLength Length of the expanded bytes.
|
||||
* @return JSON dictionary.
|
||||
*/
|
||||
+ (NSDictionary *)jsonObjectFromZippedDataWithBytes:(z_const Bytef [])bytes
|
||||
compressedLength:(NSUInteger)compressedLength
|
||||
expandedLength:(NSUInteger)expandedLength {
|
||||
// Data is a gzipped JSON file that is embedded in the binary.
|
||||
// See GeneratePhoneNumberHeader.sh and PhoneNumberMetaData.h for details.
|
||||
NSMutableData* gunzippedData = [NSMutableData dataWithLength:expandedLength];
|
||||
|
||||
z_stream zStream;
|
||||
memset(&zStream, 0, sizeof(zStream));
|
||||
__attribute((unused)) int err = inflateInit2(&zStream, 16);
|
||||
NSAssert(err == Z_OK, @"Unable to init stream. err = %d", err);
|
||||
|
||||
zStream.next_in = bytes;
|
||||
zStream.avail_in = (uint)compressedLength;
|
||||
zStream.next_out = (Bytef *)gunzippedData.bytes;
|
||||
zStream.avail_out = (uint)gunzippedData.length;
|
||||
|
||||
err = inflate(&zStream, Z_FINISH);
|
||||
NSAssert(err == Z_STREAM_END, @"Unable to inflate compressed data. err = %d", err);
|
||||
|
||||
err = inflateEnd(&zStream);
|
||||
NSAssert(err == Z_OK, @"Unable to inflate compressed data. err = %d", err);
|
||||
|
||||
NSError *error = nil;
|
||||
NSDictionary *jsonObject = [NSJSONSerialization JSONObjectWithData:gunzippedData
|
||||
options:0
|
||||
error:&error];
|
||||
NSAssert(error == nil, @"Unable to convert JSON - %@", error);
|
||||
|
||||
return jsonObject;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@ -39,14 +39,10 @@
|
||||
/* 23 */ @property(nonatomic, strong) NSString *leadingDigits;
|
||||
/* 26 */ @property(nonatomic, assign) BOOL leadingZeroPossible;
|
||||
|
||||
#if SHORT_NUMBER_SUPPORT
|
||||
|
||||
/* 29 */ @property (nonatomic, strong) NBPhoneNumberDesc *shortCode;
|
||||
/* 30 */ @property (nonatomic, strong) NBPhoneNumberDesc *standardRate;
|
||||
/* 31 */ @property (nonatomic, strong) NBPhoneNumberDesc *carrierSpecific;
|
||||
/* 33 */ @property (nonatomic, strong) NBPhoneNumberDesc *smsServices;
|
||||
|
||||
#endif // SHORT_NUMBER_SUPPORT
|
||||
/* 29 */ @property(nonatomic, strong) NBPhoneNumberDesc *shortCode;
|
||||
/* 30 */ @property(nonatomic, strong) NBPhoneNumberDesc *standardRate;
|
||||
/* 31 */ @property(nonatomic, strong) NBPhoneNumberDesc *carrierSpecific;
|
||||
/* 33 */ @property(nonatomic, strong) NBPhoneNumberDesc *smsServices;
|
||||
|
||||
- (instancetype)initWithEntry:(NSArray *)entry;
|
||||
@end
|
||||
|
||||
@ -59,12 +59,10 @@
|
||||
_leadingDigits = [entry nb_safeStringAtIndex:23];
|
||||
_leadingZeroPossible = [[entry nb_safeNumberAtIndex:26] boolValue];
|
||||
|
||||
#if SHORT_NUMBER_SUPPORT
|
||||
_shortCode = [[NBPhoneNumberDesc alloc] initWithEntry:[entry nb_safeArrayAtIndex:29]];
|
||||
_standardRate = [[NBPhoneNumberDesc alloc] initWithEntry:[entry nb_safeArrayAtIndex:30]];
|
||||
_carrierSpecific = [[NBPhoneNumberDesc alloc] initWithEntry:[entry nb_safeArrayAtIndex:31]];
|
||||
_smsServices = [[NBPhoneNumberDesc alloc] initWithEntry:[entry nb_safeArrayAtIndex:33]];
|
||||
#endif // SHORT_NUMBER_SUPPORT
|
||||
}
|
||||
|
||||
return self;
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "NBPhoneNumberDefines.h"
|
||||
|
||||
@interface NBPhoneNumber : NSObject<NSCopying, NSCoding>
|
||||
@interface NBPhoneNumber : NSObject <NSCopying, NSCoding>
|
||||
|
||||
// from phonemetadata.pb.js
|
||||
/* 1 */ @property(nonatomic, strong, readwrite) NSNumber *countryCode;
|
||||
|
||||
@ -98,8 +98,8 @@
|
||||
}
|
||||
|
||||
- (NSString *)description {
|
||||
return [NSString stringWithFormat:
|
||||
@" - countryCode[%@], nationalNumber[%@], extension[%@], "
|
||||
return [NSString
|
||||
stringWithFormat:@" - countryCode[%@], nationalNumber[%@], extension[%@], "
|
||||
@"italianLeadingZero[%@], numberOfLeadingZeros[%@], rawInput[%@] "
|
||||
@"countryCodeSource[%@] preferredDomesticCarrierCode[%@]",
|
||||
self.countryCode, self.nationalNumber, self.extension,
|
||||
|
||||
@ -24,8 +24,8 @@
|
||||
}
|
||||
|
||||
- (NSString *)description {
|
||||
return [NSString stringWithFormat:
|
||||
@"nationalNumberPattern[%@] possibleNumberPattern[%@] possibleLength[%@] "
|
||||
return [NSString
|
||||
stringWithFormat:@"nationalNumberPattern[%@] possibleNumberPattern[%@] possibleLength[%@] "
|
||||
@"possibleLengthLocalOnly[%@] exampleNumber[%@]",
|
||||
self.nationalNumberPattern, self.possibleNumberPattern, self.possibleLength,
|
||||
self.possibleLengthLocalOnly, self.exampleNumber];
|
||||
|
||||
55997
libPhoneNumber/NBPhoneNumberMetaData.json
Normal file
55997
libPhoneNumber/NBPhoneNumberMetaData.json
Normal file
File diff suppressed because it is too large
Load Diff
BIN
libPhoneNumber/NBPhoneNumberMetaData.plist
Normal file
BIN
libPhoneNumber/NBPhoneNumberMetaData.plist
Normal file
Binary file not shown.
Binary file not shown.
@ -1,198 +0,0 @@
|
||||
//
|
||||
// NBPhoneNumberUtil+ShortNumber.h
|
||||
// libPhoneNumberiOS
|
||||
//
|
||||
// Created by Paween Itthipalkul on 11/29/17.
|
||||
// Copyright © 2017 Google LLC. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "NBPhoneNumberUtil.h"
|
||||
|
||||
@class NBPhoneNumber;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
#if SHORT_NUMBER_SUPPORT
|
||||
|
||||
typedef NS_ENUM(NSUInteger, NBEShortNumberCost) {
|
||||
NBEShortNumberCostUnknown = 0,
|
||||
NBEShortNumberCostTollFree = 1,
|
||||
NBEShortNumberCostStandardRate = 2,
|
||||
NBEShortNumberCostPremiumRate = 3,
|
||||
};
|
||||
|
||||
@interface NBPhoneNumberUtil (ShortNumber)
|
||||
|
||||
// Short number related methods
|
||||
/**
|
||||
* Check whether a short number is a possible number when dialed from the given region. This
|
||||
* provides a more lenient check than {@link #isValidShortNumberForRegion}.
|
||||
*
|
||||
* @param phoneNumber the short number to check
|
||||
* @param regionDialingFrom the region from which the number is dialed
|
||||
* @return whether the number is a possible short number
|
||||
*/
|
||||
- (BOOL)isPossibleShortNumber:(NBPhoneNumber *)phoneNumber forRegion:(NSString *)regionDialingFrom;
|
||||
|
||||
/**
|
||||
* Check whether a short number is a possible number. If a country calling code is shared by
|
||||
* multiple regions, this returns true if it's possible in any of them. This provides a more
|
||||
* lenient check than {@link #isValidShortNumber}. See {@link
|
||||
* #isPossibleShortNumberForRegion(PhoneNumber, String)} for details.
|
||||
*
|
||||
* @param phoneNumber the short number to check
|
||||
* @return whether the number is a possible short number
|
||||
*/
|
||||
- (BOOL)isPossibleShortNumber:(NBPhoneNumber *)phoneNumber;
|
||||
|
||||
/**
|
||||
* Tests whether a short number matches a valid pattern in a region. Note that this doesn't verify
|
||||
* the number is actually in use, which is impossible to tell by just looking at the number
|
||||
* itself.
|
||||
*
|
||||
* @param phoneNumber the short number for which we want to test the validity
|
||||
* @param regionDialingFrom the region from which the number is dialed
|
||||
* @return whether the short number matches a valid pattern
|
||||
*/
|
||||
- (BOOL)isValidShortNumber:(NBPhoneNumber *)phoneNumber forRegion:(NSString *)regionDialingFrom;
|
||||
|
||||
/**
|
||||
* Tests whether a short number matches a valid pattern. If a country calling code is shared by
|
||||
* multiple regions, this returns true if it's valid in any of them. Note that this doesn't verify
|
||||
* the number is actually in use, which is impossible to tell by just looking at the number
|
||||
* itself. See {@link #isValidShortNumberForRegion(PhoneNumber, String)} for details.
|
||||
*
|
||||
* @param phoneNumber the short number for which we want to test the validity
|
||||
* @return whether the short number matches a valid pattern
|
||||
*/
|
||||
- (BOOL)isValidShortNumber:(NBPhoneNumber *)phoneNumber;
|
||||
|
||||
/**
|
||||
* Gets the expected cost category of a short number when dialed from a region (however, nothing
|
||||
* is implied about its validity). If it is important that the number is valid, then its validity
|
||||
* must first be checked using {@link #isValidShortNumberForRegion}. Note that emergency numbers
|
||||
* are always considered toll-free. Example usage:
|
||||
* <pre>{@code
|
||||
* // The region for which the number was parsed and the region we subsequently check against
|
||||
* // need not be the same. Here we parse the number in the US and check it for Canada.
|
||||
* PhoneNumber number = phoneUtil.parse("110", "US");
|
||||
* ...
|
||||
* String regionCode = "CA";
|
||||
* ShortNumberInfo shortInfo = ShortNumberInfo.getInstance();
|
||||
* if (shortInfo.isValidShortNumberForRegion(shortNumber, regionCode)) {
|
||||
* ShortNumberCost cost = shortInfo.getExpectedCostForRegion(number, regionCode);
|
||||
* // Do something with the cost information here.
|
||||
* }}</pre>
|
||||
*
|
||||
* @param phoneNumber the short number for which we want to know the expected cost category
|
||||
* @param regionDialingFrom the region from which the number is dialed
|
||||
* @return the expected cost category for that region of the short number. Returns UNKNOWN_COST if
|
||||
* the number does not match a cost category. Note that an invalid number may match any cost
|
||||
* category.
|
||||
*/
|
||||
- (NBEShortNumberCost)expectedCostOfPhoneNumber:(NBPhoneNumber *)phoneNumber
|
||||
forRegion:(NSString *)regionDialingFrom;
|
||||
|
||||
/**
|
||||
* Gets the expected cost category of a short number (however, nothing is implied about its
|
||||
* validity). If the country calling code is unique to a region, this method behaves exactly the
|
||||
* same as {@link #getExpectedCostForRegion(PhoneNumber, String)}. However, if the country
|
||||
* calling code is shared by multiple regions, then it returns the highest cost in the sequence
|
||||
* PREMIUM_RATE, UNKNOWN_COST, STANDARD_RATE, TOLL_FREE. The reason for the position of
|
||||
* UNKNOWN_COST in this order is that if a number is UNKNOWN_COST in one region but STANDARD_RATE
|
||||
* or TOLL_FREE in another, its expected cost cannot be estimated as one of the latter since it
|
||||
* might be a PREMIUM_RATE number.
|
||||
* <p>
|
||||
* For example, if a number is STANDARD_RATE in the US, but TOLL_FREE in Canada, the expected
|
||||
* cost returned by this method will be STANDARD_RATE, since the NANPA countries share the same
|
||||
* country calling code.
|
||||
* <p>
|
||||
* Note: If the region from which the number is dialed is known, it is highly preferable to call
|
||||
* {@link #getExpectedCostForRegion(PhoneNumber, String)} instead.
|
||||
*
|
||||
* @param phoneNumber the short number for which we want to know the expected cost category
|
||||
* @return the highest expected cost category of the short number in the region(s) with the given
|
||||
* country calling code
|
||||
*/
|
||||
- (NBEShortNumberCost)expectedCostOfPhoneNumber:(NBPhoneNumber *)phoneNumber;
|
||||
|
||||
/**
|
||||
* Given a valid short number, determines whether it is carrier-specific (however, nothing is
|
||||
* implied about its validity). Carrier-specific numbers may connect to a different end-point, or
|
||||
* not connect at all, depending on the user's carrier. If it is important that the number is
|
||||
* valid, then its validity must first be checked using {@link #isValidShortNumber} or
|
||||
* {@link #isValidShortNumberForRegion}.
|
||||
*
|
||||
* @param phoneNumber the valid short number to check
|
||||
* @return whether the short number is carrier-specific, assuming the input was a valid short
|
||||
* number
|
||||
*/
|
||||
- (BOOL)isPhoneNumberCarrierSpecific:(NBPhoneNumber *)phoneNumber;
|
||||
|
||||
/**
|
||||
* Given a valid short number, determines whether it is carrier-specific when dialed from the
|
||||
* given region (however, nothing is implied about its validity). Carrier-specific numbers may
|
||||
* connect to a different end-point, or not connect at all, depending on the user's carrier. If
|
||||
* it is important that the number is valid, then its validity must first be checked using
|
||||
* {@link #isValidShortNumber} or {@link #isValidShortNumberForRegion}. Returns false if the
|
||||
* number doesn't match the region provided.
|
||||
*
|
||||
* @param phoneNumber the valid short number to check
|
||||
* @param regionDialingFrom the region from which the number is dialed
|
||||
* @return whether the short number is carrier-specific in the provided region, assuming the
|
||||
* input was a valid short number
|
||||
*/
|
||||
- (BOOL)isPhoneNumberCarrierSpecific:(NBPhoneNumber *)phoneNumber forRegion:(NSString *)regionCode;
|
||||
|
||||
/**
|
||||
* Given a valid short number, determines whether it is an SMS service (however, nothing is
|
||||
* implied about its validity). An SMS service is where the primary or only intended usage is to
|
||||
* receive and/or send text messages (SMSs). This includes MMS as MMS numbers downgrade to SMS if
|
||||
* the other party isn't MMS-capable. If it is important that the number is valid, then its
|
||||
* validity must first be checked using {@link #isValidShortNumber} or {@link
|
||||
* #isValidShortNumberForRegion}. Returns false if the number doesn't match the region provided.
|
||||
*
|
||||
* @param phoneNumber the valid short number to check
|
||||
* @param regionDialingFrom the region from which the number is dialed
|
||||
* @return whether the short number is an SMS service in the provided region, assuming the input
|
||||
* was a valid short number
|
||||
*/
|
||||
- (BOOL)isPhoneNumberSMSService:(NBPhoneNumber *)phoneNumber forRegion:(NSString *)regionCode;
|
||||
|
||||
/**
|
||||
* Returns true if the given number, exactly as dialed, might be used to connect to an emergency
|
||||
* service in the given region.
|
||||
* <p>
|
||||
* This method accepts a string, rather than a PhoneNumber, because it needs to distinguish
|
||||
* cases such as "+1 911" and "911", where the former may not connect to an emergency service in
|
||||
* all cases but the latter would. This method takes into account cases where the number might
|
||||
* contain formatting, or might have additional digits appended (when it is okay to do that in
|
||||
* the specified region).
|
||||
*
|
||||
* @param number the phone number to test
|
||||
* @param regionCode the region where the phone number is being dialed
|
||||
* @return whether the number might be used to connect to an emergency service in the given region
|
||||
*/
|
||||
- (BOOL)connectsToEmergencyNumberFromString:(NSString *)number forRegion:(NSString *)regionCode;
|
||||
|
||||
/**
|
||||
* Returns true if the given number exactly matches an emergency service number in the given
|
||||
* region.
|
||||
* <p>
|
||||
* This method takes into account cases where the number might contain formatting, but doesn't
|
||||
* allow additional digits to be appended. Note that {@code isEmergencyNumber(number, region)}
|
||||
* implies {@code connectsToEmergencyNumber(number, region)}.
|
||||
*
|
||||
* @param number the phone number to test
|
||||
* @param regionCode the region where the phone number is being dialed
|
||||
* @return whether the number exactly matches an emergency services number in the given region
|
||||
*/
|
||||
- (BOOL)isEmergencyNumber:(NSString *)number forRegion:(NSString *)regionCode;
|
||||
|
||||
@end
|
||||
|
||||
#endif // SHORT_NUMBER_SUPPORT
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
@ -1,326 +0,0 @@
|
||||
//
|
||||
// NBPhoneNumberUtil+ShortNumber.m
|
||||
// libPhoneNumberiOS
|
||||
//
|
||||
// Created by Paween Itthipalkul on 11/29/17.
|
||||
// Copyright © 2017 Google LLC. All rights reserved.
|
||||
//
|
||||
|
||||
#import "NBPhoneNumberUtil+ShortNumber.h"
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "NBMetadataHelper.h"
|
||||
#import "NBPhoneMetaData.h"
|
||||
#import "NBPhoneNumber.h"
|
||||
#import "NBPhoneNumberDesc.h"
|
||||
#import "NBRegExMatcher.h"
|
||||
#import "NBRegularExpressionCache.h"
|
||||
|
||||
#if SHORT_NUMBER_SUPPORT
|
||||
|
||||
static NSString * const PLUS_CHARS_PATTERN = @"[+\uFF0B]+";
|
||||
|
||||
@interface NBPhoneNumberUtil()
|
||||
|
||||
@property(nonatomic, strong, readonly) NBMetadataHelper *helper;
|
||||
@property(nonatomic, strong, readonly) NBRegExMatcher *matcher;
|
||||
|
||||
@property (nonatomic) NSDictionary<NSNumber *, NSArray<NSString *> *> *countryToRegionCodeMap;
|
||||
|
||||
@end
|
||||
|
||||
@implementation NBPhoneNumberUtil (ShortNumber)
|
||||
|
||||
- (BOOL)isPossibleShortNumber:(NBPhoneNumber *)phoneNumber forRegion:(NSString *)regionDialingFrom {
|
||||
if (![self doesPhoneNumber:phoneNumber matchesRegion:regionDialingFrom]) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
NBPhoneMetaData *metadata = [self.helper shortNumberMetadataForRegion:regionDialingFrom];
|
||||
if (metadata == nil) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
NSUInteger length = [[self getNationalSignificantNumber:phoneNumber] length];
|
||||
return [metadata.generalDesc.possibleLength containsObject:@(length)];
|
||||
}
|
||||
|
||||
- (BOOL)isPossibleShortNumber:(NBPhoneNumber *)phoneNumber {
|
||||
NSArray<NSString *> *regionCodes = [self getRegionCodesForCountryCode:phoneNumber.countryCode];
|
||||
NSUInteger shortNumberLength = [[self getNationalSignificantNumber:phoneNumber] length];
|
||||
for (NSString *region in regionCodes) {
|
||||
NBPhoneMetaData *metadata = [self.helper shortNumberMetadataForRegion:region];
|
||||
if (metadata == nil) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ([metadata.generalDesc.possibleLength containsObject:@(shortNumberLength)]) {
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL)isValidShortNumber:(NBPhoneNumber *)phoneNumber
|
||||
forRegion:(NSString *)regionDialingFrom {
|
||||
if (![self doesPhoneNumber:phoneNumber matchesRegion:regionDialingFrom]) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
NBPhoneMetaData *metadata = [self.helper shortNumberMetadataForRegion:regionDialingFrom];
|
||||
if (metadata == nil) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
NSString *shortNumber = [self getNationalSignificantNumber:phoneNumber];
|
||||
NBPhoneNumberDesc *generalDesc = metadata.generalDesc;
|
||||
if (![self matchesPossibleNumber:shortNumber andNationalNumber:generalDesc]) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
NBPhoneNumberDesc *shortNumberDesc = metadata.shortCode;
|
||||
return [self matchesPossibleNumber:shortNumber andNationalNumber:shortNumberDesc];
|
||||
}
|
||||
|
||||
- (BOOL)isValidShortNumber:(NBPhoneNumber *)phoneNumber {
|
||||
NSArray<NSString *> *regionCodes = [self getRegionCodesForCountryCode:phoneNumber.countryCode];
|
||||
NSString *regionCode = [self regionCodeForShortNumber:phoneNumber fromRegionList:regionCodes];
|
||||
if (regionCodes.count > 1 && regionCode != nil) {
|
||||
// If a matching region had been found for the phone number from among two or more regions,
|
||||
// then we have already implicitly verified its validity for that region.
|
||||
return YES;
|
||||
}
|
||||
|
||||
return [self isValidShortNumber:phoneNumber forRegion:regionCode];
|
||||
}
|
||||
|
||||
- (NBEShortNumberCost)expectedCostOfPhoneNumber:(NBPhoneNumber *)phoneNumber
|
||||
forRegion:(NSString *)regionDialingFrom {
|
||||
if (![self doesRegionDialingFrom:regionDialingFrom matchesPhoneNumber:phoneNumber]) {
|
||||
return NBEShortNumberCostUnknown;
|
||||
}
|
||||
|
||||
NBPhoneMetaData *metadata = [self.helper shortNumberMetadataForRegion:regionDialingFrom];
|
||||
if (metadata == nil) {
|
||||
return NBEShortNumberCostUnknown;
|
||||
}
|
||||
|
||||
NSString *shortNumber = [self getNationalSignificantNumber:phoneNumber];
|
||||
|
||||
// The possible lengths are not present for a particular sub-type if they match the general
|
||||
// description; for this reason, we check the possible lengths against the general description
|
||||
// first to allow an early exit if possible.
|
||||
if (![metadata.generalDesc.possibleLength containsObject:@(shortNumber.length)]) {
|
||||
return NBEShortNumberCostUnknown;
|
||||
}
|
||||
|
||||
// The cost categories are tested in order of decreasing expense, since if for some reason the
|
||||
// patterns overlap the most expensive matching cost category should be returned.
|
||||
if ([self matchesPossibleNumber:shortNumber andNationalNumber:metadata.premiumRate]) {
|
||||
return NBEShortNumberCostPremiumRate;
|
||||
} else if ([self matchesPossibleNumber:shortNumber andNationalNumber:metadata.standardRate]) {
|
||||
return NBEShortNumberCostStandardRate;
|
||||
} else if ([self matchesPossibleNumber:shortNumber andNationalNumber:metadata.tollFree]) {
|
||||
return NBEShortNumberCostTollFree;
|
||||
}
|
||||
|
||||
if ([self isEmergencyNumber:shortNumber forRegion:regionDialingFrom]) {
|
||||
// Emergency numbers are implicitly toll-free.
|
||||
return NBEShortNumberCostTollFree;
|
||||
}
|
||||
|
||||
return NBEShortNumberCostUnknown;
|
||||
}
|
||||
|
||||
- (NBEShortNumberCost)expectedCostOfPhoneNumber:(NBPhoneNumber *)phoneNumber {
|
||||
NSArray<NSString *> *regionCodes = [self getRegionCodesForCountryCode:phoneNumber.countryCode];
|
||||
if (regionCodes.count == 0) {
|
||||
return NBEShortNumberCostUnknown;
|
||||
}
|
||||
if (regionCodes.count == 1) {
|
||||
return [self expectedCostOfPhoneNumber:phoneNumber forRegion:regionCodes[0]];
|
||||
}
|
||||
|
||||
NBEShortNumberCost cost = NBEShortNumberCostTollFree;
|
||||
for (NSString *regionCode in regionCodes) {
|
||||
NBEShortNumberCost costForRegion = [self expectedCostOfPhoneNumber:phoneNumber
|
||||
forRegion:regionCode];
|
||||
switch (costForRegion) {
|
||||
case NBEShortNumberCostPremiumRate:
|
||||
return NBEShortNumberCostPremiumRate;
|
||||
case NBEShortNumberCostUnknown:
|
||||
cost = NBEShortNumberCostUnknown;
|
||||
break;
|
||||
case NBEShortNumberCostStandardRate:
|
||||
if (cost != NBEShortNumberCostUnknown) {
|
||||
cost = NBEShortNumberCostStandardRate;
|
||||
}
|
||||
break;
|
||||
case NBEShortNumberCostTollFree:
|
||||
// Do nothing.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return cost;
|
||||
}
|
||||
|
||||
- (BOOL)isPhoneNumberCarrierSpecific:(NBPhoneNumber *)phoneNumber {
|
||||
NSArray<NSString *> *regionCodes = [self getRegionCodesForCountryCode:phoneNumber.countryCode];
|
||||
NSString *regionCode = [self regionCodeForShortNumber:phoneNumber fromRegionList:regionCodes];
|
||||
NSString *nationalNumber = [self getNationalSignificantNumber:phoneNumber];
|
||||
NBPhoneMetaData *metadata = [self.helper shortNumberMetadataForRegion:regionCode];
|
||||
return (metadata != nil &&
|
||||
([self matchesPossibleNumber:nationalNumber andNationalNumber:metadata.carrierSpecific]));
|
||||
}
|
||||
|
||||
- (BOOL)isPhoneNumberCarrierSpecific:(NBPhoneNumber *)phoneNumber forRegion:(NSString *)regionCode {
|
||||
if (![self doesRegionDialingFrom:regionCode matchesPhoneNumber:phoneNumber]) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
NSString *nationalNumber = [self getNationalSignificantNumber:phoneNumber];
|
||||
NBPhoneMetaData *metadata = [self.helper shortNumberMetadataForRegion:regionCode];
|
||||
return (metadata != nil
|
||||
&& ([self matchesPossibleNumber:nationalNumber andNationalNumber:metadata.carrierSpecific]));
|
||||
}
|
||||
|
||||
- (BOOL)isPhoneNumberSMSService:(NBPhoneNumber *)phoneNumber forRegion:(NSString *)regionCode {
|
||||
if (![self doesRegionDialingFrom:regionCode matchesPhoneNumber:phoneNumber]) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
NSString *nationalNumber = [self getNationalSignificantNumber:phoneNumber];
|
||||
NBPhoneMetaData *metadata = [self.helper shortNumberMetadataForRegion:regionCode];
|
||||
return (metadata != nil
|
||||
&& ([self matchesPossibleNumber:nationalNumber andNationalNumber:metadata.smsServices]));
|
||||
}
|
||||
|
||||
- (BOOL)connectsToEmergencyNumberFromString:(NSString *)number forRegion:(NSString *)regionCode {
|
||||
return [self matchesEmergencyNumberHelper:number regionCode:regionCode allowsPrefixMatch:YES];
|
||||
}
|
||||
|
||||
- (BOOL)isEmergencyNumber:(NSString *)number forRegion:(NSString *)regionCode {
|
||||
return [self matchesEmergencyNumberHelper:number regionCode:regionCode allowsPrefixMatch:NO];
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
// In these countries, if extra digits are added to an emergency number, it no longer connects
|
||||
// to the emergency service.
|
||||
+ (NSSet<NSString *> *)regionsWhereEmergencyNumbersMustBeExact {
|
||||
static NSSet<NSString *> *regions;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
regions = [NSSet setWithObjects:@"BR", @"CL", @"NI", nil];
|
||||
});
|
||||
return regions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to check that the country calling code of the number matches the region it's
|
||||
* being dialed from.
|
||||
*/
|
||||
- (BOOL)doesPhoneNumber:(NBPhoneNumber *)phoneNumber matchesRegion:(NSString *)regionCode {
|
||||
NSArray<NSString *> *regionCodes = [self getRegionCodesForCountryCode:phoneNumber.countryCode];
|
||||
return [regionCodes containsObject:regionCode];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the national significant number of the a phone number. Note a national significant number
|
||||
* doesn't contain a national prefix or any formatting.
|
||||
* <p>
|
||||
* This is a temporary duplicate of the {@code getNationalSignificantNumber} method from
|
||||
* {@code PhoneNumberUtil}. Ultimately a canonical static version should exist in a separate
|
||||
* utility class (to prevent {@code ShortNumberInfo} needing to depend on PhoneNumberUtil).
|
||||
*
|
||||
* @param number the phone number for which the national significant number is needed
|
||||
* @return the national significant number of the PhoneNumber object passed in
|
||||
*/
|
||||
+ (NSString *)nationalSignificantNumberFromPhoneNumber:(NBPhoneNumber *)phoneNumber {
|
||||
// If leading zero(s) have been set, we prefix this now. Note this is not a national prefix.
|
||||
NSMutableString *nationalNumber = [[NSMutableString alloc] init];
|
||||
if (phoneNumber.italianLeadingZero) {
|
||||
[nationalNumber appendFormat:@"%*d", [phoneNumber.numberOfLeadingZeros intValue], 0];
|
||||
}
|
||||
[nationalNumber appendString:[phoneNumber.nationalNumber stringValue]];
|
||||
|
||||
return [nationalNumber copy];
|
||||
}
|
||||
|
||||
- (BOOL)matchesPossibleNumber:(NSString *)number andNationalNumber:(NBPhoneNumberDesc *)numberDesc {
|
||||
if (numberDesc.possibleLength.count > 0
|
||||
&& ![numberDesc.possibleLength containsObject:@(number.length)]) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
return [self.matcher matchNationalNumber:number phoneNumberDesc:numberDesc allowsPrefixMatch:NO];
|
||||
}
|
||||
|
||||
// Helper method to get the region code for a given phone number, from a list of possible region
|
||||
// codes. If the list contains more than one region, the first region for which the number is
|
||||
// valid is returned.
|
||||
- (NSString *)regionCodeForShortNumber:(NBPhoneNumber *)number
|
||||
fromRegionList:(NSArray<NSString *> *)regionCodes {
|
||||
if (regionCodes.count == 0) {
|
||||
return nil;
|
||||
} else if (regionCodes.count == 1) {
|
||||
return regionCodes[0];
|
||||
}
|
||||
|
||||
NSString *nationalNumber = [self getNationalSignificantNumber:number];
|
||||
for (NSString *regionCode in regionCodes) {
|
||||
NBPhoneMetaData *metadata = [self.helper shortNumberMetadataForRegion:regionCode];
|
||||
if (metadata != nil && [self matchesPossibleNumber:nationalNumber
|
||||
andNationalNumber:metadata.shortCode]) {
|
||||
// The number is valid for this region.
|
||||
return regionCode;
|
||||
}
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (BOOL)doesRegionDialingFrom:(NSString *)regionCode
|
||||
matchesPhoneNumber:(NBPhoneNumber *)phoneNumber {
|
||||
NSArray<NSString *> *regionCodes = [self getRegionCodesForCountryCode:phoneNumber.countryCode];
|
||||
return [regionCodes containsObject:regionCode];
|
||||
}
|
||||
|
||||
- (BOOL)matchesEmergencyNumberHelper:(NSString *)number regionCode:(NSString *)regionCode
|
||||
allowsPrefixMatch:(BOOL)allowsPrefixMatch {
|
||||
NSString *possibleNumber = [self extractPossibleNumber:number];
|
||||
NSRegularExpression *regex =
|
||||
[[NBRegularExpressionCache sharedInstance] regularExpressionForPattern:PLUS_CHARS_PATTERN
|
||||
error:NULL];
|
||||
|
||||
NSTextCheckingResult *result = [regex firstMatchInString:possibleNumber
|
||||
options:kNilOptions
|
||||
range:NSMakeRange(0, possibleNumber.length)];
|
||||
if (result != nil) {
|
||||
// Returns false if the number starts with a plus sign. We don't believe dialing the country
|
||||
// code before emergency numbers (e.g. +1911) works, but later, if that proves to work, we can
|
||||
// add additional logic here to handle it.
|
||||
return NO;
|
||||
}
|
||||
|
||||
NBPhoneMetaData *metadata = [self.helper shortNumberMetadataForRegion:regionCode];
|
||||
if (metadata == nil || metadata.emergency == nil) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
NSString *normalizedNumber = [self normalizeDigitsOnly:possibleNumber];
|
||||
NSSet<NSString *> *exactRegions = [NBPhoneNumberUtil regionsWhereEmergencyNumbersMustBeExact];
|
||||
|
||||
BOOL allowsPrefixMatchForRegion = allowsPrefixMatch && ![exactRegions containsObject:regionCode];
|
||||
|
||||
return [self.matcher matchNationalNumber:normalizedNumber
|
||||
phoneNumberDesc:metadata.emergency
|
||||
allowsPrefixMatch:allowsPrefixMatchForRegion];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#endif // SHORT_NUMBER_SUPPORT
|
||||
@ -9,11 +9,14 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "NBPhoneNumberDefines.h"
|
||||
|
||||
@class NBPhoneMetaData, NBPhoneNumber;
|
||||
@class NBPhoneMetaData, NBPhoneNumber, NBMetadataHelper;
|
||||
|
||||
@interface NBPhoneNumberUtil : NSObject
|
||||
|
||||
+ (NBPhoneNumberUtil *)sharedInstance;
|
||||
- (instancetype)initWithMetadataHelper:(NBMetadataHelper *)helper;
|
||||
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
@property(nonatomic, strong, readonly) NSDictionary *DIGIT_MAPPINGS;
|
||||
|
||||
@ -36,9 +39,7 @@
|
||||
|
||||
- (NSString *)extractPossibleNumber:(NSString *)phoneNumber;
|
||||
- (NSNumber *)extractCountryCode:(NSString *)fullNumber nationalNumber:(NSString **)nationalNumber;
|
||||
#if TARGET_OS_IOS
|
||||
- (NSString *)countryCodeByCarrier;
|
||||
#endif
|
||||
|
||||
- (NSString *)getNddPrefixForRegion:(NSString *)regionCode stripNonDigits:(BOOL)stripNonDigits;
|
||||
- (NSString *)getNationalSignificantNumber:(NBPhoneNumber *)phoneNumber;
|
||||
|
||||
@ -16,9 +16,8 @@
|
||||
#import "NBPhoneNumberDesc.h"
|
||||
#import "NBRegExMatcher.h"
|
||||
|
||||
#if TARGET_OS_IOS
|
||||
#import <CoreTelephony/CTCarrier.h>
|
||||
#import <CoreTelephony/CTTelephonyNetworkInfo.h>
|
||||
#if __has_include(<Contacts/Contacts.h>)
|
||||
#import "Contacts/Contacts.h"
|
||||
#endif
|
||||
|
||||
static NSString *NormalizeNonBreakingSpace(NSString *aString) {
|
||||
@ -40,11 +39,8 @@ static BOOL isNan(NSString *sourceString) {
|
||||
|
||||
@interface NBPhoneNumberUtil ()
|
||||
|
||||
@property(nonatomic, strong) NSLock *entireStringCacheLock;
|
||||
@property(nonatomic, strong) NSMutableDictionary *entireStringRegexCache;
|
||||
|
||||
@property(nonatomic, strong) NSLock *lockPatternCache;
|
||||
@property(nonatomic, strong) NSMutableDictionary *regexPatternCache;
|
||||
@property(nonatomic, strong) NSCache<NSString *, NSRegularExpression *> *entireStringRegexCache;
|
||||
@property(nonatomic, strong) NSCache<NSString *, NSRegularExpression *> *regexPatternCache;
|
||||
|
||||
@property(nonatomic, strong) NSRegularExpression *CAPTURING_DIGIT_PATTERN;
|
||||
@property(nonatomic, strong) NSRegularExpression *VALID_ALPHA_PHONE_PATTERN;
|
||||
@ -52,10 +48,6 @@ static BOOL isNan(NSString *sourceString) {
|
||||
@property(nonatomic, strong, readwrite) NBMetadataHelper *helper;
|
||||
@property(nonatomic, strong, readwrite) NBRegExMatcher *matcher;
|
||||
|
||||
#if TARGET_OS_IOS
|
||||
@property(nonatomic, readonly) CTTelephonyNetworkInfo *telephonyNetworkInfo;
|
||||
#endif
|
||||
|
||||
@end
|
||||
|
||||
@implementation NBPhoneNumberUtil
|
||||
@ -119,11 +111,24 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
static NBPhoneNumberUtil *sharedOnceInstance = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
sharedOnceInstance = [[self alloc] init];
|
||||
sharedOnceInstance = [[self alloc] initWithMetadataHelper:[[NBMetadataHelper alloc] init]];
|
||||
});
|
||||
return sharedOnceInstance;
|
||||
}
|
||||
|
||||
- (instancetype)initWithMetadataHelper:(NBMetadataHelper *)helper {
|
||||
self = [super init];
|
||||
if (self != nil) {
|
||||
_regexPatternCache = [[NSCache alloc] init];
|
||||
_entireStringRegexCache = [[NSCache alloc] init];
|
||||
_helper = helper;
|
||||
_matcher = [[NBRegExMatcher alloc] init];
|
||||
[self initRegularExpressionSet];
|
||||
[self initNormalizationMappings];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark - NSError
|
||||
|
||||
- (NSError *)errorWithObject:(id)obj withDomain:(NSString *)domain {
|
||||
@ -135,55 +140,37 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
- (NSRegularExpression *)entireRegularExpressionWithPattern:(NSString *)regexPattern
|
||||
options:(NSRegularExpressionOptions)options
|
||||
error:(NSError **)error {
|
||||
[_entireStringCacheLock lock];
|
||||
|
||||
@try {
|
||||
if (!_entireStringRegexCache) {
|
||||
_entireStringRegexCache = [[NSMutableDictionary alloc] init];
|
||||
NSRegularExpression *regex = [_entireStringRegexCache objectForKey:regexPattern];
|
||||
if (!regex) {
|
||||
NSString *finalRegexString = regexPattern;
|
||||
if ([regexPattern rangeOfString:@"^"].location == NSNotFound) {
|
||||
finalRegexString = [NSString stringWithFormat:@"^(?:%@)$", regexPattern];
|
||||
}
|
||||
|
||||
NSRegularExpression *regex = [_entireStringRegexCache objectForKey:regexPattern];
|
||||
if (!regex) {
|
||||
NSString *finalRegexString = regexPattern;
|
||||
if ([regexPattern rangeOfString:@"^"].location == NSNotFound) {
|
||||
finalRegexString = [NSString stringWithFormat:@"^(?:%@)$", regexPattern];
|
||||
}
|
||||
|
||||
regex = [self regularExpressionWithPattern:finalRegexString options:0 error:error];
|
||||
[_entireStringRegexCache setObject:regex forKey:regexPattern];
|
||||
}
|
||||
|
||||
return regex;
|
||||
} @finally {
|
||||
[_entireStringCacheLock unlock];
|
||||
regex = [self regularExpressionWithPattern:finalRegexString options:0 error:error];
|
||||
[_entireStringRegexCache setObject:regex forKey:regexPattern];
|
||||
}
|
||||
|
||||
return regex;
|
||||
}
|
||||
|
||||
- (NSRegularExpression *)regularExpressionWithPattern:(NSString *)pattern
|
||||
options:(NSRegularExpressionOptions)options
|
||||
error:(NSError **)error {
|
||||
[_lockPatternCache lock];
|
||||
|
||||
@try {
|
||||
if (!_regexPatternCache) {
|
||||
_regexPatternCache = [[NSMutableDictionary alloc] init];
|
||||
}
|
||||
|
||||
NSRegularExpression *regex = [_regexPatternCache objectForKey:pattern];
|
||||
if (!regex) {
|
||||
regex =
|
||||
[NSRegularExpression regularExpressionWithPattern:pattern options:options error:error];
|
||||
[_regexPatternCache setObject:regex forKey:pattern];
|
||||
}
|
||||
return regex;
|
||||
} @finally {
|
||||
[_lockPatternCache unlock];
|
||||
NSRegularExpression *regex = [_regexPatternCache objectForKey:pattern];
|
||||
if (!regex) {
|
||||
regex = [NSRegularExpression regularExpressionWithPattern:pattern
|
||||
options:options
|
||||
error:error];
|
||||
[_regexPatternCache setObject:regex forKey:pattern];
|
||||
}
|
||||
return regex;
|
||||
}
|
||||
|
||||
- (NSMutableArray *)componentsSeparatedByRegex:(NSString *)sourceString regex:(NSString *)pattern {
|
||||
NSString *replacedString =
|
||||
[self replaceStringByRegex:sourceString regex:pattern withTemplate:@"<SEP>"];
|
||||
NSString *replacedString = [self replaceStringByRegex:sourceString
|
||||
regex:pattern
|
||||
withTemplate:@"<SEP>"];
|
||||
NSMutableArray *resArray = [[replacedString componentsSeparatedByString:@"<SEP>"] mutableCopy];
|
||||
[resArray removeObject:@""];
|
||||
return resArray;
|
||||
@ -195,8 +182,9 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
}
|
||||
|
||||
NSError *error = nil;
|
||||
NSRegularExpression *currentPattern =
|
||||
[self regularExpressionWithPattern:pattern options:0 error:&error];
|
||||
NSRegularExpression *currentPattern = [self regularExpressionWithPattern:pattern
|
||||
options:0
|
||||
error:&error];
|
||||
NSArray *matches = [currentPattern matchesInString:sourceString
|
||||
options:0
|
||||
range:NSMakeRange(0, sourceString.length)];
|
||||
@ -226,8 +214,9 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
NSString *replacementResult = [sourceString copy];
|
||||
NSError *error = nil;
|
||||
|
||||
NSRegularExpression *currentPattern =
|
||||
[self regularExpressionWithPattern:pattern options:0 error:&error];
|
||||
NSRegularExpression *currentPattern = [self regularExpressionWithPattern:pattern
|
||||
options:0
|
||||
error:&error];
|
||||
NSRange replaceRange =
|
||||
[currentPattern rangeOfFirstMatchInString:sourceString
|
||||
options:0
|
||||
@ -247,8 +236,9 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
regex:(NSString *)pattern
|
||||
withTemplate:(NSString *)templateString {
|
||||
NSError *error = nil;
|
||||
NSRegularExpression *currentPattern =
|
||||
[self regularExpressionWithPattern:pattern options:0 error:&error];
|
||||
NSRegularExpression *currentPattern = [self regularExpressionWithPattern:pattern
|
||||
options:0
|
||||
error:&error];
|
||||
NSArray *matches = [currentPattern matchesInString:sourceString
|
||||
options:0
|
||||
range:NSMakeRange(0, sourceString.length)];
|
||||
@ -284,8 +274,9 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
|
||||
- (NSTextCheckingResult *)matchFirstByRegex:(NSString *)sourceString regex:(NSString *)pattern {
|
||||
NSError *error = nil;
|
||||
NSRegularExpression *currentPattern =
|
||||
[self regularExpressionWithPattern:pattern options:0 error:&error];
|
||||
NSRegularExpression *currentPattern = [self regularExpressionWithPattern:pattern
|
||||
options:0
|
||||
error:&error];
|
||||
NSArray *matches = [currentPattern matchesInString:sourceString
|
||||
options:0
|
||||
range:NSMakeRange(0, sourceString.length)];
|
||||
@ -295,8 +286,9 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
|
||||
- (NSArray *)matchesByRegex:(NSString *)sourceString regex:(NSString *)pattern {
|
||||
NSError *error = nil;
|
||||
NSRegularExpression *currentPattern =
|
||||
[self regularExpressionWithPattern:pattern options:0 error:&error];
|
||||
NSRegularExpression *currentPattern = [self regularExpressionWithPattern:pattern
|
||||
options:0
|
||||
error:&error];
|
||||
NSArray *matches = [currentPattern matchesInString:sourceString
|
||||
options:0
|
||||
range:NSMakeRange(0, sourceString.length)];
|
||||
@ -317,8 +309,9 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
|
||||
- (BOOL)isStartingStringByRegex:(NSString *)sourceString regex:(NSString *)pattern {
|
||||
NSError *error = nil;
|
||||
NSRegularExpression *currentPattern =
|
||||
[self regularExpressionWithPattern:pattern options:0 error:&error];
|
||||
NSRegularExpression *currentPattern = [self regularExpressionWithPattern:pattern
|
||||
options:0
|
||||
error:&error];
|
||||
NSArray *matches = [currentPattern matchesInString:sourceString
|
||||
options:0
|
||||
range:NSMakeRange(0, sourceString.length)];
|
||||
@ -401,20 +394,6 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
GEO_MOBILE_COUNTRIES = @[ @52, @54, @55 ];
|
||||
}
|
||||
|
||||
- (instancetype)init {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_lockPatternCache = [[NSLock alloc] init];
|
||||
_entireStringCacheLock = [[NSLock alloc] init];
|
||||
_helper = [[NBMetadataHelper alloc] init];
|
||||
_matcher = [[NBRegExMatcher alloc] init];
|
||||
[self initRegularExpressionSet];
|
||||
[self initNormalizationMappings];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)initRegularExpressionSet {
|
||||
NSError *error = nil;
|
||||
|
||||
@ -426,40 +405,42 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
}
|
||||
|
||||
if (!_VALID_ALPHA_PHONE_PATTERN) {
|
||||
_VALID_ALPHA_PHONE_PATTERN =
|
||||
[self regularExpressionWithPattern:VALID_ALPHA_PHONE_PATTERN_STRING options:0 error:&error];
|
||||
_VALID_ALPHA_PHONE_PATTERN = [self regularExpressionWithPattern:VALID_ALPHA_PHONE_PATTERN_STRING
|
||||
options:0
|
||||
error:&error];
|
||||
}
|
||||
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(
|
||||
&onceToken, ^{
|
||||
NSString *EXTN_PATTERNS_FOR_PARSING =
|
||||
@"(?:;ext=([0-90-9٠-٩۰-۹]{1,7})|[ "
|
||||
@"\\t,]*(?:e?xt(?:ensi(?:ó?|ó))?n?|e?xtn?|[,xxX##~~]|int|anexo|int)[:\\..]?["
|
||||
@" \\t,-]*([0-90-9٠-٩۰-۹]{1,7})#?|[- ]+([0-90-9٠-٩۰-۹]{1,5})#)$";
|
||||
dispatch_once(&onceToken, ^{
|
||||
NSString *EXTN_PATTERNS_FOR_PARSING =
|
||||
@"(?:;ext=([0-90-9٠-٩۰-۹]{1,7})|[ "
|
||||
@"\\t,]*(?:e?xt(?:ensi(?:ó?|ó))?n?|e?xtn?|[,xxX##~~]|int|anexo|int)[:\\..]?["
|
||||
@" \\t,-]*([0-90-9٠-٩۰-۹]{1,7})#?|[- ]+([0-90-9٠-٩۰-۹]{1,5})#)$";
|
||||
|
||||
LEADING_PLUS_CHARS_PATTERN = [NSString stringWithFormat:@"^[%@]+", NB_PLUS_CHARS];
|
||||
LEADING_PLUS_CHARS_PATTERN = [NSString stringWithFormat:@"^[%@]+", NB_PLUS_CHARS];
|
||||
|
||||
VALID_START_CHAR_PATTERN =
|
||||
[NSString stringWithFormat:@"[%@%@]", NB_PLUS_CHARS, NB_VALID_DIGITS_STRING];
|
||||
VALID_START_CHAR_PATTERN =
|
||||
[NSString stringWithFormat:@"[%@%@]", NB_PLUS_CHARS, NB_VALID_DIGITS_STRING];
|
||||
|
||||
SECOND_NUMBER_START_PATTERN = @"[\\\\\\/] *x";
|
||||
SECOND_NUMBER_START_PATTERN = @"[\\\\\\/] *x";
|
||||
|
||||
UNWANTED_END_CHAR_PATTERN =
|
||||
[NSString stringWithFormat:@"[^%@%@#]+$", NB_VALID_DIGITS_STRING, VALID_ALPHA];
|
||||
UNWANTED_END_CHAR_PATTERN =
|
||||
[NSString stringWithFormat:@"[^%@%@#]+$", NB_VALID_DIGITS_STRING, VALID_ALPHA];
|
||||
|
||||
EXTN_PATTERN = [NSString stringWithFormat:@"(?:%@)$", EXTN_PATTERNS_FOR_PARSING];
|
||||
EXTN_PATTERN = [NSString stringWithFormat:@"(?:%@)$", EXTN_PATTERNS_FOR_PARSING];
|
||||
|
||||
SEPARATOR_PATTERN = [NSString stringWithFormat:@"[%@]+", VALID_PUNCTUATION];
|
||||
SEPARATOR_PATTERN = [NSString stringWithFormat:@"[%@]+", VALID_PUNCTUATION];
|
||||
|
||||
VALID_PHONE_NUMBER_PATTERN =
|
||||
@"^[0-90-9٠-٩۰-۹]{2}$|^[++]*(?:[-x‐-―−ー--/ "
|
||||
@" ()()[].\\[\\]/~⁓∼~*]*[0-90-9٠-٩۰-۹]){3,}[-x‐-―−ー--/ "
|
||||
@" ()()[].\\[\\]/"
|
||||
@"~⁓∼~*A-Za-z0-90-9٠-٩۰-۹]*(?:;ext=([0-90-9٠-٩۰-۹]{1,7})|[ "
|
||||
@"\\t,]*(?:e?xt(?:ensi(?:ó?|ó))?n?|e?xtn?|[,xx##~~]|int|anexo|int)[:\\..]?[ "
|
||||
@" \\t,-]*([0-90-9٠-٩۰-۹]{1,7})#?|[- ]+([0-90-9٠-٩۰-۹]{1,5})#)?$";
|
||||
});
|
||||
VALID_PHONE_NUMBER_PATTERN =
|
||||
@"^[0-90-9٠-٩۰-۹]{2}$|^[++]*(?:[-x‐-―−ー--/ "
|
||||
@" ()()[].\\[\\]/"
|
||||
@"~⁓∼~*]*[0-90-9٠-٩۰-۹]){3,}[-x‐-―−ー--/ "
|
||||
@" "
|
||||
@" ()()[].\\[\\]/"
|
||||
@"~⁓∼~*A-Za-z0-90-9٠-٩۰-۹]*(?:;ext=([0-90-9٠-٩۰-۹]{1,7})|[ "
|
||||
@"\\t,]*(?:e?xt(?:ensi(?:ó?|ó))?n?|e?xtn?|[,xx##~~]|int|anexo|int)[:\\..]?[ "
|
||||
@" \\t,-]*([0-90-9٠-٩۰-۹]{1,7})#?|[- ]+([0-90-9٠-٩۰-۹]{1,5})#)?$";
|
||||
});
|
||||
}
|
||||
|
||||
- (NSDictionary *)DIGIT_MAPPINGS {
|
||||
@ -543,8 +524,8 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
@".", @".", @".", @"\uFF0E", nil];
|
||||
|
||||
MOBILE_TOKEN_MAPPINGS = @{
|
||||
@52: @"1",
|
||||
@54: @"9",
|
||||
@52 : @"1",
|
||||
@54 : @"9",
|
||||
};
|
||||
});
|
||||
}
|
||||
@ -576,12 +557,13 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
if (start >= 0) {
|
||||
possibleNumber = [number substringFromIndex:start];
|
||||
// Remove trailing non-alpha non-numerical characters.
|
||||
possibleNumber =
|
||||
[self replaceStringByRegex:possibleNumber regex:UNWANTED_END_CHAR_PATTERN withTemplate:@""];
|
||||
possibleNumber = [self replaceStringByRegex:possibleNumber
|
||||
regex:UNWANTED_END_CHAR_PATTERN
|
||||
withTemplate:@""];
|
||||
|
||||
// Check for extra numbers at the end.
|
||||
int secondNumberStart =
|
||||
[self stringPositionByRegex:possibleNumber regex:SECOND_NUMBER_START_PATTERN];
|
||||
int secondNumberStart = [self stringPositionByRegex:possibleNumber
|
||||
regex:SECOND_NUMBER_START_PATTERN];
|
||||
if (secondNumberStart > 0) {
|
||||
possibleNumber = [possibleNumber substringWithRange:NSMakeRange(0, secondNumberStart)];
|
||||
}
|
||||
@ -759,8 +741,8 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
@try {
|
||||
res = [self getLengthOfGeographicalAreaCode:phoneNumber];
|
||||
} @catch (NSException *exception) {
|
||||
NSDictionary *userInfo =
|
||||
[NSDictionary dictionaryWithObject:exception.reason forKey:NSLocalizedDescriptionKey];
|
||||
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:exception.reason
|
||||
forKey:NSLocalizedDescriptionKey];
|
||||
if (error != NULL) {
|
||||
(*error) = [NSError errorWithDomain:exception.name code:0 userInfo:userInfo];
|
||||
}
|
||||
@ -832,8 +814,8 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
@try {
|
||||
res = [self getLengthOfNationalDestinationCode:phoneNumber];
|
||||
} @catch (NSException *exception) {
|
||||
NSDictionary *userInfo =
|
||||
[NSDictionary dictionaryWithObject:exception.reason forKey:NSLocalizedDescriptionKey];
|
||||
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:exception.reason
|
||||
forKey:NSLocalizedDescriptionKey];
|
||||
if (error != NULL) {
|
||||
(*error) = [NSError errorWithDomain:exception.name code:0 userInfo:userInfo];
|
||||
}
|
||||
@ -852,8 +834,8 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
copiedProto = phoneNumber;
|
||||
}
|
||||
|
||||
NSString *nationalSignificantNumber =
|
||||
[self format:copiedProto numberFormat:NBEPhoneNumberFormatINTERNATIONAL];
|
||||
NSString *nationalSignificantNumber = [self format:copiedProto
|
||||
numberFormat:NBEPhoneNumberFormatINTERNATIONAL];
|
||||
NSMutableArray *numberGroups = [[self componentsSeparatedByRegex:nationalSignificantNumber
|
||||
regex:NON_DIGITS_PATTERN] mutableCopy];
|
||||
|
||||
@ -872,7 +854,7 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
return 0;
|
||||
}
|
||||
|
||||
NSArray *regionCodes = [NBMetadataHelper regionCodeFromCountryCode:phoneNumber.countryCode];
|
||||
NSArray *regionCodes = [self.helper regionCodeFromCountryCode:phoneNumber.countryCode];
|
||||
BOOL isExists = NO;
|
||||
|
||||
for (NSString *regCode in regionCodes) {
|
||||
@ -897,11 +879,11 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
}
|
||||
|
||||
- (NSString *)getCountryMobileTokenFromCountryCode:(NSInteger)countryCallingCode {
|
||||
NSString *mobileToken = MOBILE_TOKEN_MAPPINGS[@(countryCallingCode)];
|
||||
if (mobileToken != nil) {
|
||||
return mobileToken;
|
||||
}
|
||||
return @"";
|
||||
NSString *mobileToken = MOBILE_TOKEN_MAPPINGS[@(countryCallingCode)];
|
||||
if (mobileToken != nil) {
|
||||
return mobileToken;
|
||||
}
|
||||
return @"";
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1005,7 +987,7 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
* @private
|
||||
*/
|
||||
- (BOOL)hasValidCountryCallingCode:(NSNumber *)countryCallingCode {
|
||||
id res = [NBMetadataHelper regionCodeFromCountryCode:countryCallingCode];
|
||||
id res = [self.helper regionCodeFromCountryCode:countryCallingCode];
|
||||
if (res != nil) {
|
||||
return YES;
|
||||
}
|
||||
@ -1037,8 +1019,8 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
@try {
|
||||
res = [self format:phoneNumber numberFormat:numberFormat];
|
||||
} @catch (NSException *exception) {
|
||||
NSDictionary *userInfo =
|
||||
[NSDictionary dictionaryWithObject:exception.reason forKey:NSLocalizedDescriptionKey];
|
||||
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:exception.reason
|
||||
forKey:NSLocalizedDescriptionKey];
|
||||
if (error != NULL) (*error) = [NSError errorWithDomain:exception.name code:0 userInfo:userInfo];
|
||||
}
|
||||
return res;
|
||||
@ -1080,16 +1062,17 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
// for regions which share a country calling code is contained by only one
|
||||
// region for performance reasons. For example, for NANPA regions it will be
|
||||
// contained in the metadata for US.
|
||||
NSArray *regionCodeArray = [NBMetadataHelper regionCodeFromCountryCode:countryCallingCode];
|
||||
NSArray *regionCodeArray = [self.helper regionCodeFromCountryCode:countryCallingCode];
|
||||
NSString *regionCode = [regionCodeArray objectAtIndex:0];
|
||||
|
||||
// Metadata cannot be nil because the country calling code is valid (which
|
||||
// means that the region code cannot be ZZ and must be one of our supported
|
||||
// region codes).
|
||||
NBPhoneMetaData *metadata =
|
||||
[self getMetadataForRegionOrCallingCode:countryCallingCode regionCode:regionCode];
|
||||
NSString *formattedExtension =
|
||||
[self maybeGetFormattedExtension:phoneNumber metadata:metadata numberFormat:numberFormat];
|
||||
NBPhoneMetaData *metadata = [self getMetadataForRegionOrCallingCode:countryCallingCode
|
||||
regionCode:regionCode];
|
||||
NSString *formattedExtension = [self maybeGetFormattedExtension:phoneNumber
|
||||
metadata:metadata
|
||||
numberFormat:numberFormat];
|
||||
NSString *formattedNationalNumber = [self formatNsn:nationalSignificantNumber
|
||||
metadata:metadata
|
||||
phoneNumberFormat:numberFormat
|
||||
@ -1127,8 +1110,8 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
numberFormat:numberFormat
|
||||
userDefinedFormats:userDefinedFormats];
|
||||
} @catch (NSException *exception) {
|
||||
NSDictionary *userInfo =
|
||||
[NSDictionary dictionaryWithObject:exception.reason forKey:NSLocalizedDescriptionKey];
|
||||
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:exception.reason
|
||||
forKey:NSLocalizedDescriptionKey];
|
||||
if (error != NULL) (*error) = [NSError errorWithDomain:exception.name code:0 userInfo:userInfo];
|
||||
}
|
||||
return res;
|
||||
@ -1148,7 +1131,7 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
// for regions which share a country calling code is contained by only one
|
||||
// region for performance reasons. For example, for NANPA regions it will be
|
||||
// contained in the metadata for US.
|
||||
NSArray *regionCodes = [NBMetadataHelper regionCodeFromCountryCode:countryCallingCode];
|
||||
NSArray *regionCodes = [self.helper regionCodeFromCountryCode:countryCallingCode];
|
||||
NSString *regionCode = nil;
|
||||
if (regionCodes != nil && regionCodes.count > 0) {
|
||||
regionCode = [regionCodes objectAtIndex:0];
|
||||
@ -1156,8 +1139,8 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
|
||||
// Metadata cannot be nil because the country calling code is valid
|
||||
/** @type {i18n.phonenumbers.PhoneMetadata} */
|
||||
NBPhoneMetaData *metadata =
|
||||
[self getMetadataForRegionOrCallingCode:countryCallingCode regionCode:regionCode];
|
||||
NBPhoneMetaData *metadata = [self getMetadataForRegionOrCallingCode:countryCallingCode
|
||||
regionCode:regionCode];
|
||||
|
||||
NSString *formattedNumber = @"";
|
||||
NBNumberFormat *formattingPattern =
|
||||
@ -1198,8 +1181,9 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
carrierCode:nil];
|
||||
}
|
||||
|
||||
NSString *formattedExtension =
|
||||
[self maybeGetFormattedExtension:number metadata:metadata numberFormat:numberFormat];
|
||||
NSString *formattedExtension = [self maybeGetFormattedExtension:number
|
||||
metadata:metadata
|
||||
numberFormat:numberFormat];
|
||||
|
||||
// NSLog(@"!@# prefixNumberWithCountryCallingCode called [%@]", formattedExtension);
|
||||
return [self prefixNumberWithCountryCallingCode:countryCallingCode
|
||||
@ -1228,8 +1212,8 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
@try {
|
||||
res = [self formatNationalNumberWithCarrierCode:number carrierCode:carrierCode];
|
||||
} @catch (NSException *exception) {
|
||||
NSDictionary *userInfo =
|
||||
[NSDictionary dictionaryWithObject:exception.reason forKey:NSLocalizedDescriptionKey];
|
||||
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:exception.reason
|
||||
forKey:NSLocalizedDescriptionKey];
|
||||
if (error != NULL) {
|
||||
(*error) = [NSError errorWithDomain:exception.name code:0 userInfo:userInfo];
|
||||
}
|
||||
@ -1252,8 +1236,8 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
// contained in the metadata for US.
|
||||
NSString *regionCode = [self getRegionCodeForCountryCode:countryCallingCode];
|
||||
// Metadata cannot be nil because the country calling code is valid.
|
||||
NBPhoneMetaData *metadata =
|
||||
[self getMetadataForRegionOrCallingCode:countryCallingCode regionCode:regionCode];
|
||||
NBPhoneMetaData *metadata = [self getMetadataForRegionOrCallingCode:countryCallingCode
|
||||
regionCode:regionCode];
|
||||
NSString *formattedExtension = [self maybeGetFormattedExtension:number
|
||||
metadata:metadata
|
||||
numberFormat:NBEPhoneNumberFormatNATIONAL];
|
||||
@ -1309,8 +1293,8 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
@try {
|
||||
res = [self formatNationalNumberWithCarrierCode:number carrierCode:fallbackCarrierCode];
|
||||
} @catch (NSException *exception) {
|
||||
NSDictionary *userInfo =
|
||||
[NSDictionary dictionaryWithObject:exception.reason forKey:NSLocalizedDescriptionKey];
|
||||
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:exception.reason
|
||||
forKey:NSLocalizedDescriptionKey];
|
||||
if (error != NULL) {
|
||||
(*error) = [NSError errorWithDomain:exception.name code:0 userInfo:userInfo];
|
||||
}
|
||||
@ -1350,8 +1334,8 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
regionCallingFrom:regionCallingFrom
|
||||
withFormatting:withFormatting];
|
||||
} @catch (NSException *exception) {
|
||||
NSDictionary *userInfo =
|
||||
[NSDictionary dictionaryWithObject:exception.reason forKey:NSLocalizedDescriptionKey];
|
||||
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:exception.reason
|
||||
forKey:NSLocalizedDescriptionKey];
|
||||
if (error != NULL) (*error) = [NSError errorWithDomain:exception.name code:0 userInfo:userInfo];
|
||||
}
|
||||
return res;
|
||||
@ -1451,8 +1435,8 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
@try {
|
||||
res = [self formatOutOfCountryCallingNumber:number regionCallingFrom:regionCallingFrom];
|
||||
} @catch (NSException *exception) {
|
||||
NSDictionary *userInfo =
|
||||
[NSDictionary dictionaryWithObject:exception.reason forKey:NSLocalizedDescriptionKey];
|
||||
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:exception.reason
|
||||
forKey:NSLocalizedDescriptionKey];
|
||||
if (error != NULL) (*error) = [NSError errorWithDomain:exception.name code:0 userInfo:userInfo];
|
||||
}
|
||||
|
||||
@ -1476,9 +1460,9 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
if ([self isNANPACountry:regionCallingFrom]) {
|
||||
// For NANPA regions, return the national format for these regions but
|
||||
// prefix it with the country calling code.
|
||||
return [NSString
|
||||
stringWithFormat:@"%@ %@", countryCallingCode,
|
||||
[self format:number numberFormat:NBEPhoneNumberFormatNATIONAL]];
|
||||
return [NSString stringWithFormat:@"%@ %@", countryCallingCode,
|
||||
[self format:number
|
||||
numberFormat:NBEPhoneNumberFormatNATIONAL]];
|
||||
}
|
||||
} else if ([countryCallingCode
|
||||
isEqualToNumber:[self getCountryCodeForValidRegion:regionCallingFrom error:nil]]) {
|
||||
@ -1512,8 +1496,8 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
|
||||
NSString *regionCode = [self getRegionCodeForCountryCode:countryCallingCode];
|
||||
// Metadata cannot be nil because the country calling code is valid.
|
||||
NBPhoneMetaData *metadataForRegion =
|
||||
[self getMetadataForRegionOrCallingCode:countryCallingCode regionCode:regionCode];
|
||||
NBPhoneMetaData *metadataForRegion = [self getMetadataForRegionOrCallingCode:countryCallingCode
|
||||
regionCode:regionCode];
|
||||
NSString *formattedNationalNumber = [self formatNsn:nationalSignificantNumber
|
||||
metadata:metadataForRegion
|
||||
phoneNumberFormat:NBEPhoneNumberFormatINTERNATIONAL
|
||||
@ -1591,8 +1575,8 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
@try {
|
||||
res = [self formatInOriginalFormat:number regionCallingFrom:regionCallingFrom];
|
||||
} @catch (NSException *exception) {
|
||||
NSDictionary *userInfo =
|
||||
[NSDictionary dictionaryWithObject:exception.reason forKey:NSLocalizedDescriptionKey];
|
||||
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:exception.reason
|
||||
forKey:NSLocalizedDescriptionKey];
|
||||
if (error != NULL) (*error) = [NSError errorWithDomain:exception.name code:0 userInfo:userInfo];
|
||||
}
|
||||
|
||||
@ -1619,12 +1603,12 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
formattedNumber = [self format:number numberFormat:NBEPhoneNumberFormatINTERNATIONAL];
|
||||
break;
|
||||
case NBECountryCodeSourceFROM_NUMBER_WITH_IDD:
|
||||
formattedNumber =
|
||||
[self formatOutOfCountryCallingNumber:number regionCallingFrom:regionCallingFrom];
|
||||
formattedNumber = [self formatOutOfCountryCallingNumber:number
|
||||
regionCallingFrom:regionCallingFrom];
|
||||
break;
|
||||
case NBECountryCodeSourceFROM_NUMBER_WITHOUT_PLUS_SIGN:
|
||||
formattedNumber = [[self format:number numberFormat:NBEPhoneNumberFormatINTERNATIONAL]
|
||||
substringFromIndex:1];
|
||||
formattedNumber = [[self format:number
|
||||
numberFormat:NBEPhoneNumberFormatINTERNATIONAL] substringFromIndex:1];
|
||||
break;
|
||||
case NBECountryCodeSourceFROM_DEFAULT_COUNTRY:
|
||||
// Fall-through to default case.
|
||||
@ -1768,16 +1752,16 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
- (BOOL)hasFormattingPatternForNumber:(NBPhoneNumber *)number {
|
||||
NSNumber *countryCallingCode = number.countryCode;
|
||||
NSString *phoneNumberRegion = [self getRegionCodeForCountryCode:countryCallingCode];
|
||||
NBPhoneMetaData *metadata =
|
||||
[self getMetadataForRegionOrCallingCode:countryCallingCode regionCode:phoneNumberRegion];
|
||||
NBPhoneMetaData *metadata = [self getMetadataForRegionOrCallingCode:countryCallingCode
|
||||
regionCode:phoneNumberRegion];
|
||||
|
||||
if (metadata == nil) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
NSString *nationalNumber = [self getNationalSignificantNumber:number];
|
||||
NBNumberFormat *formatRule =
|
||||
[self chooseFormattingPatternForNumber:metadata.numberFormats nationalNumber:nationalNumber];
|
||||
NBNumberFormat *formatRule = [self chooseFormattingPatternForNumber:metadata.numberFormats
|
||||
nationalNumber:nationalNumber];
|
||||
return formatRule != nil;
|
||||
}
|
||||
|
||||
@ -1814,8 +1798,8 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
@try {
|
||||
res = [self formatOutOfCountryKeepingAlphaChars:number regionCallingFrom:regionCallingFrom];
|
||||
} @catch (NSException *exception) {
|
||||
NSDictionary *userInfo =
|
||||
[NSDictionary dictionaryWithObject:exception.reason forKey:NSLocalizedDescriptionKey];
|
||||
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:exception.reason
|
||||
forKey:NSLocalizedDescriptionKey];
|
||||
if (error != NULL) (*error) = [NSError errorWithDomain:exception.name code:0 userInfo:userInfo];
|
||||
}
|
||||
return res;
|
||||
@ -1864,8 +1848,8 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
return [NSString stringWithFormat:@"%@ %@", countryCode, rawInput];
|
||||
}
|
||||
} else if (metadataForRegionCallingFrom != nil &&
|
||||
[countryCode
|
||||
isEqualToNumber:[self getCountryCodeForValidRegion:regionCallingFrom error:nil]]) {
|
||||
[countryCode isEqualToNumber:[self getCountryCodeForValidRegion:regionCallingFrom
|
||||
error:nil]]) {
|
||||
NBNumberFormat *formattingPattern =
|
||||
[self chooseFormattingPatternForNumber:metadataForRegionCallingFrom.numberFormats
|
||||
nationalNumber:nationalNumber];
|
||||
@ -1908,8 +1892,8 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
|
||||
NSString *regionCode = [self getRegionCodeForCountryCode:countryCode];
|
||||
// Metadata cannot be nil because the country calling code is valid.
|
||||
NBPhoneMetaData *metadataForRegion =
|
||||
[self getMetadataForRegionOrCallingCode:countryCode regionCode:regionCode];
|
||||
NBPhoneMetaData *metadataForRegion = [self getMetadataForRegionOrCallingCode:countryCode
|
||||
regionCode:regionCode];
|
||||
NSString *formattedExtension =
|
||||
[self maybeGetFormattedExtension:number
|
||||
metadata:metadataForRegion
|
||||
@ -1956,8 +1940,8 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
([intlNumberFormats count] <= 0 || numberFormat == NBEPhoneNumberFormatNATIONAL)
|
||||
? metadata.numberFormats
|
||||
: intlNumberFormats;
|
||||
NBNumberFormat *formattingPattern =
|
||||
[self chooseFormattingPatternForNumber:availableFormats nationalNumber:phoneNumber];
|
||||
NBNumberFormat *formattingPattern = [self chooseFormattingPatternForNumber:availableFormats
|
||||
nationalNumber:phoneNumber];
|
||||
|
||||
if (formattingPattern == nil) {
|
||||
return phoneNumber;
|
||||
@ -2075,8 +2059,9 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
* instead.
|
||||
*/
|
||||
- (NBPhoneNumber *)getExampleNumber:(NSString *)regionCode error:(NSError *__autoreleasing *)error {
|
||||
NBPhoneNumber *res =
|
||||
[self getExampleNumberForType:regionCode type:NBEPhoneNumberTypeFIXED_LINE error:error];
|
||||
NBPhoneNumber *res = [self getExampleNumberForType:regionCode
|
||||
type:NBEPhoneNumberTypeFIXED_LINE
|
||||
error:error];
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -2101,8 +2086,8 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
return nil;
|
||||
}
|
||||
|
||||
NBPhoneNumberDesc *desc =
|
||||
[self getNumberDescByType:[self.helper getMetadataForRegion:regionCode] type:type];
|
||||
NBPhoneNumberDesc *desc = [self getNumberDescByType:[self.helper getMetadataForRegion:regionCode]
|
||||
type:type];
|
||||
|
||||
if ([NBMetadataHelper hasValue:desc.exampleNumber]) {
|
||||
return [self parse:desc.exampleNumber defaultRegion:regionCode error:error];
|
||||
@ -2233,8 +2218,8 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
*/
|
||||
- (NBEPhoneNumberType)getNumberType:(NBPhoneNumber *)phoneNumber {
|
||||
NSString *regionCode = [self getRegionCodeForNumber:phoneNumber];
|
||||
NBPhoneMetaData *metadata =
|
||||
[self getMetadataForRegionOrCallingCode:phoneNumber.countryCode regionCode:regionCode];
|
||||
NBPhoneMetaData *metadata = [self getMetadataForRegionOrCallingCode:phoneNumber.countryCode
|
||||
regionCode:regionCode];
|
||||
if (metadata == nil) {
|
||||
return NBEPhoneNumberTypeUNKNOWN;
|
||||
}
|
||||
@ -2363,8 +2348,8 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
*/
|
||||
- (BOOL)isValidNumberForRegion:(NBPhoneNumber *)number regionCode:(NSString *)regionCode {
|
||||
NSNumber *countryCode = [number.countryCode copy];
|
||||
NBPhoneMetaData *metadata =
|
||||
[self getMetadataForRegionOrCallingCode:countryCode regionCode:regionCode];
|
||||
NBPhoneMetaData *metadata = [self getMetadataForRegionOrCallingCode:countryCode
|
||||
regionCode:regionCode];
|
||||
if (metadata == nil ||
|
||||
([NB_REGION_CODE_FOR_NON_GEO_ENTITY isEqualToString:regionCode] == NO &&
|
||||
![countryCode isEqualToNumber:[self getCountryCodeForValidRegion:regionCode error:nil]])) {
|
||||
@ -2386,8 +2371,8 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
return numberLength > MIN_LENGTH_FOR_NSN_ && numberLength <= MAX_LENGTH_FOR_NSN_;
|
||||
}
|
||||
|
||||
return [self getNumberTypeHelper:nationalSignificantNumber metadata:metadata] !=
|
||||
NBEPhoneNumberTypeUNKNOWN;
|
||||
return [self getNumberTypeHelper:nationalSignificantNumber
|
||||
metadata:metadata] != NBEPhoneNumberTypeUNKNOWN;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2404,7 +2389,7 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
return nil;
|
||||
}
|
||||
|
||||
NSArray *regionCodes = [NBMetadataHelper regionCodeFromCountryCode:phoneNumber.countryCode];
|
||||
NSArray *regionCodes = [self.helper regionCodeFromCountryCode:phoneNumber.countryCode];
|
||||
if (regionCodes == nil || [regionCodes count] <= 0) {
|
||||
return nil;
|
||||
}
|
||||
@ -2438,8 +2423,8 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
if ([self stringPositionByRegex:nationalNumber regex:metadata.leadingDigits] == 0) {
|
||||
return regionCode;
|
||||
}
|
||||
} else if ([self getNumberTypeHelper:nationalNumber metadata:metadata] !=
|
||||
NBEPhoneNumberTypeUNKNOWN) {
|
||||
} else if ([self getNumberTypeHelper:nationalNumber
|
||||
metadata:metadata] != NBEPhoneNumberTypeUNKNOWN) {
|
||||
return regionCode;
|
||||
}
|
||||
}
|
||||
@ -2457,7 +2442,7 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
* @return {string}
|
||||
*/
|
||||
- (NSString *)getRegionCodeForCountryCode:(NSNumber *)countryCallingCode {
|
||||
NSArray *regionCodes = [NBMetadataHelper regionCodeFromCountryCode:countryCallingCode];
|
||||
NSArray *regionCodes = [self.helper regionCodeFromCountryCode:countryCallingCode];
|
||||
return regionCodes == nil ? NB_UNKNOWN_REGION : [regionCodes objectAtIndex:0];
|
||||
}
|
||||
|
||||
@ -2471,7 +2456,7 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
* @return {Array.<string>}
|
||||
*/
|
||||
- (NSArray *)getRegionCodesForCountryCode:(NSNumber *)countryCallingCode {
|
||||
NSArray *regionCodes = [NBMetadataHelper regionCodeFromCountryCode:countryCallingCode];
|
||||
NSArray *regionCodes = [self.helper regionCodeFromCountryCode:countryCallingCode];
|
||||
return regionCodes == nil ? nil : regionCodes;
|
||||
}
|
||||
|
||||
@ -2575,7 +2560,7 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
*/
|
||||
- (BOOL)isNANPACountry:(NSString *)regionCode {
|
||||
BOOL isExists = NO;
|
||||
NSArray *res = [NBMetadataHelper
|
||||
NSArray *res = [self.helper
|
||||
regionCodeFromCountryCode:[NSNumber numberWithUnsignedInteger:NANPA_COUNTRY_CODE_]];
|
||||
|
||||
for (NSString *inRegionCode in res) {
|
||||
@ -2643,8 +2628,8 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
@try {
|
||||
res = [self isPossibleNumber:number];
|
||||
} @catch (NSException *exception) {
|
||||
NSDictionary *userInfo =
|
||||
[NSDictionary dictionaryWithObject:exception.reason forKey:NSLocalizedDescriptionKey];
|
||||
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:exception.reason
|
||||
forKey:NSLocalizedDescriptionKey];
|
||||
if (error != NULL) (*error) = [NSError errorWithDomain:exception.name code:0 userInfo:userInfo];
|
||||
}
|
||||
return res;
|
||||
@ -2688,8 +2673,8 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
// non-geographical entities), so we just check mobile.
|
||||
return [self validateNumberLength:number metadata:metadata type:NBEPhoneNumberTypeMOBILE];
|
||||
} else {
|
||||
NBPhoneNumberDesc *mobileDesc =
|
||||
[self getNumberDescByType:metadata type:NBEPhoneNumberTypeMOBILE];
|
||||
NBPhoneNumberDesc *mobileDesc = [self getNumberDescByType:metadata
|
||||
type:NBEPhoneNumberTypeMOBILE];
|
||||
if ([self descHasPossibleNumberData:mobileDesc]) {
|
||||
// Merge the mobile data in if there was any. We have to make a copy to do this.
|
||||
// Note that when adding the possible lengths from mobile, we have to again check they
|
||||
@ -2823,8 +2808,8 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
@try {
|
||||
res = [self isPossibleNumberWithReason:number];
|
||||
} @catch (NSException *exception) {
|
||||
NSDictionary *userInfo =
|
||||
[NSDictionary dictionaryWithObject:exception.reason forKey:NSLocalizedDescriptionKey];
|
||||
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:exception.reason
|
||||
forKey:NSLocalizedDescriptionKey];
|
||||
if (error != NULL) (*error) = [NSError errorWithDomain:exception.name code:0 userInfo:userInfo];
|
||||
}
|
||||
|
||||
@ -2845,8 +2830,8 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
|
||||
NSString *regionCode = [self getRegionCodeForCountryCode:countryCode];
|
||||
// Metadata cannot be nil because the country calling code is valid.
|
||||
NBPhoneMetaData *metadata =
|
||||
[self getMetadataForRegionOrCallingCode:countryCode regionCode:regionCode];
|
||||
NBPhoneMetaData *metadata = [self getMetadataForRegionOrCallingCode:countryCode
|
||||
regionCode:regionCode];
|
||||
return [self testNumberLength:nationalNumber desc:metadata.generalDesc];
|
||||
}
|
||||
|
||||
@ -2878,8 +2863,9 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
error:(NSError **)error {
|
||||
number = NormalizeNonBreakingSpace(number);
|
||||
|
||||
BOOL res =
|
||||
[self isPossibleNumber:[self parse:number defaultRegion:regionDialingFrom error:error]];
|
||||
BOOL res = [self isPossibleNumber:[self parse:number
|
||||
defaultRegion:regionDialingFrom
|
||||
error:error]];
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -2943,7 +2929,7 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
NSString *subNumber = [fullNumber substringWithRange:NSMakeRange(0, i)];
|
||||
NSNumber *potentialCountryCode = [NSNumber numberWithInteger:[subNumber integerValue]];
|
||||
|
||||
NSArray *regionCodes = [NBMetadataHelper regionCodeFromCountryCode:potentialCountryCode];
|
||||
NSArray *regionCodes = [self.helper regionCodeFromCountryCode:potentialCountryCode];
|
||||
if (regionCodes != nil && regionCodes.count > 0) {
|
||||
if (nationalNumber != NULL) {
|
||||
if ((*nationalNumber) == nil) {
|
||||
@ -2967,7 +2953,7 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
*/
|
||||
|
||||
- (NSArray *)getSupportedRegions {
|
||||
NSArray *allKeys = [[NBMetadataHelper CCode2CNMap] allKeys];
|
||||
NSArray *allKeys = [[self.helper countryCodeToCountryNumberDictionary] allKeys];
|
||||
NSPredicate *predicateIsNaN =
|
||||
[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
|
||||
return isNan(evaluatedObject);
|
||||
@ -3088,8 +3074,8 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
return @0;
|
||||
}
|
||||
|
||||
NSNumber *potentialCountryCode =
|
||||
[self extractCountryCode:fullNumber nationalNumber:nationalNumber];
|
||||
NSNumber *potentialCountryCode = [self extractCountryCode:fullNumber
|
||||
nationalNumber:nationalNumber];
|
||||
|
||||
if (![potentialCountryCode isEqualToNumber:@0]) {
|
||||
(*phoneNumber).countryCode = potentialCountryCode;
|
||||
@ -3174,11 +3160,11 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
return NO;
|
||||
}
|
||||
|
||||
NSString *numberStr = [(*number)copy];
|
||||
NSString *numberStr = [(*number) copy];
|
||||
|
||||
if ([self stringPositionByRegex:numberStr regex:iddPattern] == 0) {
|
||||
NSTextCheckingResult *matched =
|
||||
[[self matchesByRegex:numberStr regex:iddPattern] objectAtIndex:0];
|
||||
NSTextCheckingResult *matched = [[self matchesByRegex:numberStr
|
||||
regex:iddPattern] objectAtIndex:0];
|
||||
NSString *matchedString = [numberStr substringWithRange:matched.range];
|
||||
NSUInteger matchEnd = matchedString.length;
|
||||
NSString *remainString = [numberStr substringFromIndex:matchEnd];
|
||||
@ -3227,9 +3213,9 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
}
|
||||
|
||||
// Check to see if the number begins with one or more plus signs.
|
||||
if ([self isStartingStringByRegex:(*numberStr)regex:LEADING_PLUS_CHARS_PATTERN]) {
|
||||
if ([self isStartingStringByRegex:(*numberStr) regex:LEADING_PLUS_CHARS_PATTERN]) {
|
||||
(*numberStr) =
|
||||
[self replaceStringByRegex:(*numberStr)regex:LEADING_PLUS_CHARS_PATTERN withTemplate:@""];
|
||||
[self replaceStringByRegex:(*numberStr) regex:LEADING_PLUS_CHARS_PATTERN withTemplate:@""];
|
||||
// Can now normalize the rest of the number since we've consumed the '+'
|
||||
// sign at the start.
|
||||
(*numberStr) = [self normalize:(*numberStr)];
|
||||
@ -3264,7 +3250,7 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
return NO;
|
||||
}
|
||||
|
||||
NSString *numberStr = [(*number)copy];
|
||||
NSString *numberStr = [(*number) copy];
|
||||
NSUInteger numberLength = numberStr.length;
|
||||
NSString *possibleNationalPrefix = metadata.nationalPrefixForParsing;
|
||||
|
||||
@ -3276,11 +3262,13 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
// Attempt to parse the first digits as a national prefix.
|
||||
NSString *prefixPattern = [NSString stringWithFormat:@"^(?:%@)", possibleNationalPrefix];
|
||||
NSError *error = nil;
|
||||
NSRegularExpression *currentPattern =
|
||||
[self regularExpressionWithPattern:prefixPattern options:0 error:&error];
|
||||
NSRegularExpression *currentPattern = [self regularExpressionWithPattern:prefixPattern
|
||||
options:0
|
||||
error:&error];
|
||||
|
||||
NSArray *prefixMatcher =
|
||||
[currentPattern matchesInString:numberStr options:0 range:NSMakeRange(0, numberLength)];
|
||||
NSArray *prefixMatcher = [currentPattern matchesInString:numberStr
|
||||
options:0
|
||||
range:NSMakeRange(0, numberLength)];
|
||||
if (prefixMatcher && [prefixMatcher count] > 0) {
|
||||
NSString *nationalNumberRule = metadata.generalDesc.nationalNumberPattern;
|
||||
NSTextCheckingResult *firstMatch = [prefixMatcher objectAtIndex:0];
|
||||
@ -3303,8 +3291,9 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
if (noTransform) {
|
||||
transformedNumber = [numberStr substringFromIndex:firstMatchString.length];
|
||||
} else {
|
||||
transformedNumber =
|
||||
[self replaceFirstStringByRegex:numberStr regex:prefixPattern withTemplate:transformRule];
|
||||
transformedNumber = [self replaceFirstStringByRegex:numberStr
|
||||
regex:prefixPattern
|
||||
withTemplate:transformRule];
|
||||
}
|
||||
// If the original number was viable, and the resultant number is not,
|
||||
// we return.
|
||||
@ -3346,7 +3335,7 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
return @"";
|
||||
}
|
||||
|
||||
NSString *numberStr = [(*number)copy];
|
||||
NSString *numberStr = [(*number) copy];
|
||||
int mStart = [self stringPositionByRegex:numberStr regex:EXTN_PATTERN];
|
||||
|
||||
// If we find a potential extension, and the number preceding this is a viable
|
||||
@ -3435,62 +3424,26 @@ static NSArray *GEO_MOBILE_COUNTRIES;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a string using the phone's carrier region (when available, ZZ otherwise).
|
||||
* This uses the country the sim card in the phone is registered with.
|
||||
* Parses a string using the phone's carrier region (when available, uses system locale otherwise).
|
||||
* This uses the country the SIM card in the phone is registered with.
|
||||
* For example if you have an AT&T sim card but are in Europe, this will parse the
|
||||
* number using +1 (AT&T is a US Carrier) as the default country code.
|
||||
* This also works for CDMA phones which don't have a sim card.
|
||||
* This also works for multi-SIM phones, using the SIM region of default voice line.
|
||||
*/
|
||||
- (NBPhoneNumber *)parseWithPhoneCarrierRegion:(NSString *)numberToParse error:(NSError **)error {
|
||||
numberToParse = NormalizeNonBreakingSpace(numberToParse);
|
||||
|
||||
NSString *defaultRegion = nil;
|
||||
#if TARGET_OS_IOS
|
||||
defaultRegion = [self countryCodeByCarrier];
|
||||
#else
|
||||
defaultRegion = [[NSLocale currentLocale] objectForKey:NSLocaleCountryCode];
|
||||
#endif
|
||||
if ([NB_UNKNOWN_REGION isEqualToString:defaultRegion]) {
|
||||
// get region from device as a failover (e.g. iPad)
|
||||
NSLocale *currentLocale = [NSLocale currentLocale];
|
||||
defaultRegion = [currentLocale objectForKey:NSLocaleCountryCode];
|
||||
}
|
||||
|
||||
NSString *defaultRegion = [self countryCodeByCarrier];
|
||||
return [self parse:numberToParse defaultRegion:defaultRegion error:error];
|
||||
}
|
||||
|
||||
#if TARGET_OS_IOS
|
||||
|
||||
static CTTelephonyNetworkInfo *_telephonyNetworkInfo;
|
||||
|
||||
- (CTTelephonyNetworkInfo *)telephonyNetworkInfo {
|
||||
// cache telephony network info;
|
||||
// CTTelephonyNetworkInfo objects are unnecessarily created for every call to
|
||||
// parseWithPhoneCarrierRegion:error: when in reality this information not change while an app
|
||||
// lives in memory real-world performance test while parsing 93 phone numbers: before change:
|
||||
// 126ms after change: 32ms using static instance prevents deallocation crashes due to ios bug
|
||||
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
_telephonyNetworkInfo = [[CTTelephonyNetworkInfo alloc] init];
|
||||
});
|
||||
|
||||
return _telephonyNetworkInfo;
|
||||
}
|
||||
|
||||
- (NSString *)countryCodeByCarrier {
|
||||
NSString *isoCode = [[self.telephonyNetworkInfo subscriberCellularProvider] isoCountryCode];
|
||||
|
||||
// The 2nd part of the if is working around an iOS 7 bug
|
||||
// If the SIM card is missing, iOS 7 returns an empty string instead of nil
|
||||
if (isoCode.length == 0) {
|
||||
isoCode = NB_UNKNOWN_REGION;
|
||||
}
|
||||
|
||||
return isoCode;
|
||||
}
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
return [[CNContactsUserDefaults sharedDefaults].countryCode uppercaseString];
|
||||
#else
|
||||
return [[NSLocale currentLocale] objectForKey:NSLocaleCountryCode];
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a string and returns it in proto buffer format. This method differs
|
||||
@ -3615,8 +3568,8 @@ static CTTelephonyNetworkInfo *_telephonyNetworkInfo;
|
||||
|
||||
// Check the region supplied is valid, or that the extracted number starts
|
||||
// with some sort of + sign so the number's region can be determined.
|
||||
if (checkRegion &&
|
||||
[self checkRegionForParsing:nationalNumber defaultRegion:defaultRegion] == NO) {
|
||||
if (checkRegion && [self checkRegionForParsing:nationalNumber
|
||||
defaultRegion:defaultRegion] == NO) {
|
||||
if (error != NULL) {
|
||||
(*error) = [self
|
||||
errorWithObject:[NSString stringWithFormat:@"INVALID_COUNTRY_CODE:%@", defaultRegion]
|
||||
@ -3686,8 +3639,8 @@ static CTTelephonyNetworkInfo *_telephonyNetworkInfo;
|
||||
NSString *phoneNumberRegion = [self getRegionCodeForCountryCode:countryCode];
|
||||
if (phoneNumberRegion != defaultRegion) {
|
||||
// Metadata cannot be nil because the country calling code is valid.
|
||||
regionMetadata =
|
||||
[self getMetadataForRegionOrCallingCode:countryCode regionCode:phoneNumberRegion];
|
||||
regionMetadata = [self getMetadataForRegionOrCallingCode:countryCode
|
||||
regionCode:phoneNumberRegion];
|
||||
}
|
||||
} else {
|
||||
// If no extracted country calling code, use the region supplied instead.
|
||||
@ -3720,8 +3673,8 @@ static CTTelephonyNetworkInfo *_telephonyNetworkInfo;
|
||||
[self maybeStripNationalPrefixAndCarrierCode:&potentialNationalNumber
|
||||
metadata:regionMetadata
|
||||
carrierCode:&carrierCode];
|
||||
NBEValidationResult validationResult =
|
||||
[self validateNumberLength:potentialNationalNumber metadata:regionMetadata];
|
||||
NBEValidationResult validationResult = [self validateNumberLength:potentialNationalNumber
|
||||
metadata:regionMetadata];
|
||||
if (validationResult != NBEValidationResultTOO_SHORT &&
|
||||
validationResult != NBEValidationResultIS_POSSIBLE_LOCAL_ONLY &&
|
||||
validationResult != NBEValidationResultINVALID_LENGTH) {
|
||||
@ -3861,8 +3814,8 @@ static CTTelephonyNetworkInfo *_telephonyNetworkInfo;
|
||||
@try {
|
||||
res = [self isNumberMatch:firstNumberIn second:secondNumberIn];
|
||||
} @catch (NSException *exception) {
|
||||
NSDictionary *userInfo =
|
||||
[NSDictionary dictionaryWithObject:exception.reason forKey:NSLocalizedDescriptionKey];
|
||||
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:exception.reason
|
||||
forKey:NSLocalizedDescriptionKey];
|
||||
if (error != NULL) (*error) = [NSError errorWithDomain:exception.name code:0 userInfo:userInfo];
|
||||
}
|
||||
return res;
|
||||
@ -3894,8 +3847,9 @@ static CTTelephonyNetworkInfo *_telephonyNetworkInfo;
|
||||
[self getRegionCodeForCountryCode:((NBPhoneNumber *)secondNumberIn).countryCode];
|
||||
if (secondNumberRegion != NB_UNKNOWN_REGION) {
|
||||
NSError *aNestedError;
|
||||
firstNumber =
|
||||
[self parse:firstNumberIn defaultRegion:secondNumberRegion error:&aNestedError];
|
||||
firstNumber = [self parse:firstNumberIn
|
||||
defaultRegion:secondNumberRegion
|
||||
error:&aNestedError];
|
||||
|
||||
if (aNestedError != nil) {
|
||||
return NBEMatchTypeNOT_A_NUMBER;
|
||||
@ -4040,8 +3994,8 @@ static CTTelephonyNetworkInfo *_telephonyNetworkInfo;
|
||||
@try {
|
||||
res = [self canBeInternationallyDialled:number];
|
||||
} @catch (NSException *exception) {
|
||||
NSDictionary *userInfo =
|
||||
[NSDictionary dictionaryWithObject:exception.reason forKey:NSLocalizedDescriptionKey];
|
||||
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:exception.reason
|
||||
forKey:NSLocalizedDescriptionKey];
|
||||
if (error != NULL) (*error) = [NSError errorWithDomain:exception.name code:0 userInfo:userInfo];
|
||||
}
|
||||
return res;
|
||||
@ -4075,11 +4029,13 @@ static CTTelephonyNetworkInfo *_telephonyNetworkInfo;
|
||||
}
|
||||
|
||||
NSError *error = nil;
|
||||
NSRegularExpression *currentPattern =
|
||||
[self entireRegularExpressionWithPattern:regex options:0 error:&error];
|
||||
NSRegularExpression *currentPattern = [self entireRegularExpressionWithPattern:regex
|
||||
options:0
|
||||
error:&error];
|
||||
NSRange stringRange = NSMakeRange(0, str.length);
|
||||
NSTextCheckingResult *matchResult =
|
||||
[currentPattern firstMatchInString:str options:NSMatchingAnchored range:stringRange];
|
||||
NSTextCheckingResult *matchResult = [currentPattern firstMatchInString:str
|
||||
options:NSMatchingAnchored
|
||||
range:stringRange];
|
||||
|
||||
if (matchResult != nil) {
|
||||
BOOL matchIsEntireString = NSEqualRanges(matchResult.range, stringRange);
|
||||
|
||||
@ -21,7 +21,7 @@
|
||||
return res;
|
||||
}
|
||||
|
||||
- (NSString *)nb_safeStringAtIndex : (NSUInteger)index {
|
||||
- (NSString *)nb_safeStringAtIndex:(NSUInteger)index {
|
||||
return [self nb_safeObjectAtIndex:index class:[NSString class]];
|
||||
}
|
||||
|
||||
|
||||
@ -1,22 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>BNDL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
</dict>
|
||||
</plist>
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,97 +0,0 @@
|
||||
//
|
||||
// NBPhoneNumberParsingPerfTest.m
|
||||
// libPhoneNumberiOSTests
|
||||
//
|
||||
// Created by Paween Itthipalkul on 2/1/18.
|
||||
// Copyright © 2018 Google LLC. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <XCTest/XCTest.h>
|
||||
#import "NBMetadataHelper.h"
|
||||
#import "NBPhoneMetaData.h"
|
||||
|
||||
#import "NBNumberFormat.h"
|
||||
#import "NBPhoneNumber.h"
|
||||
#import "NBPhoneNumberDesc.h"
|
||||
#import "NBPhoneNumberUtil.h"
|
||||
|
||||
@interface NBExampleNumber: NSObject
|
||||
|
||||
@property (nonatomic, strong) NSString *phoneNumber;
|
||||
@property (nonatomic, strong) NSString *baseRegionCode;
|
||||
|
||||
- (instancetype)initWithPhoneNumber:(NSString *)phoneNumber
|
||||
baseRegionCode:(NSString *)baseRegionCode;
|
||||
|
||||
@end
|
||||
|
||||
@implementation NBExampleNumber
|
||||
- (instancetype)initWithPhoneNumber:(NSString *)phoneNumber
|
||||
baseRegionCode:(NSString *)baseRegionCode {
|
||||
self = [super init];
|
||||
if (self != nil) {
|
||||
_phoneNumber = phoneNumber;
|
||||
_baseRegionCode = baseRegionCode;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
@end
|
||||
|
||||
|
||||
@interface NBPhoneNumberParsingPerfTest: XCTestCase
|
||||
@end
|
||||
|
||||
@implementation NBPhoneNumberParsingPerfTest
|
||||
|
||||
#if PERF_TEST
|
||||
|
||||
- (void)testParsing {
|
||||
NSArray *regionCodes = [[NBMetadataHelper CCode2CNMap] allKeys];
|
||||
|
||||
NSMutableArray<NBExampleNumber *> *exampleNumbers = [[NSMutableArray alloc] init];
|
||||
|
||||
NBPhoneNumberUtil *util = [NBPhoneNumberUtil sharedInstance];
|
||||
|
||||
for (NSString *regionCode in regionCodes) {
|
||||
NBPhoneNumber *phoneNumber = [util getExampleNumber:regionCode error:nil];
|
||||
if (phoneNumber != nil) {
|
||||
NSString *e164 = [util format:phoneNumber numberFormat:NBEPhoneNumberFormatE164 error:nil];
|
||||
NBExampleNumber *e164Sample = [[NBExampleNumber alloc] initWithPhoneNumber:e164
|
||||
baseRegionCode:regionCode];
|
||||
[exampleNumbers addObject:e164Sample];
|
||||
|
||||
NSString *national = [util format:phoneNumber
|
||||
numberFormat:NBEPhoneNumberFormatNATIONAL
|
||||
error:nil];
|
||||
NBExampleNumber *nationalSample = [[NBExampleNumber alloc] initWithPhoneNumber:national
|
||||
baseRegionCode:regionCode];
|
||||
[exampleNumbers addObject:nationalSample];
|
||||
|
||||
// intl format sample.
|
||||
NSString *intl = [util format:phoneNumber
|
||||
numberFormat:NBEPhoneNumberFormatINTERNATIONAL
|
||||
error:nil];
|
||||
NBExampleNumber * intlSample = [[NBExampleNumber alloc] initWithPhoneNumber:intl
|
||||
baseRegionCode:regionCode];
|
||||
[exampleNumbers addObject:intlSample];
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 5; i++) {
|
||||
[exampleNumbers addObjectsFromArray:exampleNumbers];
|
||||
}
|
||||
|
||||
[self measureBlock:^{
|
||||
for (NBExampleNumber *example in exampleNumbers) {
|
||||
[util parseAndKeepRawInput:example.phoneNumber
|
||||
defaultRegion:example.baseRegionCode
|
||||
error:nil];
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
#endif // PERF_TEST
|
||||
|
||||
@end
|
||||
@ -1,29 +0,0 @@
|
||||
//
|
||||
// NBPhoneNumberUtil+ShortNumberTest.h
|
||||
// libPhoneNumber
|
||||
//
|
||||
// Created by Paween Itthipalkul on 12/1/17.
|
||||
// Copyright © 2017 Google LLC. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "NBPhoneNumberUtil.h"
|
||||
#import "NBPhoneNumberUtil+ShortNumber.h"
|
||||
|
||||
#if SHORT_NUMBER_SUPPORT
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
Includes methods used only for testing NBPhoneNumberUtil+ShortNumber.
|
||||
*/
|
||||
@interface NBPhoneNumberUtil(ShortNumberTest)
|
||||
|
||||
- (NSString *)exampleShortNumberForCost:(NBEShortNumberCost)cost regionCode:(NSString *)regionCode;
|
||||
- (NSString *)exampleShortNumberWithRegionCode:(NSString *)regionCode;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
#endif // SHORT_NUMBER_SUPPORT
|
||||
@ -1,53 +0,0 @@
|
||||
//
|
||||
// NBPhoneNumberUtil+ShortNumberTest.m
|
||||
// libPhoneNumber
|
||||
//
|
||||
// Created by Paween Itthipalkul on 12/1/17.
|
||||
// Copyright © 2017 Google LLC. All rights reserved.
|
||||
//
|
||||
|
||||
#import "NBPhoneNumberUtil+ShortNumberTest.h"
|
||||
|
||||
#import "NBMetadataHelper.h"
|
||||
#import "NBPhoneMetadata.h"
|
||||
#import "NBPhoneNumberDesc.h"
|
||||
#import "NBPhoneNumberUtil+Category.h"
|
||||
|
||||
#if SHORT_NUMBER_SUPPORT
|
||||
|
||||
@implementation NBPhoneNumberUtil(ShortNumberTest)
|
||||
|
||||
- (NSString *)exampleShortNumberForCost:(NBEShortNumberCost)cost regionCode:(NSString *)regionCode {
|
||||
NBPhoneMetaData *metadata = [self.helper shortNumberMetadataForRegion:regionCode];
|
||||
if (metadata == nil) {
|
||||
return @"";
|
||||
}
|
||||
|
||||
NBPhoneNumberDesc *desc = nil;
|
||||
switch (cost) {
|
||||
case NBEShortNumberCostTollFree:
|
||||
desc = metadata.tollFree;
|
||||
break;
|
||||
case NBEShortNumberCostPremiumRate:
|
||||
desc = metadata.premiumRate;
|
||||
break;
|
||||
case NBEShortNumberCostStandardRate:
|
||||
desc = metadata.standardRate;
|
||||
break;
|
||||
case NBEShortNumberCostUnknown:
|
||||
// UNKNOWN_COST numbers are computed by the process of elimination from the other cost
|
||||
// categories.
|
||||
break;
|
||||
}
|
||||
|
||||
return desc.exampleNumber ?: @"";
|
||||
}
|
||||
|
||||
- (NSString *)exampleShortNumberWithRegionCode:(NSString *)regionCode {
|
||||
NBPhoneMetaData *metadata = [self.helper shortNumberMetadataForRegion:regionCode];
|
||||
return metadata.shortCode.exampleNumber ?: @"";
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#endif // SHORT_NUMBER_SUPPORT
|
||||
@ -1,29 +0,0 @@
|
||||
//
|
||||
// NBPhoneNumberUtil+ShortNumberTestHelper.h
|
||||
// libPhoneNumber
|
||||
//
|
||||
// Created by Paween Itthipalkul on 12/1/17.
|
||||
// Copyright © 2017 Google LLC. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "NBPhoneNumberUtil.h"
|
||||
#import "NBPhoneNumberUtil+ShortNumber.h"
|
||||
|
||||
#if SHORT_NUMBER_SUPPORT
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
Includes methods used only for testing NBPhoneNumberUtil+ShortNumber.
|
||||
*/
|
||||
@interface NBPhoneNumberUtil(ShortNumberTestHelper)
|
||||
|
||||
- (NSString *)exampleShortNumberForCost:(NBEShortNumberCost)cost regionCode:(NSString *)regionCode;
|
||||
- (NSString *)exampleShortNumberWithRegionCode:(NSString *)regionCode;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
#endif // SHORT_NUMBER_SUPPORT
|
||||
@ -1,58 +0,0 @@
|
||||
//
|
||||
// NBPhoneNumberUtil+ShortNumberTestHelper.m
|
||||
// libPhoneNumber
|
||||
//
|
||||
// Created by Paween Itthipalkul on 12/1/17.
|
||||
// Copyright © 2017 Google LLC. All rights reserved.
|
||||
//
|
||||
|
||||
#import "NBPhoneNumberUtil+ShortNumberTestHelper.h"
|
||||
|
||||
#import "NBMetadataHelper.h"
|
||||
#import "NBPhoneMetadata.h"
|
||||
#import "NBPhoneNumberDesc.h"
|
||||
|
||||
#if SHORT_NUMBER_SUPPORT
|
||||
|
||||
@interface NBPhoneNumberUtil()
|
||||
|
||||
@property (nonatomic, strong, readonly) NBMetadataHelper *helper;
|
||||
|
||||
@end
|
||||
|
||||
@implementation NBPhoneNumberUtil(ShortNumberTestHelper)
|
||||
|
||||
- (NSString *)exampleShortNumberForCost:(NBEShortNumberCost)cost regionCode:(NSString *)regionCode {
|
||||
NBPhoneMetaData *metadata = [self.helper shortNumberMetadataForRegion:regionCode];
|
||||
if (metadata == nil) {
|
||||
return @"";
|
||||
}
|
||||
|
||||
NBPhoneNumberDesc *desc = nil;
|
||||
switch (cost) {
|
||||
case NBEShortNumberCostTollFree:
|
||||
desc = metadata.tollFree;
|
||||
break;
|
||||
case NBEShortNumberCostPremiumRate:
|
||||
desc = metadata.premiumRate;
|
||||
break;
|
||||
case NBEShortNumberCostStandardRate:
|
||||
desc = metadata.standardRate;
|
||||
break;
|
||||
case NBEShortNumberCostUnknown:
|
||||
// UNKNOWN_COST numbers are computed by the process of elimination from the other cost
|
||||
// categories.
|
||||
break;
|
||||
}
|
||||
|
||||
return desc.exampleNumber ?: @"";
|
||||
}
|
||||
|
||||
- (NSString *)exampleShortNumberWithRegionCode:(NSString *)regionCode {
|
||||
NBPhoneMetaData *metadata = [self.helper shortNumberMetadataForRegion:regionCode];
|
||||
return metadata.shortCode.exampleNumber ?: @"";
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#endif // SHORT_NUMBER_SUPPORT
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,495 +0,0 @@
|
||||
//
|
||||
// NBShortNumberInfoTest.m
|
||||
// libPhoneNumber
|
||||
//
|
||||
// Created by Paween Itthipalkul on 11/29/17.
|
||||
// Copyright © 2017 Google LLC. All rights reserved.
|
||||
//
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
#import "NBMetadataHelper.h"
|
||||
#import "NBPhoneMetaData.h"
|
||||
#import "NBPhoneNumber.h"
|
||||
#import "NBPhoneNumberDesc.h"
|
||||
#import "NBPhoneNumberUtil+ShortNumber.h"
|
||||
#import "NBPhoneNumberUtil+ShortNumberTest.h"
|
||||
|
||||
#if SHORT_NUMBER_SUPPORT
|
||||
|
||||
@interface NBShortNumberInfoTest: XCTestCase
|
||||
@end
|
||||
|
||||
@implementation NBShortNumberInfoTest
|
||||
|
||||
- (void)testMetadataParsing_US {
|
||||
NBMetadataHelper *metadataHelper = [[NBMetadataHelper alloc] init];
|
||||
|
||||
NBPhoneMetaData *metadata = [metadataHelper shortNumberMetadataForRegion:@"US"];
|
||||
XCTAssertNotNil(metadata.shortCode);
|
||||
XCTAssertNotNil(metadata.standardRate);
|
||||
XCTAssertNotNil(metadata.carrierSpecific);
|
||||
XCTAssertNotNil(metadata.smsServices);
|
||||
}
|
||||
|
||||
- (void)testIsPossibleShortNumber {
|
||||
NBPhoneNumberUtil *util = [[NBPhoneNumberUtil alloc] init];
|
||||
|
||||
NBPhoneNumber *possibleNumber = [[NBPhoneNumber alloc] init];
|
||||
possibleNumber.countryCode = @33;
|
||||
possibleNumber.nationalNumber = @123456;
|
||||
XCTAssertTrue([util isPossibleShortNumber:possibleNumber]);
|
||||
|
||||
NBPhoneNumber *impossibleNumber = [[NBPhoneNumber alloc] init];
|
||||
impossibleNumber.countryCode = @33;
|
||||
impossibleNumber.nationalNumber = @9;
|
||||
XCTAssertFalse([util isPossibleShortNumber:impossibleNumber]);
|
||||
|
||||
// Note that GB and GG share the country calling code 44, and that this number is possible but
|
||||
// not valid.
|
||||
NBPhoneNumber *possibleButInvalid = [[NBPhoneNumber alloc] init];
|
||||
possibleButInvalid.countryCode = @44;
|
||||
possibleButInvalid.nationalNumber = @11001;
|
||||
XCTAssertTrue([util isPossibleShortNumber:possibleButInvalid]);
|
||||
}
|
||||
|
||||
- (void)testIsValidShortNumber {
|
||||
NBPhoneNumberUtil *util = [[NBPhoneNumberUtil alloc] init];
|
||||
|
||||
NBPhoneNumber *valid = [[NBPhoneNumber alloc] init];
|
||||
valid.countryCode = @33;
|
||||
valid.nationalNumber = @1010;
|
||||
XCTAssertTrue([util isValidShortNumber:valid]);
|
||||
|
||||
NBPhoneNumber *validWithRegion = [util parse:@"1010" defaultRegion:@"FR" error:nil];
|
||||
XCTAssertNotNil(validWithRegion);
|
||||
XCTAssertTrue([util isValidShortNumber:validWithRegion forRegion:@"FR"]);
|
||||
|
||||
NBPhoneNumber *invalid = [[NBPhoneNumber alloc] init];
|
||||
invalid.countryCode = @33;
|
||||
invalid.nationalNumber = @123456;
|
||||
XCTAssertFalse([util isValidShortNumber:invalid]);
|
||||
|
||||
NBPhoneNumber *invalidWithRegion = [util parse:@"123456" defaultRegion:@"FR" error:nil];
|
||||
XCTAssertNotNil(invalidWithRegion);
|
||||
XCTAssertFalse([util isValidShortNumber:invalidWithRegion forRegion:@"FR"]);
|
||||
|
||||
// Note that GB and GG share the country calling code 44.
|
||||
NBPhoneNumber *valid2 = [[NBPhoneNumber alloc] init];
|
||||
valid2.countryCode = @44;
|
||||
valid2.nationalNumber = @18001;
|
||||
XCTAssertTrue([util isValidShortNumber:valid2]);
|
||||
}
|
||||
|
||||
- (void)testIsCarrierSpecific {
|
||||
NBPhoneNumberUtil *util = [[NBPhoneNumberUtil alloc] init];
|
||||
|
||||
NBPhoneNumber *carrierSpecificNumber = [[NBPhoneNumber alloc] init];
|
||||
carrierSpecificNumber.countryCode = @1;
|
||||
carrierSpecificNumber.nationalNumber = @33669;
|
||||
XCTAssertTrue([util isPhoneNumberCarrierSpecific:carrierSpecificNumber]);
|
||||
// TODO(paween): Fix this -- should be 33669
|
||||
XCTAssertTrue([util isPhoneNumberCarrierSpecific:[util parse:@"33669"
|
||||
defaultRegion:@"US"
|
||||
error:nil] forRegion:@"US"]);
|
||||
|
||||
NBPhoneNumber *notCarrierSpecific = [[NBPhoneNumber alloc] init];
|
||||
notCarrierSpecific.countryCode = @1;
|
||||
notCarrierSpecific.nationalNumber = @911;
|
||||
XCTAssertFalse([util isPhoneNumberCarrierSpecific:notCarrierSpecific]);
|
||||
XCTAssertFalse([util isPhoneNumberCarrierSpecific:[util parse:@"911"
|
||||
defaultRegion:@"US"
|
||||
error:nil] forRegion:@"US"]);
|
||||
|
||||
NBPhoneNumber *carrierSpecificForSomeRegion = [[NBPhoneNumber alloc] init];
|
||||
carrierSpecificForSomeRegion.countryCode = @1;
|
||||
carrierSpecificForSomeRegion.nationalNumber = @211;
|
||||
XCTAssertTrue([util isPhoneNumberCarrierSpecific:carrierSpecificForSomeRegion]);
|
||||
XCTAssertTrue([util isPhoneNumberCarrierSpecific:carrierSpecificForSomeRegion forRegion:@"US"]);
|
||||
XCTAssertFalse([util isPhoneNumberCarrierSpecific:carrierSpecificForSomeRegion forRegion:@"BB"]);
|
||||
}
|
||||
|
||||
- (void)testExpectedCost {
|
||||
NBPhoneNumberUtil *util = [[NBPhoneNumberUtil alloc] init];
|
||||
|
||||
// Premium rate.
|
||||
NSString *premiumRateSample = [util exampleShortNumberForCost:NBEShortNumberCostPremiumRate
|
||||
regionCode:@"FR"];
|
||||
XCTAssertEqual(NBEShortNumberCostPremiumRate,
|
||||
[util expectedCostOfPhoneNumber:[util parse:premiumRateSample defaultRegion:@"FR" error:nil]
|
||||
forRegion:@"FR"]);
|
||||
|
||||
NBPhoneNumber *premiumRateNumber = [[NBPhoneNumber alloc] init];
|
||||
premiumRateNumber.countryCode = @33;
|
||||
premiumRateNumber.nationalNumber = @([premiumRateSample integerValue]);
|
||||
XCTAssertEqual(NBEShortNumberCostPremiumRate,
|
||||
[util expectedCostOfPhoneNumber:premiumRateNumber forRegion:@"FR"]);
|
||||
|
||||
// Standard rate.
|
||||
NSString *standardRateSample = [util exampleShortNumberForCost:NBEShortNumberCostStandardRate
|
||||
regionCode:@"FR"];
|
||||
XCTAssertEqual(NBEShortNumberCostStandardRate,
|
||||
[util expectedCostOfPhoneNumber:[util parse:standardRateSample defaultRegion:@"FR" error:nil]
|
||||
forRegion:@"FR"]);
|
||||
|
||||
NBPhoneNumber *standardRateNumber = [[NBPhoneNumber alloc] init];
|
||||
standardRateNumber.countryCode = @33;
|
||||
standardRateNumber.nationalNumber = @([standardRateSample integerValue]);
|
||||
XCTAssertEqual(NBEShortNumberCostStandardRate, [util expectedCostOfPhoneNumber:standardRateNumber
|
||||
forRegion:@"FR"]);
|
||||
|
||||
// Toll free.
|
||||
NSString *tollFreeSample = [util exampleShortNumberForCost:NBEShortNumberCostTollFree
|
||||
regionCode:@"FR"];
|
||||
XCTAssertEqual(NBEShortNumberCostTollFree,
|
||||
[util expectedCostOfPhoneNumber:[util parse:tollFreeSample defaultRegion:@"FR" error:nil]
|
||||
forRegion:@"FR"]);
|
||||
|
||||
NBPhoneNumber *tollFreeNumber = [[NBPhoneNumber alloc] init];
|
||||
tollFreeNumber.countryCode = @33;
|
||||
tollFreeNumber.nationalNumber = @([tollFreeSample integerValue]);
|
||||
XCTAssertEqual(NBEShortNumberCostTollFree, [util expectedCostOfPhoneNumber:tollFreeNumber
|
||||
forRegion:@"FR"]);
|
||||
|
||||
// Unknown cost.
|
||||
XCTAssertEqual(NBEShortNumberCostUnknown,
|
||||
[util expectedCostOfPhoneNumber:[util parse:@"12345" defaultRegion:@"FR" error:nil]
|
||||
forRegion:@"FR"]);
|
||||
NBPhoneNumber *unknownCostNumber = [[NBPhoneNumber alloc] init];
|
||||
unknownCostNumber.countryCode = @33;
|
||||
unknownCostNumber.nationalNumber = @12345;
|
||||
XCTAssertEqual(NBEShortNumberCostUnknown, [util expectedCostOfPhoneNumber:unknownCostNumber
|
||||
forRegion:@"FR"]);
|
||||
|
||||
// Test that an invalid number may nevertheless have a cost other than UNKNOWN_COST.
|
||||
NBPhoneNumber *invalidShortNumber = [util parse:@"116123" defaultRegion:@"FR" error:nil];
|
||||
XCTAssertFalse([util isValidShortNumber:invalidShortNumber forRegion:@"FR"]);
|
||||
XCTAssertEqual(NBEShortNumberCostTollFree, [util expectedCostOfPhoneNumber:invalidShortNumber
|
||||
forRegion:@"FR"]);
|
||||
|
||||
NBPhoneNumber *invalidShortNumber2 = [[NBPhoneNumber alloc] init];
|
||||
invalidShortNumber2.countryCode = @33;
|
||||
invalidShortNumber2.nationalNumber = @116123;
|
||||
XCTAssertFalse([util isValidShortNumber:invalidShortNumber2 forRegion:@"FR"]);
|
||||
XCTAssertEqual(NBEShortNumberCostTollFree, [util expectedCostOfPhoneNumber:invalidShortNumber2
|
||||
forRegion:@"FR"]);
|
||||
|
||||
// Test a nonexistent country code.
|
||||
NBPhoneNumber *usNumber = [util parse:@"911" defaultRegion:@"US" error:nil];
|
||||
XCTAssertEqual(NBEShortNumberCostUnknown, [util expectedCostOfPhoneNumber:usNumber
|
||||
forRegion:@"ZZ"]);
|
||||
NBPhoneNumber *unknownNumber2 = [[NBPhoneNumber alloc] init];
|
||||
unknownNumber2.countryCode = @123;
|
||||
unknownNumber2.nationalNumber = @911;
|
||||
XCTAssertEqual(NBEShortNumberCostUnknown, [util expectedCostOfPhoneNumber:unknownNumber2]);
|
||||
}
|
||||
|
||||
- (void)testExpectedCostForSharedCountryCallingCode {
|
||||
NBPhoneNumberUtil *util = [[NBPhoneNumberUtil alloc] init];
|
||||
|
||||
NSString *ambiguousPremiumRateString = @"1234";
|
||||
NBPhoneNumber *ambiguousPremiumRateNumber = [[NBPhoneNumber alloc] init];
|
||||
ambiguousPremiumRateNumber.countryCode = @61;
|
||||
ambiguousPremiumRateNumber.nationalNumber = @1234;
|
||||
|
||||
NSString *ambiguousStandardRateString = @"1194";
|
||||
NBPhoneNumber *ambiguousStandardRateNumber = [[NBPhoneNumber alloc] init];
|
||||
ambiguousStandardRateNumber.countryCode = @61;
|
||||
ambiguousStandardRateNumber.nationalNumber = @1194;
|
||||
|
||||
NSString *ambiguousTollFreeString = @"733";
|
||||
NBPhoneNumber *ambiguousTollFreeNumber = [[NBPhoneNumber alloc] init];
|
||||
ambiguousTollFreeNumber.countryCode = @61;
|
||||
ambiguousTollFreeNumber.nationalNumber = @733;
|
||||
|
||||
XCTAssertTrue([util isValidShortNumber:ambiguousPremiumRateNumber]);
|
||||
XCTAssertTrue([util isValidShortNumber:ambiguousStandardRateNumber]);
|
||||
XCTAssertTrue([util isValidShortNumber:ambiguousTollFreeNumber]);
|
||||
|
||||
XCTAssertTrue([util isValidShortNumber:[util parse:ambiguousPremiumRateString
|
||||
defaultRegion:@"AU"
|
||||
error:nil] forRegion:@"AU"]);
|
||||
XCTAssertEqual(NBEShortNumberCostPremiumRate,
|
||||
[util expectedCostOfPhoneNumber:[util parse:ambiguousPremiumRateString
|
||||
defaultRegion:@"AU"
|
||||
error:nil] forRegion:@"AU"]);
|
||||
XCTAssertFalse([util isValidShortNumber:[util parse:ambiguousPremiumRateString
|
||||
defaultRegion:@"CX"
|
||||
error:nil] forRegion:@"CX"]);
|
||||
XCTAssertEqual(NBEShortNumberCostUnknown,
|
||||
[util expectedCostOfPhoneNumber:[util parse:ambiguousPremiumRateString
|
||||
defaultRegion:@"CX"
|
||||
error:nil] forRegion:@"CX"]);
|
||||
// PREMIUM_RATE takes precedence over UNKNOWN_COST.
|
||||
XCTAssertEqual(NBEShortNumberCostPremiumRate,
|
||||
[util expectedCostOfPhoneNumber:ambiguousPremiumRateNumber]);
|
||||
|
||||
XCTAssertTrue([util isValidShortNumber:[util parse:ambiguousStandardRateString
|
||||
defaultRegion:@"AU"
|
||||
error:nil] forRegion:@"AU"]);
|
||||
XCTAssertEqual(NBEShortNumberCostStandardRate,
|
||||
[util expectedCostOfPhoneNumber:[util parse:ambiguousStandardRateString
|
||||
defaultRegion:@"AU"
|
||||
error:nil] forRegion:@"AU"]);
|
||||
XCTAssertFalse([util isValidShortNumber:[util parse:ambiguousStandardRateString
|
||||
defaultRegion:@"CX"
|
||||
error:nil] forRegion:@"CX"]);
|
||||
XCTAssertEqual(NBEShortNumberCostUnknown,
|
||||
[util expectedCostOfPhoneNumber:[util parse:ambiguousStandardRateString
|
||||
defaultRegion:@"CX"
|
||||
error:nil] forRegion:@"CX"]);
|
||||
XCTAssertEqual(NBEShortNumberCostUnknown,
|
||||
[util expectedCostOfPhoneNumber:ambiguousStandardRateNumber]);
|
||||
|
||||
XCTAssertTrue([util isValidShortNumber:[util parse:ambiguousTollFreeString
|
||||
defaultRegion:@"AU"
|
||||
error:nil] forRegion:@"AU"]);
|
||||
XCTAssertEqual(NBEShortNumberCostTollFree,
|
||||
[util expectedCostOfPhoneNumber:[util parse:ambiguousTollFreeString
|
||||
defaultRegion:@"AU"
|
||||
error:nil] forRegion:@"AU"]);
|
||||
XCTAssertFalse([util isValidShortNumber:[util parse:ambiguousTollFreeString
|
||||
defaultRegion:@"CX"
|
||||
error:nil] forRegion:@"CX"]);
|
||||
XCTAssertEqual(NBEShortNumberCostUnknown,
|
||||
[util expectedCostOfPhoneNumber:[util parse:ambiguousTollFreeString
|
||||
defaultRegion:@"CX"
|
||||
error:nil] forRegion:@"CX"]);
|
||||
XCTAssertEqual(NBEShortNumberCostUnknown,
|
||||
[util expectedCostOfPhoneNumber:ambiguousTollFreeNumber]);
|
||||
}
|
||||
|
||||
- (void)testGetExampleShortNumber {
|
||||
NBPhoneNumberUtil *util = [[NBPhoneNumberUtil alloc] init];
|
||||
|
||||
XCTAssertEqualObjects(@"8711", [util exampleShortNumberWithRegionCode:@"AM"]);
|
||||
XCTAssertEqualObjects(@"1010", [util exampleShortNumberWithRegionCode:@"FR"]);
|
||||
XCTAssertEqualObjects(@"", [util exampleShortNumberWithRegionCode:@"UN001"]);
|
||||
}
|
||||
|
||||
- (void)testGetExampleShortNumberForCost {
|
||||
NBPhoneNumberUtil *util = [[NBPhoneNumberUtil alloc] init];
|
||||
|
||||
XCTAssertEqualObjects(@"3010", [util exampleShortNumberForCost:NBEShortNumberCostTollFree
|
||||
regionCode:@"FR"]);
|
||||
XCTAssertEqualObjects(@"1023", [util exampleShortNumberForCost:NBEShortNumberCostStandardRate
|
||||
regionCode:@"FR"]);
|
||||
XCTAssertEqualObjects(@"42000", [util exampleShortNumberForCost:NBEShortNumberCostPremiumRate
|
||||
regionCode:@"FR"]);
|
||||
XCTAssertEqualObjects(@"", [util exampleShortNumberForCost:NBEShortNumberCostUnknown
|
||||
regionCode:@"FR"]);
|
||||
}
|
||||
|
||||
- (void)testConnectsToEmergencyNumber_US {
|
||||
NBPhoneNumberUtil *util = [[NBPhoneNumberUtil alloc] init];
|
||||
|
||||
XCTAssertTrue([util connectsToEmergencyNumberFromString:@"911" forRegion:@"US"]);
|
||||
XCTAssertTrue([util connectsToEmergencyNumberFromString:@"112" forRegion:@"US"]);
|
||||
XCTAssertFalse([util connectsToEmergencyNumberFromString:@"999" forRegion:@"US"]);
|
||||
}
|
||||
|
||||
- (void)testConnectsToEmergencyNumberLongNumber_US {
|
||||
NBPhoneNumberUtil *util = [[NBPhoneNumberUtil alloc] init];
|
||||
|
||||
XCTAssertTrue([util connectsToEmergencyNumberFromString:@"9116666666" forRegion:@"US"]);
|
||||
XCTAssertTrue([util connectsToEmergencyNumberFromString:@"1126666666" forRegion:@"US"]);
|
||||
XCTAssertFalse([util connectsToEmergencyNumberFromString:@"9996666666" forRegion:@"US"]);
|
||||
}
|
||||
|
||||
- (void)testConnectsToEmergencyNumberWithFormatting_US {
|
||||
NBPhoneNumberUtil *util = [[NBPhoneNumberUtil alloc] init];
|
||||
|
||||
XCTAssertTrue([util connectsToEmergencyNumberFromString:@"9-1-1" forRegion:@"US"]);
|
||||
XCTAssertTrue([util connectsToEmergencyNumberFromString:@"1-1-2" forRegion:@"US"]);
|
||||
XCTAssertFalse([util connectsToEmergencyNumberFromString:@"9-9-9" forRegion:@"US"]);
|
||||
}
|
||||
|
||||
- (void)testConnectsToEmergencyNumberWithPlusSign_US {
|
||||
NBPhoneNumberUtil *util = [[NBPhoneNumberUtil alloc] init];
|
||||
|
||||
XCTAssertFalse([util connectsToEmergencyNumberFromString:@"+911" forRegion:@"US"]);
|
||||
XCTAssertFalse([util connectsToEmergencyNumberFromString:@"\uFF0B911" forRegion:@"US"]);
|
||||
XCTAssertFalse([util connectsToEmergencyNumberFromString:@" +911" forRegion:@"US"]);
|
||||
XCTAssertFalse([util connectsToEmergencyNumberFromString:@"+112" forRegion:@"US"]);
|
||||
XCTAssertFalse([util connectsToEmergencyNumberFromString:@"+999" forRegion:@"US"]);
|
||||
}
|
||||
|
||||
- (void)testConnectsToEmergencyNumber_BR {
|
||||
NBPhoneNumberUtil *util = [[NBPhoneNumberUtil alloc] init];
|
||||
|
||||
XCTAssertTrue([util connectsToEmergencyNumberFromString:@"911" forRegion:@"BR"]);
|
||||
XCTAssertTrue([util connectsToEmergencyNumberFromString:@"190" forRegion:@"BR"]);
|
||||
XCTAssertFalse([util connectsToEmergencyNumberFromString:@"999" forRegion:@"BR"]);
|
||||
}
|
||||
|
||||
- (void)testConnectsToEmergencyNumberLongNumber_BR {
|
||||
NBPhoneNumberUtil *util = [[NBPhoneNumberUtil alloc] init];
|
||||
|
||||
// Brazilian emergency numbers don't work when additional digits are appended.
|
||||
XCTAssertFalse([util connectsToEmergencyNumberFromString:@"9111" forRegion:@"BR"]);
|
||||
XCTAssertFalse([util connectsToEmergencyNumberFromString:@"1900" forRegion:@"BR"]);
|
||||
XCTAssertFalse([util connectsToEmergencyNumberFromString:@"9996" forRegion:@"BR"]);
|
||||
}
|
||||
|
||||
- (void)testConnectsToEmergencyNumber_CL {
|
||||
NBPhoneNumberUtil *util = [[NBPhoneNumberUtil alloc] init];
|
||||
|
||||
XCTAssertTrue([util connectsToEmergencyNumberFromString:@"131" forRegion:@"CL"]);
|
||||
XCTAssertTrue([util connectsToEmergencyNumberFromString:@"133" forRegion:@"CL"]);
|
||||
}
|
||||
|
||||
- (void)testConnectsToEmergencyNumberLongNumber_CL {
|
||||
NBPhoneNumberUtil *util = [[NBPhoneNumberUtil alloc] init];
|
||||
|
||||
// Chilean emergency numbers don't work when additional digits are appended.
|
||||
XCTAssertFalse([util connectsToEmergencyNumberFromString:@"1313" forRegion:@"CL"]);
|
||||
XCTAssertFalse([util connectsToEmergencyNumberFromString:@"1330" forRegion:@"CL"]);
|
||||
}
|
||||
|
||||
- (void)testConnectsToEmergencyNumber_AO {
|
||||
NBPhoneNumberUtil *util = [[NBPhoneNumberUtil alloc] init];
|
||||
|
||||
// Angola doesn't have any metadata for emergency numbers.
|
||||
XCTAssertFalse([util connectsToEmergencyNumberFromString:@"911" forRegion:@"AO"]);
|
||||
XCTAssertFalse([util connectsToEmergencyNumberFromString:@"222123456" forRegion:@"AO"]);
|
||||
XCTAssertFalse([util connectsToEmergencyNumberFromString:@"923123456" forRegion:@"AO"]);
|
||||
}
|
||||
|
||||
- (void)testConnectsToEmergencyNumber_ZW {
|
||||
NBPhoneNumberUtil *util = [[NBPhoneNumberUtil alloc] init];
|
||||
|
||||
// Zimbabwe doesn't have any metadata.
|
||||
XCTAssertFalse([util connectsToEmergencyNumberFromString:@"911" forRegion:@"ZW"]);
|
||||
XCTAssertFalse([util connectsToEmergencyNumberFromString:@"01312345" forRegion:@"ZW"]);
|
||||
XCTAssertFalse([util connectsToEmergencyNumberFromString:@"0711234567" forRegion:@"ZW"]);
|
||||
}
|
||||
|
||||
- (void)testIsEmergencyNumber_US {
|
||||
NBPhoneNumberUtil *util = [[NBPhoneNumberUtil alloc] init];
|
||||
|
||||
XCTAssertTrue([util isEmergencyNumber:@"911" forRegion:@"US"]);
|
||||
XCTAssertTrue([util isEmergencyNumber:@"112" forRegion:@"US"]);
|
||||
XCTAssertFalse([util isEmergencyNumber:@"999" forRegion:@"US"]);
|
||||
}
|
||||
|
||||
- (void)testIsEmergencyNumberLongNumber_US {
|
||||
NBPhoneNumberUtil *util = [[NBPhoneNumberUtil alloc] init];
|
||||
|
||||
XCTAssertFalse([util isEmergencyNumber:@"9116666666" forRegion:@"US"]);
|
||||
XCTAssertFalse([util isEmergencyNumber:@"1126666666" forRegion:@"US"]);
|
||||
XCTAssertFalse([util isEmergencyNumber:@"9996666666" forRegion:@"US"]);
|
||||
}
|
||||
|
||||
- (void)testIsEmergencyNumberWithFormatting_US {
|
||||
NBPhoneNumberUtil *util = [[NBPhoneNumberUtil alloc] init];
|
||||
|
||||
XCTAssertTrue([util isEmergencyNumber:@"9-1-1" forRegion:@"US"]);
|
||||
XCTAssertTrue([util isEmergencyNumber:@"*911" forRegion:@"US"]);
|
||||
XCTAssertTrue([util isEmergencyNumber:@"1-1-2" forRegion:@"US"]);
|
||||
XCTAssertTrue([util isEmergencyNumber:@"*112" forRegion:@"US"]);
|
||||
XCTAssertFalse([util isEmergencyNumber:@"9-9-9" forRegion:@"US"]);
|
||||
XCTAssertFalse([util isEmergencyNumber:@"*999" forRegion:@"US"]);
|
||||
}
|
||||
|
||||
- (void)testIsEmergencyNumberWithPlusSign_US {
|
||||
NBPhoneNumberUtil *util = [[NBPhoneNumberUtil alloc] init];
|
||||
|
||||
XCTAssertFalse([util isEmergencyNumber:@"+911" forRegion:@"US"]);
|
||||
XCTAssertFalse([util isEmergencyNumber:@"\uFF0B911" forRegion:@"US"]);
|
||||
XCTAssertFalse([util isEmergencyNumber:@" +911" forRegion:@"US"]);
|
||||
XCTAssertFalse([util isEmergencyNumber:@"+112" forRegion:@"US"]);
|
||||
XCTAssertFalse([util isEmergencyNumber:@"+999" forRegion:@"US"]);
|
||||
}
|
||||
|
||||
- (void)testIsEmergencyNumber_BR {
|
||||
NBPhoneNumberUtil *util = [[NBPhoneNumberUtil alloc] init];
|
||||
|
||||
XCTAssertTrue([util connectsToEmergencyNumberFromString:@"911" forRegion:@"BR"]);
|
||||
XCTAssertTrue([util connectsToEmergencyNumberFromString:@"190" forRegion:@"BR"]);
|
||||
XCTAssertFalse([util connectsToEmergencyNumberFromString:@"999" forRegion:@"BR"]);
|
||||
}
|
||||
|
||||
- (void)testIsEmergencyNumberLongNumber_BR {
|
||||
NBPhoneNumberUtil *util = [[NBPhoneNumberUtil alloc] init];
|
||||
|
||||
// Brazilian emergency numbers don't work when additional digits are appended.
|
||||
XCTAssertFalse([util connectsToEmergencyNumberFromString:@"9111" forRegion:@"BR"]);
|
||||
XCTAssertFalse([util connectsToEmergencyNumberFromString:@"1900" forRegion:@"BR"]);
|
||||
XCTAssertFalse([util connectsToEmergencyNumberFromString:@"9996" forRegion:@"BR"]);
|
||||
}
|
||||
|
||||
- (void)testIsEmergencyNumber_AO {
|
||||
NBPhoneNumberUtil *util = [[NBPhoneNumberUtil alloc] init];
|
||||
|
||||
// Angola doesn't have any metadata for emergency numbers.
|
||||
XCTAssertFalse([util connectsToEmergencyNumberFromString:@"911" forRegion:@"AO"]);
|
||||
XCTAssertFalse([util connectsToEmergencyNumberFromString:@"222123456" forRegion:@"AO"]);
|
||||
XCTAssertFalse([util connectsToEmergencyNumberFromString:@"923123456" forRegion:@"AO"]);
|
||||
}
|
||||
|
||||
- (void)testIsEmergencyNumber_ZW {
|
||||
NBPhoneNumberUtil *util = [[NBPhoneNumberUtil alloc] init];
|
||||
|
||||
// Zimbabwe doesn't have any metadata.
|
||||
XCTAssertFalse([util connectsToEmergencyNumberFromString:@"911" forRegion:@"ZW"]);
|
||||
XCTAssertFalse([util connectsToEmergencyNumberFromString:@"01312345" forRegion:@"ZW"]);
|
||||
XCTAssertFalse([util connectsToEmergencyNumberFromString:@"0711234567" forRegion:@"ZW"]);
|
||||
}
|
||||
|
||||
- (void)testEmergencyNumberForSharedCountryCallingCode {
|
||||
NBPhoneNumberUtil *util = [[NBPhoneNumberUtil alloc] init];
|
||||
|
||||
// Test the emergency number 112, which is valid in both Australia and the Christmas Islands.
|
||||
NBPhoneNumber *auEmergencyNumber = [util parse:@"112" defaultRegion:@"AU" error:nil];
|
||||
XCTAssertTrue([util isEmergencyNumber:@"112" forRegion:@"AU"]);
|
||||
XCTAssertTrue([util isValidShortNumber:auEmergencyNumber forRegion:@"AU"]);
|
||||
XCTAssertEqual(NBEShortNumberCostTollFree,
|
||||
[util expectedCostOfPhoneNumber:auEmergencyNumber forRegion:@"AU"]);
|
||||
|
||||
XCTAssertTrue([util isEmergencyNumber:@"112" forRegion:@"CX"]);
|
||||
XCTAssertTrue([util isValidShortNumber:auEmergencyNumber forRegion:@"CX"]);
|
||||
XCTAssertEqual(NBEShortNumberCostTollFree,
|
||||
[util expectedCostOfPhoneNumber:auEmergencyNumber forRegion:@"CX"]);
|
||||
|
||||
NBPhoneNumber *sharedEmergencyNumber = [[NBPhoneNumber alloc] init];
|
||||
sharedEmergencyNumber.countryCode = @61;
|
||||
sharedEmergencyNumber.nationalNumber = @112;
|
||||
XCTAssertTrue([util isValidShortNumber:sharedEmergencyNumber]);
|
||||
XCTAssertEqual(NBEShortNumberCostTollFree,
|
||||
[util expectedCostOfPhoneNumber:sharedEmergencyNumber]);
|
||||
}
|
||||
|
||||
- (void)testOverlappingNANPANumber {
|
||||
// 211 is an emergency number in Barbados, while it is a toll-free information line in Canada
|
||||
// and the USA.
|
||||
NBPhoneNumberUtil *util = [[NBPhoneNumberUtil alloc] init];
|
||||
|
||||
NBPhoneNumber *bb211 = [util parse:@"211" defaultRegion:@"BB" error:nil];
|
||||
NBPhoneNumber *us211 = [util parse:@"211" defaultRegion:@"US" error:nil];
|
||||
NBPhoneNumber *ca211 = [util parse:@"211" defaultRegion:@"CA" error:nil];
|
||||
|
||||
XCTAssertTrue([util isEmergencyNumber:@"211" forRegion:@"BB"]);
|
||||
XCTAssertEqual(NBEShortNumberCostTollFree,
|
||||
[util expectedCostOfPhoneNumber:bb211 forRegion:@"BB"]);
|
||||
XCTAssertFalse([util isEmergencyNumber:@"211" forRegion:@"US"]);
|
||||
XCTAssertEqual(NBEShortNumberCostUnknown,
|
||||
[util expectedCostOfPhoneNumber:us211 forRegion:@"US"]);
|
||||
XCTAssertFalse([util isEmergencyNumber:@"211" forRegion:@"CA"]);
|
||||
XCTAssertEqual(NBEShortNumberCostTollFree,
|
||||
[util expectedCostOfPhoneNumber:ca211 forRegion:@"CA"]);
|
||||
}
|
||||
|
||||
- (void)testCountryCallingCodeIsNotIgnored {
|
||||
NBPhoneNumberUtil *util = [[NBPhoneNumberUtil alloc] init];
|
||||
|
||||
// +46 is the country calling code for Sweden (SE), and 40404 is a valid short number in the US.
|
||||
NBPhoneNumber *seNumber = [util parse:@"+4640404" defaultRegion:@"SE" error:nil];
|
||||
XCTAssertFalse([util isPossibleShortNumber:seNumber forRegion:@"US"]);
|
||||
XCTAssertFalse([util isValidShortNumber:seNumber forRegion:@"US"]);
|
||||
XCTAssertEqual(NBEShortNumberCostUnknown,
|
||||
[util expectedCostOfPhoneNumber:seNumber forRegion:@"US"]);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#endif // SHORT_NUMBER_SUPPORT
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,53 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<?PHP
|
||||
$mode = isset($_REQUEST['test']) ? true:false;
|
||||
$metadataSrc = "http://libphonenumber.googlecode.com/svn/trunk/javascript/i18n/phonenumbers/metadata.js";
|
||||
$fileName = "PhoneNumberMetaData";
|
||||
|
||||
if ($mode)
|
||||
{
|
||||
$metadataSrc = "http://libphonenumber.googlecode.com/svn/trunk/javascript/i18n/phonenumbers/metadatafortesting.js";
|
||||
$fileName = "PhoneNumberMetaDataForTesting";
|
||||
}
|
||||
?>
|
||||
|
||||
<head>
|
||||
<title>libPhoneNumber for iOS metadata generator</title>
|
||||
<script src="http://cdn.rawgit.com/google/closure-library/master/closure/goog/base.js"></script>
|
||||
<script>
|
||||
goog.require('goog.proto2.Message');
|
||||
goog.require('goog.dom');
|
||||
goog.require('goog.json');
|
||||
goog.require('goog.array');
|
||||
goog.require('goog.proto2.ObjectSerializer');
|
||||
goog.require('goog.string.StringBuffer');
|
||||
</script>
|
||||
<script src="http://libphonenumber.googlecode.com/svn/trunk/javascript/i18n/phonenumbers/phonemetadata.pb.js"></script>
|
||||
<script src="http://libphonenumber.googlecode.com/svn/trunk/javascript/i18n/phonenumbers/phonenumber.pb.js"></script>
|
||||
<script src=<?PHP echo '"'.$metadataSrc.'"'; ?>></script>
|
||||
<script src="http://libphonenumber.googlecode.com/svn/trunk/javascript/i18n/phonenumbers/phonenumberutil.js"></script>
|
||||
<script src="http://libphonenumber.googlecode.com/svn/trunk/javascript/i18n/phonenumbers/asyoutypeformatter.js"></script>
|
||||
<script src="http://code.jquery.com/jquery-1.8.3.min.js"></script>
|
||||
<script>
|
||||
goog.require('i18n.phonenumbers.metadata');
|
||||
$(document).ready(function () {
|
||||
var goodDomElement = goog.dom.getElement;
|
||||
var jsonData = encodeURIComponent(JSON.stringify(i18n.phonenumbers.metadata));
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "libPhoneNumberGenerator.php",
|
||||
data: { jsonData: jsonData, fileName: <?php echo '"'.$fileName.'"'; ?> }
|
||||
}).done(function(msg) {
|
||||
$('#console').html(""+msg);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="console">Generate libPhoneNumber metadata for iOS</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@ -1,15 +0,0 @@
|
||||
<?PHP
|
||||
$str = urldecode($_REQUEST['jsonData']);
|
||||
$name = $_REQUEST['fileName'];
|
||||
|
||||
if ($str && $name)
|
||||
{
|
||||
$fp = fopen('./generatedJSON/'.$name.'.json', 'w');
|
||||
fwrite($fp, $str);
|
||||
fclose($fp);
|
||||
echo "complete generate : ".$name;
|
||||
exit;
|
||||
}
|
||||
|
||||
echo "error";
|
||||
?>
|
||||
@ -1,142 +0,0 @@
|
||||
#!/usr/bin/swift
|
||||
|
||||
//
|
||||
// metadataGenerator.swift
|
||||
// libPhoneNumber-iOS
|
||||
//
|
||||
// Created by Paween Itthipalkul on 2/16/18.
|
||||
// Copyright © 2018 Google LLC. All rights reserved.
|
||||
//
|
||||
|
||||
import Darwin
|
||||
import Foundation
|
||||
import JavaScriptCore
|
||||
|
||||
enum GeneratorError: Error {
|
||||
case dataNotString
|
||||
case genericError
|
||||
}
|
||||
|
||||
func synchronouslyLoadStringResource(from url: URL) throws -> String {
|
||||
let session = URLSession(configuration: .default)
|
||||
var resultData: Data?
|
||||
var resultError: Error?
|
||||
let semaphore = DispatchSemaphore(value: 0)
|
||||
|
||||
let dataTask = session.dataTask(with: url) { data, _, error in
|
||||
resultData = data
|
||||
resultError = error
|
||||
semaphore.signal()
|
||||
}
|
||||
dataTask.resume()
|
||||
|
||||
semaphore.wait()
|
||||
|
||||
if let error = resultError {
|
||||
throw error
|
||||
}
|
||||
|
||||
if let data = resultData {
|
||||
guard let string = String(data: data, encoding: .utf8) else {
|
||||
throw GeneratorError.dataNotString
|
||||
}
|
||||
|
||||
return string
|
||||
}
|
||||
|
||||
throw GeneratorError.genericError
|
||||
}
|
||||
|
||||
func loadJS(from url: URL, to context: JSContext) {
|
||||
guard let script = try? synchronouslyLoadStringResource(from: url) else {
|
||||
fputs("Cannot load dependency at \(url)\n", __stderrp)
|
||||
exit(1)
|
||||
}
|
||||
|
||||
context.evaluateScript(script)
|
||||
}
|
||||
|
||||
// Create JavaScript context.
|
||||
let context = JSContext()!
|
||||
context.exceptionHandler = { _, exception in
|
||||
fputs("Javascript exception thrown: \(exception!)\n", __stderrp)
|
||||
// exit(1)
|
||||
}
|
||||
|
||||
// Load required dependencies.
|
||||
let googleClosure = URL(
|
||||
string: "http://cdn.rawgit.com/google/closure-library/master/closure/goog/base.js")!
|
||||
loadJS(from: googleClosure, to: context)
|
||||
|
||||
let jQuery = URL(string: "http://code.jquery.com/jquery-1.8.3.min.js")!
|
||||
loadJS(from: jQuery, to: context)
|
||||
|
||||
// Evaluate requires.
|
||||
let requires = """
|
||||
goog.require('goog.proto2.Message');
|
||||
goog.require('goog.dom');
|
||||
goog.require('goog.json');
|
||||
goog.require('goog.array');
|
||||
goog.require('goog.proto2.ObjectSerializer');
|
||||
goog.require('goog.string.StringBuffer');
|
||||
goog.require('i18n.phonenumbers.metadata');
|
||||
"""
|
||||
context.evaluateScript(requires)
|
||||
|
||||
// Load metadata file from GitHub.
|
||||
let phoneMetadata = URL(string: "https://raw.githubusercontent.com/googlei18n/libphonenumber/master/javascript/i18n/phonenumbers/metadata.js")!
|
||||
let phoneMetadataForTesting = URL(string: "https://raw.githubusercontent.com/googlei18n/libphonenumber/master/javascript/i18n/phonenumbers/metadatafortesting.js")!
|
||||
let shortNumberMetadata = URL(string: "https://raw.githubusercontent.com/googlei18n/libphonenumber/master/javascript/i18n/phonenumbers/shortnumbermetadata.js")!
|
||||
|
||||
let currentDir = FileManager.default.currentDirectoryPath
|
||||
let baseURL = URL(fileURLWithPath: currentDir).appendingPathComponent("generatedJSON")
|
||||
|
||||
// Phone metadata.
|
||||
do {
|
||||
let metadata = try synchronouslyLoadStringResource(from: phoneMetadata)
|
||||
context.evaluateScript(metadata)
|
||||
let result = context.evaluateScript("JSON.stringify(i18n.phonenumbers.metadata)")!.toString()!
|
||||
let url = baseURL.appendingPathComponent("PhoneNumberMetaData.json")
|
||||
try result.write(
|
||||
to: url,
|
||||
atomically: true,
|
||||
encoding: .utf8)
|
||||
// Clean up
|
||||
context.evaluateScript("i18n.phonenumbers.metadata = null")
|
||||
} catch (let error) {
|
||||
fputs("Error loading phone number metadata \(error)\n", __stderrp)
|
||||
exit(1)
|
||||
}
|
||||
|
||||
// Phone metadata for testing.
|
||||
do {
|
||||
let metadata = try synchronouslyLoadStringResource(from: phoneMetadataForTesting)
|
||||
context.evaluateScript(metadata)
|
||||
let result = context.evaluateScript("JSON.stringify(i18n.phonenumbers.metadata)")!.toString()!
|
||||
let url = baseURL.appendingPathComponent("PhoneNumberMetaDataForTesting.json")
|
||||
try result.write(
|
||||
to: url,
|
||||
atomically: true,
|
||||
encoding: .utf8)
|
||||
} catch (let error) {
|
||||
fputs("Error loading phone number metadata for testing \(error)\n", __stderrp)
|
||||
exit(1)
|
||||
}
|
||||
|
||||
// Short number metadata.
|
||||
do {
|
||||
let metadata = try synchronouslyLoadStringResource(from: shortNumberMetadata)
|
||||
context.evaluateScript(metadata)
|
||||
let result = context.evaluateScript(
|
||||
"JSON.stringify(i18n.phonenumbers.shortnumbermetadata)")!.toString()!
|
||||
let url = baseURL.appendingPathComponent("ShortNumberMetadata.json")
|
||||
try result.write(
|
||||
to: url,
|
||||
atomically: true,
|
||||
encoding: .utf8)
|
||||
} catch (let error) {
|
||||
fputs("Error loading short number metadata \(error)\n", __stderrp)
|
||||
exit(1)
|
||||
}
|
||||
|
||||
print("Done")
|
||||
@ -1,2 +0,0 @@
|
||||
require 'coveralls'
|
||||
Coveralls.wear!
|
||||
Loading…
Reference in New Issue
Block a user