{"id":37631,"date":"2016-07-14T16:26:42","date_gmt":"2016-07-14T10:56:42","guid":{"rendered":"http:\/\/www.tothenew.com\/blog\/?p=37631"},"modified":"2022-01-13T14:32:35","modified_gmt":"2022-01-13T09:02:35","slug":"introduction-to-core-spotlight-framework","status":"publish","type":"post","link":"https:\/\/www.tothenew.com\/blog\/introduction-to-core-spotlight-framework\/","title":{"rendered":"Introduction to Core Spotlight Framework"},"content":{"rendered":"<p>Core Spotlight APIs <a href=\"http:\/\/www.tothenew.com\/blog\/stack-view-in-ios-9\/\">introduced in iOS 9<\/a> that allows your content searchable to users. Core Spotlight Framework has a design different than NSUserActivity that also allows apps content to be Searchable. It follows a database-style design and allows you to provide more information about a searchable content.<\/p>\n<p>For more on NSUserActivity read Spotlight Search APIs and Introduction to NSUserActivity.<\/p>\n<h2 style=\"text-align: center;\">Indexing Data For The Spotlight<\/h2>\n<p>Now let&#8217;s say we have a list and on selection, it shows some details for the selected item. We need these items to show up in our spotlight results.<\/p>\n<p>To make this happen we index the searchable items with Core Spotlight API. But neither our app nor the CS API decides what kind of data this is going to be. It\u2019s our responsibility to prepare that data and provide it to the API in a specific format. Each searchable result is represented by a single CSSearchableItem object which contains all the attributes with details of the searchable item.<\/p>\n<p>For your reference, please refer to <a href=\"https:\/\/developer.apple.com\/library\/ios\/documentation\/CoreSpotlight\/Reference\/CSSearchableItemAttributeSet_Class\/index.html\">official documentation link<\/a> so that you check out all the supported properties.<\/p>\n<p>Indexing the data for the Spotlight is the last action that should always be done. The usual and normal flow involve the following steps (including indexing):<\/p>\n<p>Set the attributes for each CSSearchableItemAttributeSet object.<br \/>\nInitialise a searchable item for each CSSearchableItem object.<br \/>\nCollect all searchable items into an array.<br \/>\nIndex the data for the Spotlight using the above array.<\/p>\n<p>We need import two frameworks first:<\/p>\n<p><code>import CoreSpotlight<br \/>\nimport MobileCoreServices<\/code><\/p>\n<p>Method to index the items for search is as follows.<\/p>\n<p><code>func setupSearchableContent() {<br \/>\n\/\/<br \/>\nvar searchableItems = [CSSearchableItem]()<br \/>\nfor i in 0...(moviesInfo.count - 1) {<br \/>\nlet movie = moviesInfo[i] as! [String: String]<br \/>\n\/\/ ----- Set the attributes for each CSSearchableItemAttributeSet object.------<br \/>\nlet searchableItemAttributeSet = CSSearchableItemAttributeSet(itemContentType: kUTTypeText as String)<br \/>\n\/\/ Set the title.<br \/>\nsearchableItemAttributeSet.title = movie[\"Title\"]!<br \/>\n\/\/ Set the movie image.<br \/>\nlet imagePathParts = movie[\"Image\"]!.componentsSeparatedByString(\".\")<br \/>\nsearchableItemAttributeSet.thumbnailURL = NSBundle.mainBundle().URLForResource(imagePathParts[0], withExtension: imagePathParts[1])<br \/>\n\/\/ Set the description.<br \/>\nsearchableItemAttributeSet.contentDescription = movie[\"Description\"]!<br \/>\nvar keywords = [String]()<br \/>\nlet movieCategories = movie[\"Category\"]!.componentsSeparatedByString(\", \")<br \/>\nfor movieCategory in movieCategories {<br \/>\nkeywords.append(movieCategory)<br \/>\n}<br \/>\nlet stars = movie[\"Stars\"]!.componentsSeparatedByString(\", \")<br \/>\nfor star in stars {<br \/>\nkeywords.append(star)<br \/>\n}<br \/>\nsearchableItemAttributeSet.keywords = keywords<br \/>\n\/\/ ----- Initialise a searchable item for each CSSearchableItem object. -----<br \/>\nlet searchableItem = CSSearchableItem(uniqueIdentifier: \u201ccom.ttnd.appName\u201d, domainIdentifier: \"movies\", attributeSet: searchableItemAttributeSet)<br \/>\n\/\/ ----- Collect all searchable items into an array. -----<br \/>\nsearchableItems.append(searchableItem)<br \/>\n}<br \/>\n\/\/ ----- Index the data for the Spotlight using the above array -----<br \/>\nCSSearchableIndex.defaultSearchableIndex().indexSearchableItems(searchableItems) { (error) -&gt; Void in<br \/>\nif error != nil {<br \/>\nprint(error?.localizedDescription)<br \/>\n}<br \/>\n}<br \/>\n}<\/code><\/p>\n<h2 style=\"text-align: center;\">Implementing Targeted Landing<\/h2>\n<p>For now, we made the item searchable. It won&#8217;t take us to details page just yet, it will only open the application. Now we need to make the action wherein the user selects the result.<br \/>\nFor this, we need to implement two methods in our Application.<\/p>\n<p><code>application(_:continueUserActivity:restorationHandler:)<br \/>\nrestoreUserActivityState(_:)<\/code><\/p>\n<p>Implement the application(_:continueUserActivity:restorationHandler:) method in the AppDelegate class as follows.<\/p>\n<p><code>func application(application: UIApplication, continueUserActivity userActivity: NSUserActivity, restorationHandler: ([AnyObject]?) -&gt; Void) -&gt; Bool {<br \/>\nlet viewController = (window?.rootViewController as! UINavigationController).viewControllers[0] as! ViewController<br \/>\nviewController.restoreUserActivityState(userActivity)<br \/>\nreturn true<br \/>\n}<\/code><\/p>\n<p>Now in viewController implement the restoreUserActivityState(_:) method as follows.<\/p>\n<p><code>override func restoreUserActivityState(activity: NSUserActivity) {<br \/>\nif activity.activityType == CSSearchableItemActionType {<br \/>\nif let userInfo = activity.userInfo {<br \/>\nlet selectedMovie = userInfo[CSSearchableItemActivityIdentifier] as! String<br \/>\nselectedMovieIndex = Int(selectedMovie.componentsSeparatedByString(\".\").last!)<br \/>\nperformSegueWithIdentifier(\"idSegueShowMovieDetails\", sender: self)<br \/>\n}<br \/>\n}<br \/>\n}<\/code><\/p>\n<p>Check out the gif example below which shows the app &#8220;Programmers&#8221; with Search API Implemented and performing the search using keywords.<\/p>\n<p>http:\/\/resizeimage.net\/viewimg\/nNqKlt5C6f2qH3sF\/qIfm6\/ezgif-com-video-to-gif.gif<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Core Spotlight APIs introduced in iOS 9 that allows your content searchable to users. Core Spotlight Framework has a design different than NSUserActivity that also allows apps content to be Searchable. It follows a database-style design and allows you to provide more information about a searchable content. For more on NSUserActivity read Spotlight Search APIs [&hellip;]<\/p>\n","protected":false},"author":326,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"aside","meta":{"iawp_total_views":5},"categories":[1400,1772,1994,1],"tags":[4848,3207,3566,2703,3752],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/37631"}],"collection":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/users\/326"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/comments?post=37631"}],"version-history":[{"count":1,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/37631\/revisions"}],"predecessor-version":[{"id":54648,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/37631\/revisions\/54648"}],"wp:attachment":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/media?parent=37631"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/categories?post=37631"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/tags?post=37631"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}