點擊下載 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://
然后重試