iOS Convert phone number to international format

2019-06-27 04:13发布

问题:

In my iOS app I have to convert a phone number (taken in the contacts) and convert it in international format (to send SMS automatically with an extern library). I saw libPhoneNumber but the problem is that we have to enter the country code, and the app have to work in all (almost) countries, so I don't know what is the user's country.

Here is how the library works :

let phoneUtil = NBPhoneNumberUtil()
let phoneNumberConverted = try phoneUtil.parse("0665268242", defaultRegion: "FR") // So I don't know the country of the user here
print(try? phoneUtil.format(phoneNumberConverted, numberFormat: NBEPhoneNumberFormat.INTERNATIONAL))

回答1:

formattedPhoneNumberSubstring takes a partial phone number string and formats it as the beginning of a properly formatted international number, e.g. "16463" turns to "+1 646-3".

NSString *formattedPhoneNumberSubstring(NSString *phoneNumber) {
NBPhoneNumberUtil *phoneUtil = [NBPhoneNumberUtil sharedInstance];
phoneNumber = [phoneUtil normalizeDigitsOnly:phoneNumber];
NSString *nationalNumber;
NSNumber *countryCode = [phoneUtil extractCountryCode:phoneNumber nationalNumber:&nationalNumber];
if ([countryCode isEqualToNumber:@0])
    return phoneNumber;

NSString *regionCode = [[phoneUtil regionCodeFromCountryCode:countryCode] objectAtIndex:0];
NSString *paddedNationalNumber = [nationalNumber stringByPaddingToLength:15 withString:@"0" startingAtIndex:0];
NSString *formatted;
NSString *formattedSubstr;
for (int i=0; i < paddedNationalNumber.length; i++) {
    NSError *error = nil;
    formattedSubstr = [phoneUtil format:[phoneUtil parse:[paddedNationalNumber substringToIndex:i] defaultRegion:regionCode error:&error]
                           numberFormat:NBEPhoneNumberFormatINTERNATIONAL error:&error];
    if (getExtraCharacters(formattedSubstr) > getExtraCharacters(formatted)) // extra characters means more formatted
        formatted = formattedSubstr;
}

// Preparing the buffer for phoneNumber
unichar phoneNumberBuffer[phoneNumber.length+1];
[phoneNumber getCharacters:phoneNumberBuffer range:NSMakeRange(0, phoneNumber.length)];

// Preparing the buffer for formatted
unichar formattedBuffer[formatted.length+1];
[formatted getCharacters:formattedBuffer range:NSMakeRange(0, formatted.length)];

int j=0;
for(int i = 0; i < phoneNumber.length && j < formatted.length; i++) {
    while(formattedBuffer[j] != phoneNumberBuffer[i]) j++;
    j++;
}

return [formatted substringToIndex:j];

}



回答2:

You can get the region using either the users locale or the users geo position. See stackoverflow question get device location country code for more details.



回答3:

If you don’t know the country code of a phone number, you can’t generate the international format of it.

You could try using the location of the phone or its region settings to guess the country code, but it won’t be reliable. For example, my phone number is Spanish, I’m currently in Italy and my region is set to New Zealand. My contact list contains numbers from all over the world, and if they weren’t entered in international format there would be no way to guess what country code to use for each number.

If you absolutely have to guess, the best approach might be to think about how the phone would interpret the numbers in the contact list itself. This would require you to determine the country code of the phone’s SIM card. See this answer to a related question for a way of doing that, or here’s some Swift code I’ve used:

let networkInfo = CTTelephonyNetworkInfo()
if let carrier = networkInfo.subscriberCellularProvider {
    NSLog("Carrier: \(carrier.carrierName)")
    NSLog("ISO: \(carrier.isoCountryCode)")
    NSLog("MCC: \(carrier.mobileCountryCode)")
    NSLog("MNC: \(carrier.mobileNetworkCode)")
}

The ISO country code can be used to look up a country code for dialling; an example table is in the answer linked above.