Over a million developers have joined DZone.

A Swift Introduction to iOS 10: SiriKit

We'll start our journey of the key features in iOS 10 by looking at SiriKit, providing you with info on how you can implement it in your app.

· Mobile Zone

A few weeks ago, on the day that iOS 10 was launched, I delivered a talk at a local developer event that introduced some of the new features available: SiriKit, iMessage Apps, Sticker Packs, User Notifications, and Speech Recognition. If you want to get the whole lot, you can watch the video here. Or, you can follow this series where I'll break down each of the key features.

Today, we'll focus on SiriKit. 

SiriKit was one of the big announcements at WWDC this year. It’s the first time that Siri has been made open to third party developers rather than Siri being limited to the apps provided by Apple themselves.

There are some limitations, though; SiriKit is only available to a certain set of domains. So, if you have a productivity app, for the time being, you’re out of luck. However, ride booking, photo, payments, messaging and calling, and workouts all are included as domains that SiriKit will work with. 

Image title

The great thing about SiriKit is that it looks after a lot of handling itself. In the example above, WeChat is able to understand a number of different ways that a request is expressed vocally. This way you can address the app in variety of ways, just like you would in natural conversation. Also, the keyword in these examples is the app name "WeChat", but there is the option for your app to work with other keywords beyond this. 

It’s a good idea to do a little groundwork to your existing apps before adding SiriKit in by extracting common code into an Embedded Framework. This best practice is recommended for all extensions, whether Siri, Messaging, Photo Editing, or others. This is just a neat way of sharing code across your app—a little like a microservice and it makes unit testing much easier. In general, you should look to include the data model, networking code, decision-making logic, and common user interface here. 

Adding an Intents Extension

Image title

In your existing app, you will use extensions to implement Siri. To add an extension, click on File/New/Add Target and choose an Intents Extension in the dialog presented to you. 

When you create your Intent Extension, you will actually get two extensions added to your app: one for the Intent Handler and one for the User Interface. Creating the user interface is the same as any other view controller in iOS: you get a storyboard and an IntentViewController class waiting for you. 

Image title

Requesting Permission 

Users will need to give your app permission to be invoked from Siri. To do this you will need to add an NSSiriUsageDescription key in Info.plist to describe what your app plans to do with Siri. Then, when it's appropriate to make the request to the user to enable Siri, make a call to requestSiriAuthorization to display the alert to the user.

Don't forget that the end users can make their own decisions on which apps should be Siri-enabled. This is done through the Settings app, clicking through to Siri, and switching on or off the app in question.

The Process of Handling Intents

Before we dive into the code that will handle the intent, let's take a quick look at the workflow that's involved broken down into three steps: Resolve, Confirm, and Handle. 

Image title

The best example of this in action can be explained through a voice command enabled phone application. First, the user asks to phone James. The resolve step will check your contacts list and see how many instances of James are available. If there are more than one, then you will want to show a listing of those James'. 

Next, comes the confirm step. The user will have chosen which James to call, and then you will ask the user if he/she is sure that they want to call that person through a simple confirmation dialog. Finally, you'll hit the handle step, where the call is actually made. 

Of course, there will be variations on this, such as having to cancel because there are no matching names. Check out the complete deep dive on how this process works on the SiriKit Programming Guide.

The IntentHandler 

In Xcode 8, the example IntentHandler that is created for you is a handler for messaging apps. If you look at the documentation for the domain, you'll see that there are three possible intents for such an app: sending a message, searching for messages, or setting attributes on a message.

Now, look at the generated code, you'll see that the IntentHandler inherits from INExtension and then includes these three specific intent handlers. The example code shows simple handlers as well as a more complex example of sending a message where the resolve, confirm, and handle functions are outlined.

//
//  IntentHandler.swift
//  Siri Intents Extension
//
//  Created by James Sugrue on 12/09/2016.
//  Copyright © 2016 James Sugrue. All rights reserved.
//

import Intents

// As an example, this class is set up to handle Message intents.
// You will want to replace this or add other intents as appropriate.
// The intents you wish to handle must be declared in the extension's Info.plist.

// You can test your example integration by saying things to Siri like:
// "Send a message using <myApp>"
// "<myApp> John saying hello"
// "Search for messages in <myApp>"

class IntentHandler: INExtension, INSendMessageIntentHandling, 
INSearchForMessagesIntentHandling, INSetMessageAttributeIntentHandling {



    // MARK: - INSendMessageIntentHandling

    // Implement resolution methods to provide additional information about your intent (optional).
    func resolveRecipients(forSendMessage intent: INSendMessageIntent, with completion: @escaping ([INPersonResolutionResult]) -> Void) {

    }

    func resolveContent(forSendMessage intent: INSendMessageIntent, with completion: @escaping (INStringResolutionResult) -> Void) {

    }

    // Once resolution is completed, perform validation on the intent and provide confirmation (optional).

    func confirm(sendMessage intent: INSendMessageIntent, completion: @escaping (INSendMessageIntentResponse) -> Void) {
        // Verify user is authenticated and your app is ready to send a message.

    }

    // Handle the completed intent (required).

    func handle(sendMessage intent: INSendMessageIntent, completion: @escaping (INSendMessageIntentResponse) -> Void) {
        // Implement your application logic to send a message here.

    }

    // Implement handlers for each intent you wish to handle.  
  //As an example for messages, you may wish to also handle searchForMessages and setMessageAttributes.

    // MARK: - INSearchForMessagesIntentHandling

    func handle(searchForMessages intent: INSearchForMessagesIntent, completion: @escaping (INSearchForMessagesIntentResponse) -> Void) {
        // Implement your application logic to find a message that 
//matches the information in the intent.

    }

    // MARK: - INSetMessageAttributeIntentHandling

    func handle(setMessageAttribute intent: INSetMessageAttributeIntent, completion: @escaping (INSetMessageAttributeIntentResponse) -> Void) {
        // Implement your application logic to set the message attribute here.
        }
}


As well as these specific handlers for events, you can use the general handle message and then delegate the work for dealing with the intent after, like so: 

override func handler(for intent: INIntent) -> Any {
        // This is the default implementation.  
  //If you want different objects to handle different intents,
        // you can override this and return the handler you want for 
  //that particular intent.

        return self
    }


You will also need to list the intents that your app supports in the Info.plist file in the IntentsSupported array. As well as doing this, you can list a subset of Intents that are restricted when the phone is locked through the IntentsRestrictedWhileLocked listing.

Image title

You can add your own custom content to the Siri user interface, provided that your intent is in the Messaging, Payments, Ride booking, or Workout domain. You'll find more information on that in the Intents UI Guide.

Examples and Tutorials 

Here's a list of some more in-depth tutorials and samples diving into SiriKit that will help you get started: 

Want to see the full presentation? Be my guest: 


Topics:
swift ,ios ,ios 10 ,sirikit

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}