更聰明的搜索 Spotlight

人們已經(jīng)越來(lái)越離不開搜索锥忿,搜索最大的目的其實(shí)就是讓人在短時(shí)間內(nèi)得到想要的東西,簡(jiǎn)單的說(shuō)就是提升效率怠肋。

使用App也是在提升效率敬鬓,淘寶、京東提升購(gòu)物效率笙各,微信钉答、陌陌提升射交效率,獵聘杈抢、拉鉤提升招聘效率...

iOS中的Spotlight已經(jīng)不新鮮了数尿,個(gè)人使用習(xí)慣的不同可能讓有些人不知道她的存在,在手機(jī)存儲(chǔ)暴增的今天惶楼,手機(jī)里不裝個(gè)幾百個(gè)App可能有點(diǎn)對(duì)不住你128G的存儲(chǔ)了右蹦,但如果還滑來(lái)滑去的找應(yīng)用那就說(shuō)不過(guò)去了,在最新的iOS9中歼捐,Spotlight的功能肯定不止應(yīng)用搜索這么簡(jiǎn)單何陆。

簡(jiǎn)單的計(jì)算:


計(jì)算器

貨幣轉(zhuǎn)換:

貨幣轉(zhuǎn)換

以前可能還需要你打開App才能做到的,現(xiàn)在只需要簡(jiǎn)單幾步就搞定窥岩,可能還有一些小驚喜等著你去發(fā)掘甲献,如果你還有其他的好玩的,記得告訴我颂翼。

iOS 9 中的Spotlight還能搜索包括第三應(yīng)用程序提供的app內(nèi)信息晃洒,讓用戶搜索到的信息更可靠慨灭、更豐富、更人性化球及、更具聯(lián)動(dòng)性氧骤,并且允許開發(fā)者設(shè)置任意內(nèi)容讓Spotlight索引到。
我們能做些什么吃引?
你不需要打開App 就能快速定位到想要找到的內(nèi)容筹陵。
而且可以把更多的快捷操作放入搜索中。

  • 輸入好友名字立即打開聊天窗口镊尺;
  • 輸入歌名立即播放朦佩;
  • 輸入患者信息進(jìn)入至患者詳情;
  • 輸入cpatient(create patient)立即進(jìn)入創(chuàng)建患者頁(yè)面庐氮;
  • ...

Apple也給了一些應(yīng)用場(chǎng)景

新的API

在iOS 9 中提供了三種API來(lái)幫助我們實(shí)現(xiàn)搜索:

NSUserActivity

NSUserActivity 從iOS 8開始就已經(jīng)在Handoff中使用了语稠,可以通過(guò)activity 中傳輸?shù)臄?shù)據(jù)在另一臺(tái)設(shè)備上繼續(xù)。

Handoff

文檔也說(shuō)的很詳細(xì)弄砍,本文主要講搜索仙畦,就不對(duì)Handoff做過(guò)多說(shuō)明。
在iOS 9中 NSUserActivity提供了一些新的方法和屬性來(lái)幫助我們索引到指定的某個(gè)導(dǎo)航頁(yè)面來(lái)繼續(xù)操作音婶,可以是新建或者查看列表內(nèi)容等等慨畸。

Core Spotlight

新的Core Spotlight框架允許所有應(yīng)用程序中的任何內(nèi)容添加索引,來(lái)用Spotlight方便訪問(wèn)衣式,當(dāng)然你也可以對(duì)索引進(jìn)行添加寸士、刪除、更新瞳收。使用Core Spotlight可以索引到應(yīng)用程序中的內(nèi)容碉京,即使應(yīng)用程序沒(méi)有運(yùn)行。

Using a search extension, you can index content in the background even if your app is not running. This allows you to keep the index up to date as content changes even if the user isn't actively using your app. This is great for things like messages and conversations stored on your server but accessed through your app, or for locally generated user content.

Web Markup

這個(gè)特性就是你如果在你的網(wǎng)站上打上了Apple規(guī)范的markup內(nèi)容螟深,Applebot爬蟲就會(huì)爬你的網(wǎng)站谐宙,然后出現(xiàn)在Spotlight 和Safari的搜索結(jié)果中。也就是說(shuō)用戶不用安裝你的應(yīng)用界弧,你的應(yīng)用也有機(jī)會(huì)展示給潛在用戶凡蜻。

寫幾行代碼吧

接下來(lái)要做的是讓應(yīng)用可以在Spotlight中根據(jù)更多的關(guān)鍵字搜索到。

搜索

先看看搜索結(jié)果是如何展示的垢箕。


import Foundation
import CoreSpotlight
import MobileCoreServices

@available(iOS 9.0, *)
class SpotlightManager: NSObject {

    class func setupOpenAppAction() {
        var searchableItems: [CSSearchableItem] = []

        let openAppSet = CSSearchableItemAttributeSet(itemContentType: kUTTypeItem as String)
        openAppSet.title = "MedClipper"
        openAppSet.keywords = ["patient", "diagnosis", "doctor", "病歷夾"]
        let openAppSetItem = CSSearchableItem(uniqueIdentifier: "openApp", domainIdentifier: nil, attributeSet: openAppSet)
        searchableItems.append(openAppSetItem)

        CSSearchableIndex.defaultSearchableIndex().indexSearchableItems(searchableItems, completionHandler: { (error) -> Void in
            if let error = error {
                print("SearchableIndex error: \(error.localizedDescription)")
            }
        })
    }
}

我加入了"patient", "diagnosis", "doctor", "病歷夾" 關(guān)鍵字划栓,通過(guò)這些關(guān)鍵字都能搜索出App,在應(yīng)用啟動(dòng)之后調(diào)用setupOpenAppAction,退出應(yīng)用就可以搜索了条获。
然后我們只需要在Spotlight中輸入定義好的關(guān)鍵字忠荞,你的App就會(huì)出現(xiàn)在搜索結(jié)果中了。

doctor

當(dāng)然,除了這種方式委煤,你還可以給你的App起一個(gè)很長(zhǎng)的名字或者副標(biāo)題堂油。

QQ音樂(lè)

你除了可以通過(guò)QQ音樂(lè)搜索到之外,還能通過(guò)聽歌碧绞、K歌府框、FM、電臺(tái)等關(guān)鍵字搜索到QQ音樂(lè)讥邻。

小眾音樂(lè)

通過(guò)我們迫靖、音樂(lè)、傾聽兴使、彼此都能在Spotlight中搜索到小眾音樂(lè)系宜。

這樣的命名方式無(wú)論是Spotlight 還是 App store 都可以讓你的App在用戶面前有更多的展示機(jī)會(huì)。

搜索結(jié)果處理

接下來(lái)我們來(lái)處理搜索結(jié)果发魄,點(diǎn)擊之后的跳轉(zhuǎn)蜈首,讓用戶可以通過(guò)搜索結(jié)果跳轉(zhuǎn)到創(chuàng)建頁(yè)面,或者是詳情頁(yè)面欠母。

我們需要再定義一個(gè)用來(lái)執(zhí)行創(chuàng)建操作的CSSearchableItem和多個(gè)可以被搜索用來(lái)查看詳情的CSSearchableItem

import Foundation
import CoreSpotlight
import MobileCoreServices

@available(iOS 9.0, *)
class SpotlightManager: NSObject {
    class func setupOpenAppAction() {
        var searchableItems: [CSSearchableItem] = []

        let openAppSet = CSSearchableItemAttributeSet(itemContentType: kUTTypeItem as String)
        openAppSet.title = "MedClipper"
        openAppSet.keywords = ["patient", "diagnosis", "doctor", "病歷夾"]
        let openAppSetItem = CSSearchableItem(uniqueIdentifier: "openApp", domainIdentifier: nil, attributeSet: openAppSet)
        searchableItems.append(openAppSetItem)

        let createPatientSet = CSSearchableItemAttributeSet(itemContentType: kUTTypeItem as String)
        createPatientSet.title = "Create Patient Info"
        createPatientSet.contentDescription = "創(chuàng)建患者信息"
        createPatientSet.keywords = ["cp", "create patient", "patient", "sick", "create patient", "cs"]
        let createPatientItem = CSSearchableItem(uniqueIdentifier: "create-Patient", domainIdentifier:nil, attributeSet:createPatientSet)
        searchableItems.append(createPatientItem)
        CSSearchableIndex.defaultSearchableIndex().indexSearchableItems(searchableItems, completionHandler: { (error) -> Void in
            if let error = error {
                print("SearchableIndex error: \(error.localizedDescription)")
            }
        })
    }

    class func setupUserData() {
        CSSearchableIndex.defaultSearchableIndex().deleteSearchableItemsWithDomainIdentifiers(["patient"]) { (error) -> Void in
            if let error = error {
                print("SearchableIndex delete error: \(error.localizedDescription)")
            } else {
                var searchableItems: [CSSearchableItem] = []
                let patients = Patient.findAll()
                for (index, patient) in patients.enumerate() {
                    let patientSet = CSSearchableItemAttributeSet(itemContentType: kUTTypeItem as String)
                    patientSet.title = "\(patient.firstName) \(patient.lastName)"
                    patientSet.contentDescription = patient.medicalHistory
                    patientSet.keywords = [patient.firstName, patient.lastName]
                    let patientItem = CSSearchableItem(uniqueIdentifier: "patient-\(index)", domainIdentifier:"patient", attributeSet:patientSet)
                    searchableItems.append(patientItem)
                }
                CSSearchableIndex.defaultSearchableIndex().indexSearchableItems(searchableItems, completionHandler: { (error) -> Void in
                    if let error = error {
                        print("SearchableIndex error: \(error.localizedDescription)")
                    }
                })

            }
        }
    }
}

setupOpenAppAction() 定義快捷打開方式的索引吆寨。
setupUserData() 定義可搜索的數(shù)據(jù)索引赏淌。
由于用戶在App中會(huì)對(duì)數(shù)據(jù)進(jìn)行修改新增,所以把setupUserData()在用戶按Home退出之后再更新數(shù)據(jù)索引啄清。

func applicationDidEnterBackground(application: UIApplication) {
    if #available(iOS 9.0, *) {
        SpotlightManager.setupUserData()
    }
}

然后通過(guò)代理方法來(lái)處理用戶點(diǎn)擊搜索結(jié)果之后的回調(diào)六水,如果不做處理默認(rèn)只會(huì)打開App。

func application(application: UIApplication, continueUserActivity userActivity: NSUserActivity, restorationHandler: ([AnyObject]?) -> Void) -> Bool {
    if #available(iOS 9.0, *) {
        if userActivity.activityType == CSSearchableItemActionType {
            guard let identifier = userActivity.userInfo?[CSSearchableItemActivityIdentifier] as? String else {
                return true
            }
            if identifier == "create-Patient" {
                //跳轉(zhuǎn)到新建的頁(yè)面
            } else if identifier.hasPrefix("patient-") {
                let patientId = identifier.substringFromIndex(identifier.startIndex.advancedBy(8))
                //通過(guò)patientId 跳轉(zhuǎn)到詳情頁(yè)面
            }
        }
    }
    return true
}

我們通過(guò)userInfo中的identifier來(lái)確定用戶的動(dòng)作來(lái)執(zhí)行下一步操作
好的辣卒,完成了掷贾,我們來(lái)看下效果:

Activity Result

是的,就是這么簡(jiǎn)單荣茫,讓搜索變得更聰明想帅。

據(jù)說(shuō)聰明的人都懂得用搜索。

參考:
App Search Programming Guide

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末啡莉,一起剝皮案震驚了整個(gè)濱河市港准,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌咧欣,老刑警劉巖浅缸,帶你破解...
    沈念sama閱讀 216,651評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異魄咕,居然都是意外死亡衩椒,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)毛萌,“玉大人苟弛,你說(shuō)我怎么就攤上這事〕” “怎么了嗡午?”我有些...
    開封第一講書人閱讀 162,931評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)冀痕。 經(jīng)常有香客問(wèn)我荔睹,道長(zhǎng),這世上最難降的妖魔是什么言蛇? 我笑而不...
    開封第一講書人閱讀 58,218評(píng)論 1 292
  • 正文 為了忘掉前任僻他,我火速辦了婚禮,結(jié)果婚禮上腊尚,老公的妹妹穿的比我還像新娘吨拗。我一直安慰自己,他們只是感情好婿斥,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,234評(píng)論 6 388
  • 文/花漫 我一把揭開白布劝篷。 她就那樣靜靜地躺著,像睡著了一般民宿。 火紅的嫁衣襯著肌膚如雪娇妓。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,198評(píng)論 1 299
  • 那天活鹰,我揣著相機(jī)與錄音哈恰,去河邊找鬼。 笑死志群,一個(gè)胖子當(dāng)著我的面吹牛着绷,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播锌云,決...
    沈念sama閱讀 40,084評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼荠医,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了宾抓?” 一聲冷哼從身側(cè)響起子漩,我...
    開封第一講書人閱讀 38,926評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎石洗,沒(méi)想到半個(gè)月后幢泼,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,341評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡讲衫,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,563評(píng)論 2 333
  • 正文 我和宋清朗相戀三年缕棵,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了孵班。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,731評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡招驴,死狀恐怖篙程,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情别厘,我是刑警寧澤虱饿,帶...
    沈念sama閱讀 35,430評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站触趴,受9級(jí)特大地震影響氮发,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜冗懦,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,036評(píng)論 3 326
  • 文/蒙蒙 一爽冕、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧披蕉,春花似錦颈畸、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至爬凑,卻和暖如春困乒,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背贰谣。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留迁霎,地道東北人吱抚。 一個(gè)月前我還...
    沈念sama閱讀 47,743評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像考廉,于是被迫代替她去往敵國(guó)和親秘豹。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,629評(píng)論 2 354

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