diff --git a/SignalMessaging/contacts/OWSContactsManager.h b/SignalMessaging/contacts/OWSContactsManager.h index a03c06d00..4a6f2ed70 100644 --- a/SignalMessaging/contacts/OWSContactsManager.h +++ b/SignalMessaging/contacts/OWSContactsManager.h @@ -76,7 +76,6 @@ extern NSString *const OWSContactsManagerSignalAccountsDidChangeNotification; - (BOOL)isSystemContact:(NSString *)recipientId; - (BOOL)isSystemContactWithSignalAccount:(NSString *)recipientId; - (BOOL)hasNameInSystemContactsForRecipientId:(NSString *)recipientId; -- (NSString *)displayNameForPhoneIdentifier:(nullable NSString *)identifier; - (NSString *)displayNameForSignalAccount:(SignalAccount *)signalAccount; /** diff --git a/SignalMessaging/contacts/OWSContactsManager.m b/SignalMessaging/contacts/OWSContactsManager.m index 8ef395490..d98a329a6 100644 --- a/SignalMessaging/contacts/OWSContactsManager.m +++ b/SignalMessaging/contacts/OWSContactsManager.m @@ -87,7 +87,7 @@ NSString *const OWSContactsManagerKeyNextFullIntersectionDate = @"OWSContactsMan - (void)setup { __block NSMutableArray *signalAccounts; - [self.dbReadConnection readWithBlock:^(YapDatabaseReadTransaction *_Nonnull transaction) { + [self.dbReadConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) { NSUInteger signalAccountCount = [SignalAccount numberOfKeysInCollectionWithTransaction:transaction]; OWSLogInfo(@"loading %lu signal accounts from cache.", (unsigned long)signalAccountCount); @@ -480,7 +480,7 @@ NSString *const OWSContactsManagerKeyNextFullIntersectionDate = @"OWSContactsMan } NSMutableDictionary *oldSignalAccounts = [NSMutableDictionary new]; - [self.dbReadConnection readWithBlock:^(YapDatabaseReadTransaction *_Nonnull transaction) { + [self.dbReadConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) { [SignalAccount enumerateCollectionObjectsWithTransaction:transaction usingBlock:^(id _Nonnull object, BOOL *_Nonnull stop) { @@ -585,10 +585,27 @@ NSString *const OWSContactsManagerKeyNextFullIntersectionDate = @"OWSContactsMan } - (NSString *_Nullable)cachedContactNameForRecipientId:(NSString *)recipientId +{ + SignalAccount *_Nullable signalAccount = [self fetchSignalAccountForRecipientId:recipientId]; + return [self cachedContactNameForRecipientId:recipientId signalAccount:signalAccount]; +} + +- (NSString *_Nullable)cachedContactNameForRecipientId:(NSString *)recipientId + transaction:(YapDatabaseReadTransaction *)transaction +{ + OWSAssertDebug(recipientId.length > 0); + OWSAssertDebug(transaction); + + SignalAccount *_Nullable signalAccount = + [self fetchSignalAccountForRecipientId:recipientId transaction:transaction]; + return [self cachedContactNameForRecipientId:recipientId signalAccount:signalAccount]; +} + +- (NSString *_Nullable)cachedContactNameForRecipientId:(NSString *)recipientId + signalAccount:(nullable SignalAccount *)signalAccount { OWSAssertDebug(recipientId.length > 0); - SignalAccount *_Nullable signalAccount = [self fetchSignalAccountForRecipientId:recipientId]; if (!signalAccount) { // search system contacts for no-longer-registered signal users, for which there will be no SignalAccount OWSLogDebug(@"no signal account"); @@ -723,8 +740,19 @@ NSString *const OWSContactsManagerKeyNextFullIntersectionDate = @"OWSContactsMan return [self cachedContactNameForRecipientId:recipientId]; } +- (nullable NSString *)nameFromSystemContactsForRecipientId:(NSString *)recipientId + transaction:(YapDatabaseReadTransaction *)transaction +{ + OWSAssertDebug(recipientId.length > 0); + OWSAssertDebug(transaction); + + return [self cachedContactNameForRecipientId:recipientId transaction:transaction]; +} + - (NSString *_Nonnull)displayNameForPhoneIdentifier:(NSString *_Nullable)recipientId { + OWSAssertDebug(recipientId.length > 0); + if (!recipientId) { return self.unknownContactName; } @@ -739,6 +767,26 @@ NSString *const OWSContactsManagerKeyNextFullIntersectionDate = @"OWSContactsMan return displayName; } +- (NSString *_Nonnull)displayNameForPhoneIdentifier:(NSString *_Nullable)recipientId + transaction:(YapDatabaseReadTransaction *)transaction +{ + OWSAssertDebug(recipientId.length > 0); + OWSAssertDebug(transaction); + + if (!recipientId) { + return self.unknownContactName; + } + + NSString *_Nullable displayName = [self nameFromSystemContactsForRecipientId:recipientId transaction:transaction]; + + // Fall back to just using their recipientId + if (displayName.length < 1) { + displayName = recipientId; + } + + return displayName; +} + - (NSString *_Nonnull)displayNameForSignalAccount:(SignalAccount *)signalAccount { OWSAssertDebug(signalAccount); @@ -925,7 +973,7 @@ NSString *const OWSContactsManagerKeyNextFullIntersectionDate = @"OWSContactsMan if (profileName.length > 0) { NSString *numberAndProfileNameFormat = NSLocalizedString(@"PROFILE_NAME_AND_PHONE_NUMBER_LABEL_FORMAT", @"Label text combining the phone number and profile name separated by a simple demarcation character. " - @"Phone number should be most prominent. '%1$@' is replaced with {{phone number}} and '%2$@' is replaced " + @"Phone number should be masost prominent. '%1$@' is replaced with {{phone number}} and '%2$@' is replaced " @"with {{profile name}}"); NSString *numberAndProfileName = @@ -947,7 +995,7 @@ NSString *const OWSContactsManagerKeyNextFullIntersectionDate = @"OWSContactsMan // If contact intersection hasn't completed, it might exist on disk // even if it doesn't exist in memory yet. if (!signalAccount) { - [self.dbReadConnection readWithBlock:^(YapDatabaseReadTransaction *_Nonnull transaction) { + [self.dbReadConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) { signalAccount = [SignalAccount fetchObjectWithUniqueID:recipientId transaction:transaction]; }]; } @@ -955,6 +1003,23 @@ NSString *const OWSContactsManagerKeyNextFullIntersectionDate = @"OWSContactsMan return signalAccount; } +- (nullable SignalAccount *)fetchSignalAccountForRecipientId:(NSString *)recipientId + transaction:(YapDatabaseReadTransaction *)transaction +{ + OWSAssertDebug(recipientId.length > 0); + OWSAssertDebug(transaction); + + __block SignalAccount *signalAccount = self.signalAccountMap[recipientId]; + + // If contact intersection hasn't completed, it might exist on disk + // even if it doesn't exist in memory yet. + if (!signalAccount) { + signalAccount = [SignalAccount fetchObjectWithUniqueID:recipientId transaction:transaction]; + } + + return signalAccount; +} + - (SignalAccount *)fetchOrBuildSignalAccountForRecipientId:(NSString *)recipientId { OWSAssertDebug(recipientId.length > 0); diff --git a/SignalServiceKit/src/Messages/Interactions/TSErrorMessage.m b/SignalServiceKit/src/Messages/Interactions/TSErrorMessage.m index cc901929d..f5796cc3e 100644 --- a/SignalServiceKit/src/Messages/Interactions/TSErrorMessage.m +++ b/SignalServiceKit/src/Messages/Interactions/TSErrorMessage.m @@ -125,7 +125,8 @@ NSUInteger TSErrorMessageSchemaVersion = 1; @"Shown when signal users safety numbers changed, embeds the user's {{name or phone number}}"); NSString *recipientDisplayName = - [SSKEnvironment.shared.contactsManager displayNameForPhoneIdentifier:self.recipientId]; + [SSKEnvironment.shared.contactsManager displayNameForPhoneIdentifier:self.recipientId + transaction:transaction]; return [NSString stringWithFormat:messageFormat, recipientDisplayName]; } else { // recipientId will be nil for legacy errors diff --git a/SignalServiceKit/src/Messages/Interactions/TSInfoMessage.m b/SignalServiceKit/src/Messages/Interactions/TSInfoMessage.m index 4667c3691..3b232380c 100644 --- a/SignalServiceKit/src/Messages/Interactions/TSInfoMessage.m +++ b/SignalServiceKit/src/Messages/Interactions/TSInfoMessage.m @@ -121,7 +121,8 @@ NSUInteger TSInfoMessageSchemaVersion = 1; case TSInfoMessageUserNotRegistered: if (self.unregisteredRecipientId.length > 0) { id contactsManager = SSKEnvironment.shared.contactsManager; - NSString *recipientName = [contactsManager displayNameForPhoneIdentifier:self.unregisteredRecipientId]; + NSString *recipientName = [contactsManager displayNameForPhoneIdentifier:self.unregisteredRecipientId + transaction:transaction]; return [NSString stringWithFormat:NSLocalizedString(@"ERROR_UNREGISTERED_USER_FORMAT", @"Format string for 'unregistered user' error. Embeds {{the " @"unregistered user's name or signal id}}."), diff --git a/SignalServiceKit/src/Messages/OWSDisappearingMessagesJob.m b/SignalServiceKit/src/Messages/OWSDisappearingMessagesJob.m index 4e0a15de5..8765de154 100644 --- a/SignalServiceKit/src/Messages/OWSDisappearingMessagesJob.m +++ b/SignalServiceKit/src/Messages/OWSDisappearingMessagesJob.m @@ -199,7 +199,8 @@ void AssertIsOnDisappearingMessagesQueue() NSString *remoteContactName = nil; if ([message isKindOfClass:[TSIncomingMessage class]]) { TSIncomingMessage *incomingMessage = (TSIncomingMessage *)message; - remoteContactName = [contactsManager displayNameForPhoneIdentifier:incomingMessage.messageAuthorId]; + remoteContactName = + [contactsManager displayNameForPhoneIdentifier:incomingMessage.messageAuthorId transaction:transaction]; } [self becomeConsistentWithDisappearingDuration:message.expiresInSeconds diff --git a/SignalServiceKit/src/Messages/OWSMessageManager.m b/SignalServiceKit/src/Messages/OWSMessageManager.m index 55daef3f5..514d5c3d2 100644 --- a/SignalServiceKit/src/Messages/OWSMessageManager.m +++ b/SignalServiceKit/src/Messages/OWSMessageManager.m @@ -934,7 +934,7 @@ NS_ASSUME_NONNULL_BEGIN } OWSAssertDebug(disappearingMessagesConfiguration); [disappearingMessagesConfiguration saveWithTransaction:transaction]; - NSString *name = [self.contactsManager displayNameForPhoneIdentifier:envelope.source]; + NSString *name = [self.contactsManager displayNameForPhoneIdentifier:envelope.source transaction:transaction]; OWSDisappearingConfigurationUpdateInfoMessage *message = [[OWSDisappearingConfigurationUpdateInfoMessage alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp] thread:thread @@ -1192,7 +1192,8 @@ NS_ASSUME_NONNULL_BEGIN oldGroupThread.groupModel.groupMemberIds = [newMemberIds.allObjects mutableCopy]; [oldGroupThread saveWithTransaction:transaction]; - NSString *nameString = [self.contactsManager displayNameForPhoneIdentifier:envelope.source]; + NSString *nameString = + [self.contactsManager displayNameForPhoneIdentifier:envelope.source transaction:transaction]; NSString *updateGroupInfo = [NSString stringWithFormat:NSLocalizedString(@"GROUP_MEMBER_LEFT", @""), nameString]; [[[TSInfoMessage alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp] diff --git a/SignalServiceKit/src/Protocols/ContactsManagerProtocol.h b/SignalServiceKit/src/Protocols/ContactsManagerProtocol.h index 4954610d5..bbb042786 100644 --- a/SignalServiceKit/src/Protocols/ContactsManagerProtocol.h +++ b/SignalServiceKit/src/Protocols/ContactsManagerProtocol.h @@ -9,10 +9,13 @@ NS_ASSUME_NONNULL_BEGIN @class PhoneNumber; @class SignalAccount; @class UIImage; +@class YapDatabaseReadTransaction; @protocol ContactsManagerProtocol -- (NSString *)displayNameForPhoneIdentifier:(NSString *_Nullable)phoneNumber; +- (NSString *)displayNameForPhoneIdentifier:(nullable NSString *)recipientId; +- (NSString *_Nonnull)displayNameForPhoneIdentifier:(NSString *_Nullable)recipientId + transaction:(YapDatabaseReadTransaction *)transaction; - (NSArray *)signalAccounts; - (BOOL)isSystemContact:(NSString *)recipientId; diff --git a/SignalServiceKit/src/Storage/FullTextSearchFinder.swift b/SignalServiceKit/src/Storage/FullTextSearchFinder.swift index 72691e95d..1ccf7f988 100644 --- a/SignalServiceKit/src/Storage/FullTextSearchFinder.swift +++ b/SignalServiceKit/src/Storage/FullTextSearchFinder.swift @@ -172,8 +172,8 @@ public class FullTextSearchFinder: NSObject { return recipientIndexer.index(recipientId, transaction: transaction) } - private static let recipientIndexer: SearchIndexer = SearchIndexer { (recipientId: String, _: YapDatabaseReadTransaction) in - let displayName = contactsManager.displayName(forPhoneIdentifier: recipientId) + private static let recipientIndexer: SearchIndexer = SearchIndexer { (recipientId: String, transaction: YapDatabaseReadTransaction) in + let displayName = contactsManager.displayName(forPhoneIdentifier: recipientId, transaction: transaction) let nationalNumber: String = { (recipientId: String) -> String in