標籤:
金田(github樣本源碼)
前言
在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來載入不同的使用者資料:
然後使用一個TableView用來索引他們這一部分的代碼就不贅述具體結構
圖3 Demo 初始化
圖4 iPhone Demo
好,萬事具備,只欠CoreSpotlight啦
CoreSpotlight
先將framework匯入
工程->BuildPhases->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轉移。
iOS 9 應用程式內搜尋(CoreSpotlight)API