Implementing shortcuts through NSUserActivity

The simplest way to implement Siri Shortcuts is to use NSUserActivity objects. An NSUserActivity object contains information about the current activity that a user is performing, and can be used to achieve several goals, one of which is to implement Siri Shortcuts. To find out about other uses of NSUserActivity, have a look at Chapter 21, Improved Discoverability with Spotlight and Universal Links.

Your app must register the identifiers, in the Info.plist file, for the user activity objects that it will handle. Add a new entry to the Info.plist for Hairdressers, and name it NSUserActivityTypes. The object type for this key should be an array. In this array, you should add the identifier for the user activity object you are going to use for Siri shortcuts. Usually, this will be a reverse domain name kind of identifier, such as, for example, com.donnywals.hairdressers.appointment.

After adding the identifier to your Info.plist, you are ready to implement user activities in your app. To nicely encapsulate all logic related to the appointment booking activity, add an extension called NSUserActivity to the extensions folder, and implement the following extension in it:

extension NSUserActivity {
  static var identifierForAppointment: String {
    return "com.donnywals.hairdressers.appointment"
  }

  static func appointmentActivity() -> NSUserActivity {
    return NSUserActivity(activityType: identifierForAppointment)
  }
}

The preceding extension contains the identifier you entered earlier, and a convenience method to create a new user activity that uses the type identifier for an appointment booking activity.

Next, create a folder called Helpers, and add a file called AppointmentShortcutHelper. You will implement all the logic surrounding shortcuts in this file.

When a user books a new appointment, you should create a new user activity and pass it to Siri Shortcuts. Passing shortcuts to Siri Shortcuts is also called donating a shortcut. Every user activity you donate to Siri needs to have a title property, a userInfo, a persistentIdentifier, and it needs to be marked as isEligibleForPrediction.

The following helper method creates a user activity object and should be added to the AppointmentShortcutHelper:

static func activityForAppointment(_ appointment: Appointment) -> NSUserActivity {
  let userActivity = NSUserActivity.appointmentActivity()
  let title = "Book an appointment with (appointment.hairdresser!) for (appointment.day!)"

  userActivity.requiredUserInfoKeys = ["hairdresser", "day"]
  userActivity.userInfo = ["hairdresser": appointment.hairdresser!, "day": appointment.day!]
  userActivity.title = title
  userActivity.isEligibleForPrediction = true
  userActivity.persistentIdentifier = "(appointment.hairdresser!)-(appointment.day!)"
  userActivity.suggestedInvocationPhrase = title

  return userActivity
}

The preceding block of code creates a user activity. Note that the sample code uses some force unwrapping with a ! symbol used to keep the code brief and simple. Make sure to asses whether this is appropriate in your own app, and preferably use safe unwrapping instead. To use and donate the user activity that the preceding snippet creates, add the following code to AddAppointmentViewController in the didTapSave() method, right before dismiss(animated:completion:) is called:

let activity = AppointmentShortcutHelper.activityForAppointment(appointment)
self.userActivity = activity

To make an activity the current activity, you need to assign it as the current user activity for the current view controller. If you run the app now, creating a new appointment will donate that appointment to Siri. Normally, Siri will begin showing donations once the user has performed a certain action many times, so Siri is quite sure that it makes sense for your user to see the action offered to them. For debugging purposes, you can go to Settings | Developer, scroll down a bit, and then enable Display Recent Shortcuts and Display Donations on Lock Screen, as shown in the following screenshot:

Doing this will immediately show your new donated shortcuts in the notification center and on the lock screen, as shown in the following screenshot:

If you only donate your shortcuts to Siri, you're not quite done yet. When a user taps on your shortcut, your application should receive the user activity object and then perform the action the user wants to perform—in this case, booking a repeat appointment with a certain hairdresser.

Add the following helper method to the AppointmentShortcutHelper to convert a user activity to an appointment and store it in Core Data:

static func storeAppointmentForActivity(_ userActivity: NSUserActivity) {
  guard let userInfo = userActivity.userInfo,
    let hairdresser = userInfo["hairdresser"] as? String,
    let day = userInfo["day"] as? String
    else { return }

  let moc = PersistentHelper.shared.persistentContainer.viewContext

  moc.persist {
    let appointment = Appointment(context: moc)
    appointment.day = day
    appointment.hairdresser = hairdresser
  }
}

When your app is asked to handle a user activity, the application(_:continue:restorationHandler:) method is called on your AppDelegate. Add the following implementation for this method to check whether the received user activity is related to booking an appointment, and pass it on to the helper method to store a new appointment:

func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {

  guard userActivity.userActivityType == NSUserActivity.identifierForAppointment
    else { return false }

  AppointmentShortcutHelper.storeAppointmentForActivity(userActivity)

  return true
}

After you implement this code, go ahead and book an appointment in the Hairdressers app. You should see your appointment appear in the list of suggested shortcuts, and when you tap on your shortcut, a new appointment should immediately be created.

Users can also add their own voice command for the shortcuts you donate. Users can do this by navigating to the following page in the settings app: Hairdressers | Siri & Search | My "Hairdressers" Shortcuts. A user can then tap on a shortcut to record their own phrase, which can then be used to execute the shortcut they chose, as shown in the following screenshot:

When you donate shortcuts using a user activity, your app will be launched to handle the shortcut. If you want to handle shortcuts in the background, you can create a custom intent and Intents extension to achieve this. Let's see how.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset