{"id":22554,"date":"2015-11-09T14:28:16","date_gmt":"2015-11-09T22:28:16","guid":{"rendered":"https:\/\/blog.xamarin.com\/?p=22554"},"modified":"2015-11-09T14:28:16","modified_gmt":"2015-11-09T22:28:16","slug":"getting-started-with-handoff-in-ios","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/xamarin\/getting-started-with-handoff-in-ios\/","title":{"rendered":"Getting Started with Handoff in iOS"},"content":{"rendered":"<p style=\"margin: 0in\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/handoff-icon.png\" alt=\"handoff_icon\" width=\"150\" height=\"250\" class=\"alignright size-thumbnail wp-image-22593\" \/>The users of your application should always be at the center of the functionality you implement. With the beautiful, seamless user experiences that exist in popular mobile apps today, users have high expectations for a great mobile experience. Adding handoff to your iOS apps helps easily deliver a seamless user experience between Apple devices logged into the same iCloud account. Also known as <i>Continuity<\/i>, <a href=\"https:\/\/developer.xamarin.com\/guides\/ios\/platform_features\/introduction_to_ios9\/handoff\/\">Handoff<\/a> was introduced by Apple in iOS 8 and OS X Yosemite. It allows users to\u00a0start an activity on one of their Apple devices and continue that same activity on another of device. Have you ever noticed an app icon on the bottom left corner of your iPhone&#8217;s lock screen? This was an app giving you the option to continue an activity that you had already started on your iPad or your Mac. In this blog post, I will explain how to implement handoff in your iOS apps and the improvements\u00a0Apple has added\u00a0to the Handoff APIs in iOS 9, specifically to NSUserActivity.<\/p>\n<h2>Introducing the NSUserActivity<\/h2>\n<p>One thing that you need to know for this blog post is exactly what a <a href=\"https:\/\/developer.xamarin.com\/api\/type\/Foundation.NSUserActivity\/\">NSUserActivity<\/a> is and how it works. The NSUserActivity class is the primary object in a Handoff exchange and is used to encapsulate the state of a User Activity that is available to pass between Apple devices. Here&#8217;s a diagram of what a Handoff looks like:<\/p>\n<p><img decoding=\"async\" class=\"aligncenter wp-image-22557\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/Screen-Shot-2015-11-03-at-6.01.42-PM-1024x704.png\" alt=\"Handoff Diagram\" width=\"600\" height=\"412\" \/><\/p>\n<p>In this diagram you&#8217;ll notice that the devices need to be logged into the same iCloud account. You can get more details about NSUserActivity class from <a href=\"https:\/\/developer.apple.com\/library\/ios\/documentation\/UserExperience\/Conceptual\/Handoff\/HandoffFundamentals\/HandoffFundamentals.html\">Apple&#8217;s documentation<\/a>.<\/p>\n<h2>NSUserActivity\u00a0for iOS 9<\/h2>\n<p>In iOS 9, the NSUserActivity class that is used for Handoff now gives developers some <a href=\"http:\/\/developer.xamarin.com\/guides\/ios\/platform_features\/introduction_to_ios9\/search\/nsuseractivity\/#Additional_Benefits\">additional benefits<\/a>. In iOS 8, Activities were only used for Handoff, but with the release of iOS 9 Activities are used for App Search, Siri Suggestions, and Siri Smart Reminders. This means it&#8217;s very easy to add <a href=\"http:\/\/developer.xamarin.com\/guides\/ios\/platform_features\/introduction_to_ios9\/search\/nsuseractivity\/\">App Search<\/a> capabilities to an app that is already using Handoff, or vice versa!<\/p>\n<h2>How To Implement Handoff<\/h2>\n<p>Implementing Handoff in a Xamarin.iOS app requires you to create a User Activity Object, update the object&#8217;s state to track the activity, and continue the activity on a receiving device. For this post, we are going to use an app that has four tabs, each with a web browser in them, and Handoff the most recent tab to another device.<\/p>\n<p><b>Note:<\/b> Please make sure you <a href=\"https:\/\/developer.xamarin.com\/guides\/ios\/platform_features\/introduction_to_ios9\/handoff\/#Enabling_Handoff_in_a_Xamarin_App\">enable Handoff<\/a>\u00a0in your Xamarin app before you start adding the new functionality.<\/p>\n<h3>Getting Set Up<\/h3>\n<p><span style=\"line-height: 1.5\">1. Add NSUserActivityTypes to your info.plist.<\/span><\/p>\n<p style=\"padding-left: 30px\">a. Since I have four tabs in my app, I&#8217;m going to add four Activity Types to my info.plist file like this:<\/p>\n<p style=\"line-height: 1.5\"><img decoding=\"async\" class=\"wp-image-22563 alignleft\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/Screen-Shot-2015-11-03-at-6.22.48-PM-1024x228.png\" alt=\"Activity Types\" width=\"450\" height=\"100\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>2. Add NSUserActivity constants to AppDelegate.<\/p>\n<p style=\"padding-left: 30px\">a.\u00a0Notice that my constants are consistent with the values in my info.plist.<\/p>\n<pre class=\"lang:csharp decode:true\" style=\"padding-left: 60px\">public NSString UserActivityTab1 = new NSString (\"com.xamarin.monkeybrowser.tab1\");\npublic NSString UserActivityTab2 = new NSString (\"com.xamarin.monkeybrowser.tab2\");\npublic NSString UserActivityTab3 = new NSString (\"com.xamarin.monkeybrowser.tab3\");\npublic NSString UserActivityTab4 = new NSString (\"com.xamarin.monkeybrowser.tab4\");\n<\/pre>\n<h3>Creating a NSUserActivity<\/h3>\n<p>In my app, I want to create a new NSUserActivity each time a user enters a new URL in the WebView.<\/p>\n<p>1. On each ViewController, I want to add a public NSUserActivity object:<\/p>\n<pre class=\"lang:csharp decode:true\" style=\"padding-left: 60px\">public NSUserActivity UserActivity { get; set; }\n<\/pre>\n<p>2. Now, in the method used to navigate to a new URL, I&#8217;ll create a new NSUserActivity (after invalidating the existing one:<\/p>\n<pre class=\"lang:csharp decode:true\" style=\"padding-left: 60px\">if (UserActivity != null) {\n     UserActivity.Invalidate();\n     UserActivity = null;\n}\nUserActivity = new NSUserActivity (ThisApp.UserActivityTab1){\n     Title = \"Weather Tab\",\n     SupportsContinuationStreams = true\n};\n<\/pre>\n<p>3. Finally, I&#8217;ll add some User Info to the new Activity and I&#8217;ll make it the <em>Current<\/em> activity.<\/p>\n<pre class=\"lang:csharp decode:true\" style=\"padding-left: 60px\">var userInfo = new NSMutableDictionary ();\nuserInfo.Add (new NSString (\"Url\"), new NSString (url));\nUserActivity.AddUserInfoEntries (userInfo);\nUserActivity.BecomeCurrent ();\n<\/pre>\n<h3>Continuing an Activity<\/h3>\n<p>1. Add a PerformHandoff method to each ViewController:<\/p>\n<pre class=\"lang:csharp decode:true\" style=\"padding-left: 60px\">public void PerformHandoff(NSUserActivity activity) \n{\n     var url = activity.UserInfo [\"Url\"].ToString ();\n     URL.Text = url;\n     WebView.LoadRequest(new NSUrlRequest(NSUrl.FromString(url)));\n     UserActivity = activity;\n     UserActivity.BecomeCurrent ();\n}\n<\/pre>\n<p>2. Add properties to UIApplicationDelegate for each ViewController so that I can access the <em>PerformHandoff<\/em> method I just implemented:<\/p>\n<pre class=\"lang:csharp decode:true\" style=\"padding-left: 60px\">public FirstViewController Tab1 { get; set; }\npublic SecondViewController Tab2 { get; set;}\npublic ThirdViewController Tab3 { get; set; }\npublic FourthViewController Tab4 { get; set; }\n<\/pre>\n<p>3. Override the <em>ContinueUserActivity<\/em> method in App Delegate:<\/p>\n<pre class=\"lang:csharp decode:true\" style=\"padding-left: 60px\">public override bool ContinueUserActivity (UIApplication application, NSUserActivity userActivity, UIApplicationRestorationHandler completionHandler)\n{\n     switch (userActivity.ActivityType) {\n          case \"com.xamarin.monkeybrowser.tab1\":\n\t       Tab1.PerformHandoff (userActivity);\n\t       completionHandler (new NSObject[]{Tab1});\n\t       break;\n\t  case \"com.xamarin.monkeybrowser.tab2\":\n\t       Tab2.PerformHandoff (userActivity);\n\t       completionHandler (new NSObject[]{Tab2});\n\t       break;\n\t  case \"com.xamarin.monkeybrowser.tab3\":\n\t       Tab3.PerformHandoff (userActivity);\n\t       completionHandler (new NSObject[]{Tab3});\n\t       break;\n\t  case \"com.xamarin.monkeybrowser.tab4\":\n\t       Tab4.PerformHandoff (userActivity);\n\t       completionHandler (new NSObject[]{Tab4});\n\t       break;\n     }\n     return true;\n}\n<\/pre>\n<h2>Additional Resources<\/h2>\n<p>We have a detailed <a href=\"https:\/\/developer.xamarin.com\/guides\/ios\/platform_features\/introduction_to_ios9\/handoff\/\">Introduction to Handoff<\/a> guide that has more screenshots and details on how to gracefully handle failures with handoff, best practices, and more. There&#8217;s also a <a href=\"https:\/\/developer.xamarin.com\/samples\/monotouch\/ios8\/MonkeyBrowser\/\">sample handoff app<\/a> for iOS 8 that you could easily add some code to that makes each of\u00a0the NSUserActivity used for Handoff <a href=\"http:\/\/developer.xamarin.com\/guides\/ios\/platform_features\/introduction_to_ios9\/search\/nsuseractivity\/\">searchable through spotlight<\/a>.\t\t<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The users of your application should always be at the center of the functionality you implement. With the beautiful, seamless user experiences that exist in popular mobile apps today, users have high expectations for a great mobile experience. Adding handoff to your iOS apps helps easily deliver a seamless user experience between Apple devices logged [&hellip;]<\/p>\n","protected":false},"author":544,"featured_media":22593,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[2],"tags":[6],"class_list":["post-22554","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-developers","tag-ios"],"acf":[],"blog_post_summary":"<p>The users of your application should always be at the center of the functionality you implement. With the beautiful, seamless user experiences that exist in popular mobile apps today, users have high expectations for a great mobile experience. Adding handoff to your iOS apps helps easily deliver a seamless user experience between Apple devices logged [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts\/22554","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/users\/544"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/comments?post=22554"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts\/22554\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/media?parent=22554"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/categories?post=22554"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/tags?post=22554"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}