iOS9 App Search之NSUserActivity與Core Spotlight

最近因為項目要求,開始研究起iOS9推出的feature--App Search APIs。何為App Search?在iOS9之前,用戶通過spotlight只能搜索app的名字,或者蘋果自帶app的一些內(nèi)容,比如搜索通訊錄、備忘錄中的內(nèi)容。iOS9開始,用戶可以通過spotlight搜索網(wǎng)頁內(nèi)容或者任何app內(nèi)的數(shù)據(jù)。

1、search APIs主要包括三部分

1.1、NSUserActivity

NSUserActivity在iOS8中就出現(xiàn)了,當(dāng)時用于Handoff。
在iOS9中,我們可以把想要在spotlight中搜出來的內(nèi)容放到NSUserActivity中。userActivityUIResponser的屬性,通常會在用戶訪問某一個頁面時,對UIViewControlleruserActivity屬性賦值。
NSUserActivity可以用來對歷史訪問記錄

1.2、Core Spotlight

通過該技術(shù),用戶可以通過spotlight搜到app中曾經(jīng)出現(xiàn)過或者現(xiàn)有的所有內(nèi)容。

1.3、Web Markup

當(dāng)你web頁面添加了標(biāo)記語言,蘋果的爬蟲會根據(jù)用戶在spotlight的輸入,去抓取你網(wǎng)站的數(shù)據(jù),如果有找到合適的結(jié)果,你的網(wǎng)站就可能會(蘋果有自己的權(quán)重計算方法)顯示在spotlight的結(jié)果列表中。這時候如果安裝了相對應(yīng)的app并且支持deep link,用戶就可以打開對應(yīng)的app內(nèi)容頁面。
對于經(jīng)常使用spotlight的用戶來說,這會很有助于提升app的曝光度。
蘋果官方推薦Web Markup結(jié)合smart app banneruniversal links使用。
這次花了很多時間在搞的這個東西,不難搞,但是需要web端和服務(wù)端配合。重要的是,你的web站點要支持https訪問,我們公司的還不支持,糾結(jié)再三之后,暫時放棄這個功能。

在本文會簡單記錄第一、二部分內(nèi)容的實現(xiàn)。至于第三部分內(nèi)容,雖然因為https不支持,無法成功實現(xiàn),但是還是會在下文中做一個學(xué)習(xí)整理。

2、NSUserActivity

2.1、創(chuàng)建NSUSerActivity實例

在viewModel層中創(chuàng)建的NSUSerActivity實例

- (NSUserActivity *)serviceProjectUserActivity
{
    if (!_serviceProjectUserActivity) {
        _serviceProjectUserActivity = [[NSUserActivity alloc] initWithActivityType:@"com.xxxx.appIdentifier.serviceProject"];
        _serviceProjectUserActivity.title = self.projectEntity.projectTitle ?: @"";
        _serviceProjectUserActivity.userInfo = @{@"id" : self.projectEntity.projectId ?: @""};
        _serviceProjectUserActivity.keywords = [NSSet setWithObjects:self.projectEntity.destination ?: @"", nil];
        // 好像并沒有什么卵用,不知道哪里用錯了
        _serviceProjectUserActivity.expirationDate = [NSDate dateWithTimeIntervalSinceNow:60 * 60 * 24 *31];
        // 如果沒有顯示設(shè)置為yes,則不可搜索到
        _serviceProjectUserActivity.eligibleForSearch = YES;
        //
        CSSearchableItemAttributeSet *attributeSet = [[CSSearchableItemAttributeSet alloc] initWithItemContentType:CFBridgingRelease(kUTTypeContact)];
        attributeSet.contentDescription = self.projectEntity.features ?: @"";
        // ??????網(wǎng)絡(luò)路徑不可顯示
        attributeSet.thumbnailURL = [NSURL URLWithString:self.projectEntity.backImgUrl ?: @""];
        // 防止NSUserActivity和Core Spotlight可能重復(fù)索引,這里設(shè)置為nil
        attributeSet.relatedUniqueIdentifier = nil;
        _serviceProjectUserActivity.contentAttributeSet = attributeSet;
    }
    return _serviceProjectUserActivity;
}

2.2、賦值給UIViewController的userActivity屬性

在viewController層監(jiān)測,如果頁面數(shù)據(jù)請求完成,給userActivity屬性賦值

 __weak typeof(self)weakSelf = self;
    [RACObserve(self.viewModel, projectEntity) subscribeNext:^(id x) {
        if (x) {
            __strong __typeof(weakSelf)strongSelf = weakSelf;
            strongSelf.userActivity = strongSelf.viewModel.serviceProjectUserActivity;
        }
    }];

2.3、在Appdelegate中處理頁面跳轉(zhuǎn)

- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler
{
    if ([userActivity.activityType isEqualToString:@"com.xxxx.appIdentifier.serviceProject"]) {
        NSString *projectID = userActivity.userInfo[@"id"];
        if (projectID.length > 0) {
            // 處理具體頁面跳轉(zhuǎn)
            return YES;
        }
        return NO;
    }
    return NO;
}

3、Core Spotlight

3.1、創(chuàng)建要搜索的項,并將所有的項加入默認(rèn)索引空間

- (void)indexAllDomesticCityForAppSearch
{
    // 把國內(nèi)一級城市從數(shù)據(jù)庫中拿出來
    NSString *sql = [NSString stringWithFormat:@"select cn, zone_id from %@ where rank == '1' and zone_id <= 900000", self.tableName];
    
    [self loadDestinationWithSQL:sql andResultSetHandler:^(FMResultSet *result) {
        NSMutableArray *searchableItems = [[NSMutableArray alloc] init];
        while ([result next]) {
            NSString *zoneName = [result stringForColumnIndex:0];
            NSString *zoneID = [result stringForColumnIndex:1];
           // 創(chuàng)建對應(yīng)的CSSearchableItem
            CSSearchableItemAttributeSet *attributeSet = [[CSSearchableItemAttributeSet alloc] initWithItemContentType:kUTTypeContent];
            attributeSet.title = zoneName;
            attributeSet.contentDescription = @"專業(yè)旅游";
            // 這個屬性主要是將NSUserActivity與Core Spotlight indexed object進(jìn)行一個關(guān)聯(lián),防止出現(xiàn)重復(fù)的內(nèi)容(如果出現(xiàn)重復(fù)內(nèi)容,是因為開始的時候測試NSUserActivity的時候沒有設(shè)置id,還原一下模擬器就好了)
            attributeSet.relatedUniqueIdentifier = zoneID;
            CSSearchableItem *item = [[CSSearchableItem alloc] initWithUniqueIdentifier:zoneID domainIdentifier:@"com.xxxx.appIndetifier.destinations" attributeSet:attributeSet];
            [searchableItems addObject:item];
        }
         // 所有的items加入索引
        CSSearchableIndex *defaultSearchableIndex = [CSSearchableIndex defaultSearchableIndex];
        [defaultSearchableIndex indexSearchableItems:[searchableItems copy] completionHandler:^(NSError * _Nullable error) {
            
        }];
    }];
}

3.2、在Appdelegate中處理從spotlight打開app

- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler
{
    if ([userActivity.activityType isEqualToString:@"com.xxxx.appIndetifier.destinations"]) {
        NSString *zoneID = userActivity.userInfo[CSSearchableItemActivityIdentifier];
        if (zoneID.length > 0) {
            // 處理具體頁面跳轉(zhuǎn)
            return YES;
        }
        return NO;
    }
    return NO;
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • SearchAPI是什么 iOS 9.0 系統(tǒng)以后,下拉屏幕或者向右滑到最后會顯示"spotlight"頁面(不支...
    superD閱讀 964評論 0 4
  • 原文地址 在 iOS9 之前,你只能在 spotlight 中輸入關(guān)鍵字,比如應(yīng)用名字,搜索到應(yīng)用。在 iOS9 ...
    Nathan_Bao閱讀 6,885評論 4 12
  • 前言:先放出原文地址: AppCoda, 支持原創(chuàng)作品哈.本文為上面這篇文章的譯文, 原文中使用 Swift 語言...
    李國安閱讀 1,980評論 0 2
  • iOS9新特性:App搜索編程 這里基本按照官方文檔, 但是沒有百分百一致, 夾帶了私貨. 下面是一個總的結(jié)構(gòu)圖,...
    windgo閱讀 1,257評論 0 1
  • 健全學(xué)術(shù)剽竊法律法規(guī),立法主體要對學(xué)術(shù)剽竊主體及涉及學(xué)校,平臺等進(jìn)行深入調(diào)查分析把握該行為的特點和產(chǎn)生背景,初步明...
    來自申論55的覺悟閱讀 276評論 0 0