From 1a1a043b27274d69e38fc8e2798de7d3da5c5799 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Wed, 2 May 2018 14:13:55 -0400 Subject: [PATCH] Format phone numbers of contacts. --- .../ContactViewController.swift | 26 ++++-------- .../Cells/OWSContactShareView.m | 2 +- SignalServiceKit/src/Contacts/PhoneNumber.h | 3 +- SignalServiceKit/src/Contacts/PhoneNumber.m | 41 ++++++++++++++++++- 4 files changed, 52 insertions(+), 20 deletions(-) diff --git a/Signal/src/ViewControllers/ContactViewController.swift b/Signal/src/ViewControllers/ContactViewController.swift index b52e81c89..029e25db3 100644 --- a/Signal/src/ViewControllers/ContactViewController.swift +++ b/Signal/src/ViewControllers/ContactViewController.swift @@ -209,19 +209,7 @@ class ContactViewController: OWSViewController, CNContactViewControllerDelegate colorSeed: contact.displayName, diameter: UInt(avatarSize), contactsManager: contactsManager) -// [[OWSContactAvatarBuilder alloc] initWithNonSignalName:self.contactShare.displayName -// colorSeed:self.contactShare.displayName -// diameter:(NSUInteger)self.iconSize -// contactsManager:[Environment current].contactsManager]; avatarView.image = avatarBuilder.build() -// [avatarView autoSetDimension:ALDimensionWidth toSize:self.iconSize]; -// [avatarView autoSetDimension:ALDimensionHeight toSize:self.iconSize]; -// [avatarView setCompressionResistanceHigh]; -// [avatarView setContentHuggingHigh]; - -// let avatarView = UIView.container() -// avatarView.backgroundColor = UIColor.ows_materialBlue -// avatarView.layer.cornerRadius = avatarSize * 0.5 topView.addSubview(avatarView) avatarView.autoPin(toTopLayoutGuideOf: self, withInset: 20) avatarView.autoHCenterInSuperview() @@ -243,7 +231,7 @@ class ContactViewController: OWSViewController, CNContactViewControllerDelegate if let firstPhoneNumber = contact.phoneNumbers.first { let phoneNumberLabel = UILabel() - phoneNumberLabel.text = firstPhoneNumber.phoneNumber + phoneNumberLabel.text = PhoneNumber.bestEffortFormatE164(asLocalizedPhoneNumber: firstPhoneNumber.phoneNumber) phoneNumberLabel.font = UIFont.ows_dynamicTypeCaption2 phoneNumberLabel.textColor = UIColor.black phoneNumberLabel.lineBreakMode = .byTruncatingTail @@ -376,9 +364,11 @@ class ContactViewController: OWSViewController, CNContactViewControllerDelegate // } for phoneNumber in contact.phoneNumbers { - // TODO: Try to format the phone number nicely. + let formattedPhoneNumber = + PhoneNumber.bestEffortFormatE164(asLocalizedPhoneNumber: phoneNumber.phoneNumber) + addRow(createNameValueRow(name: phoneNumber.localizedLabel(), - value: phoneNumber.phoneNumber, + value: formattedPhoneNumber, actionBlock: { guard let url = NSURL(string: "tel:\(phoneNumber.phoneNumber)") else { owsFail("\(ContactViewController.logTag) could not open phone number.") @@ -428,7 +418,7 @@ class ContactViewController: OWSViewController, CNContactViewControllerDelegate return row } - private func createNameValueRow(name: String, value: String, actionBlock : @escaping () -> Void) -> UIView { + private func createNameValueRow(name: String, value: String?, actionBlock : @escaping () -> Void) -> UIView { let row = TappableView(actionBlock: actionBlock) row.layoutMargins.left = 0 row.layoutMargins.right = 0 @@ -444,7 +434,9 @@ class ContactViewController: OWSViewController, CNContactViewControllerDelegate nameLabel.autoPinTrailingToSuperviewMargin(withInset: hMargin) let valueLabel = UILabel() - valueLabel.text = value + if let value = value { + valueLabel.text = value + } valueLabel.font = UIFont.ows_dynamicTypeCaption1 valueLabel.textColor = UIColor.ows_materialBlue valueLabel.lineBreakMode = .byTruncatingTail diff --git a/Signal/src/ViewControllers/ConversationView/Cells/OWSContactShareView.m b/Signal/src/ViewControllers/ConversationView/Cells/OWSContactShareView.m index 7001104df..8dcb55b3a 100644 --- a/Signal/src/ViewControllers/ConversationView/Cells/OWSContactShareView.m +++ b/Signal/src/ViewControllers/ConversationView/Cells/OWSContactShareView.m @@ -136,7 +136,7 @@ NS_ASSUME_NONNULL_BEGIN NSString *_Nullable firstPhoneNumber = self.contactShare.phoneNumbers.firstObject.phoneNumber; if (firstPhoneNumber.length > 0) { UILabel *bottomLabel = [UILabel new]; - bottomLabel.text = firstPhoneNumber; + bottomLabel.text = [PhoneNumber bestEffortFormatE164AsLocalizedPhoneNumber:firstPhoneNumber]; // TODO: bottomLabel.textColor = [UIColor ows_darkGrayColor]; bottomLabel.lineBreakMode = NSLineBreakByTruncatingTail; diff --git a/SignalServiceKit/src/Contacts/PhoneNumber.h b/SignalServiceKit/src/Contacts/PhoneNumber.h index 2d717bc9c..72e0e2d71 100644 --- a/SignalServiceKit/src/Contacts/PhoneNumber.h +++ b/SignalServiceKit/src/Contacts/PhoneNumber.h @@ -1,5 +1,5 @@ // -// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. // #define COUNTRY_CODE_PREFIX @"+" @@ -30,6 +30,7 @@ + (NSString *)bestEffortFormatPartialUserSpecifiedTextToLookLikeAPhoneNumber:(NSString *)input; + (NSString *)bestEffortFormatPartialUserSpecifiedTextToLookLikeAPhoneNumber:(NSString *)input withSpecifiedCountryCodeString:(NSString *)countryCodeString; ++ (NSString *)bestEffortFormatE164AsLocalizedPhoneNumber:(NSString *)phoneNumber; + (NSString *)regionCodeFromCountryCodeString:(NSString *)countryCodeString; diff --git a/SignalServiceKit/src/Contacts/PhoneNumber.m b/SignalServiceKit/src/Contacts/PhoneNumber.m index ce78fdd19..770affee2 100644 --- a/SignalServiceKit/src/Contacts/PhoneNumber.m +++ b/SignalServiceKit/src/Contacts/PhoneNumber.m @@ -1,5 +1,5 @@ // -// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. // #import "PhoneNumber.h" @@ -119,6 +119,45 @@ static NSString *const RPDefaultsKeyPhoneNumberCanonical = @"RPDefaultsKeyPhoneN return result; } ++ (NSString *)formatIntAsEN:(int)value +{ + static NSNumberFormatter *formatter = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + formatter = [NSNumberFormatter new]; + formatter.locale = [NSLocale localeWithLocaleIdentifier:@"en_US"]; + }); + return [formatter stringFromNumber:@(value)]; +} + ++ (NSString *)bestEffortFormatE164AsLocalizedPhoneNumber:(NSString *)phoneNumber +{ + OWSAssert(phoneNumber); + + PhoneNumber *_Nullable parsedPhoneNumber = [self tryParsePhoneNumberFromE164:phoneNumber]; + if (!parsedPhoneNumber) { + DDLogWarn(@"%@ could not parse phone number.", self.logTag); + return phoneNumber; + } + NSNumber *_Nullable countryCode = [parsedPhoneNumber getCountryCode]; + if (!countryCode) { + DDLogWarn(@"%@ parsed phone number has no country code.", self.logTag); + return phoneNumber; + } + NSString *countryCodeString = [self formatIntAsEN:countryCode.intValue]; + if (countryCodeString.length < 1) { + DDLogWarn(@"%@ invalid country code.", self.logTag); + return phoneNumber; + } + NSString *_Nullable formattedPhoneNumber = + [self bestEffortFormatPartialUserSpecifiedTextToLookLikeAPhoneNumber:phoneNumber + withSpecifiedRegionCode:countryCodeString]; + if (!countryCode) { + DDLogWarn(@"%@ could not format phone number.", self.logTag); + return phoneNumber; + } + return formattedPhoneNumber; +} + (NSString *)regionCodeFromCountryCodeString:(NSString *)countryCodeString { NBPhoneNumberUtil *phoneUtil = [PhoneNumberUtil sharedUtil].nbPhoneNumberUtil;