diff --git a/Signal/src/ConversationSearch.swift b/Signal/src/ConversationSearch.swift index ebfc27fe0..85cbc0085 100644 --- a/Signal/src/ConversationSearch.swift +++ b/Signal/src/ConversationSearch.swift @@ -82,11 +82,12 @@ extension ConversationSearchController: UISearchResultsUpdating { public func updateSearchResults(for searchController: UISearchController) { Logger.verbose("searchBar.text: \( searchController.searchBar.text ?? "")") - guard let searchText = searchController.searchBar.text?.stripped else { + guard let rawSearchText = searchController.searchBar.text?.stripped else { self.resultsBar.updateResults(resultSet: nil) self.delegate?.conversationSearchController(self, didUpdateSearchResults: nil) return } + let searchText = FullTextSearchFinder.normalize(text: rawSearchText) BenchManager.startEvent(title: "Conversation Search", eventId: searchText) guard searchText.count >= ConversationSearchController.kMinimumSearchTextLength else { diff --git a/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageBubbleView.m b/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageBubbleView.m index d97b87c8f..1e87f7043 100644 --- a/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageBubbleView.m +++ b/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageBubbleView.m @@ -708,10 +708,12 @@ NS_ASSUME_NONNULL_BEGIN initWithString:text attributes:@{ NSFontAttributeName : font, NSForegroundColorAttributeName : textColor }]; if (searchText.length >= ConversationSearchController.kMinimumSearchTextLength) { + NSString *searchableText = [FullTextSearchFinder normalizeWithText:searchText]; NSError *error; - NSRegularExpression *regex = [[NSRegularExpression alloc] initWithPattern:searchText - options:NSRegularExpressionCaseInsensitive - error:&error]; + NSRegularExpression *regex = + [[NSRegularExpression alloc] initWithPattern:[NSRegularExpression escapedPatternForString:searchableText] + options:NSRegularExpressionCaseInsensitive + error:&error]; OWSAssertDebug(error == nil); for (NSTextCheckingResult *match in [regex matchesInString:text options:NSMatchingWithoutAnchoringBounds range:NSMakeRange(0, text.length)]) { diff --git a/Signal/src/ViewControllers/ConversationView/ConversationViewController.m b/Signal/src/ViewControllers/ConversationView/ConversationViewController.m index 05924083e..2860fcc93 100644 --- a/Signal/src/ViewControllers/ConversationView/ConversationViewController.m +++ b/Signal/src/ViewControllers/ConversationView/ConversationViewController.m @@ -4210,7 +4210,16 @@ typedef enum : NSUInteger { // restore first responder to VC [self becomeFirstResponder]; - [self reloadInputViews]; + if (@available(iOS 10, *)) { + [self reloadInputViews]; + } else { + // We want to change the inputAccessoryView from SearchResults -> MessageInput + // reloading too soon on an old iOS9 device caused the inputAccessoryView to go from + // SearchResults -> MessageInput -> SearchResults + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + [self reloadInputViews]; + }); + } } #pragma mark ConversationSearchControllerDelegate diff --git a/SignalServiceKit/src/Storage/FullTextSearchFinder.swift b/SignalServiceKit/src/Storage/FullTextSearchFinder.swift index 00b64dd11..90d680ab8 100644 --- a/SignalServiceKit/src/Storage/FullTextSearchFinder.swift +++ b/SignalServiceKit/src/Storage/FullTextSearchFinder.swift @@ -138,6 +138,7 @@ public class FullTextSearchFinder: NSObject { // This is a hot method, especially while running large migrations. // Changes to it should go through a profiler to make sure large migrations // aren't adversely affected. + @objc public class func normalize(text: String) -> String { // 1. Filter out invalid characters. let filtered = text.removeCharacters(characterSet: charactersToRemove)