How To Add Siri Shortcuts in Your App in Swift

Implementing Siri Shortcuts in your app is easier than you think

Domenico Nicoli
Nov 20 · 4 min read
Photo by Émile Perron on Unsplash

With the release of iOS 12, Apple allows developers to create custom intent that can be used with Siri. This new feature gives developers the possibility to create custom action inside the applications that can be triggered with Siri without needing to open the app.

Today in this tutorial, you will learn how to use a simple shortcut that does an action when called with Siri.


Getting Started

First, open Xcode and create a new project. Select Single View App.

Go to your Targets setting, Signing & Capabilities, and add Siri.

Now right click on the project folder and click on New File. Then, filter for intent and click on next to create a SiriKit Intent Definition File, which we will need soon in the next steps.


Implementation

We start creating a new intent. Select the intents file, click on + at the bottom of the screen and then select New Intent.

Now set Title and Description for the intent and save it.

Go on your ViewController and add the following code:

import UIKit
import IntentsUI

class ViewController: UIViewController {

override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
addSiriButton(to: self.view)
}

func addSiriButton(to view: UIView) {
if #available(iOS 12.0, *) {
let button = INUIAddVoiceShortcutButton(style: .whiteOutline)
button.shortcut = INShortcut(intent: intent )
button.delegate = self
button.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(button)
view.centerXAnchor.constraint(equalTo: button.centerXAnchor).isActive = true
view.centerYAnchor.constraint(equalTo: button.centerYAnchor).isActive = true
}

}

func showMessage() {
let alert = UIAlertController(title: "Done!", message: "This is your first shortcut action!", preferredStyle: UIAlertController.Style.alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
self.present(alert, animated: true, completion: nil)
}

}

extension ViewController {
@available(iOS 12.0, *)
public var intent: DoSomethingIntent {
let testIntent = DoSomethingIntent()
testIntent.suggestedInvocationPhrase = "Test command"
return testIntent
}
}

extension ViewController: INUIAddVoiceShortcutButtonDelegate {
@available(iOS 12.0, *)
func present(_ addVoiceShortcutViewController: INUIAddVoiceShortcutViewController, for addVoiceShortcutButton: INUIAddVoiceShortcutButton) {
addVoiceShortcutViewController.delegate = self
addVoiceShortcutViewController.modalPresentationStyle = .formSheet
present(addVoiceShortcutViewController, animated: true, completion: nil)
}

@available(iOS 12.0, *)
func present(_ editVoiceShortcutViewController: INUIEditVoiceShortcutViewController, for addVoiceShortcutButton: INUIAddVoiceShortcutButton) {
editVoiceShortcutViewController.delegate = self
editVoiceShortcutViewController.modalPresentationStyle = .formSheet
present(editVoiceShortcutViewController, animated: true, completion: nil)
}


}

extension ViewController: INUIAddVoiceShortcutViewControllerDelegate {
@available(iOS 12.0, *)
func addVoiceShortcutViewController(_ controller: INUIAddVoiceShortcutViewController, didFinishWith voiceShortcut: INVoiceShortcut?, error: Error?) {
controller.dismiss(animated: true, completion: nil)
}

@available(iOS 12.0, *)
func addVoiceShortcutViewControllerDidCancel(_ controller: INUIAddVoiceShortcutViewController) {
controller.dismiss(animated: true, completion: nil)
}


}

extension ViewController: INUIEditVoiceShortcutViewControllerDelegate {
@available(iOS 12.0, *)
func editVoiceShortcutViewController(_ controller: INUIEditVoiceShortcutViewController, didUpdate voiceShortcut: INVoiceShortcut?, error: Error?) {
controller.dismiss(animated: true, completion: nil)
}

@available(iOS 12.0, *)
func editVoiceShortcutViewController(_ controller: INUIEditVoiceShortcutViewController, didDeleteVoiceShortcutWithIdentifier deletedVoiceShortcutIdentifier: UUID) {
controller.dismiss(animated: true, completion: nil)
}

@available(iOS 12.0, *)
func editVoiceShortcutViewControllerDidCancel(_ controller: INUIEditVoiceShortcutViewController) {
controller.dismiss(animated: true, completion: nil)
}
}

Now, if you run the app, you should have a blank screen with a button in the middle to add the shortcut that we have just created to Siri. You can tap on the button and use the default text or set a new one to trigger the shortcut.

Now if you trigger Siri and say the chosen command, your app will be open automatically!

Now our app will open when we say the command to Siri, but what do we have to do to link this phrase to a specific action in our app?

First, go to Main.storyboard and set ViewController on StoryboardID property.

Now on SceneDelegate.swift (on iOS 13) or on AppDelegate.swift (before iOS 13), copy the following code (this is the version for SceneDelegate, but on AppDelegate the method to add is really similar):

func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
if let _ = userActivity.interaction?.intent as? DoSomethingIntent {

if let windowScene = scene as? UIWindowScene {
self.window = UIWindow(windowScene: windowScene)
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let initialViewController = storyboard.instantiateViewController(withIdentifier: "ViewController") as! ViewController
self.window!.rootViewController = initialViewController
self.window!.makeKeyAndVisible()
initialViewController.showMessage()
}
}
}

Test

Finally, you are ready to test your app! Tell Siri your command and this should be the result:


Full Code

You can find the full code on GitHub.

Thank you for reading. If you have any questions or suggestions, please let me know in the comments.

Better Programming

Advice for programmers.

Domenico Nicoli

Written by

Backend Developer (C#, VB.NET, Microsoft SQL Server), iOS developer (Swift). Parma, Italy 🇮🇹 https://linkedin.com/in/domenico-nicoli-5738ba15a

Better Programming

Advice for programmers.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade