iOS應用內搜索CoreSpotlight使用

點擊下載 Demo

一、Core Spotlight 簡介

iOS9 推出了 Core Spotlight 框架,這個框架可以為 iOS 的搜索 App 內部的數據,能夠使我們在 iPhone 上下拉出現得搜索框中,搜索我們使用的 App 里面的內容。它創建的索引存儲在設備上,不與Apple共享,也不能被其他應用或者設備訪問。
Apple的指南中特別提到Core Spotlight創建的索引最好在幾千的數量級別之下。索引太多很有可能會帶來性能問題。

應用內搜索示例

二、添加索引

1、引用 spotlight 頭文件

在需要的地方引用以下頭文件:

 #import <CoreSpotlight/CoreSpotlight.h>
2、創建 CSSearchableItemAttributeSet 對象

應用內搜索,想搜索到多少個界面就要創建多少個set ,每個set都要對應一個 CSSearchableItem 對象。

 CSSearchableItemAttributeSet *set =
 [[CSSearchableItemAttributeSet alloc] initWithItemContentType:@"ContentType"];

然后就可以根據需求設置不同的搜索樣式圖,效果如上圖所示。下面列取幾種常用設置

基本展示:

set.title = @"基本展示";
set.contentDescription = @"我是基本展示詳情,包含標題和詳情描述。這里沒設置圖片,默認展示 App icon";
// 搜索關鍵詞務必要設置,不然會搜索不到
set.contactKeywords = @[@"我是", @"基本", @"展示"];

圖片與星評:

set.title = @"圖片與星評";
set.contentDescription = @"我是圖片與星評展示,設置的圖片展示的效果系統并不會給你處理,設置什么樣的圖片就會展示什么樣的圖片。還可以設置星評";
set.contactKeywords = @[@"我是", @"圖片", @"星評"];
set.rating = @(3.5);
set.thumbnailData = UIImagePNGRepresentation([UIImage imageNamed:@"share_qq"]);

導航設置:

set.title = @"導航設置";
set.contentDescription = @"我是導航設置,點擊導航會跳轉到地圖,然后系統自動導航";
set.latitude = @(31.239);
set.longitude = @(121.499);
set.supportsNavigation = @(YES);
set.contactKeywords = @[@"我是", @"導航", @"設置"];

撥打電話:

set.title = @"撥打電話";
set.contentDescription = @"我是撥打電話樣式,只在真機上有效,模擬器無效";
set.phoneNumbers = @[@"10086"];
set.supportsPhoneCall = @(YES);
set.contactKeywords = @[@"我是", @"撥打", @"電話"];
3、創建 CSSearchableItem 對象
CSSearchableItem *item =
[[CSSearchableItem alloc] initWithUniqueIdentifier:@"uniqueIdentifier"
                                  domainIdentifier:@"domainIdentifier"
                                      attributeSet:attributeSet];

uniqueIdentifier 每個搜索都有一個唯一標示,當用戶點擊搜索到得某個內容的時候,系統會調用代理方法,會將這個唯一標示傳給你,以便讓你確定是點擊了哪一,方便做頁面跳轉。
domainIdentifier 搜索域標識,刪除條目的時候調用的delegate會傳過來這個值。
attributeSet 就是剛才我們創建的 CSSearchableItemAttributeSet 對象。

4、添加 CSSearchableIndex 中

接下來是調用 Core Spotlight 相應的 API 來對數據進行索引操作,將前兩步創建完成的 CSSearchableItem 對象,加入 CSSearchableIndex 中,該方法可以對索引進行添加或更新。

    // 把上面的設置item都添加進入
    NSArray *items = @[item1, item2, item3, item4];
    CSSearchableIndex *searchIndex = [CSSearchableIndex defaultSearchableIndex];
    [searchIndex indexSearchableItems:items
                    completionHandler:^(NSError * _Nullable error) {
                        if (!error) { // 回調方法在子線程
                            NSLog(@"添加成功");
                        } else {
                            NSLog(@"添加失敗%@",error);
                        }
                    }];

三、點擊索引

在 AppDelegate.m 文件中, 我們需要實現一個代理方法,用來響應搜索結果。 這個代理方法將會在 Spotlight 搜索結果點擊后被調用,在這里,我們可以處理被點擊的索引。

-(BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler
{
    NSString *idetifier = userActivity.userInfo[CSSearchableItemActivityIdentifier];
    NSLog(@"idetifier : %@",idetifier);
    NSString *activityType = userActivity.activityType;
    NSLog(@"activityType : %@",activityType);

    UINavigationController *nav = (UINavigationController *)self.window.rootViewController;
    UIViewController *vc = [UIViewController new];
    vc.view.backgroundColor = [UIColor whiteColor];
    
    // 根據 activityType、idetifier 識別索引
    if ([idetifier isEqualToString:@"baseId"]) {
        vc.title = @"基本展示";
    } else if ([idetifier isEqualToString:@"iconId"]){
        vc.title = @"圖片與星評";
    } else if ([idetifier isEqualToString:@"navigationId"]) {
        vc.title = @"導航設置";
    } else if ([idetifier isEqualToString:@"phoneId"]) {
        vc.title = @"撥打電話";
    }
    
    if (vc.title) {
        [nav pushViewController:vc animated:YES];
    }
    
    return YES;
}

四、刪除索引

CSSearchableIndex類提供了三個方法來刪除索引,分別刪除應用所創建的所有索引,按domain ID刪除索引,按ID刪除索引。

- deleteAllSearchableItemsWithCompletionHandler:
- deleteSearchableItemsWithDomainIdentifiers:completionHandler:
- deleteSearchableItemsWithIdentifiers:completionHandler:

根據 UniqueIdentifier 刪除索引示例:

- (IBAction)deleteSearchItem {
    // 根據 UniqueIdentifier 刪除索引
    NSArray *identifiers = @[@"navigationId", @"phoneId"];
    CSSearchableIndex *searchIndex = [CSSearchableIndex defaultSearchableIndex];
    [searchIndex deleteSearchableItemsWithIdentifiers:identifiers
                                    completionHandler:^(NSError * _Nullable error) {
                                        if (!error) {
                                            NSLog(@"刪除成功");
                                        } else {
                                            NSLog(@"刪除失敗%@",error);
                                        }
    }];
}

五、注意事項

1、搜索結果的位置和順序是系統自動排布的,大致是點擊頻率越高就越靠前

2、同一個應用,搜索結果列表默認展示3個,然后展開后最多展示13個

3、批量添加過多(測試:1000條索引,每個索引10個關鍵詞),會阻塞線程,導致卡頓

4、可以不設置 thumbnailData ,這樣默認就是當前應用的 LOGO;另外注意 thumbnailURL 并不是用來指定網絡圖片地址的,所以你要加縮略圖的話需要先把網上的下載到本地再設置。設置 thumbnailURL 時,如果顯示不出圖片,可以拼接前綴 file:// 然后重試

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容