From ab55e853041fb0133a5ef4f49cae6e709d407982 Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Thu, 20 Sep 2018 17:12:56 -0600 Subject: [PATCH] step 1: timestampForSorting audit, change signature No change in functionality in this commit, I just broke the signature to have a systematic audit of the callsites. Added TODO's with the plan for each call. --- .../Cells/OWSMessageHeaderView.m | 3 +- .../ConversationViewController.m | 24 ++++++++++----- .../DebugUI/DebugUIDiskUsage.m | 5 ++-- .../MediaGalleryViewController.swift | 9 ++++-- .../MessageDetailViewController.swift | 3 +- .../migrations/OWS110SortIdMigration.swift | 3 +- SignalMessaging/utils/OWSUnreadIndicator.h | 1 + SignalMessaging/utils/ThreadUtil.m | 30 ++++++++++++------- SignalServiceKit/src/Contacts/TSThread.m | 3 +- .../src/Messages/Interactions/TSInteraction.h | 4 +-- .../src/Messages/Interactions/TSInteraction.m | 6 ++-- .../src/Messages/Interactions/TSMessage.m | 3 +- .../src/Messages/OWSDisappearingMessagesJob.m | 3 +- .../src/Messages/OWSMessageSender.m | 4 ++- .../src/Messages/OWSReadReceiptManager.m | 9 +++--- .../src/Messages/OWSReadTracking.h | 2 +- .../src/Storage/OWSMediaGalleryFinder.m | 4 +-- SignalServiceKit/src/Storage/TSDatabaseView.m | 6 ++-- 18 files changed, 79 insertions(+), 43 deletions(-) diff --git a/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageHeaderView.m b/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageHeaderView.m index 73ea82277..a1f20008b 100644 --- a/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageHeaderView.m +++ b/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageHeaderView.m @@ -126,7 +126,8 @@ const CGFloat OWSMessageHeaderViewDateHeaderVMargin = 23; { OWSAssertDebug(viewItem); - NSDate *date = viewItem.interaction.dateForSorting; + // MJK FIXME - use receivedDate for clarity + NSDate *date = viewItem.interaction.dateForLegacySorting; NSString *dateString = [DateUtil formatDateForConversationDateBreaks:date].localizedUppercaseString; // Update cell to reflect changes in dynamic text. diff --git a/Signal/src/ViewControllers/ConversationView/ConversationViewController.m b/Signal/src/ViewControllers/ConversationView/ConversationViewController.m index f9bf77c06..a06f92ca4 100644 --- a/Signal/src/ViewControllers/ConversationView/ConversationViewController.m +++ b/Signal/src/ViewControllers/ConversationView/ConversationViewController.m @@ -2679,7 +2679,8 @@ typedef enum : NSUInteger { ConversationViewItem *lastViewItem = [self.viewItems lastObject]; OWSAssertDebug(lastViewItem); - if (lastViewItem.interaction.timestampForSorting > self.lastVisibleTimestamp) { + // MJK FIXME - use sortId + if (lastViewItem.interaction.timestampForLegacySorting > self.lastVisibleTimestamp) { shouldShowScrollDownButton = YES; } else if (isScrolledUp) { shouldShowScrollDownButton = YES; @@ -2778,7 +2779,8 @@ typedef enum : NSUInteger { OWSAssertIsOnMainThread(); OWSAssertDebug(message); - [self updateLastVisibleTimestamp:message.timestampForSorting]; + // MJK FIXME - use sortId + [self updateLastVisibleTimestamp:message.timestampForLegacySorting]; self.lastMessageSentDate = [NSDate new]; [self clearUnreadMessagesIndicator]; self.inputToolbar.quotedReply = nil; @@ -3875,7 +3877,8 @@ typedef enum : NSUInteger { ConversationViewItem *_Nullable lastVisibleViewItem = [self.viewItems lastObject]; if (lastVisibleViewItem) { - uint64_t lastVisibleTimestamp = lastVisibleViewItem.interaction.timestampForSorting; + // MJK FIXME - use sortId + uint64_t lastVisibleTimestamp = lastVisibleViewItem.interaction.timestampForLegacySorting; self.lastVisibleTimestamp = MAX(self.lastVisibleTimestamp, lastVisibleTimestamp); } @@ -3888,7 +3891,8 @@ typedef enum : NSUInteger { { ConversationViewItem *_Nullable lastVisibleViewItem = [self lastVisibleViewItem]; if (lastVisibleViewItem) { - uint64_t lastVisibleTimestamp = lastVisibleViewItem.interaction.timestampForSorting; + // MJK FIXME - use sortId + uint64_t lastVisibleTimestamp = lastVisibleViewItem.interaction.timestampForLegacySorting; self.lastVisibleTimestamp = MAX(self.lastVisibleTimestamp, lastVisibleTimestamp); } @@ -4935,7 +4939,9 @@ typedef enum : NSUInteger { break; } - uint64_t viewItemTimestamp = viewItem.interaction.timestampForSorting; + // MJK FIXME - should this be sentTime or receivedTime? + // we sorted by received time, but we should display sent time + uint64_t viewItemTimestamp = viewItem.interaction.timestampForLegacySorting; OWSAssertDebug(viewItemTimestamp > 0); BOOL shouldShowDate = NO; @@ -4977,7 +4983,10 @@ typedef enum : NSUInteger { // Place the unread indicator onto the first appropriate view item, // if any. - if (unreadIndicator && viewItem.interaction.timestampForSorting >= unreadIndicator.timestamp) { + // MJK FIXME - use sortId + // I'm not sure why we need a comparison here, vs. an equality. Maybe if the first unread + // message is deleted, we'd need to be sure everything still works. + if (unreadIndicator && viewItem.interaction.timestampForLegacySorting >= unreadIndicator.timestamp) { viewItem.unreadIndicator = unreadIndicator; unreadIndicator = nil; hasPlacedUnreadIndicator = YES; @@ -5127,7 +5136,8 @@ typedef enum : NSUInteger { } } - if (viewItem.interaction.timestampForSorting > collapseCutoffTimestamp) { + // MJK FIXME - investigate this more + if (viewItem.interaction.timestampForLegacySorting > collapseCutoffTimestamp) { shouldHideFooter = NO; } diff --git a/Signal/src/ViewControllers/DebugUI/DebugUIDiskUsage.m b/Signal/src/ViewControllers/DebugUI/DebugUIDiskUsage.m index 2675d3df1..c16e9194c 100644 --- a/Signal/src/ViewControllers/DebugUI/DebugUIDiskUsage.m +++ b/Signal/src/ViewControllers/DebugUI/DebugUIDiskUsage.m @@ -93,8 +93,9 @@ NS_ASSUME_NONNULL_BEGIN TSInteraction *interaction, NSUInteger index, BOOL *stop) { - NSTimeInterval ageSeconds - = fabs(interaction.dateForSorting.timeIntervalSinceNow); + // MJK FIXME - use receivedTime? + NSTimeInterval ageSeconds = fabs( + interaction.dateForLegacySorting.timeIntervalSinceNow); if (ageSeconds < maxAgeSeconds) { *stop = YES; return; diff --git a/Signal/src/ViewControllers/MediaGalleryViewController.swift b/Signal/src/ViewControllers/MediaGalleryViewController.swift index 019dc7f09..c72077d17 100644 --- a/Signal/src/ViewControllers/MediaGalleryViewController.swift +++ b/Signal/src/ViewControllers/MediaGalleryViewController.swift @@ -54,7 +54,8 @@ public struct GalleryDate: Hashable, Comparable, Equatable { let month: Int init(message: TSMessage) { - let date = message.dateForSorting() + // MJK FIXME - use `receivedTime` semantics are the same but would be clearer + let date = message.dateForLegacySorting() self.year = Calendar.current.component(.year, from: date) self.month = Calendar.current.component(.month, from: date) @@ -730,13 +731,15 @@ class MediaGalleryViewController: OWSNavigationController, MediaGalleryDataSourc Bench(title: "sorting gallery items") { galleryItems.sort { lhs, rhs -> Bool in - return lhs.message.timestampForSorting() < rhs.message.timestampForSorting() + // MJK FIXME - use sortID + return lhs.message.timestampForLegacySorting() < rhs.message.timestampForLegacySorting() } sectionDates.sort() for (date, galleryItems) in sections { sortedSections[date] = galleryItems.sorted { lhs, rhs -> Bool in - return lhs.message.timestampForSorting() < rhs.message.timestampForSorting() + // MJK FIXME - use sortID + return lhs.message.timestampForLegacySorting() < rhs.message.timestampForLegacySorting() } } } diff --git a/Signal/src/ViewControllers/MessageDetailViewController.swift b/Signal/src/ViewControllers/MessageDetailViewController.swift index 261481460..c7b6c4563 100644 --- a/Signal/src/ViewControllers/MessageDetailViewController.swift +++ b/Signal/src/ViewControllers/MessageDetailViewController.swift @@ -292,9 +292,10 @@ class MessageDetailViewController: OWSViewController, MediaGalleryDataSourceDele rows.append(sentRow) if message as? TSIncomingMessage != nil { + // MJK FIXME - expose and use `receivedTime`? rows.append(valueRow(name: NSLocalizedString("MESSAGE_METADATA_VIEW_RECEIVED_DATE_TIME", comment: "Label for the 'received date & time' field of the 'message metadata' view."), - value: DateUtil.formatPastTimestampRelativeToNow(message.timestampForSorting()))) + value: DateUtil.formatPastTimestampRelativeToNow(message.timestampForLegacySorting()))) } rows += addAttachmentMetadataRows() diff --git a/SignalMessaging/environment/migrations/OWS110SortIdMigration.swift b/SignalMessaging/environment/migrations/OWS110SortIdMigration.swift index e469d1bfd..0187c6aa1 100644 --- a/SignalMessaging/environment/migrations/OWS110SortIdMigration.swift +++ b/SignalMessaging/environment/migrations/OWS110SortIdMigration.swift @@ -29,7 +29,8 @@ class OWS110SortIdMigration: OWSDatabaseMigration { } interaction.saveNextSortId(transaction: transaction) - Logger.debug("thread: \(interaction.uniqueThreadId), timestampForSorting:\(interaction.timestampForSorting()), sortId: \(interaction.sortId)") + // Legit usage of legacy sorting for migration to new sorting + Logger.debug("thread: \(interaction.uniqueThreadId), timestampForLegacySorting:\(interaction.timestampForLegacySorting()), sortId: \(interaction.sortId)") } } } diff --git a/SignalMessaging/utils/OWSUnreadIndicator.h b/SignalMessaging/utils/OWSUnreadIndicator.h index b2d5ba9c0..142d9c28c 100644 --- a/SignalMessaging/utils/OWSUnreadIndicator.h +++ b/SignalMessaging/utils/OWSUnreadIndicator.h @@ -6,6 +6,7 @@ NS_ASSUME_NONNULL_BEGIN @interface OWSUnreadIndicator : NSObject +// MJK FIXME - do we need this timestamp column? @property (nonatomic, readonly) uint64_t timestamp; @property (nonatomic, readonly) BOOL hasMoreUnseenMessages; diff --git a/SignalMessaging/utils/ThreadUtil.m b/SignalMessaging/utils/ThreadUtil.m index 97e3534e3..89b6a7cc9 100644 --- a/SignalMessaging/utils/ThreadUtil.m +++ b/SignalMessaging/utils/ThreadUtil.m @@ -370,7 +370,8 @@ NS_ASSUME_NONNULL_BEGIN TSInteraction *_Nullable firstUnseenInteraction = [[TSDatabaseView unseenDatabaseViewExtension:transaction] firstObjectInGroup:thread.uniqueId]; if (firstUnseenInteraction) { - firstUnseenInteractionTimestamp = @(firstUnseenInteraction.timestampForSorting); + // MJK FIXME - use sortId + firstUnseenInteractionTimestamp = @(firstUnseenInteraction.timestampForLegacySorting); } } @@ -482,9 +483,10 @@ NS_ASSUME_NONNULL_BEGIN } if (existingContactOffers && !shouldHaveContactOffers) { + // MJK FIXME - use sortId OWSLogInfo(@"Removing contact offers: %@ (%llu)", existingContactOffers.uniqueId, - existingContactOffers.timestampForSorting); + existingContactOffers.timestampForLegacySorting); [existingContactOffers removeWithTransaction:transaction]; } else if (shouldHaveContactOffers) { if (existingContactOffers) { @@ -492,9 +494,10 @@ NS_ASSUME_NONNULL_BEGIN if (existingContactOffers.hasBlockOffer != shouldHaveBlockOffer || existingContactOffers.hasAddToContactsOffer != shouldHaveAddToContactsOffer || existingContactOffers.hasAddToProfileWhitelistOffer != shouldHaveAddToProfileWhitelistOffer) { + // MJK FIXME - use sortId OWSLogInfo(@"Updating stale contact offers: %@ (%llu)", existingContactOffers.uniqueId, - existingContactOffers.timestampForSorting); + existingContactOffers.timestampForLegacySorting); [existingContactOffers updateHasBlockOffer:shouldHaveBlockOffer hasAddToContactsOffer:shouldHaveAddToContactsOffer @@ -514,8 +517,10 @@ NS_ASSUME_NONNULL_BEGIN recipientId:recipientId]; [offersMessage saveWithTransaction:transaction]; - OWSLogInfo( - @"Creating contact offers: %@ (%llu)", offersMessage.uniqueId, offersMessage.timestampForSorting); + // MJK FIXME - use sortId + OWSLogInfo(@"Creating contact offers: %@ (%llu)", + offersMessage.uniqueId, + offersMessage.timestampForLegacySorting); } } @@ -595,7 +600,9 @@ NS_ASSUME_NONNULL_BEGIN return; } - if (interaction.timestampForSorting < firstUnseenInteractionTimestamp.unsignedLongLongValue) { + // MJK FIXME - use sortId + if (interaction.timestampForLegacySorting + < firstUnseenInteractionTimestamp.unsignedLongLongValue) { // By default we want the unread indicator to appear just before // the first unread message. *stop = YES; @@ -627,13 +634,15 @@ NS_ASSUME_NONNULL_BEGIN if (hasMoreUnseenMessages) { NSMutableSet *missingUnseenSafetyNumberChanges = [NSMutableSet set]; for (TSInvalidIdentityKeyErrorMessage *safetyNumberChange in blockingSafetyNumberChanges) { + // MJK FIXME - use sortId BOOL isUnseen - = safetyNumberChange.timestampForSorting >= firstUnseenInteractionTimestamp.unsignedLongLongValue; + = safetyNumberChange.timestampForLegacySorting >= firstUnseenInteractionTimestamp.unsignedLongLongValue; if (!isUnseen) { continue; } - BOOL isMissing - = safetyNumberChange.timestampForSorting < interactionAfterUnreadIndicator.timestampForSorting; + // MJK FIXME - use sortId + BOOL isMissing = safetyNumberChange.timestampForLegacySorting + < interactionAfterUnreadIndicator.timestampForLegacySorting; if (!isMissing) { continue; } @@ -658,8 +667,9 @@ NS_ASSUME_NONNULL_BEGIN unreadIndicatorPosition++; } + // MJK FIXME - use sortId, or maybe just timestamp, do we even need timestamp? dynamicInteractions.unreadIndicator = [[OWSUnreadIndicator alloc] - initUnreadIndicatorWithTimestamp:interactionAfterUnreadIndicator.timestampForSorting + initUnreadIndicatorWithTimestamp:interactionAfterUnreadIndicator.timestampForLegacySorting hasMoreUnseenMessages:hasMoreUnseenMessages missingUnseenSafetyNumberChangeCount:missingUnseenSafetyNumberChangeCount unreadIndicatorPosition:unreadIndicatorPosition diff --git a/SignalServiceKit/src/Contacts/TSThread.m b/SignalServiceKit/src/Contacts/TSThread.m index 768b1e751..023a9b2a1 100644 --- a/SignalServiceKit/src/Contacts/TSThread.m +++ b/SignalServiceKit/src/Contacts/TSThread.m @@ -355,7 +355,8 @@ NS_ASSUME_NONNULL_BEGIN self.hasEverHadMessage = YES; - NSDate *lastMessageDate = [lastMessage dateForSorting]; + // MJK FIXME - this needs to use sortId + NSDate *lastMessageDate = lastMessage.dateForLegacySorting; if (!_lastMessageDate || [lastMessageDate timeIntervalSinceDate:self.lastMessageDate] > 0) { _lastMessageDate = lastMessageDate; diff --git a/SignalServiceKit/src/Messages/Interactions/TSInteraction.h b/SignalServiceKit/src/Messages/Interactions/TSInteraction.h index 929dea0a6..5cf95122e 100644 --- a/SignalServiceKit/src/Messages/Interactions/TSInteraction.h +++ b/SignalServiceKit/src/Messages/Interactions/TSInteraction.h @@ -55,8 +55,8 @@ NSString *NSStringFromOWSInteractionType(OWSInteractionType value); filter:(BOOL (^_Nonnull)(TSInteraction *))filter withTransaction:(YapDatabaseReadTransaction *)transaction; -- (NSDate *)dateForSorting; -- (uint64_t)timestampForSorting; +- (NSDate *)dateForLegacySorting; +- (uint64_t)timestampForLegacySorting; - (NSComparisonResult)compareForSorting:(TSInteraction *)other; // "Dynamic" interactions are not messages or static events (like diff --git a/SignalServiceKit/src/Messages/Interactions/TSInteraction.m b/SignalServiceKit/src/Messages/Interactions/TSInteraction.m index c7b052e32..6434d259d 100644 --- a/SignalServiceKit/src/Messages/Interactions/TSInteraction.m +++ b/SignalServiceKit/src/Messages/Interactions/TSInteraction.m @@ -116,12 +116,12 @@ NSString *NSStringFromOWSInteractionType(OWSInteractionType value) #pragma mark Date operations -- (NSDate *)dateForSorting +- (NSDate *)dateForLegacySorting { - return [NSDate ows_dateWithMillisecondsSince1970:self.timestampForSorting]; + return [NSDate ows_dateWithMillisecondsSince1970:self.timestampForLegacySorting]; } -- (uint64_t)timestampForSorting +- (uint64_t)timestampForLegacySorting { return self.timestamp; } diff --git a/SignalServiceKit/src/Messages/Interactions/TSMessage.m b/SignalServiceKit/src/Messages/Interactions/TSMessage.m index 06ac2abe2..700a8ddf9 100644 --- a/SignalServiceKit/src/Messages/Interactions/TSMessage.m +++ b/SignalServiceKit/src/Messages/Interactions/TSMessage.m @@ -47,6 +47,7 @@ static const NSUInteger OWSMessageSchemaVersion = 4; */ @property (nonatomic, readonly) NSUInteger schemaVersion; +// MJK FIXME - update this comment // The timestamp property is populated by the envelope, // which is created by the sender. // @@ -340,7 +341,7 @@ static const NSUInteger OWSMessageSchemaVersion = 4; return self.expiresInSeconds > 0; } -- (uint64_t)timestampForSorting +- (uint64_t)timestampForLegacySorting { if ([self shouldUseReceiptDateForSorting] && self.receivedAtTimestamp > 0) { return self.receivedAtTimestamp; diff --git a/SignalServiceKit/src/Messages/OWSDisappearingMessagesJob.m b/SignalServiceKit/src/Messages/OWSDisappearingMessagesJob.m index f6e6ed087..c2502c759 100644 --- a/SignalServiceKit/src/Messages/OWSDisappearingMessagesJob.m +++ b/SignalServiceKit/src/Messages/OWSDisappearingMessagesJob.m @@ -393,7 +393,8 @@ void AssertIsOnDisappearingMessagesQueue() OWSFailDebug(@"starting old timer for message timestamp: %lu", (unsigned long)message.timestamp); // We don't know when it was actually read, so assume it was read as soon as it was received. - uint64_t readTimeBestGuess = message.timestampForSorting; + // MJK FIXME - this needs to use sortId + uint64_t readTimeBestGuess = message.timestampForLegacySorting; [self startAnyExpirationForMessage:message expirationStartedAt:readTimeBestGuess transaction:transaction]; } transaction:transaction]; diff --git a/SignalServiceKit/src/Messages/OWSMessageSender.m b/SignalServiceKit/src/Messages/OWSMessageSender.m index c8b133c53..484196e4c 100644 --- a/SignalServiceKit/src/Messages/OWSMessageSender.m +++ b/SignalServiceKit/src/Messages/OWSMessageSender.m @@ -466,8 +466,10 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; OWSAssertDebug(message.recipientIds.count == 1); [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { for (NSString *recipientId in message.sendingRecipientIds) { + // MJK FIXME - read time == creation time. (the stakes are low here, self sent messages should have + // more or less identical timestamp vs. legacyTimestampForSorting) [message updateWithReadRecipientId:recipientId - readTimestamp:message.timestampForSorting + readTimestamp:message.timestampForLegacySorting transaction:transaction]; } }]; diff --git a/SignalServiceKit/src/Messages/OWSReadReceiptManager.m b/SignalServiceKit/src/Messages/OWSReadReceiptManager.m index c55432b67..850c3f9ae 100644 --- a/SignalServiceKit/src/Messages/OWSReadReceiptManager.m +++ b/SignalServiceKit/src/Messages/OWSReadReceiptManager.m @@ -497,7 +497,8 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE // // Use `timestampForSorting` which reflects local received order, rather than `timestamp` // which reflect sender time. - [self markAsReadBeforeTimestamp:message.timestampForSorting + // MJK FIXME - use sortID + [self markAsReadBeforeTimestamp:message.timestampForLegacySorting thread:[message threadWithTransaction:transaction] readTimestamp:readTimestamp wasLocal:NO @@ -536,12 +537,12 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE return; } id possiblyRead = (id)object; - - if (possiblyRead.timestampForSorting > timestamp) { + // MJK FIXME - use sortId + if (possiblyRead.timestampForLegacySorting > timestamp) { *stop = YES; return; } - + OWSAssertDebug(!possiblyRead.read); OWSAssertDebug(possiblyRead.expireStartedAt == 0); if (!possiblyRead.read) { diff --git a/SignalServiceKit/src/Messages/OWSReadTracking.h b/SignalServiceKit/src/Messages/OWSReadTracking.h index 5686e744f..04f5d83e6 100644 --- a/SignalServiceKit/src/Messages/OWSReadTracking.h +++ b/SignalServiceKit/src/Messages/OWSReadTracking.h @@ -16,7 +16,7 @@ @property (nonatomic, readonly, getter=wasRead) BOOL read; @property (nonatomic, readonly) uint64_t expireStartedAt; -@property (nonatomic, readonly) uint64_t timestampForSorting; +@property (nonatomic, readonly) uint64_t timestampForLegacySorting; @property (nonatomic, readonly) NSString *uniqueThreadId; diff --git a/SignalServiceKit/src/Storage/OWSMediaGalleryFinder.m b/SignalServiceKit/src/Storage/OWSMediaGalleryFinder.m index 4c9c0a11e..6eb166957 100644 --- a/SignalServiceKit/src/Storage/OWSMediaGalleryFinder.m +++ b/SignalServiceKit/src/Storage/OWSMediaGalleryFinder.m @@ -137,8 +137,8 @@ static NSString *const OWSMediaGalleryFinderExtensionName = @"OWSMediaGalleryFin return NSOrderedSame; } TSMessage *message2 = (TSMessage *)object2; - - return [@(message1.timestampForSorting) compare:@(message2.timestampForSorting)]; + // MJK FIXME - this needs to use sortId + return [@(message1.timestampForLegacySorting) compare:@(message2.timestampForLegacySorting)]; }]; YapDatabaseViewGrouping *grouping = [YapDatabaseViewGrouping withObjectBlock:^NSString * _Nullable(YapDatabaseReadTransaction * _Nonnull transaction, NSString * _Nonnull collection, NSString * _Nonnull key, id _Nonnull object) { diff --git a/SignalServiceKit/src/Storage/TSDatabaseView.m b/SignalServiceKit/src/Storage/TSDatabaseView.m index c1669e512..00b4af302 100644 --- a/SignalServiceKit/src/Storage/TSDatabaseView.m +++ b/SignalServiceKit/src/Storage/TSDatabaseView.m @@ -204,8 +204,10 @@ NSString *const TSLazyRestoreAttachmentsGroup = @"TSLazyRestoreAttachmentsGroup" TSInteraction *interaction1 = (TSInteraction *)object1; TSInteraction *interaction2 = (TSInteraction *)object2; - uint64_t timestamp1 = interaction1.timestampForSorting; - uint64_t timestamp2 = interaction2.timestampForSorting; + // Legit usage of timestampForLegacySorting since we're registering the + // legacy extension + uint64_t timestamp1 = interaction1.timestampForLegacySorting; + uint64_t timestamp2 = interaction2.timestampForLegacySorting; if (timestamp1 > timestamp2) { return NSOrderedDescending;