iOS9推出后,為了順應(yīng)時代,給自己項目加了個Spotlight搜索功能,下面是使用過程中的一點記錄
在iOS9中提供了新的APIs,允許你去索引APP里面的內(nèi)容或者界面狀態(tài),通過Spotlight來快速顯示APP中的內(nèi)容。 這些新的搜索APIs的三大組件為:
- NSUserActivity (iOS8 出現(xiàn)的類,提供handoff功能支持)
- Core Spotlight (新庫,提供Spotlight索引APP內(nèi)容的功能)
- web markup(鬼知道什么東西,看名字不像APP開發(fā)用的)
1、NSUserActivity
最開始NSUserActivity是iOS8的新特性:HandOff功能所使用的API,用于保存和復(fù)原APP的狀態(tài)。由于項目對HandOff并沒啥友好性,所以去年也沒有太多的研究,順道學(xué)習(xí)一下。
學(xué)習(xí)鏈接
簡單的說,使用NSUserActivity主要有以下幾點:
- unique identifier(唯一的標(biāo)識符,通過此標(biāo)識符,可以鏈接不同設(shè)備的同一APP,也是能實現(xiàn)HandOff功能的基礎(chǔ))
<key>NSUserActivityTypes</key>
<array>
<string>com.xxx.iOS-9-Search.displayShow</string>
</array>
- 保存一個UserActivity
NSUserActivity * activity = [[NSUserActivity alloc] initWithActivityType:@"com.xxx.iOS-9-Search.displayShow"];
activity.title = @"test";
activity.userInfo = [NSDictionary dictionaryWithObjectsAndKeys:item.name, @"name", item.id, @"id", nil];
[activity becomeCurrent];
- 恢復(fù)restore
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler
- update UserActivity
[activity addUserInfoEntriesFromDictionary:dic];
上面4點是NSUserActivity使用過程中需要用到的主要情景。實例化的NSUserActivity對象,可以通過屬性retain住,根據(jù)情況調(diào)用update方法,更新userActivity的userInfo(dictionary)
-
其他
eligibleForHandoff,eligibleForSearch:兩個屬性,區(qū)分HandOff和SpotLight。expirationDate:當(dāng)這個屬性被設(shè)置時,你的user activity 只會在設(shè)置的時期之前才會展示在搜索結(jié)果里。
2、Core Spotlight
當(dāng)然,先導(dǎo)入最新的庫CoreSpotlight.framework
使用起來非常簡單,通常在獲取網(wǎng)絡(luò)數(shù)據(jù)返回后,講獲得數(shù)據(jù)item,添加到searchIndex中。
NSMutableArray *items = [NSMutableArray array];
for (likeItem *item in self.Model.likeItems) {
CSSearchableItemAttributeSet * attrSet = [[CSSearchableItemAttributeSet alloc] initWithItemContentType:@"text"];
NSString *title = item.forumName;
[attrSet setTitle:title];
NSString *desc = [NSString stringWithFormat:@"bar"];
[attrSet setContentDescription:desc];
CSSearchableItem *item = [[CSSearchableItem alloc] initWithUniqueIdentifier:item.uniqueIdentifier domainIdentifier:@"like items" attributeSet:attrSet];
[items addObject:item];
}
[[CSSearchableIndex defaultSearchableIndex] indexSearchableItems:items completionHandler:^(NSError * _Nullable error) {
}];
添加完搜索索引以后,與userActivity相同,通過spotLight搜索到的內(nèi)容,點擊需要跳轉(zhuǎn)到我們自己的app中,并能夠跳轉(zhuǎn)到對應(yīng)的界面。
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler
{
UITabBarController *tabBarController = (UITabBarController *)[self getTabBarController];
UIViewController *vc = [tabBarController viewControllerAtIndex:0];
[vc restoreUserActivityState:userActivity];
return YES;
}
3、NSUserActivity與Spotlight相結(jié)合
在iOS9中NSUserActivity類的新增特性就是contentAttributeSet屬性。這個屬性允許你賦予一個CSSearchableItemAttributeSet, 正如你先前創(chuàng)建的那個。這個屬性集合(attribute set)允許NSUserActivity對象的搜索結(jié)果可以展示如同 Core Spotlight搜索結(jié)果那樣的相同數(shù)量的詳細(xì)信息。
但是,在嘗試兩者結(jié)合時,遇到了一些問題,首先,activity中構(gòu)造的userInfo字典不能夠搜索完了restore,userInfo中只包涵一個key:(媽蛋,為啥上不了圖)
kCSSearchableItemActivityIdentifier
這個key從哪來的呢?
CSSearchableItem *item = [[CSSearchableItem alloc] initWithUniqueIdentifier:item.uniqueIdentifier domainIdentifier:@"like items" attributeSet:attrSet];
就是這句話,kCSSearchableItemActivityIdentifier的Value就是CSSearchableItem初始化時,傳入的參數(shù)uniqueIdentifier
再看下文檔里怎么說:
// When opening a document from Spotlight, the application's application:willContinueUserActivityWithType:
// method will get called with CSSearchableItemActionType, followed by application:continueUserActivity:restorationHandler: with an NSUserActivity where the userInfo dictionary has a single key value pair where CSSearchableItemActivityIdentifier is the key and the value is the uniqueIdentifier used when creating the item.
CORESPOTLIGHT_EXPORT NSString * const CSSearchableItemActionType CS_AVAILABLE(NA, 9_0);
CORESPOTLIGHT_EXPORT NSString * const CSSearchableItemActivityIdentifier CS_AVAILABLE(NA, 9_0);
CS_CLASS_AVAILABLE(NA, 9_0)
@interface CSSearchableItem : NSObject <NSSecureCoding, NSCopying>
- (instancetype)initWithUniqueIdentifier:(nullable NSString *)uniqueIdentifier //Can be null, one will be generated
domainIdentifier:(nullable NSString *)domainIdentifier
attributeSet:(CSSearchableItemAttributeSet *)attributeSet;
// Should be unique to your application group.
// REQUIRED since this is the way you will refer to the item to update the index / delete it from the index
// Starts with an UUID for ease of use, but you can replace it with an UID of your own before the item is first indexed if you wish.
@property (copy) NSString *uniqueIdentifier;
英文不好也能看懂,關(guān)鍵的方法:
application:willContinueUserActivityWithType:
會自動生成一個NSUserActivity對象,該對象的userInfo中只有一個Key,也就是上面看到的那個key。而對應(yīng)的value就是在初始化CSSearchableItem時,傳入的參數(shù),相對于你的app,它必須是唯一的,同時,你可以傳一個nil,但是,app會自動給你生成一個唯一的,作為restore時的唯一標(biāo)識。
由此可見可以在CSSearchableItem初始化時,控制傳入的參數(shù),達(dá)到自己目的。比如,在我的項目中,我希望可以搜索兩種信息,簡單的說就是希望可以判斷搜索內(nèi)容的類型,并根據(jù)該類型跳轉(zhuǎn)到對應(yīng)ViewController,我是用的方法就是通過傳入的uniqueIdentifier來做判斷,進(jìn)而根據(jù)其他參數(shù)初始化ViewController,跳轉(zhuǎn)到該vc。
這樣做挺low的,但是確實實現(xiàn)了我的需求,想來蘋果不會搞出這么low的方法,先這樣,等下篇文章(2)中,在對實現(xiàn)這個小需求中遇到的問題做進(jìn)一步的探索,對NSUserActivity與Spotlight的結(jié)合問題再搞搞,搞清楚點,特別是那個userinfo字典,到底啥機(jī)制,好像初始化了沒啥卵用哦,就為了多點信息?