前言
在iOS9之前我們只能使用Spotlight來搜索應用名稱來打開指定App,而其他的內容都是提供給系統使用(信息,聯系人,郵件等)。在iOS9以后Apple允許開發者設置應用中任意內容可以被Spotlight索引到以及用戶在選擇了搜索內容時會發生什么。如demo所示:
圖1 Spotlight搜索應用內結果示意圖
簡單介紹
在iOS9中提供了三種API來幫助我們實現搜索,如下:
圖2 iOS 9新增搜索API
NSUserActivity
NSUserActivity包含了一些新的方法和屬性來幫助我們實現索引activities和應用狀態使他們在搜索結果中可用。每一個應用都可以利用NSUserActivity API來生成對於用戶來說更有用的內容。順便提一句NSUserActivity在iOS8中的Handoff就已經被引入了。
Web Markup
這一特性允許應用鏡像自己的內容,並在Spotlight中建立自己的引用。蘋果的爬蟲會抓取你的網站上打了markup的內容,而這些內容會提供給Safari和Spotlight。這個特性的神奇之處在於。用戶不需要將你的應用安裝在手機上。這樣你的應用可以更多的展示給潛在用戶。蘋果的雲服務會索引你的內容,讓你的應用與Public Search API保持深度的鏈接會讓你收益頗多。
Core Spotlight
新的CoreSpotlight(framework)是iOS9提供的一組新的API來幫助你建立起你的應用中的索引。CoreSpotlight是用來處理用戶數據的比如:文檔,照片以及其他類型的由用戶產生的內容。
讓我們開始吧
准備工作
首先我們使用三個不同的ViewController來加載不同的用戶數據:
- Image
- TXT
- Web
然后使用一個TableView用來索引他們這一部分的代碼就不贅述具體結構如圖
圖3 Demo 初始化
圖4 iPhone Demo截圖
好,萬事具備,只欠CoreSpotlight啦
CoreSpotlight
先將framework導入
工程->Build Phases->Link Binary With Libraries->搜索CoreSpotlight
如果搜索不到請確認自己使用的是Xcode7
圖 5 添加CoreSpotlight框架
接下來就是最重要的代碼部分了
首先,導入頭文件
#import <CoreSpotlight/CoreSpotlight.h>
然后將需要索引的數據保存至CoreSpotlight
- (void)saveData{
NSMutableArray *seachableItems = [NSMutableArray new];
[self.tableData enumerateObjectsUsingBlock:^(NSString *__nonnull obj, NSUInteger idx, BOOL * __nonnull stop) {
CSSearchableItemAttributeSet *attributeSet = [[CSSearchableItemAttributeSet alloc] initWithItemContentType:@"views"];
attributeSet.title = obj;
attributeSet.contentDescription = [NSString stringWithFormat:NSLocalizedString(@"a easy way to open %@", nil),obj];
UIImage *thumbImage = [UIImage imageNamed:[NSString stringWithFormat:@"icon_%@.png",obj]];
attributeSet.thumbnailData = UIImagePNGRepresentation(thumbImage);//beta 1 there is a bug
CSSearchableItem *item = [[CSSearchableItem alloc] initWithUniqueIdentifier:obj domainIdentifier:@"com.kdanmobile.CoreSpotlightDemo" attributeSet:attributeSet];
[seachableItems addObject:item];
}];
[[CSSearchableIndex defaultSearchableIndex] indexSearchableItems:seachableItems
completionHandler:^(NSError * __nullable error) {
if (!error)
NSLog(@"%@",error.localizedDescription);
}];
}
執行下程序然后到Spotlight查看是否有保存進去
如果沒保存進去不要緊,嘗試重啟下模擬器再到Spotlight中查看應該就有了。這應該事Xcode的一個bug
另外關於CSSearchableItemAttributeSet的各個屬性的含義如下圖所示
圖 6 Demo Spotlight搜索示意圖
現在我們點擊搜索到相應的項還只能打開我們的應用,如果要實現跳轉還需要進行一小步的工作:在AppDelegate中實現
- (BOOL)application:(nonnull UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity restorationHandler:(nonnull void (^)(NSArray * __nullable))restorationHandler{
NSString *idetifier = userActivity.userInfo[@"kCSSearchableItemActivityIdentifier"];
UINavigationController *navigationController = (UINavigationController *)self.window.rootViewController;
[navigationController popToRootViewControllerAnimated:YES];
CoreSpotlightTableViewController *coreViewController = [[navigationController viewControllers] firstObject];
[coreViewController showViewControllerWithIdentifier:idetifier];
return YES;
}
而在實現這個方法后在點擊spotlight中點擊相應的項就會跳轉到我們相應的ViewController中啦
圖7 Demo Spolight 搜索截圖
最后需要提到的就是索引的刪除。CoreSpotlight給我們提供了三個方法來進行刪除分別是:
- (void)deleteSearchableItemsWithIdentifiers:(NSArray<NSString *> *)identifiers completionHandler:(void (^ __nullable)(NSError * __nullable error))completionHandler;
- (void)deleteSearchableItemsWithDomainIdentifiers:(NSArray<NSString *> *)domainIdentifiers completionHandler:(void (^ __nullable)(NSError * __nullable error))completionHandler;
- (void)deleteAllSearchableItemsWithCompletionHandler:(void (^ __nullable)(NSError * __nullable error))completionHandler;
根據identifier來刪除,根據domain來刪除以及刪除所有的索引。
從Xcode7自動補全的代碼看來出現了很多以前不常見的代碼如:nonnull , __nullable,NSArray<NSString *>,等,其中nonull在Xcode6的某個版本往后就提供了。目的是用來更好的與swift中的optional變量連接。從這些看來以后蘋果的重心將慢慢往swift轉移。