Permalink
Browse files

Added support for better buddy search with yap and search controller

  • Loading branch information...
1 parent 77dba05 commit 6d00310ac838f53a076b0aa3294d129c4d13df55 @davidchiles davidchiles committed Apr 27, 2016
@@ -14,6 +14,7 @@
633107201A16D1A300C17BAE /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 633106661A16D1A300C17BAE /* LaunchScreen.xib */; };
6331072B1A16D1F200C17BAE /* DemoImages.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 633107291A16D1F200C17BAE /* DemoImages.xcassets */; };
6331072C1A16D1F200C17BAE /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6331072A1A16D1F200C17BAE /* Images.xcassets */; };
+ 63363FAE1CCAE29B00B0C720 /* OTRYapExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63363FAD1CCAE29B00B0C720 /* OTRYapExtensions.swift */; };
634043191BD5AAF300ECA95A /* OTRBuddyEnums.h in Headers */ = {isa = PBXBuildFile; fileRef = 634043181BD5AAF300ECA95A /* OTRBuddyEnums.h */; };
6340431B1BD5BCD800ECA95A /* OTRXMPPRoomMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6340431A1BD5BCD800ECA95A /* OTRXMPPRoomMessage.swift */; };
6340431D1BD5BD0400ECA95A /* OTRXMPPRoomOccupant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6340431C1BD5BD0400ECA95A /* OTRXMPPRoomOccupant.swift */; };
@@ -679,6 +680,7 @@
6336209B1A76E88C006E8739 /* OTRVideoItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OTRVideoItem.m; sourceTree = "<group>"; };
6336209D1A76E89A006E8739 /* OTRAudioItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OTRAudioItem.h; sourceTree = "<group>"; };
6336209E1A76E89A006E8739 /* OTRAudioItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OTRAudioItem.m; sourceTree = "<group>"; };
+ 63363FAD1CCAE29B00B0C720 /* OTRYapExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OTRYapExtensions.swift; sourceTree = "<group>"; };
633821C81BA8D48D0019C906 /* PushContainers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PushContainers.swift; sourceTree = "<group>"; };
633AF2F81A7C3DBB0030A3FF /* OTRAudioSessionManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OTRAudioSessionManager.h; sourceTree = "<group>"; };
633AF2F91A7C3DBC0030A3FF /* OTRAudioSessionManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OTRAudioSessionManager.m; sourceTree = "<group>"; };
@@ -943,6 +945,7 @@
children = (
63CBD67F1C642B6B00AC6D1F /* YapExtensions */,
631098B01BD6FED000494A47 /* YapDatabse+ChatSecure.swift */,
+ 63363FAD1CCAE29B00B0C720 /* OTRYapExtensions.swift */,
634364221CC192F1009E169F /* YapDatabaseConstants.swift */,
63C0C4421BE010B00086B529 /* YapDatabaseReadTransaction+ChatSecure.swift */,
D9315CB11BB606890077D2EE /* ShareController.swift */,
@@ -2181,6 +2184,7 @@
D93DDA951BA79A2400CD8331 /* OTRXMPPManager.m in Sources */,
D93DDA961BA79A2400CD8331 /* OTRXMPPProxyStream.m in Sources */,
D9AE3A331BA8D9AB00255537 /* OTRConstants.m in Sources */,
+ 63363FAE1CCAE29B00B0C720 /* OTRYapExtensions.swift in Sources */,
D93DDA971BA79A2400CD8331 /* OTRXMPPTorManager.m in Sources */,
D93DDA981BA79A2400CD8331 /* OTRYapDatabaseRosterStorage.m in Sources */,
D93DDA991BA79A2400CD8331 /* OTRXMPPServerInfo.m in Sources */,
@@ -23,7 +23,7 @@
#import "NSFileManager+ChatSecure.h"
@import OTRAssets;
@import YapDatabase.YapDatabaseSecondaryIndex;
-@import YapDatabase.YapDatabaseActionManager;
+@import YapDatabase.YapDatabaseSearchResultsView;
#import "OTRLanguageManager.h"
#import <ChatSecureCore/ChatSecureCore-Swift.h>
@@ -132,10 +132,18 @@ - (BOOL)setupYapDatabaseWithName:(NSString *)name
[OTRDatabaseView registerAllAccountsDatabaseView];
[OTRDatabaseView registerConversationDatabaseView];
[OTRDatabaseView registerChatDatabaseView];
- [OTRDatabaseView registerBuddyNameSearchDatabaseView];
[OTRDatabaseView registerAllBuddiesDatabaseView];
[OTRDatabaseView registerAllSubscriptionRequestsView];
[OTRDatabaseView registerUnreadMessagesView];
+
+ //Register Buddy username & displayName FTS and corresponding view
+ YapDatabaseFullTextSearch *buddyFTS = [OTRYapExtensions buddyFTS];
+ NSString *FTSName = [YapDatabaseConstants extensionName:DatabaseExtensionNameBuddyFTSExtensionName];
+ NSString *AllBuddiesName = OTRAllBuddiesDatabaseViewExtensionName;
+ [self.database registerExtension:buddyFTS withName:FTSName];
+ YapDatabaseSearchResultsView *searchResultsView = [[YapDatabaseSearchResultsView alloc] initWithFullTextSearchName:FTSName parentViewName:AllBuddiesName versionTag:nil options:nil];
+ NSString* viewName = [YapDatabaseConstants extensionName:DatabaseExtensionNameBuddySearchResultsViewName];
+ [self.database registerExtension:searchResultsView withName:viewName];
});
if (self.database != nil) {
@@ -14,7 +14,6 @@
extern NSString *OTRConversationDatabaseViewExtensionName;
extern NSString *OTRChatDatabaseViewExtensionName;
extern NSString *OTRAllAccountDatabaseViewExtensionName;
-extern NSString *OTRBuddyNameSearchDatabaseViewExtensionName;
extern NSString *OTRAllBuddiesDatabaseViewExtensionName;
extern NSString *OTRAllSubscriptionRequestsViewExtensionName;
extern NSString *OTRAllPushAccountInfoViewExtensionName;
@@ -47,8 +46,6 @@ extern NSString *OTRPushTokenGroup;
*/
+ (BOOL)registerChatDatabaseView;
-+ (BOOL)registerBuddyNameSearchDatabaseView;
-
+ (BOOL)registerAllBuddiesDatabaseView;
+ (BOOL)registerAllSubscriptionRequestsView;
@@ -20,7 +20,6 @@
NSString *OTRConversationGroup = @"Conversation";
NSString *OTRConversationDatabaseViewExtensionName = @"OTRConversationDatabaseViewExtensionName";
NSString *OTRChatDatabaseViewExtensionName = @"OTRChatDatabaseViewExtensionName";
-NSString *OTRBuddyNameSearchDatabaseViewExtensionName = @"OTRBuddyBuddyNameSearchDatabaseViewExtensionName";
NSString *OTRAllBuddiesDatabaseViewExtensionName = @"OTRAllBuddiesDatabaseViewExtensionName";
NSString *OTRAllSubscriptionRequestsViewExtensionName = @"AllSubscriptionRequestsViewExtensionName";
NSString *OTRAllPushAccountInfoViewExtensionName = @"OTRAllPushAccountInfoViewExtensionName";
@@ -170,36 +169,6 @@ + (BOOL)registerChatDatabaseView
return [[OTRDatabaseManager sharedInstance].database registerExtension:view withName:OTRChatDatabaseViewExtensionName sendNotification:YES];
}
-+ (BOOL)registerBuddyNameSearchDatabaseView
-{
- if ([[OTRDatabaseManager sharedInstance].database registeredExtension:OTRBuddyNameSearchDatabaseViewExtensionName]) {
- return YES;
- }
-
- NSArray *propertiesToIndex = @[OTRBuddyAttributes.username,OTRBuddyAttributes.displayName];
-
- YapDatabaseFullTextSearchHandler *searchHandler = [YapDatabaseFullTextSearchHandler withObjectBlock:^(NSMutableDictionary *dict, NSString *collection, NSString *key, id object) {
- if ([object isKindOfClass:[OTRBuddy class]])
- {
- OTRBuddy *buddy = (OTRBuddy *)object;
-
- if([buddy.username length]) {
- [dict setObject:buddy.username forKey:OTRBuddyAttributes.username];
- }
-
- if ([buddy.displayName length]) {
- [dict setObject:buddy.displayName forKey:OTRBuddyAttributes.displayName];
- }
-
-
- }
- }];
-
- YapDatabaseFullTextSearch *fullTextSearch = [[YapDatabaseFullTextSearch alloc] initWithColumnNames:propertiesToIndex handler:searchHandler];
-
- return [[OTRDatabaseManager sharedInstance].database registerExtension:fullTextSearch withName:OTRBuddyNameSearchDatabaseViewExtensionName sendNotification:YES];
-}
-
+ (BOOL)registerAllBuddiesDatabaseView
{
if ([[OTRDatabaseManager sharedInstance].database registeredExtension:OTRAllBuddiesDatabaseViewExtensionName]) {
@@ -94,7 +94,7 @@ public class OTRSplitViewCoordinator: NSObject, OTRConversationViewControllerDel
//MARK: OTRComposeViewControllerDelegate Methods
public func controller(viewController: OTRComposeViewController, didSelectBuddies buddies: [String]?, accountId: String?, name: String?) {
- viewController .dismissViewControllerAnimated(true) { () -> Void in
+ self.splitViewController?.dismissViewControllerAnimated(true) { () -> Void in
guard let buds = buddies else {
return
@@ -113,6 +113,10 @@ public class OTRSplitViewCoordinator: NSObject, OTRConversationViewControllerDel
}
}
}
+
+ public func controllerDidCancel(viewController: OTRComposeViewController) {
+ self.splitViewController?.dismissViewControllerAnimated(true, completion: nil)
+ }
}
/*
@@ -0,0 +1,41 @@
+//
+// OTRYapExtensions.swift
+// ChatSecure
+//
+// Created by David Chiles on 4/22/16.
+// Copyright © 2016 Chris Ballinger. All rights reserved.
+//
+
+import Foundation
+import YapDatabase.YapDatabaseFullTextSearch
+import YapDatabase.YapDatabaseSearchResultsView
+
+public class OTRYapExtensions:NSObject {
+
+ /// Creates a FTS extension on the buddy's username and display name
+ public class func buddyFTS() -> YapDatabaseFullTextSearch {
+
+ let usernameColumnName = BuddyFTSColumnName.Username.name()
+ let displayNameColumnName = BuddyFTSColumnName.DisplayName.name()
+
+ let searchHandler = YapDatabaseFullTextSearchHandler.withObjectBlock { (dict, collection, key, object) in
+ guard let buddy = object as? OTRBuddy else {
+ return
+ }
+
+ if let username = buddy.username {
+ dict.setObject(username, forKey: usernameColumnName)
+ }
+
+ if let displayNme = buddy.displayName {
+ dict.setObject(displayNme, forKey: displayNameColumnName)
+ }
+
+ }
+
+ let columnNames = [usernameColumnName,displayNameColumnName]
+
+ return YapDatabaseFullTextSearch(columnNames: columnNames, handler: searchHandler)
+
+ }
+}
@@ -27,6 +27,11 @@ public struct keyCollectionPair {
}
}
+private enum ViewGroups {
+ case Array([String])
+ case Block(YapDatabaseViewMappingGroupFilter, YapDatabaseViewMappingGroupSort)
+}
+
public class OTRYapKeyCollectionHandler:NSObject {
var storage = Dictionary<String, keyCollectionPair>()
@@ -47,17 +52,11 @@ public class OTRYapViewHandler: NSObject {
var notificationToken:NSObjectProtocol? = nil
public var viewName:String? = nil
- public var groups:[String]? = nil
+ private var groups:ViewGroups? = nil
public weak var delegate:OTRYapViewHandlerDelegateProtocol? = nil
public let keyCollectionObserver = OTRYapKeyCollectionHandler()
- public var mappings:YapDatabaseViewMappings? {
- didSet {
- self.databaseConnection.asyncReadWithBlock { (transaction) -> Void in
- self.mappings?.updateWithTransaction(transaction)
- }
- }
- }
+ public var mappings:YapDatabaseViewMappings?
public var databaseConnection:YapDatabaseConnection {
didSet {
@@ -86,20 +85,46 @@ public class OTRYapViewHandler: NSObject {
public func setup(view:String,groups:[String]) {
self.viewName = view
- self.groups = groups
+ let groupsArray = ViewGroups.Array(groups)
+ self.groups = groupsArray
self.mappings = nil;
- self.setupMappings(view, groups: groups);
+ self.setupMappings(view, groups: groupsArray);
+ }
+
+ public func setup(view:String, groupBlock:YapDatabaseViewMappingGroupFilter, sortBlock:YapDatabaseViewMappingGroupSort) {
+ self.viewName = view
+ let groups = ViewGroups.Block(groupBlock,sortBlock)
+ self.groups = groups
+ self.mappings = nil
+ self.setupMappings(view, groups: groups)
}
- func setupMappings(view:String,groups:[String]) {
- self.databaseConnection.asyncReadWithBlock({ (transaction) -> Void in
+ public func groupsArray() -> [String]? {
+ guard let groups = self.groups else {
+ return nil
+ }
+ switch groups {
+ case .Array(let array): return array
+ default: return nil
+ }
+ }
+
+ private func setupMappings(view:String,groups:ViewGroups) {
+
+ self.databaseConnection.readWithBlock({ (transaction) in
+ // Check if extensions exists. If not then don't setup. https://github.com/yapstudios/YapDatabase/issues/203
if let _ = transaction.ext(view) {
- self.mappings = YapDatabaseViewMappings(groups: groups, view: view)
- }
- }, completionQueue: dispatch_get_main_queue()) { () -> Void in
- if(self.mappings != nil) {
- self.delegate?.didSetupMappings?(self)
+ switch groups {
+ case .Array(let array):
+ self.mappings = YapDatabaseViewMappings(groups: array, view: view)
+ case .Block(let filterBlock, let sortBlock):
+ self.mappings = YapDatabaseViewMappings(groupFilterBlock: filterBlock, sortBlock: sortBlock, view: view)
}
+ self.mappings?.updateWithTransaction(transaction)
+ }
+ })
+ if(self.mappings != nil) {
+ self.delegate?.didSetupMappings?(self)
}
}
@@ -128,8 +153,6 @@ public class OTRYapViewHandler: NSObject {
func yapDatbaseModified(notification:NSNotification) {
let notifications = self.databaseConnection.beginLongLivedReadTransaction()
- //There are no mappings so we need to set them up first
- //TODO: Some sort of check if the view is registered
guard let mappings = self.mappings else {
if let view = self.viewName {
if let groups = self.groups {
@@ -147,13 +170,12 @@ public class OTRYapViewHandler: NSObject {
var rowChanges:NSArray? = nil
databaseView.getSectionChanges(&sectionChanges, rowChanges: &rowChanges, forNotifications: notifications, withMappings: mappings)
-
- if let sc = sectionChanges as? [YapDatabaseViewSectionChange] {
- if let rc = rowChanges as? [YapDatabaseViewRowChange] {
- if sc.count > 0 || rc.count > 0 {
- self.delegate?.didReceiveChanges?(self, sectionChanges: sc, rowChanges: rc)
- }
- }
+
+ let sc = sectionChanges as? [YapDatabaseViewSectionChange] ?? [YapDatabaseViewSectionChange]()
+ let rc = rowChanges as? [YapDatabaseViewRowChange] ?? [YapDatabaseViewRowChange]()
+
+ if sc.count > 0 || rc.count > 0 {
+ self.delegate?.didReceiveChanges?(self, sectionChanges: sc, rowChanges: rc)
}
for (_,value) in self.keyCollectionObserver.storage {
@@ -78,7 +78,7 @@ - (NSString *)joinRoom:(XMPPJID *)jid withNickname:(NSString *)name subject:(NSS
//Update view mappings with this room
- NSArray *groups = self.unsentMessagesViewHandler.groups;
+ NSArray *groups = [self.unsentMessagesViewHandler groupsArray];
if (!groups) {
groups = [[NSArray alloc] init];
}
@@ -15,6 +15,8 @@ import Foundation
case RelationshipExtensionName
case ActionManagerName
case SecondaryIndexName
+ case BuddyFTSExtensionName
+ case BuddySearchResultsViewName
public func name() -> String {
switch self {
@@ -24,6 +26,8 @@ import Foundation
case RelationshipExtensionName: return "OTRYapDatabaseRelationshipName"
case ActionManagerName: return "OTRYapDatabaseActionManager"
case SecondaryIndexName: return "OTRYapDatabseMessageIdSecondaryIndexExtension"
+ case BuddyFTSExtensionName: return "OTRBuddyBuddyNameSearchDatabaseViewExtensionName"
+ case BuddySearchResultsViewName: return "DatabaseExtensionName.BuddySearchResultsView"
}
}
}
@@ -64,6 +68,18 @@ import Foundation
}
}
+@objc public enum BuddyFTSColumnName:Int {
+ case Username
+ case DisplayName
+
+ public func name() -> String {
+ switch self {
+ case Username: return "username"
+ case DisplayName: return "displayName"
+ }
+ }
+}
+
/// This is for briding to obj-c. Looking for a better way of using swift enums and stirngs.
@objc public class YapDatabaseConstants: NSObject {
@@ -83,4 +99,8 @@ import Foundation
return notificationKeyName.name()
}
+ public class func buddyFTSColumnName(columnName:BuddyFTSColumnName) -> String {
+ return columnName.name()
+ }
+
}
@@ -10,20 +10,27 @@
@class OTRBuddy;
@class OTRComposeViewController;
+@class OTRAccount;
@protocol OTRComposeViewControllerDelegate <NSObject>
+@required
/**
This method is called when the view controller 'done' button is pressed. Sends all the selected buddies the accountId to use and an optional name for groups.
*/
- (void)controller:(nonnull OTRComposeViewController *)viewController didSelectBuddies:(nullable NSArray<NSString *> *)buddies accountId:(nullable NSString *)accountId name:(nullable NSString *)name;
+/**
+ This method is called when the view controller's cacnel button is pressed and should be dismissed and no action taken.
+ */
+- (void)controllerDidCancel:(nonnull OTRComposeViewController *)viewController;
+
@end
@interface OTRComposeViewController : UIViewController
-@property (nonatomic, weak) id<OTRComposeViewControllerDelegate> delegate;
+@property (nonatomic, weak, nullable) id<OTRComposeViewControllerDelegate> delegate;
-- (void)addBuddy:(NSArray *)accountsAbleToAddBuddies;
+- (void)addBuddy:(nullable NSArray <OTRAccount *>*)accountsAbleToAddBuddies;
@end
Oops, something went wrong.

0 comments on commit 6d00310

Please sign in to comment.