
Core Spotlight allows iOS apps to index their content and make it searchable within the device. This is particularly useful for apps like a recipe app, where users can quickly find recipes by searching for keywords in Spotlight. In this guide, we will build a simple recipe app that indexes recipes using Core Spotlight.
Prerequisites
- Basic knowledge of Swift and iOS development
- Xcode installed
Step 1: Setting Up the Project
- Create a New Xcode Project:
- Open Xcode and create a new project.
- Choose the “App” template.
- Name your project (e.g., “RecipeApp”).
- Select Swift as the language.
- Add Core Spotlight Framework:
- Go to your project settings.
- Under “General”, find “Frameworks, Libraries, and Embedded Content”.
- Click the “+” button and add the
CoreSpotlight
framework.
Step 2: Creating the Recipe Model
Create a model to represent a recipe.
import Foundation
struct Recipe {
let id: String
let title: String
let ingredients: String
let instructions: String
}
Step 3: Indexing Recipes with Core Spotlight
- Import Core Spotlight:
import CoreSpotlight
import MobileCoreServices
Create a Method to Index a Recipe:
func indexRecipe(_ recipe: Recipe) {
let attributeSet = CSSearchableItemAttributeSet(itemContentType: kUTTypeText as String)
attributeSet.title = recipe.title
attributeSet.contentDescription = recipe.ingredients
attributeSet.keywords = recipe.ingredients.components(separatedBy: ", ")
let item = CSSearchableItem(uniqueIdentifier: recipe.id, domainIdentifier: "com.yourdomain.recipeapp", attributeSet: attributeSet)
CSSearchableIndex.default().indexSearchableItems([item]) { error in
if let error = error {
print("Indexing error: \(error.localizedDescription)")
} else {
print("Recipe successfully indexed!")
}
}
}
- Call the Indexing Method:
You can call this method when a recipe is added or updated in your app.
let recipe = Recipe(id: "1", title: "Pasta Carbonara", ingredients: "Pasta, Eggs, Cheese, Bacon", instructions: "Cook pasta. Mix eggs and cheese. Add bacon.")
indexRecipe(recipe)
Step 4: Handling Spotlight Searches
To handle Spotlight searches and open the app to the specific recipe, you’ll need to handle the URL scheme or the NSUserActivity
.
- Update AppDelegate to Handle Searchable Items:
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
if userActivity.activityType == CSSearchableItemActionType {
if let identifier = userActivity.userInfo?[CSSearchableItemActivityIdentifier] as? String {
// Handle the identifier and navigate to the specific recipe
navigateToRecipe(with: identifier)
}
}
return true
}
Implement Navigation Logic:
func navigateToRecipe(with identifier: String) {
// Logic to navigate to the specific recipe in your app
print("Navigate to recipe with ID: \(identifier)")
}
Step 5: User Interface
Create a simple UI to display the list of recipes and a detail view for each recipe.
- Recipe List View:
import UIKit
class RecipeListViewController: UITableViewController {
var recipes: [Recipe] = []
override func viewDidLoad() {
super.viewDidLoad()
title = "Recipes"
// Add some sample recipes
recipes = [
Recipe(id: "1", title: "Pasta Carbonara", ingredients: "Pasta, Eggs, Cheese, Bacon", instructions: "Cook pasta. Mix eggs and cheese. Add bacon."),
Recipe(id: "2", title: "Chicken Curry", ingredients: "Chicken, Curry Powder, Coconut Milk", instructions: "Cook chicken. Add curry powder and coconut milk.")
]
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return recipes.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "RecipeCell", for: indexPath)
cell.textLabel?.text = recipes[indexPath.row].title
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let recipe = recipes[indexPath.row]
let detailVC = RecipeDetailViewController()
detailVC.recipe = recipe
navigationController?.pushViewController(detailVC, animated: true)
}
}
Recipe Detail View:
import UIKit
class RecipeDetailViewController: UIViewController {
var recipe: Recipe?
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
if let recipe = recipe {
title = recipe.title
let ingredientsLabel = UILabel()
ingredientsLabel.text = "Ingredients: \(recipe.ingredients)"
ingredientsLabel.numberOfLines = 0
ingredientsLabel.frame = CGRect(x: 20, y: 100, width: view.frame.width - 40, height: 100)
view.addSubview(ingredientsLabel)
let instructionsLabel = UILabel()
instructionsLabel.text = "Instructions: \(recipe.instructions)"
instructionsLabel.numberOfLines = 0
instructionsLabel.frame = CGRect(x: 20, y: 220, width: view.frame.width - 40, height: 200)
view.addSubview(instructionsLabel)
}
}
}
Step 6: Integrating Core Spotlight
Now, index your recipes when you add them to the list.
- Index Recipes on Addition:
Update the RecipeListViewController
to index recipes when they are added.
override func viewDidLoad() {
super.viewDidLoad()
title = "Recipes"
recipes = [
Recipe(id: "1", title: "Pasta Carbonara", ingredients: "Pasta, Eggs, Cheese, Bacon", instructions: "Cook pasta. Mix eggs and cheese. Add bacon."),
Recipe(id: "2", title: "Chicken Curry", ingredients: "Chicken, Curry Powder, Coconut Milk", instructions: "Cook chicken. Add curry powder and coconut milk.")
]
for recipe in recipes {
indexRecipe(recipe)
}
}
You have now built a simple recipe app that uses Core Spotlight to index and search for recipes. This example covers the basic setup, indexing content, handling searches, and creating a simple user interface. You can expand this app with more features, such as adding the ability to edit and delete recipes, adding images, and improving the UI/UX design.