Merge branch 'charlesmchen/nonUSNonContactSearch'

pull/1/head
Matthew Chen 8 years ago
commit 312f398ddd

@ -14,11 +14,25 @@ NS_ASSUME_NONNULL_BEGIN
- (nullable SignalRecipient *)synchronousLookup:(NSString *)identifier error:(NSError **)error;
// This asynchronously updates the SignalRecipient for a given contactId.
// This asynchronously tries to verify whether or not a contact id
// corresponds to a service account.
//
// The failure callback is invoked if the lookup fails _or_ if the
// contact id doesn't correspond to an account.
- (void)lookupIdentifier:(NSString *)identifier
success:(void (^)(SignalRecipient *recipient))success
failure:(void (^)(NSError *error))failure;
// This asynchronously tries to verify whether or not a group of possible
// contact ids correspond to service accounts.
//
// The failure callback is only invoked if the lookup fails. Otherwise,
// the success callback is invoked with the (possibly empty) set of contacts
// that were found.
- (void)lookupIdentifiers:(NSArray<NSString *> *)identifiers
success:(void (^)(NSArray<SignalRecipient *> *recipients))success
failure:(void (^)(NSError *error))failure;
- (void)updateSignalContactIntersectionWithABContacts:(NSArray<Contact *> *)abContacts
success:(void (^)())success
failure:(void (^)(NSError *error))failure;

@ -60,7 +60,7 @@ NS_ASSUME_NONNULL_BEGIN
failure(OWSErrorWithCodeDescription(OWSErrorCodeInvalidMethodParameters, @"Cannot lookup nil identifier"));
return;
}
[self contactIntersectionWithSet:[NSSet setWithObject:identifier]
success:^(NSSet<NSString *> *_Nonnull matchedIds) {
if (matchedIds.count == 1) {
@ -72,6 +72,31 @@ NS_ASSUME_NONNULL_BEGIN
failure:failure];
}
- (void)lookupIdentifiers:(NSArray<NSString *> *)identifiers
success:(void (^)(NSArray<SignalRecipient *> *recipients))success
failure:(void (^)(NSError *error))failure
{
if (identifiers.count < 1) {
OWSAssert(NO);
failure(OWSErrorWithCodeDescription(OWSErrorCodeInvalidMethodParameters, @"Cannot lookup zero identifiers"));
return;
}
[self contactIntersectionWithSet:[NSSet setWithArray:identifiers]
success:^(NSSet<NSString *> *_Nonnull matchedIds) {
if (matchedIds.count == 1) {
NSMutableArray<SignalRecipient *> *recipients = [NSMutableArray new];
for (NSString *identifier in matchedIds) {
[recipients addObject:[SignalRecipient recipientWithTextSecureIdentifier:identifier]];
}
success([recipients copy]);
} else {
failure(OWSErrorMakeNoSuchSignalRecipientError());
}
}
failure:failure];
}
- (void)updateSignalContactIntersectionWithABContacts:(NSArray<Contact *> *)abContacts
success:(void (^)())success
failure:(void (^)(NSError *error))failure {

@ -1,3 +1,7 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <libPhoneNumber-iOS/NBPhoneNumberUtil.h>
@ -24,6 +28,14 @@
+ (PhoneNumber *)tryParsePhoneNumberFromUserSpecifiedText:(NSString *)text;
+ (PhoneNumber *)tryParsePhoneNumberFromE164:(NSString *)text;
// This will try to parse the input text as a phone number using
// the default region and the country code for this client's phone
// number.
//
// Order matters; better results will appear first.
+ (NSArray<PhoneNumber *> *)tryParsePhoneNumbersFromsUserSpecifiedText:(NSString *)text
clientPhoneNumber:(NSString *)clientPhoneNumber;
+ (NSString *)removeFormattingCharacters:(NSString *)inputString;
+ (NSString *)bestEffortFormatPartialUserSpecifiedTextToLookLikeAPhoneNumber:(NSString *)input;
+ (NSString *)bestEffortFormatPartialUserSpecifiedTextToLookLikeAPhoneNumber:(NSString *)input

@ -1,3 +1,7 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "NBAsYouTypeFormatter.h"
#import "NBPhoneNumber.h"
#import "PhoneNumber.h"
@ -9,8 +13,8 @@ static NSString *const RPDefaultsKeyPhoneNumberCanonical = @"RPDefaultsKeyPhoneN
@implementation PhoneNumber
+ (PhoneNumber *)phoneNumberFromText:(NSString *)text andRegion:(NSString *)regionCode {
assert(text != nil);
assert(regionCode != nil);
OWSAssert(text != nil);
OWSAssert(regionCode != nil);
NBPhoneNumberUtil *phoneUtil = [PhoneNumberUtil sharedUtil].nbPhoneNumberUtil;
@ -36,7 +40,7 @@ static NSString *const RPDefaultsKeyPhoneNumberCanonical = @"RPDefaultsKeyPhoneN
}
+ (PhoneNumber *)phoneNumberFromUserSpecifiedText:(NSString *)text {
assert(text != nil);
OWSAssert(text != nil);
return [PhoneNumber phoneNumberFromText:text andRegion:[self defaultRegionCode]];
}
@ -56,11 +60,11 @@ static NSString *const RPDefaultsKeyPhoneNumberCanonical = @"RPDefaultsKeyPhoneN
}
+ (PhoneNumber *)phoneNumberFromE164:(NSString *)text {
assert(text != nil);
assert([text hasPrefix:COUNTRY_CODE_PREFIX]);
OWSAssert(text != nil);
OWSAssert([text hasPrefix:COUNTRY_CODE_PREFIX]);
PhoneNumber *number = [PhoneNumber phoneNumberFromText:text andRegion:@"ZZ"];
assert(number != nil);
OWSAssert(number != nil);
return number;
}
@ -98,14 +102,14 @@ static NSString *const RPDefaultsKeyPhoneNumberCanonical = @"RPDefaultsKeyPhoneN
+ (PhoneNumber *)tryParsePhoneNumberFromText:(NSString *)text fromRegion:(NSString *)regionCode {
assert(text != nil);
assert(regionCode != nil);
OWSAssert(text != nil);
OWSAssert(regionCode != nil);
return [self phoneNumberFromText:text andRegion:regionCode];
}
+ (PhoneNumber *)tryParsePhoneNumberFromUserSpecifiedText:(NSString *)text {
assert(text != nil);
OWSAssert(text != nil);
if ([text isEqualToString:@""]) {
return nil;
@ -115,6 +119,76 @@ static NSString *const RPDefaultsKeyPhoneNumberCanonical = @"RPDefaultsKeyPhoneN
return [self phoneNumberFromUserSpecifiedText:sanitizedString];
}
+ (NSArray<PhoneNumber *> *)tryParsePhoneNumbersFromsUserSpecifiedText:(NSString *)text
clientPhoneNumber:(NSString *)clientPhoneNumber
{
OWSAssert(text != nil);
text = [text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
if ([text isEqualToString:@""]) {
return nil;
}
NSString *sanitizedString = [self removeFormattingCharacters:text];
OWSAssert(sanitizedString != nil);
NSMutableArray *result = [NSMutableArray new];
NSMutableSet *phoneNumberSet = [NSMutableSet new];
void (^tryParsingWithCountryCode)(NSString *, NSString *) = ^(NSString *text,
NSString *countryCode) {
PhoneNumber *phoneNumber = [PhoneNumber phoneNumberFromText:text
andRegion:countryCode];
if (phoneNumber && [phoneNumber toE164] && ![phoneNumberSet containsObject:[phoneNumber toE164]]) {
[result addObject:phoneNumber];
[phoneNumberSet addObject:[phoneNumber toE164]];
}
};
if ([sanitizedString hasPrefix:@"+"]) {
// If the text starts with "+", just parse it.
tryParsingWithCountryCode(sanitizedString, [self defaultRegionCode]);
return result;
}
// Order matters; better results should appear first so prefer
// matches with the same country code as this client's phone number.
OWSAssert(clientPhoneNumber.length > 0);
if (clientPhoneNumber.length > 0) {
NSNumber *callingCodeForLocalNumber = [[PhoneNumber phoneNumberFromE164:clientPhoneNumber] getCountryCode];
if (callingCodeForLocalNumber != nil) {
tryParsingWithCountryCode([NSString stringWithFormat:@"+%@%@",
callingCodeForLocalNumber,
sanitizedString],
[self defaultRegionCode]);
if ([sanitizedString hasPrefix:[NSString stringWithFormat:@"%d", callingCodeForLocalNumber.intValue]]) {
// If the text starts with the calling code for the local number, try
// just adding "+" and parsing it.
tryParsingWithCountryCode(
[NSString stringWithFormat:@"+%@", sanitizedString], [self defaultRegionCode]);
}
// It's gratuitous to try all country codes associated with a given
// calling code, but it can't hurt and this isn't a performance
// hotspot.
NSArray *possibleLocalCountryCodes = [PhoneNumberUtil countryCodesFromCallingCode:[NSString stringWithFormat:@"+%@",
callingCodeForLocalNumber]];
for (NSString *countryCode in possibleLocalCountryCodes) {
tryParsingWithCountryCode([NSString stringWithFormat:@"+%@%@",
callingCodeForLocalNumber,
sanitizedString],
countryCode);
}
}
}
// Also try matches using the phone's default region.
tryParsingWithCountryCode(sanitizedString, [self defaultRegionCode]);
return result;
}
+ (NSString *)removeFormattingCharacters:(NSString *)inputString {
char outputString[inputString.length + 1];
@ -131,7 +205,7 @@ static NSString *const RPDefaultsKeyPhoneNumberCanonical = @"RPDefaultsKeyPhoneN
}
+ (PhoneNumber *)tryParsePhoneNumberFromE164:(NSString *)text {
assert(text != nil);
OWSAssert(text != nil);
return [self phoneNumberFromE164:text];
}

@ -10,9 +10,10 @@
@property (nonatomic, retain) NBPhoneNumberUtil *nbPhoneNumberUtil;
+ (NSString *)callingCodeFromCountryCode:(NSString *)code;
+ (NSString *)countryNameFromCountryCode:(NSString *)code;
+ (NSString *)callingCodeFromCountryCode:(NSString *)countryCode;
+ (NSString *)countryNameFromCountryCode:(NSString *)countryCode;
+ (NSArray *)countryCodesForSearchTerm:(NSString *)searchTerm;
+ (NSArray *)countryCodesFromCallingCode:(NSString *)callingCode;
+ (NSUInteger)translateCursorPosition:(NSUInteger)offset
from:(NSString *)source

@ -30,8 +30,8 @@
}
// country code -> country name
+ (NSString *)countryNameFromCountryCode:(NSString *)code {
NSDictionary *countryCodeComponent = @{NSLocaleCountryCode : code};
+ (NSString *)countryNameFromCountryCode:(NSString *)countryCode {
NSDictionary *countryCodeComponent = @{NSLocaleCountryCode : countryCode};
NSString *identifier = [NSLocale localeIdentifierFromComponents:countryCodeComponent];
NSString *country = [NSLocale.currentLocale displayNameForKey:NSLocaleIdentifier value:identifier];
return country;
@ -86,6 +86,17 @@
return callingCode;
}
+ (NSArray *)countryCodesFromCallingCode:(NSString *)callingCode {
NSMutableArray *countryCodes = [NSMutableArray new];
for (NSString *countryCode in NSLocale.ISOCountryCodes) {
NSString *callingCodeForCountryCode = [self callingCodeFromCountryCode:countryCode];
if ([callingCode isEqualToString:callingCodeForCountryCode]) {
[countryCodes addObject:countryCode];
}
}
return countryCodes;
}
// search term -> country codes
+ (NSArray *)countryCodesForSearchTerm:(NSString *)searchTerm {
searchTerm = [searchTerm stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];

Loading…
Cancel
Save