iOS9 SpotLight新功能(1)

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ī)制,好像初始化了沒啥卵用哦,就為了多點信息?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容