diff --git a/Example/TSKitiOSTestApp/TSKitiOSTestApp.xcodeproj/project.pbxproj b/Example/TSKitiOSTestApp/TSKitiOSTestApp.xcodeproj/project.pbxproj index e8581235..5bec2474 100644 --- a/Example/TSKitiOSTestApp/TSKitiOSTestApp.xcodeproj/project.pbxproj +++ b/Example/TSKitiOSTestApp/TSKitiOSTestApp.xcodeproj/project.pbxproj @@ -16,6 +16,7 @@ 45458B7A1CC342B600A02153 /* TSStorageSignedPreKeyStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 45458B711CC342B600A02153 /* TSStorageSignedPreKeyStore.m */; }; 45458B7B1CC342B600A02153 /* CryptographyTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 45458B731CC342B600A02153 /* CryptographyTests.m */; }; 45458B7C1CC342B600A02153 /* MessagePaddingTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 45458B741CC342B600A02153 /* MessagePaddingTests.m */; }; + 459850C11D22C6F2006FFEDB /* PhoneNumberTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 459850C01D22C6F2006FFEDB /* PhoneNumberTest.m */; }; 45A856AC1D220BFF0056CD4D /* TSAttributesTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 45A856AB1D220BFF0056CD4D /* TSAttributesTest.m */; }; 51520592F83F2440F2DE4D67 /* libPods-TSKitiOSTestApp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B8362AB8E280E0F64352F08A /* libPods-TSKitiOSTestApp.a */; }; B6273DD61C13A2E500738558 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = B6273DD51C13A2E500738558 /* main.m */; }; @@ -48,6 +49,7 @@ 45458B711CC342B600A02153 /* TSStorageSignedPreKeyStore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSStorageSignedPreKeyStore.m; sourceTree = ""; }; 45458B731CC342B600A02153 /* CryptographyTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CryptographyTests.m; sourceTree = ""; }; 45458B741CC342B600A02153 /* MessagePaddingTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MessagePaddingTests.m; sourceTree = ""; }; + 459850C01D22C6F2006FFEDB /* PhoneNumberTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = PhoneNumberTest.m; path = ../../../tests/Contacts/PhoneNumberTest.m; sourceTree = ""; }; 45A856AB1D220BFF0056CD4D /* TSAttributesTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSAttributesTest.m; sourceTree = ""; }; B6273DD11C13A2E500738558 /* TSKitiOSTestApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TSKitiOSTestApp.app; sourceTree = BUILT_PRODUCTS_DIR; }; B6273DD51C13A2E500738558 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; @@ -127,6 +129,14 @@ path = ../../../tests/Util; sourceTree = ""; }; + 459850BF1D22C6C4006FFEDB /* Contacts */ = { + isa = PBXGroup; + children = ( + 459850C01D22C6F2006FFEDB /* PhoneNumberTest.m */, + ); + name = Contacts; + sourceTree = ""; + }; 5183572EFCE99F6F1791272A /* Pods */ = { isa = PBXGroup; children = ( @@ -196,6 +206,7 @@ children = ( 45458B691CC342B600A02153 /* Account */, 45458B6B1CC342B600A02153 /* Attachments */, + 459850BF1D22C6C4006FFEDB /* Contacts */, 45458B6D1CC342B600A02153 /* Storage */, 45458B721CC342B600A02153 /* Util */, B6273DF01C13A2E500738558 /* Info.plist */, @@ -417,6 +428,7 @@ 45458B7B1CC342B600A02153 /* CryptographyTests.m in Sources */, 45458B791CC342B600A02153 /* TSStoragePreKeyStoreTests.m in Sources */, 45458B761CC342B600A02153 /* TSAttachmentsTest.m in Sources */, + 459850C11D22C6F2006FFEDB /* PhoneNumberTest.m in Sources */, 45458B7A1CC342B600A02153 /* TSStorageSignedPreKeyStore.m in Sources */, 45458B771CC342B600A02153 /* TSMessageStorageTests.m in Sources */, 45458B7C1CC342B600A02153 /* MessagePaddingTests.m in Sources */, diff --git a/SignalServiceKit.podspec b/SignalServiceKit.podspec index 29461f44..970228c7 100644 --- a/SignalServiceKit.podspec +++ b/SignalServiceKit.podspec @@ -8,7 +8,7 @@ Pod::Spec.new do |s| s.name = "SignalServiceKit" - s.version = "0.0.4" + s.version = "0.0.5" s.summary = "An Objective-C library for communicating with the Signal messaging service." s.description = <<-DESC diff --git a/src/Contacts/PhoneNumber.h b/src/Contacts/PhoneNumber.h index 2d6c0fb2..a1effb58 100644 --- a/src/Contacts/PhoneNumber.h +++ b/src/Contacts/PhoneNumber.h @@ -24,7 +24,7 @@ + (PhoneNumber *)tryParsePhoneNumberFromUserSpecifiedText:(NSString *)text; + (PhoneNumber *)tryParsePhoneNumberFromE164:(NSString *)text; - ++ (NSString *)removeFormattingCharacters:(NSString *)inputString; + (NSString *)bestEffortFormatPartialUserSpecifiedTextToLookLikeAPhoneNumber:(NSString *)input; + (NSString *)bestEffortFormatPartialUserSpecifiedTextToLookLikeAPhoneNumber:(NSString *)input withSpecifiedCountryCodeString:(NSString *)countryCodeString; diff --git a/src/Contacts/PhoneNumber.m b/src/Contacts/PhoneNumber.m index da40aafe..1341bbb0 100644 --- a/src/Contacts/PhoneNumber.m +++ b/src/Contacts/PhoneNumber.m @@ -110,21 +110,24 @@ + (PhoneNumber *)tryParsePhoneNumberFromUserSpecifiedText:(NSString *)text { if ([text isEqualToString:@""]) { return nil; } - - char s[text.length + 1]; - int xx = 0; - for (NSUInteger i = 0; i < text.length; i++) { - unichar x = [text characterAtIndex:i]; - if (x == '+' || (x >= '0' && x <= '9')) { - s[xx++] = (char)x; - } - } + NSString *sanitizedString = [self removeFormattingCharacters:text]; + + return [self phoneNumberFromUserSpecifiedText:sanitizedString]; +} - s[xx] = 0; - text = [NSString stringWithUTF8String:(void *)s]; ++ (NSString *)removeFormattingCharacters:(NSString *)inputString { + char outputString[inputString.length + 1]; + int outputLength = 0; + for (NSUInteger i = 0; i < inputString.length; i++) { + unichar c = [inputString characterAtIndex:i]; + if (c == '+' || (c >= '0' && c <= '9')) { + outputString[outputLength++] = (char)c; + } + } - return [self phoneNumberFromUserSpecifiedText:text]; + outputString[outputLength] = 0; + return [NSString stringWithUTF8String:(void *)outputString]; } + (PhoneNumber *)tryParsePhoneNumberFromE164:(NSString *)text { diff --git a/tests/Contacts/PhoneNumberTest.m b/tests/Contacts/PhoneNumberTest.m new file mode 100644 index 00000000..009afbba --- /dev/null +++ b/tests/Contacts/PhoneNumberTest.m @@ -0,0 +1,50 @@ +// +// PhoneNumberTest.m +// Signal +// +// Created by Michael Kirk on 6/28/16. +// Copyright © 2016 Open Whisper Systems. All rights reserved. +// + +#import +#import "PhoneNumber.h" + +@interface PhoneNumberTest : XCTestCase + +@end + +@implementation PhoneNumberTest + +- (void)testTryParsePhoneNumberFromUserSpecifiedTextAssumesLocalRegion { + PhoneNumber *actual = [PhoneNumber tryParsePhoneNumberFromUserSpecifiedText:@"3235551234"]; + XCTAssertEqualObjects(@"+13235551234", [actual toE164]); +} + +- (void)testTryParsePhoneNumberFromUserSpecifiedTextWithExplicitRegionCode { + PhoneNumber *actual = [PhoneNumber tryParsePhoneNumberFromUserSpecifiedText:@"+33 1 70 39 38 00"]; + XCTAssertEqualObjects(@"+33170393800", [actual toE164]); +} + +- (void)testTryParsePhoneNumberFromUserSpecifiedTextWithoutPlus { + PhoneNumber *actual = [PhoneNumber tryParsePhoneNumberFromUserSpecifiedText:@"33 1 70 39 38 00"]; + + // This might not be desired, but documents existing behavior. + // You *must* include a plus when dialing outside of your locale. + XCTAssertEqualObjects(@"+133170393800", [actual toE164]); +} + +- (void)testTryParsePhoneNumberFromUserSpecifiedTextRemovesAnyFormatting { + PhoneNumber *actual = [PhoneNumber tryParsePhoneNumberFromUserSpecifiedText:@"323 555 1234"]; + XCTAssertEqualObjects(@"+13235551234", [actual toE164]); + + actual = [PhoneNumber tryParsePhoneNumberFromUserSpecifiedText:@"323-555-1234"]; + XCTAssertEqualObjects(@"+13235551234", [actual toE164]); + + actual = [PhoneNumber tryParsePhoneNumberFromUserSpecifiedText:@"323.555.1234"]; + XCTAssertEqualObjects(@"+13235551234", [actual toE164]); + + actual = [PhoneNumber tryParsePhoneNumberFromUserSpecifiedText:@"1-323-555-1234"]; + XCTAssertEqualObjects(@"+13235551234", [actual toE164]); +} + +@end