{"id":2040,"date":"2016-06-14T01:05:34","date_gmt":"2016-06-14T07:05:34","guid":{"rendered":"http:\/\/jamesonquave.com\/blog\/?p=2040"},"modified":"2016-06-20T07:46:41","modified_gmt":"2016-06-20T13:46:41","slug":"adding-siri-to-ios-10-apps-in-swift-tutorial","status":"publish","type":"post","link":"https:\/\/jamesonquave.com\/blog\/adding-siri-to-ios-10-apps-in-swift-tutorial\/","title":{"rendered":"Siri Integration in iOS 10 with Swift &#8211; SiriKit Tutorial (Part 1)"},"content":{"rendered":"<h1 id=\"siri-integration-on-ios-10-swift-tutorial\">Siri integration on iOS 10 &#8211; Swift Tutorial<\/h1>\n<p><strong><em>This tutorial written on June 13th, 2016 using the Xcode 8 Beta 1, and is using the Swift 3.0 toolchain.<\/em><\/strong><\/p>\n<h3 id=\"get-xcode-8-set-up-for-ios-10-and-swift-3-compilation-\">Get Xcode 8 set up for iOS 10 and Swift 3 compilation.<\/h3>\n<p>If you have not yet downloaded Xcode 8 Beta 1, please do so <a href=\"https:\/\/developer.apple.com\/download\/\">here<\/a>.<\/p>\n<h2 id=\"-optional-compiling-from-the-command-line\">(Optional) Compiling from the command line<\/h2>\n<p>To opt in to the Swift 3.0 toolchain you shouldn&#8217;t need to change anything unless you want to build from the command line. If you plan to build from the command line, open Xcode-beta and from the OS menu bar select <strong>Xcode &gt; Preferences<\/strong>. Then select the <strong>Locations<\/strong> tab. At the bottom of the page here you will see &#8220;Command Line Tools&#8221;. Make sure this is set to Xcode 8.0. <\/p>\n<p>Now if you navigate to the project directory containing the .xcodeproj file, you can optional compile your project by calling <code>xcodebuild<\/code> from the command line.<\/p>\n<h2 id=\"-optional-migrating-from-an-existing-swift-2-app\">(Optional) Migrating from an existing Swift 2 app<\/h2>\n<p>If you are working with an existing Swift 2 project and want to add Siri integration with Swift 3.0, click on the root of your project and select <strong>Build Settings<\/strong>. Under <strong>Swift Compiler &#8211; Version<\/strong>, find the field labeled <strong>Use Legacy Swift Language Version<\/strong> and set it to <strong>No<\/strong>. This will lead to compiler errors most likely that you will need to fix throughout your project, but it&#8217;s a step I recommend to keep up with Swift&#8217;s ever-changing semantics.<\/p>\n<h2 id=\"getting-started-with-sirikit\">Getting started with SiriKit<\/h2>\n<p>First, in your app (or in a new single-view Swift app template if you are starting fresh), switch to the general view by selecting the root of your project. Under this tab you can click the (+) icon in the lower land corner of the side-pane on the left. From the dropdown that appears selection <strong>iOS &gt; Application Extension<\/strong>, and then select <strong>Intents Extension<\/strong>.<\/p>\n<p><img decoding=\"async\" src=\"\/blog\/wp-content\/uploads\/siri-1-1.png\" alt=\"Select Intents Extension\"><\/p>\n<p>This adds a new intent to the project, and we&#8217;ll use it to listen for Siri commands. The product name should be something similar to your app so it&#8217;s easy to identify, for example if your app is called <strong>MusicMatcher<\/strong>, you could call the Product Name of this intent <strong>MusicMatcherSiriIntent<\/strong>. Make sure to also check the checkbox to <strong>Include UI Extension<\/strong>. We will need this later in the tutorial, and it&#8217;s easiest to just include the additional extension now.<\/p>\n<p><img decoding=\"async\" src=\"\/blog\/wp-content\/uploads\/siri-1-2.png\" alt=\"Intents Extension Options\"><\/p>\n<p>&#8212;<\/p>\n<p>What we&#8217;ve created are two new targets as you can see in the project heirarchy. Let&#8217;s jump in to the boilerplate code and take a look at the example in the <strong>IntentHandler.swift<\/strong> file inside of the Intent extension folder. By default this will be populated with some sample code for the workout intent, allowing a user to say commands such as &#8220;Start my workout using MusicMatcher&#8221;, where <strong>MusicMatcher<\/strong> is the name of our app.<\/p>\n<p><img decoding=\"async\" src=\"\/blog\/wp-content\/uploads\/siri-1-3.png\" alt=\"IntentHandler.swift\"><\/p>\n<h2 id=\"run-the-template-app-as-is\">Run the Template App as-is<\/h2>\n<p>It&#8217;s helpful at this point to compile this code as-is and try out the command on an actual iOS device. So go ahead and build the app target, by selecting the app <strong>MusicMatcher<\/strong> from the Scheme dropdown, and when the target device set to your test iOS device, press the Build &amp; Run button.<\/p>\n<p><img decoding=\"async\" src=\"\/blog\/wp-content\/uploads\/siri-1-4.png\" alt=\"Select the MusicMatcher target\"><\/p>\n<p>You should see a blank app appear, and in the background your extensions will also be loaded in to the device&#8217;s file system. Now you can close your app using the Stop button in Xcode to kill the app.<\/p>\n<p>Then, switch your scheme to select the Intent target, and press build &amp; run again.<\/p>\n<p><img decoding=\"async\" src=\"\/blog\/wp-content\/uploads\/siri-1-5.png\" alt=\"Select the MusicMatcherSiriIntent target\"><\/p>\n<p>This will now prompt asking which app to attach to, just select the app you just ran, <strong>MusicMatcher<\/strong>. This will present the app again on your device (a white screen\/blank app most likely), but this time the debugger will be attached to the Intent extension.<\/p>\n<p><img decoding=\"async\" src=\"\/blog\/wp-content\/uploads\/siri-1-6.png\" alt=\"Select the app to run with the extension\"><\/p>\n<p>You can now exit to the home screen by pressing the home button, or the app may exit on it&#8217;s own since you are running the Intent and not the app itself (This is not a crash!!!)<\/p>\n<h2 id=\"enable-the-extension\">Enable the extension<\/h2>\n<p>The extension should now be in place, but we as an iOS device user still may need to enable the extension in our Siri settings. On your test device enter the <strong>Settings<\/strong> app. Select the <strong>Siri<\/strong> menu, and near the bottom you should see <strong>MusicMatcher<\/strong> listed as a Siri App. Make sure the app is enabled in order to enable Siri to pick up the intents from the sample app.<\/p>\n<h2 id=\"testing-our-first-siri-command-\">Testing our first Siri command!<\/h2>\n<p>Try the Siri command. Activate Siri either by long pressing the Home button, or by saying &#8220;Hey Siri!&#8221; (note the &#8220;Hey Siri!&#8221; feature must be enabled in the settings first)<\/p>\n<p>Try out some of the command &#8220;Start my workout using MusicMatcher&#8221;.<\/p>\n<h3 id=\"-sorry-you-ll-need-to-continue-in-the-app-\">&#8220;Sorry, you&#8217;ll need to continue in the app.&#8221;<\/h3>\n<p>If you&#8217;re like me this will bail with an error saying &#8220;Sorry, you&#8217;ll need to continue in the app.&#8221; (For some reason this occassionally was not a problem. Ghosts?)<\/p>\n<p>In the console you may see something like this:<\/p>\n<pre><code><div id=\"highlighter_858088\" class=\"syntaxhighlighter nogutter highlightedCode \"><table border=\"0\" cellpadding=\"0\" cellspacing=\"0\"><tbody><tr><td class=\"code\"><div class=\"container\"><div class=\"line number1 index0 alt2\"><code class=\"plain\">dyld: <\/code><code class=\"color2\">Library<\/code> <code class=\"plain\">not loaded: <\/code><code class=\"keyword\">@rpath<\/code><code class=\"plain\">\/libswiftCoreLocation.dylib<\/code><\/div><div class=\"line number2 index1 alt1\"><code class=\"undefined spaces\">&nbsp;&nbsp;<\/code><code class=\"color2\">Referenced<\/code> <code class=\"plain\">from: \/<\/code><code class=\"keyword\">private<\/code><code class=\"plain\">\/<\/code><code class=\"keyword\">var<\/code><code class=\"plain\">\/containers\/<\/code><code class=\"color2\">Bundle<\/code><code class=\"plain\">\/<\/code><code class=\"color2\">Application<\/code><code class=\"plain\">\/<\/code><code class=\"color2\">CC815FA3<\/code><code class=\"plain\">-<\/code><code class=\"color2\">EB04<\/code><code class=\"plain\">-4322-<\/code><code class=\"color2\">B2BB<\/code><code class=\"plain\">-8E3F960681A0\/<\/code><code class=\"color2\">LockScreenWidgets<\/code><code class=\"plain\">.app\/<\/code><code class=\"color2\">PlugIns<\/code><code class=\"plain\">\/<\/code><code class=\"color2\">JQIntentWithUI<\/code><code class=\"plain\">.appex\/<\/code><code class=\"color2\">JQIntentWithUI<\/code><\/div><div class=\"line number3 index2 alt2\"><code class=\"undefined spaces\">&nbsp;&nbsp;<\/code><code class=\"color2\">Reason<\/code><code class=\"plain\">: image not found<\/code><\/div><div class=\"line number4 index3 alt1\"><code class=\"color2\">Program<\/code> <code class=\"plain\">ended with exit code: 1<\/code><\/div><\/div><\/td><\/tr><\/tbody><\/table><\/div><\/code><\/pre>\n<p>We need to add the CoreLocation library to our main project, to make sure it gets copied in with our compiled Swift code.<\/p>\n<p>Select the project root again and then select your main <strong>MusicMatcher<\/strong> target. Here under <strong>General<\/strong> you&#8217;ll find area area for <strong>Linked Frameworks and Libraries<\/strong>. Click the (+) symbol and add CoreLocation.framework. Now you can rebuild and run your app on the device, then follow the same steps as above and rebuild and run your intent target.<\/p>\n<p>Finally, you can activate Siri again from your home screen.<\/p>\n<p>&#8220;Hey Siri!&#8221;<br \/>\n&#8220;Start my workout using MusicMatcher&#8221;<\/p>\n<p>Siri should finally respond, &#8220;OK. exercise started on MusicMatcher&#8221; and a UI will appear saying &#8220;Workout Started&#8221;<\/p>\n<p><img decoding=\"async\" src=\"\/blog\/wp-content\/uploads\/siri-1-7.png\" alt=\"MusicMatcher Workout Started\"><\/p>\n<h2 id=\"how-does-it-work-\">How does it work?<\/h2>\n<p>The IntentHandler class defined in the template uses a laundry list of protocols:<\/p>\n<p>First an foremost is <code>INExtension<\/code> which is what allows us to use the class as an intent extension in the first place. The remaining protocols are all intent handler types that we want to get callbacks for in our class:<\/p>\n<pre><code><div id=\"highlighter_216819\" class=\"syntaxhighlighter nogutter highlightedCode \"><table border=\"0\" cellpadding=\"0\" cellspacing=\"0\"><tbody><tr><td class=\"code\"><div class=\"container\"><div class=\"line number1 index0 alt2\"><code class=\"color2\">INStartWorkoutIntentHandling<\/code><\/div><div class=\"line number2 index1 alt1\"><code class=\"color2\">INPauseWorkoutIntentHandling<\/code><\/div><div class=\"line number3 index2 alt2\"><code class=\"color2\">INResumeWorkoutIntentHandling<\/code><\/div><div class=\"line number4 index3 alt1\"><code class=\"color2\">INCancelWorkoutIntentHandling<\/code><\/div><div class=\"line number5 index4 alt2\"><code class=\"color2\">INEndWorkoutIntentHandling<\/code><\/div><\/div><\/td><\/tr><\/tbody><\/table><\/div><\/code><\/pre>\n<p>The first one is the one we just tested, <code>INStartWorkoutIntentHandling<\/code>.<\/p>\n<p>If you command-click this protocol name you&#8217;ll see in the Apple docs this documentation:<\/p>\n<pre><code><div id=\"highlighter_358844\" class=\"syntaxhighlighter nogutter highlightedCode \"><table border=\"0\" cellpadding=\"0\" cellspacing=\"0\"><tbody><tr><td class=\"code\"><div class=\"container\"><div class=\"line number1 index0 alt2\"><code class=\"comments\">\/*!<\/code><\/div><div class=\"line number2 index1 alt1\"><code class=\"undefined spaces\">&nbsp;<\/code><code class=\"comments\">@brief Protocol to declare support for handling an INStartWorkoutIntent <\/code><\/div><div class=\"line number3 index2 alt2\"><code class=\"undefined spaces\">&nbsp;<\/code><code class=\"comments\">@abstract By implementing this protocol, a class can provide logic for resolving, confirming and handling the intent.<\/code><\/div><div class=\"line number4 index3 alt1\"><code class=\"undefined spaces\">&nbsp;<\/code><code class=\"comments\">@discussion The minimum requirement for an implementing class is that it should be able to handle the intent. The resolution and confirmation methods are optional. The handling method is always called last, after resolving and confirming the intent.<\/code><\/div><div class=\"line number5 index4 alt2\"><code class=\"undefined spaces\">&nbsp;<\/code><code class=\"comments\">*\/<\/code><\/div><\/div><\/td><\/tr><\/tbody><\/table><\/div><\/code><\/pre>\n<p>Or in other words, this protocol tells SiriKit that we&#8217;re prepared to handle the English phrase &#8220;Start my workout with <em>AppName Here<\/em>.&#8221;<br \/>\nThis will vary based on the language spoken by the user, but the intent will always be to start a workout. The <code>INStartWorkoutIntentHandling<\/code> protocol calls on several more methods, and they are implemented in the sample code. I&#8217;ll leave you to learn more about them if you want to build a workout app, but what I&#8217;d rather do in the remainder of this tutorial is add a new intent handler for handling the sending of messages.<\/p>\n<p>&#8212;<\/p>\n<h1 id=\"let-s-add-a-new-message-intent\">Let&#8217;s Add a New Message Intent<\/h1>\n<p>Now that we&#8217;ve confirmed that works, let&#8217;s move on to adding a new type of intent for sending messages. The docs <a href=\"https:\/\/developer.apple.com\/library\/prerelease\/content\/documentation\/Intents\/Conceptual\/SiriIntegrationGuide\/SiriDomains.html\">here<\/a> show the following:<\/p>\n<pre><code><div id=\"highlighter_961846\" class=\"syntaxhighlighter nogutter highlightedCode \"><table border=\"0\" cellpadding=\"0\" cellspacing=\"0\"><tbody><tr><td class=\"code\"><div class=\"container\"><div class=\"line number1 index0 alt2\"><code class=\"color2\">Send<\/code> <code class=\"plain\">a message<\/code><\/div><div class=\"line number2 index1 alt1\"><code class=\"color2\">Handler<\/code><code class=\"plain\">:<\/code><code class=\"color2\">INSendMessageIntentHandling<\/code> <code class=\"keyword\">protocol<\/code><\/div><div class=\"line number3 index2 alt2\"><code class=\"color2\">Intent<\/code><code class=\"plain\">:<\/code><code class=\"color2\">INSendMessageIntent<\/code><\/div><div class=\"line number4 index3 alt1\"><code class=\"color2\">Response<\/code><code class=\"plain\">:<\/code><code class=\"color2\">INSendMessageIntentResponse<\/code><\/div><\/div><\/td><\/tr><\/tbody><\/table><\/div><\/code><\/pre>\n<p>So let&#8217;s add the <code>INSendMessageIntentHandling<\/code> protocol to our class. First we&#8217;ll just specify we want to use it by appending it to the list of protocols our class adheres to in IntentHandler.swift. Since I don&#8217;t actually want the workout intent&#8217;s, I&#8217;ll also remove those, leaving us with just this for the class declaration:<\/p>\n<pre><code><div id=\"highlighter_33684\" class=\"syntaxhighlighter nogutter highlightedCode \"><table border=\"0\" cellpadding=\"0\" cellspacing=\"0\"><tbody><tr><td class=\"code\"><div class=\"container\"><div class=\"line number1 index0 alt2\"><code class=\"keyword\">class<\/code> <code class=\"color2\">IntentHandler<\/code><code class=\"plain\">: <\/code><code class=\"color2\">INExtension<\/code><code class=\"plain\">, <\/code><code class=\"color2\">INSendMessageIntentHandling<\/code> <code class=\"plain\">{<\/code><\/div><div class=\"line number2 index1 alt1\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"plain\">...<\/code><\/div><\/div><\/td><\/tr><\/tbody><\/table><\/div><\/code><\/pre>\n<p>If we just left it at that we wouldn&#8217;t be able to compile our code since we stil need to implement the required methods from the <code>INSendMessageIntentHandling<\/code> protocol.<\/p>\n<p>Again, if you ever need to check what those methods are, just command+click the text <code>INSendMessageIntentHandling<\/code> and take a look at what method signatures are present that are not marked with the <code>optional<\/code> keyword.<\/p>\n<p>In this case we find only one required method:<\/p>\n<pre><code><div id=\"highlighter_445570\" class=\"syntaxhighlighter nogutter highlightedCode \"><table border=\"0\" cellpadding=\"0\" cellspacing=\"0\"><tbody><tr><td class=\"code\"><div class=\"container\"><div class=\"line number1 index0 alt2\"><code class=\"comments\">\/*!<\/code><\/div><div class=\"line number2 index1 alt1\"><code class=\"undefined spaces\">&nbsp;<\/code><code class=\"comments\">@brief handling method<\/code><\/div><div class=\"line number3 index2 alt2\">&nbsp;<\/div><div class=\"line number4 index3 alt1\"><code class=\"undefined spaces\">&nbsp;<\/code><code class=\"comments\">@abstract Execute the task represented by the INSendMessageIntent that's passed in<\/code><\/div><div class=\"line number5 index4 alt2\"><code class=\"undefined spaces\">&nbsp;<\/code><code class=\"comments\">@discussion This method is called to actually execute the intent. The app must return a response for this intent.<\/code><\/div><div class=\"line number6 index5 alt1\">&nbsp;<\/div><div class=\"line number7 index6 alt2\"><code class=\"undefined spaces\">&nbsp;<\/code><code class=\"comments\">@param&nbsp; sendMessageIntent The input intent<\/code><\/div><div class=\"line number8 index7 alt1\"><code class=\"undefined spaces\">&nbsp;<\/code><code class=\"comments\">@param&nbsp; completion The response handling block takes a INSendMessageIntentResponse containing the details of the result of having executed the intent<\/code><\/div><div class=\"line number9 index8 alt2\">&nbsp;<\/div><div class=\"line number10 index9 alt1\"><code class=\"undefined spaces\">&nbsp;<\/code><code class=\"comments\">@see&nbsp; INSendMessageIntentResponse<\/code><\/div><div class=\"line number11 index10 alt2\"><code class=\"undefined spaces\">&nbsp;<\/code><code class=\"comments\">*\/<\/code><\/div><div class=\"line number12 index11 alt1\"><code class=\"keyword\">public<\/code> <code class=\"keyword\">func<\/code> <code class=\"plain\">handle(sendMessage intent: <\/code><code class=\"color2\">INSendMessageIntent<\/code><code class=\"plain\">, completion: (<\/code><code class=\"color2\">INSendMessageIntentResponse<\/code><code class=\"plain\">) -&gt; <\/code><code class=\"color2\">Swift<\/code><code class=\"plain\">.<\/code><code class=\"color1\">Void<\/code><code class=\"plain\">)<\/code><\/div><\/div><\/td><\/tr><\/tbody><\/table><\/div><\/code><\/pre>\n<h3 id=\"adhering-to-the-new-message-intent-protocol\">Adhering to the new Message Intent protocol<\/h3>\n<p>So back in our IntentHandler.swift, let&#8217;s add a line seperator (useful for navigating code with the jump bar)<\/p>\n<pre><code><div id=\"highlighter_395503\" class=\"syntaxhighlighter nogutter highlightedCode \"><table border=\"0\" cellpadding=\"0\" cellspacing=\"0\"><tbody><tr><td class=\"code\"><div class=\"container\"><div class=\"line number1 index0 alt2\"><code class=\"comments\">\/\/ MARK: - INSendMessageIntentHandling<\/code><\/div><\/div><\/td><\/tr><\/tbody><\/table><\/div><\/code><\/pre>\n<p>Underneath this MARK, we can implement the function. I find it&#8217;s most useful with Xcode 8 to simply begin typing the method name, and let autocomplete take it from there, choosing the relevant option.<\/p>\n<p><img decoding=\"async\" src=\"\/blog\/wp-content\/uploads\/siri-1-8.png\" alt=\"Fill out the handle method with autocomplete\"><\/p>\n<p>In our handler, we&#8217;ll need to construct an <code>INSendMessageIntentResponse<\/code> in order to call back the completion handler. We&#8217;ll just assume all messages are successful here and return a success value for the user activity in the <code>INSendMessageIntentResponse<\/code> constructor, similar to how this is done in the template app. We&#8217;ll also add a print statement so we can see when this handle method is triggered by a Siri event:<\/p>\n<pre><code><div id=\"highlighter_853322\" class=\"syntaxhighlighter nogutter highlightedCode \"><table border=\"0\" cellpadding=\"0\" cellspacing=\"0\"><tbody><tr><td class=\"code\"><div class=\"container\"><div class=\"line number1 index0 alt2\"><code class=\"keyword\">func<\/code> <code class=\"plain\">handle(sendMessage intent: <\/code><code class=\"color2\">INSendMessageIntent<\/code><code class=\"plain\">, completion: (<\/code><code class=\"color2\">INSendMessageIntentResponse<\/code><code class=\"plain\">) -&gt; <\/code><code class=\"color1\">Void<\/code><code class=\"plain\">) {<\/code><\/div><div class=\"line number2 index1 alt1\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"functions\">print<\/code><code class=\"plain\">(<\/code><code class=\"string\">\"Message intent is being handled.\"<\/code><code class=\"plain\">)<\/code><\/div><div class=\"line number3 index2 alt2\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"keyword\">let<\/code> <code class=\"plain\">userActivity = <\/code><code class=\"color2\">NSUserActivity<\/code><code class=\"plain\">(activityType: <\/code><code class=\"color1\">NSStringFromClass<\/code><code class=\"plain\">(<\/code><code class=\"color2\">INSendMessageIntent<\/code><code class=\"plain\">))<\/code><\/div><div class=\"line number4 index3 alt1\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"keyword\">let<\/code> <code class=\"plain\">response = <\/code><code class=\"color2\">INSendMessageIntentResponse<\/code><code class=\"plain\">(code: .success, userActivity: userActivity)<\/code><\/div><div class=\"line number5 index4 alt2\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"plain\">completion(response)<\/code><\/div><div class=\"line number6 index5 alt1\"><code class=\"plain\">}<\/code><\/div><\/div><\/td><\/tr><\/tbody><\/table><\/div><\/code><\/pre>\n<h3 id=\"adding-the-intent-type-to-the-info-plist\">Adding the intent type to the Info.plist<\/h3>\n<p>Before this app will be capable of handling <code>INSendMessageIntent<\/code>, we need to add the value to our Info.plist. Think of this as something like an app entitlement.<\/p>\n<p>In the Info.plist file of <strong>the intent<\/strong>, find and expand the <code>NSExtension<\/code> key. Then extend <code>NSExtensionAttributes<\/code>, and then <code>IntentsSupported<\/code> under that. Here we need to add a new row for our <code>INSendMessageIntent<\/code> to allow the app to process Message intents.<\/p>\n<p><img decoding=\"async\" src=\"\/blog\/wp-content\/uploads\/siri-1-9.png\" alt=\"Add support for INSendMessageIntent aka messages intent\"><\/p>\n<h3 id=\"testing-the-new-intent\">Testing the new intent<\/h3>\n<p>Now that we&#8217;ve got our new intent set up, let&#8217;s give it a try. Recall that you must build the app, run it on the device, and then run the extension in order to debug the extension. If you don&#8217;t do run in this order the extension will either not work, or it will not log to the Xcode console.<\/p>\n<p>Try calling upon our intent in Siri, and you will now see a new message window appear! The window is pretty empty, and there isn&#8217;t much logic to tie in to our app just yet. We need to implement the remaining callbacks and add some of our app&#8217;s messaging logic to provide a better experience. We&#8217;ll cover that in <a href=\"http:\/\/jamesonquave.com\/blog\/sirikit-swift-3-resolutions-sirikit-tutorial-part-2\/\">Part 2, which is available now<\/a>. If you want me to email you about it when other tutorials come out as well, <a href=\"http:\/\/eepurl.com\/sDFL9\">sign up for my newsletter to get the scoop<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Siri integration on iOS 10 &#8211; Swift Tutorial This tutorial written on June 13th, 2016 using the Xcode 8 Beta 1, and is using the Swift 3.0 toolchain. Get Xcode 8 set up for iOS 10 and Swift 3 compilation. If you have not yet downloaded Xcode 8 Beta 1, please do so here. (Optional)&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_links_to":"","_links_to_target":""},"categories":[7,10,89],"tags":[15,90,34,33,36,16],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v19.13 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Siri Integration in iOS 10 with Swift - SiriKit Tutorial (Part 1) - Jameson Quave<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/jamesonquave.com\/blog\/adding-siri-to-ios-10-apps-in-swift-tutorial\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Siri Integration in iOS 10 with Swift - SiriKit Tutorial (Part 1) - Jameson Quave\" \/>\n<meta property=\"og:description\" content=\"Siri integration on iOS 10 &#8211; Swift Tutorial This tutorial written on June 13th, 2016 using the Xcode 8 Beta 1, and is using the Swift 3.0 toolchain. Get Xcode 8 set up for iOS 10 and Swift 3 compilation. If you have not yet downloaded Xcode 8 Beta 1, please do so here. (Optional)...\" \/>\n<meta property=\"og:url\" content=\"https:\/\/jamesonquave.com\/blog\/adding-siri-to-ios-10-apps-in-swift-tutorial\/\" \/>\n<meta property=\"og:site_name\" content=\"Jameson Quave\" \/>\n<meta property=\"article:published_time\" content=\"2016-06-14T07:05:34+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2016-06-20T13:46:41+00:00\" \/>\n<meta name=\"author\" content=\"Jameson Quave\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Jameson Quave\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"9 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/jamesonquave.com\/blog\/adding-siri-to-ios-10-apps-in-swift-tutorial\/\",\"url\":\"https:\/\/jamesonquave.com\/blog\/adding-siri-to-ios-10-apps-in-swift-tutorial\/\",\"name\":\"Siri Integration in iOS 10 with Swift - SiriKit Tutorial (Part 1) - Jameson Quave\",\"isPartOf\":{\"@id\":\"https:\/\/jamesonquave.com\/blog\/#website\"},\"datePublished\":\"2016-06-14T07:05:34+00:00\",\"dateModified\":\"2016-06-20T13:46:41+00:00\",\"author\":{\"@id\":\"https:\/\/jamesonquave.com\/blog\/#\/schema\/person\/db6184f355c7f4e3b876d0f228c2fcfc\"},\"breadcrumb\":{\"@id\":\"https:\/\/jamesonquave.com\/blog\/adding-siri-to-ios-10-apps-in-swift-tutorial\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/jamesonquave.com\/blog\/adding-siri-to-ios-10-apps-in-swift-tutorial\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/jamesonquave.com\/blog\/adding-siri-to-ios-10-apps-in-swift-tutorial\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/jamesonquave.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Siri Integration in iOS 10 with Swift &#8211; SiriKit Tutorial (Part 1)\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/jamesonquave.com\/blog\/#website\",\"url\":\"https:\/\/jamesonquave.com\/blog\/\",\"name\":\"Jameson Quave\",\"description\":\"Using computer technology to educate, and improve lives.\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/jamesonquave.com\/blog\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/jamesonquave.com\/blog\/#\/schema\/person\/db6184f355c7f4e3b876d0f228c2fcfc\",\"name\":\"Jameson Quave\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/jamesonquave.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/d9786c83345117d560bbeab0e1f26814?s=96&d=retro&r=pg\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/d9786c83345117d560bbeab0e1f26814?s=96&d=retro&r=pg\",\"caption\":\"Jameson Quave\"},\"sameAs\":[\"http:\/\/jamesonquave.com\"],\"url\":\"https:\/\/jamesonquave.com\/blog\/author\/jquave\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Siri Integration in iOS 10 with Swift - SiriKit Tutorial (Part 1) - Jameson Quave","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/jamesonquave.com\/blog\/adding-siri-to-ios-10-apps-in-swift-tutorial\/","og_locale":"en_US","og_type":"article","og_title":"Siri Integration in iOS 10 with Swift - SiriKit Tutorial (Part 1) - Jameson Quave","og_description":"Siri integration on iOS 10 &#8211; Swift Tutorial This tutorial written on June 13th, 2016 using the Xcode 8 Beta 1, and is using the Swift 3.0 toolchain. Get Xcode 8 set up for iOS 10 and Swift 3 compilation. If you have not yet downloaded Xcode 8 Beta 1, please do so here. (Optional)...","og_url":"https:\/\/jamesonquave.com\/blog\/adding-siri-to-ios-10-apps-in-swift-tutorial\/","og_site_name":"Jameson Quave","article_published_time":"2016-06-14T07:05:34+00:00","article_modified_time":"2016-06-20T13:46:41+00:00","author":"Jameson Quave","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Jameson Quave","Est. reading time":"9 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/jamesonquave.com\/blog\/adding-siri-to-ios-10-apps-in-swift-tutorial\/","url":"https:\/\/jamesonquave.com\/blog\/adding-siri-to-ios-10-apps-in-swift-tutorial\/","name":"Siri Integration in iOS 10 with Swift - SiriKit Tutorial (Part 1) - Jameson Quave","isPartOf":{"@id":"https:\/\/jamesonquave.com\/blog\/#website"},"datePublished":"2016-06-14T07:05:34+00:00","dateModified":"2016-06-20T13:46:41+00:00","author":{"@id":"https:\/\/jamesonquave.com\/blog\/#\/schema\/person\/db6184f355c7f4e3b876d0f228c2fcfc"},"breadcrumb":{"@id":"https:\/\/jamesonquave.com\/blog\/adding-siri-to-ios-10-apps-in-swift-tutorial\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/jamesonquave.com\/blog\/adding-siri-to-ios-10-apps-in-swift-tutorial\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/jamesonquave.com\/blog\/adding-siri-to-ios-10-apps-in-swift-tutorial\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/jamesonquave.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Siri Integration in iOS 10 with Swift &#8211; SiriKit Tutorial (Part 1)"}]},{"@type":"WebSite","@id":"https:\/\/jamesonquave.com\/blog\/#website","url":"https:\/\/jamesonquave.com\/blog\/","name":"Jameson Quave","description":"Using computer technology to educate, and improve lives.","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/jamesonquave.com\/blog\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/jamesonquave.com\/blog\/#\/schema\/person\/db6184f355c7f4e3b876d0f228c2fcfc","name":"Jameson Quave","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/jamesonquave.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/d9786c83345117d560bbeab0e1f26814?s=96&d=retro&r=pg","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/d9786c83345117d560bbeab0e1f26814?s=96&d=retro&r=pg","caption":"Jameson Quave"},"sameAs":["http:\/\/jamesonquave.com"],"url":"https:\/\/jamesonquave.com\/blog\/author\/jquave\/"}]}},"_links":{"self":[{"href":"https:\/\/jamesonquave.com\/blog\/wp-json\/wp\/v2\/posts\/2040"}],"collection":[{"href":"https:\/\/jamesonquave.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/jamesonquave.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/jamesonquave.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/jamesonquave.com\/blog\/wp-json\/wp\/v2\/comments?post=2040"}],"version-history":[{"count":8,"href":"https:\/\/jamesonquave.com\/blog\/wp-json\/wp\/v2\/posts\/2040\/revisions"}],"predecessor-version":[{"id":2102,"href":"https:\/\/jamesonquave.com\/blog\/wp-json\/wp\/v2\/posts\/2040\/revisions\/2102"}],"wp:attachment":[{"href":"https:\/\/jamesonquave.com\/blog\/wp-json\/wp\/v2\/media?parent=2040"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jamesonquave.com\/blog\/wp-json\/wp\/v2\/categories?post=2040"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jamesonquave.com\/blog\/wp-json\/wp\/v2\/tags?post=2040"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}