{"id":8514,"date":"2013-12-06T10:50:54","date_gmt":"2013-12-06T15:50:54","guid":{"rendered":"http:\/\/blog.xamarin.com\/?p=8514"},"modified":"2013-12-06T10:50:54","modified_gmt":"2013-12-06T15:50:54","slug":"apple-stores-use-ibeacons-and-so-can-you","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/xamarin\/apple-stores-use-ibeacons-and-so-can-you\/","title":{"rendered":"Apple Stores use iBeacons (and so can you!)"},"content":{"rendered":"<p>\t\t\t\tToday, <a href=\"http:\/\/mobile.theverge.com\/2013\/12\/6\/5181302\/apple-store-ibeacon-rollout\" target=\"_blank\">Apple began using iBeacons in all of their retail stores<\/a> across the United States. In this article, I&#8217;ll show you how C# developers can also take advantage of this exciting technology.<\/p>\n<p>We&#8217;re going to take a look at <a href=\"\/play-find-the-monkey-with-ios-7-ibeacons\/\">iBeacons<\/a> and <a href=\"\/send-the-monkey-a-message-with-multipeer-connectivity\/\">Multipeer Connectivity<\/a>, and show how they can be used in concert to create a unique in-store experience for customers with a coupon-serving iOS app.<\/p>\n<p><img decoding=\"async\" style=\"margin-left: auto;margin-right: auto\" title=\"InStoreCoupon.png\" alt=\"InStoreCoupon\" src=\"\/wp-content\/uploads\/sites\/44\/2019\/04\/InStoreCoupon.png\" width=\"433\" height=\"422\" border=\"0\" \/><\/p>\n<p>For this app, when a customer enters the store, the iPhone version of the application will find an iBeacon in the store, and enable the customer to get a coupon for that store. In the store itself, an iPad will serve as the iBeacon, as well as handle sending the coupon information to the customer.<\/p>\n<p>To advertise itself as an iBeacon, the app will:<\/p>\n<ol>\n<li>Create a beacon region.<\/li>\n<li>Get peripheral data from the beacon region.<\/li>\n<li>Create a peripheral manager.<\/li>\n<li>Use the peripheral manager to advertise the peripheral data.<\/li>\n<\/ol>\n<p>Creating a beacon region is done by passing an NSUuid to a CLBeaconRegion instance:<\/p>\n<pre class=\"lang:csharp decode:true\">\n\/\/ Create a beacon region\nvar storeUUID = new NSUuid (uuid);\nvar beaconRegion = new CLBeaconRegion (storeUUID, storeId) {\n  NotifyEntryStateOnDisplay = true,\n  NotifyOnEntry = true,\n  NotifyOnExit = true\n};\n<\/pre>\n<p>Then, we can use the CLBeaconRegion\u00a0to get an NSMutableDictionary containing the peripheral data for a specified beacon power:<\/p>\n<pre class=\"lang:csharp decode:true\">\n\/\/ Get peripheral data from the beacon region\nNSMutableDictionary peripheralData = beaconRegion.GetPeripheralData (new NSNumber (-59));\n<\/pre>\n<p>With the\u00a0CLBeaconRegion\u00a0and peripheral data in place, we can create a CBPeripheralManager to advertise the beacon:<\/p>\n<pre class=\"lang:csharp decode:true\">\n\/\/ Create a peripheral manager and start advertising\nperipheralMgr = new CBPeripheralManager (peripheralDelegate, DispatchQueue.DefaultGlobalQueue);\nperipheralMgr.StartAdvertising (peripheralData);\n<\/pre>\n<p>That\u2019s all you need to do to advertise an iBeacon. Now let\u2019s see how we can discover it from the iPhone app.<\/p>\n<p>To discover when we enter the beacon region, we use the Core Location framework. In Xamarin.iOS we can take advantage of location manager delegate methods being wrapped in C# events. We need to handle the RegionEntered event for when the region is entered, in addition to the DidDetermineState event, for the case where the beacon is first discovered when already in the beacon region (such as the case where the iPad is turned on with the customer carrying the iPhone already being in the store). Note, we set NotifyEntryStateOnDisplay above to get this event in all cases.<\/p>\n<pre class=\"lang:csharp decode:true\">\nlocationMgr = new CLLocationManager ();\n\nlocationMgr.RegionEntered += (object sender, CLRegionEventArgs e) =&gt; {\n  if (e.Region.Identifier == storeId) {\n    WelcomeBackCustomer ();\n  }\n};\n\nlocationMgr.DidDetermineState += (object sender, CLRegionStateDeterminedEventArgs e) =&gt; {\n  if(e.State == CLRegionState.Inside){\n    if(!DealofDay.Enabled){\n      WelcomeBackCustomer ();\n    }\n  }\n};\n<\/pre>\n<p>The WelcomeBackCustomer method simply presents a notification and enables a button to allow the user to connect to the iPad to get a coupon.<\/p>\n<p>In this case, we use the iPad to browse for peers (customers) using Multipeer Connectivity framework\u2019s MCBrowserViewController, as shown below:<\/p>\n<pre class=\"lang:csharp decode:true\">\npeer = new MCPeerID (storeId);\n\nsession = new MCSession (peer) {\n  Delegate = sessionDel\n};\n\nbrowser = new MCBrowserViewController (serviceType, session) {\n  Delegate = browserDel,\n  ModalPresentationStyle = UIModalPresentationStyle.None\n};\n<\/pre>\n<p>On the iPhone, the app uses an MCAdvertiserAssistant to advertise itself to peers:<\/p>\n<pre class=\"lang:csharp decode:true\">\npeer = new MCPeerID (customer.ToString ());\n\nsession = new MCSession (peer) {\n  Delegate = sessionDel\n};\n\nassistant = new MCAdvertiserAssistant (serviceType, dict, session);\nassistant.Start ();\n<\/pre>\n<p>Then, in the MCSessionDelegate, we send a coupon when the customer has connected:<\/p>\n<pre class=\"lang:csharp decode:true\">\npublic override void DidChangeState (MCSession session, MCPeerID peerID, MCSessionState state)\n{\n  switch (state) {\n  case MCSessionState.Connected:\n    if (peerID.DisplayName != storeId) {\n      vc.SendCoupon (&quot;buy 1 widget, get a second for 1\/2 price&quot;, peerID);\n    }\n    break;\n  ...\n  }\n}\n<\/pre>\n<p>Finally SendCoupon uses the MCSession to send the coupon information in a string for simplicity.<\/p>\n<pre class=\"lang:csharp decode:true\">\nvoid SendCoupon (string message, MCPeerID peer)\n{\n  NSError error;\n\n  session.SendData (NSData.FromString (peer.DisplayName + &quot;:&quot; + message), new MCPeerID[]{peer},\u00a0MCSessionSendDataMode.Reliable,\u00a0out error);\n}\n<\/pre>\n<p>The coupon\u00a0image is generated on the receiver using the CIQRCodeGenerator filter from Core Image:<\/p>\n<pre class=\"lang:csharp decode:true\">\nvar qrCode = new CIQRCodeGenerator {\n  Message = NSData.FromString (text),\n  CorrectionLevel = &quot;Q&quot;\n}.OutputImage;\n<\/pre>\n<p>The code for this post is available in my <a href=\"https:\/\/github.com\/mikebluestein\/InStoreCoupons\" target=\"_blank\">github repo<\/a>.<\/p>\n<p><span style=\"font-family: Menlo\"><span style=\"color: #444444\">\u00a0<\/span><\/span>\t\t<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Today, Apple began using iBeacons in all of their retail stores across the United States. In this article, I&#8217;ll show you how C# developers can also take advantage of this exciting technology. We&#8217;re going to take a look at iBeacons and Multipeer Connectivity, and show how they can be used in concert to create a [&hellip;]<\/p>\n","protected":false},"author":1932,"featured_media":39167,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[2],"tags":[4],"class_list":["post-8514","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-developers","tag-xamarin-platform"],"acf":[],"blog_post_summary":"<p>Today, Apple began using iBeacons in all of their retail stores across the United States. In this article, I&#8217;ll show you how C# developers can also take advantage of this exciting technology. We&#8217;re going to take a look at iBeacons and Multipeer Connectivity, and show how they can be used in concert to create a [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts\/8514","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\/1932"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/comments?post=8514"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts\/8514\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/media\/39167"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/media?parent=8514"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/categories?post=8514"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/tags?post=8514"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}