{"id":133,"date":"2014-06-15T23:12:00","date_gmt":"2014-06-16T07:12:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/vbteam\/2014\/06\/15\/vb-universal-windows-app-part-3-for-the-end-user-roaming-settings-and-in-app-purchases\/"},"modified":"2024-07-05T12:37:50","modified_gmt":"2024-07-05T19:37:50","slug":"vb-universal-windows-app-part-3-for-the-end-user-roaming-settings-and-in-app-purchases","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/vbteam\/vb-universal-windows-app-part-3-for-the-end-user-roaming-settings-and-in-app-purchases\/","title":{"rendered":"VB Universal Windows App Part 3 (for the end-user): roaming settings, and in-app purchases"},"content":{"rendered":"<p>This is Part 3 of the &#8220;<a href=\"http:\/\/blogs.msdn.com\/b\/vbteam\/archive\/tags\/universal\/\">VB Universal Windows App<\/a>&#8221; series:<\/p>\n<ul>\n<li><a href=\"http:\/\/blogs.msdn.com\/b\/vbteam\/archive\/2014\/06\/15\/vb-universal-app-part-1-getting-started.aspx\">Part 1: Setting up the universal Windows app in the Dev Centers, and in VS Solution Explorer<\/a><\/li>\n<li><a href=\"http:\/\/blogs.msdn.com\/b\/vbteam\/archive\/2014\/06\/15\/vb-universal-app-part-2-for-the-developer-sharing-xaml-assets-and-code.aspx\">Part 2: Sharing XAML, Assets and Code<\/a><\/li>\n<li><strong>&gt; Part 3: Local and Roaming settings, and In-App purchases<\/strong><\/li>\n<li><span style=\"color: #000000\"><a href=\"http:\/\/blogs.msdn.com\/b\/vbteam\/archive\/2014\/06\/15\/vb-universal-app-part-4-using-sharpdx-for-sound-effects-with-ioc-and-linkedfiles.aspx\">Part 4: Sound effects with SharpDX<\/a><\/span><\/li>\n<li><span style=\"color: #000000\"><a href=\"http:\/\/blogs.msdn.com\/b\/vbteam\/archive\/2014\/06\/20\/vb-universal-windows-app-part-5-calling-into-platform-specific-apis-from-pcl.aspx\">Part 5: How to call platform-specific APIs from common code<\/a><\/span><\/li>\n<li><span style=\"color: #000000\"><a href=\"http:\/\/blogs.msdn.com\/b\/vbteam\/archive\/2014\/06\/21\/vb-universal-app-downloads.aspx\">Download full source code<\/a><\/span><\/li>\n<\/ul>\n<p>In the first two parts we set up a VS Solution that helped us to share between our two app projects. In this post, we&#8217;re going to code in the user-facing benefits of universal Windows apps.<\/p>\n<p>From an end-user perspective, the benefit of universal Windows apps is that (1) if you buy the app in one store then it counts as bought in both, (2) if you buy a durable in-app purchase on one device then it counts as bought on both, (3) settings will roam between the Windows and Windows Phone versions of an app.<\/p>\n<p>The first part (buy the app in one store and it counts as bought in both) is already complete, simply by registering the app with the same name in both stores. What we&#8217;re going to implement is roaming settings, and in-app purchases.<\/p>\n<p>I want to point out that the <em>entirety<\/em> of today&#8217;s blog post is authored in the common PCL. We&#8217;ve &#8220;won&#8221; &#8211; we&#8217;ve set up the universal Windows app so we can do our work just once, and it works for both apps.<\/p>\n<p>&nbsp;<\/p>\n<h2>Roaming settings<\/h2>\n<p>We&#8217;ll create some settings which will roam, and some settings which are local to each device.<\/p>\n<ul>\n<li><a href=\"http:\/\/media.ch9.ms\/ch9\/5ba6\/d6be44db-6937-4c7f-bdd1-379526d15ba6\/5settings_Source.wmv\">How Do I video: roam settings between devices<\/a> [2mins]<\/li>\n<\/ul>\n<p>Don&#8217;t panic! The task of saving state can sometimes seem daunting. But as you can see it&#8217;s only a two minute video to code it up from beginning to end.<\/p>\n<p>What helps is to plan your app&#8217;s data <em>before <\/em>you start coding the app. Keep in mind that all Windows and Windows Phone apps might be summarily terminated. When they&#8217;re re-launched, the user will expect them to resume right where they left off. Therefore you need a way to save the current <em>state <\/em>of your app, and reload it later. That&#8217;s the reason for the two &#8220;TODO&#8221; comments in the above code:<\/p>\n<p><span style=\"font-size: 9.0pt;font-family: Consolas;color: green;background: white\">&#8216; TODO: Save application state and stop any background activity<\/span><br \/><span style=\"font-size: 9.0pt;font-family: Consolas;color: green;background: white\">&#8216; TODO: Load state from previously suspended application<\/span><br \/><span style=\"font-size: 9.0pt;font-family: Consolas;color: green;background: white\">&nbsp;<\/span><br \/><strong>&nbsp;<\/strong><br \/><strong>Step 1<\/strong>: replace those comments with calls to two functions that we&#8217;re going to write:<\/p>\n<p><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Shared<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Sub<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> LoadState()<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Shared<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Sub<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> SaveState()<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><br \/><span style=\"font-size: 9.0pt;font-family: Consolas;color: green;background: white\">&nbsp;<\/span><\/p>\n<p style=\"margin-left: .5in\"><strong><em>Pro tip:<\/em><\/strong><em> The Windows and Windows Phone design guidelines recommend that if the user manually launches the app then it should start in a &#8220;fresh&#8221; state, but if app is relaunched because (for instance) it had been shut down and the user navigated back to it, then it should resume where it left off. However many users nowadays prefer apps that violate these guidelines by <strong>always<\/strong> resuming where the user left off. Twitter on Windows Phone does this, for instance. You can achieve this Twitter effect just by commenting-out this &#8220;If&#8221; check in the OnLaunched method, i.e. by always reloading state.<\/em><\/p>\n<p><span style=\"font-size: 9.0pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"font-size: 9.0pt;font-family: Consolas;color: green;background: white\">&#8216; If e.PreviousExecutionState = ApplicationExecutionState.Terminated Then<br \/> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"font-size: 9.0pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;<\/span><s><span style=\"font-size: 9.0pt;font-family: Consolas;color: green;background: white\">&#8216; TODO: Load state from previously suspended application<\/span><\/s><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LoadState()<\/span>&nbsp;<span style=\"font-size: 9.0pt;font-family: Consolas;color: green;background: white\"><br \/> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8216; End If<\/span><br \/><span style=\"font-size: 9.0pt;font-family: Consolas;color: green;background: white\">&nbsp;<\/span><\/p>\n<p><strong>&nbsp;<\/strong><\/p>\n<p><strong>Plan in advance the three kinds of state.<\/strong><\/p>\n<p><em>Transient state<\/em> is stuff that will be constructed when the application starts, and not persisted. Example: the current mouse coordinates, or a single app-wide instance of &#8220;Dim RND As New System.Random()&#8221;. (However, if you were writing say a card game and wanted to continue with the same random number sequence, then RND would be local state&#8230; see <a href=\"http:\/\/stackoverflow.com\/questions\/8188844\/is-there-a-way-to-grab-the-actual-state-of-system-random\/8188878#8188878\">here<\/a> for ideas how).<\/p>\n<p><em>Local state<\/em> is stuff that will be saved onto the current device when your app suspends, and reloaded when the app resumes. Example: the currently open page and its values; or the current position of all pieces in a Checkers game.<\/p>\n<p><em>Roaming state<\/em> is stuff that will be saved and reloaded just like local data. But it will also be synced to other devices, at times outside the control of the app developer or end user. The other device might even sync its data to your app <em>while your app is currently running!<\/em> Example: user preferences for whether they like inches or centimeters, or whether your app&#8217;s flying toasters should be lightly toasted or dark brown. Roaming state cannot be larger than 100k at present.<\/p>\n<p><strong>&nbsp;<\/strong><\/p>\n<p style=\"margin-left: 20.5pt\"><strong><em>Pro tip:<\/em><\/strong><em> as your app &#8220;grows up&#8221;, you&#8217;ll find it easiest to completely decouple the state+logic from the UI, in a design pattern called MVVM. There are lots of training resources on the topic, e.g. <\/em><a href=\"http:\/\/visualstudiomagazine.com\/articles\/2011\/10\/01\/mvvm-in-5-minutes.aspx\"><em>MVVM in 5 Minutes<\/em><\/a><em> and <\/em><a href=\"http:\/\/maligui.hubpages.com\/hub\/MVVM-in-VBNet-Lesson-4-The-Model\"><em>MVVM in VB.Net<\/em><\/a><em> and <\/em><a href=\"http:\/\/msdn.microsoft.com\/en-us\/magazine\/jj651572.aspx\"><em>MVVM in Windows 8<\/em><\/a><em>.<\/em><\/p>\n<p>&nbsp;<\/p>\n<p><strong>Plan in advance how you will <em>serialize<\/em> your local and roaming data to disk. <\/strong>For instance, you&#8217;ll have to figure out how to serialize the current open page (including position of all scrollbars and checkboxes), or how to serialize the current position of all game pieces.<\/p>\n<p>Again, don&#8217;t panic! There are two techniques presented here. The first, <em>settings dictionaries<\/em>, are very easy to use for small amounts of data. The second, <em>data contracts<\/em>, become easy to use once you&#8217;ve put some initial plumbing in place.<\/p>\n<p>&nbsp;<\/p>\n<p style=\"margin-left: 0in\"><em>Settings dictionaries <\/em>are provided by Windows and can be used to manually serialize and deserialize key\/value pairs. They are convenient if there isn&#8217;t much data to serialize, but can&#8217;t hold more than 8k per setting. (Note: we&#8217;ve factored the &#8220;reload-roaming-state&#8221; into a separate method, for reasons we&#8217;ll come to later).<\/p>\n<p><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Shared<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Sub<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> SaveState()<br \/><\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\"><span style=\"color: #000000\">&nbsp;&nbsp;&nbsp; <\/span>ApplicationData<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">.Current.LocalSettings.Values(<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #a31515;background: white\">&#8220;x&#8221;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">) = x<\/span><br \/> <span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;ApplicationData<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">.Current.LocalSettings.Values(<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #a31515;background: white\">&#8220;y&#8221;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">) = y<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">&nbsp;&nbsp;&nbsp; ApplicationData<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">.Current.RoamingSettings.Values(<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #a31515;background: white\">&#8220;burntToast&#8221;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">) = burntToast<br \/><\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">End Sub<\/p>\n<p> Shared<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Sub<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> LoadState()<br \/> &nbsp;&nbsp;&nbsp; x = <\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">CDbl<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">(<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">ApplicationData<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">.Current.LocalSettings.Values(<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #a31515;background: white\">&#8220;x&#8221;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">))<\/span><br \/> <span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;y = <\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">CDbl<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">(<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">ApplicationData<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">.Current.LocalSettings.Values(<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #a31515;background: white\">&#8220;y&#8221;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">))<br \/> &nbsp;&nbsp;&nbsp; ReloadRoamingState(<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">ApplicationData<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">.Current, <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Nothing<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">)<br \/><\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">End Sub<br \/>&nbsp;<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"><br \/> <\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Shared Sub<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> ReloadRoamingState(appData <\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">As<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">ApplicationData<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">, o <\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">As<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Object<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">)<br \/> &nbsp;&nbsp;&nbsp; burntToast = <\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">CBool<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">(<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">ApplicationData<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">.Current.LocalSettings.Values(<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #a31515;background: white\">&#8220;burntToast&#8221;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">))<br \/><\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">End Sub<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><\/p>\n<p style=\"margin-top: 0in;margin-right: 0in;margin-bottom: .0001pt;margin-left: 20.5pt;line-height: normal\"><strong><em>Pro tip:<\/em><\/strong><em> when you release v2 of your app and users will first install it, your apps LoadState method will find only v1 state. Make sure you plan for the future. One common idea is to include a version number in the state, so their LoadState method knows exactly what it&#8217;s loading.<\/em><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><\/p>\n<p><em>DataContracts<\/em> are useful if you have complex classes or structures to serialize. They are explained on MSDN <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms733811(v=vs.110).aspx\">here<\/a>. Briefly, you put the &lt;DataContract&gt; attribute on your class or structure, and &lt;DataMember&gt; on members, and the entire whole thing serializes easily.<\/p>\n<p><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&lt;<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">DataContract<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&gt;<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Public<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Class<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">GameState<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; &lt;<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">DataMember<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&gt; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Public<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> balls <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">As<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">List<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">(<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Of <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">BallInfo<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">)<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; &lt;<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">DataMember<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&gt; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Public<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> background <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">As<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">Color<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">End<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Class<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&lt;<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">DataContract<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&gt;<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Public<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Class<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">BallInfo<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; &lt;<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">DataMember<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&gt; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Public<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> x <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">As<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Double<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; &lt;<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">DataMember<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&gt; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Public<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> y <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">As<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Double<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; &lt;<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">DataMember<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&gt; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Public<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> dx <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">As<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Double<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; &lt;<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">DataMember<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&gt; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Public<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> dy <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">As<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Double<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">End<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Class<\/span><br \/>&nbsp;<br \/>I&#8217;m going to show how to use DataContracts to serialize state to a file in the LocalFolder or RoamingFolder. By using files we bypass the 8k limit faced by Settings, but it&#8217;s more complicated to load. That&#8217;s because reading files is an async operation, which might take time to complete, so the OnLaunched method can merely <em>kick off<\/em> the state-loading process. It&#8217;s up to you to make sure the rest of your app deals gracefully with it, maybe by having your main page show a progress indicator until the load has finished.<br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Shared<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Async<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Function<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> SaveStateAsync() <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">As<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">Task<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Dim<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> file = <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Await<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">ApplicationData<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">.Current.LocalFolder.CreateFileAsync(<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #a31515;background: white\">&#8220;settings.dat&#8221;<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">, <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">CreationCollisionOption<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">.ReplaceExisting)<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Using<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> stream = <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Await<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> file.OpenStreamForWriteAsync()<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Dim<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> d <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">As<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">New<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">DataContractSerializer<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">(<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">GetType<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">(<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">GameState<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">))<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; d.WriteObject(stream, currentGameState)<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">End<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Using<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">End<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Function<\/span><\/p>\n<p><span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: green;background: white\">&nbsp;<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Shared<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Async<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Sub<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> StartLoadStateAsync()<\/span><br \/> <span style=\"font-size: 9.5pt;font-family: Consolas;color: green;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&#8216; Async Subs are generally bad practice, because there&#8217;s no way for the<\/span><br \/> <span style=\"font-size: 9.5pt;font-family: Consolas;color: green;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&#8216; caller to know when we&#8217;re finished or to catch exceptions.<\/span><br \/> <span style=\"font-size: 9.5pt;font-family: Consolas;color: green;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&#8216; But in this case we have no choice &#8211; so we&#8217;ll handle exceptions ourselves,<br \/> &nbsp;&nbsp;&nbsp; &#8216; and expect the rest of the app to respond gracefully when<br \/> &nbsp;&nbsp;&nbsp; &#8216; &#8220;currentGameState&#8221; gets assigned.<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Try<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Dim<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> file = <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Await<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">ApplicationData<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">.Current.LocalFolder.GetFileAsync(<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #a31515;background: white\">&#8220;settings.dat&#8221;<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">)<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Using<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> stream = <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Await<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> file.OpenStreamForReadAsync()<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Dim<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> d <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">As<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">New<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">DataContractSerializer<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">(<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">GetType<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">(<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">GameState<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">))<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; currentGameState = <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">CType<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">(d.ReadObject(stream), <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">GameState<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">)<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">End<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Using<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Catch<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> ex <\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">As<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">Exception<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">When<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">TypeOf<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> ex <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Is<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">FileNotFoundException<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">OrElse<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">TypeOf<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> ex <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Is<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">SerializationException<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: green;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8216; If we couldn&#8217;t load existing state, then we&#8217;ll start with fresh default state:<br \/>&nbsp;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gs = <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">New<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">GameState<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gs.background = Windows.UI.<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">Colors<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">.Aquamarine<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gs.balls.Add(<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">New<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">BallInfo<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">With<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> {.x = 15, .y = 10, .dx = 1, .dy = 2})<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gs.balls.Add(<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">New<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">BallInfo<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">With<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> {.x = 1, .y = 2, .dx = 3, .dy = 4})<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Catch<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> ex <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">As<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">Exception<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SendErrorReport(ex)<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">End<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Try<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">End<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Sub<\/span><\/p>\n<p><span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: green;background: white\">&nbsp;<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Public<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Shared<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Sub<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> OnLaunched(e <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">As<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">LaunchActivatedEventArgs<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">)<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Dim<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> rootFrame = <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">TryCast<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">(<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">Window<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">.Current.Content, <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">Frame<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">)<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">If<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> rootFrame <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Is<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Nothing<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Then<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rootFrame = <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">New<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">Frame<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">()<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">If<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> e.PreviousExecutionState = <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">ApplicationExecutionState<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">.Terminated <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Then<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; StartLoadStateAsync() <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: green;background: white\">&#8216; Kick off this long-running method<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">End<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">If<br \/> <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; &#8230;.<br \/> <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">End<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Sub<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><\/p>\n<p><span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><strong>How to deal with <em>syncing of roaming data<\/em>.<\/strong><\/p>\n<p>Roaming data should be loaded in OnLaunched, and saved upon app suspension, as normal. But you should also deal with what happens when roaming data is delivered onto the device while your app is currently running. The process is straightforward. Here are the hooks:<\/p>\n<p><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Sub<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> OnLaunched(e <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">As<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">LaunchActivatedEventArgs<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">)<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">AddHandler<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">ApplicationData<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">.Current.DataChanged, <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">AddressOf<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> ReloadRoamingState<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black\">&nbsp;&nbsp;&nbsp; &#8230;<br \/> <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">End Sub<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue\"><\/p>\n<p> <span style=\"background: white\">Async<\/span><\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Function<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> OnSuspendingAsync() <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">As<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">Task<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">RemoveHandler<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">ApplicationData<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">.Current.DataChanged, <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">AddressOf<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> ReloadRoamingState<\/span><br \/> <span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: black\">&nbsp;&nbsp;&nbsp;&nbsp;&#8230;<br \/> <\/span>&nbsp;<span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: blue;background: white\">End Sub<\/span>&nbsp;<span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: blue\"><\/p>\n<p> <span style=\"background: white\">Sub<\/span><\/span>&nbsp;<span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: black;background: white\"> ReloadRoamingState(appData <\/span>&nbsp;<span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: blue;background: white\">As<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: #2b91af;background: white\">ApplicationData<\/span>&nbsp;<span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: black;background: white\">, o <\/span>&nbsp;<span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: blue;background: white\">As<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: blue;background: white\">Object<\/span>&nbsp;<span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: black;background: white\">)<\/span>&nbsp;<span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: black\"><br \/> &nbsp;&nbsp;&nbsp; &#8230; deserialize the data as discussed previously<br \/> <\/span>&nbsp;<span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: blue;background: white\">End Sub<\/span><\/p>\n<p style=\"margin-left: 20.5pt\"><strong><em>&nbsp;<\/em><\/strong><\/p>\n<h2>In-app purchases<\/h2>\n<p>We already created an in-app purchase in the two dev centers for something we called &#8220;SpeedBoost&#8221;. Now we&#8217;ll add code to use it, and to allow the user to purchase it from within the app.<\/p>\n<ul>\n<li><a href=\"http:\/\/media.ch9.ms\/ch9\/a97d\/715151cf-a968-4b84-a3fd-514f4ffaa97d\/6purchase_Source.wmv\">How Do I video: code an in-app purchase<\/a> [2mins]<\/li>\n<\/ul>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/vbteam\/wp-content\/uploads\/sites\/7\/2014\/06\/8358.image33.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/vbteam\/wp-content\/uploads\/sites\/7\/2014\/06\/8358.image33.png\" alt=\"\" border=\"0\" \/><\/a><\/p>\n<p>The point about an in-app purchase is that the user can buy it from within the app! Here&#8217;s a screenshot of the &#8220;purchase&#8221; button I created for Paddle Game (in this case for a computer guidance system, rather than a speed boost):<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/vbteam\/wp-content\/uploads\/sites\/7\/2014\/06\/1651.image34.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/vbteam\/wp-content\/uploads\/sites\/7\/2014\/06\/1651.image34.png\" alt=\"\" border=\"0\" \/><\/a><\/p>\n<p>As for what the user sees after they click your purchase button, that&#8217;s entirely implemented by the system. The bad news is that you&#8217;re only going to see success or dialogs until after your app has been finished and uploaded to the stores (and even after that it sometimes takes a day or two for everything to be approved).<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/vbteam\/wp-content\/uploads\/sites\/7\/2014\/06\/2425.image35.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/vbteam\/wp-content\/uploads\/sites\/7\/2014\/06\/2425.image35.png\" alt=\"\" border=\"0\" \/><\/a>&nbsp;<a href=\"https:\/\/devblogs.microsoft.com\/vbteam\/wp-content\/uploads\/sites\/7\/2014\/06\/0652.image36.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/vbteam\/wp-content\/uploads\/sites\/7\/2014\/06\/0652.image36.png\" alt=\"\" border=\"0\" \/><\/a>&nbsp; <a href=\"https:\/\/devblogs.microsoft.com\/vbteam\/wp-content\/uploads\/sites\/7\/2014\/06\/1754.image37.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/vbteam\/wp-content\/uploads\/sites\/7\/2014\/06\/1754.image37.png\" alt=\"\" border=\"0\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p><strong>Step 1: <\/strong>add a field to App.vb to record whether user owns the in-app product. I use a nullable Boolean, where I&#8217;ll interpret &#8220;Nothing&#8221; to mean &#8220;still need to check&#8221;<\/p>\n<p><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Private Shared<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> _HasSpeedBoost <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">As<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Boolean<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">? = <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Nothing<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><strong>Step 2: <\/strong>add a property to App.vb to perform the check if necessary:<\/p>\n<p><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Shared<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">ReadOnly Property<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> HasSpeedBoost <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">As<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Boolean<br \/> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Get<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">If<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> _HasSpeedBoost <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Is<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Nothing<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Then<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> _HasSpeedBoost =<br \/> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">CurrentApp<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">.LicenseInformation.ProductLicenses(<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #a31515;background: white\">&#8220;SpeedBoost&#8221;<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">).IsActive<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Return<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> _HasSpeedBoost.Value<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">End<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Get<br \/> &nbsp;&nbsp;&nbsp; End Property<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><strong>Step 3: <\/strong>add a method to App.vb which will perform the purchase. In it, I reset the nullable field back to _Nothing, meaning &#8220;still need to check&#8221;. That way the property getter will be re-run, and will work correctly whether the user completed or declined the purchase.<\/p>\n<p><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Shared<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Async<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Function<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> PurchaseSpeedBoostAsync() <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">As<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">Task<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">If<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> HasSpeedBoost() <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Then<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Return<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _HasSpeedBoost = <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Nothing<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Await<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">CurrentApp<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">.RequestProductPurchaseAsync(<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #a31515;background: white\">&#8220;SpeedBoost&#8221;<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">)<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">End<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Function<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><strong>Step 4:<\/strong> add a button in your AdaptiveMainPage.xaml (or elsewhere in your UI) where the user can make the purchase:<\/p>\n<p><span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: blue;background: white\">&lt;<\/span>&nbsp;<span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: #a31515;background: white\">Button<\/span>&nbsp;<span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: red;background: white\"> x<\/span><span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: blue;background: white\">:<\/span><span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: red;background: white\">Name<\/span><span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: blue;background: white\">=&#8221;purchase1&#8243;<\/span>&nbsp;<span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: red;background: white\"> Content<\/span><span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: blue;background: white\">=&#8221;Purchase Speed Boost&#8221;\/&gt;<\/span>&nbsp;<span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: blue\"><\/p>\n<p> <\/span><\/p>\n<p><strong>Step 5: <\/strong>respond to the button-click:<\/p>\n<p><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Async<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Sub<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> purchase1_Click(sender <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">As<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Object<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">, e <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">As<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">RoutedEventArgs<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">) <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Handles<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> purchase1.Click<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Await<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">App<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">.PurchaseSpeedBoostAsync()<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UpdatePurchaseButtonVisibility()<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">End<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Sub<\/span><\/p>\n<p><strong>&nbsp;<\/strong><\/p>\n<p><strong>Step 6: <\/strong>Show or hide the visibility of the purchase button according to whether the user has already purchased the speed boost:<\/p>\n<p><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Overrides<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Async<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Sub<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> OnNavigatedTo(e <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">As<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">NavigationEventArgs<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">)<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UpdatePurchaseButtonVisibility()<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8230;.<\/span><br \/> <span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;End Sub<\/span><\/p>\n<p style=\"margin-bottom: .0001pt;text-indent: 20.5pt;line-height: normal\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">&nbsp;<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Sub<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> UpdatePurchaseButtonVisibility()<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; purchase1.Visibility = <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">If<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">(<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">App<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">.HasSpeedBoost(),<br \/> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Windows.UI.Xaml.<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">Visibility<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">.Collapsed,<br \/> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Windows.UI.Xaml.<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">Visibility<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">.Visible)<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">End<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Sub<\/span><\/p>\n<p><span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: blue\">&nbsp;<\/span><\/p>\n<p><strong>Step 7: <\/strong>Remember that your app has to be made better in some way by the in-app purchase! In my case, if the user purchased the SpeedBoost, then I doubled the ball&#8217;s speed&#8230;<\/p>\n<p><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Shared<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Sub<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> Tick()<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; x += dx : y += dy<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">If<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> HasSpeedBoost() <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Then<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> x += dx : y += dy<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8230;.<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">&nbsp;&nbsp;&nbsp; End<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Sub<\/span><\/p>\n<p>&nbsp;<\/p>\n<h2>Telemetry and debugging<\/h2>\n<p>There are lots of bugs that you&#8217;ll only discover after publishing your app. It&#8217;s important that you get back good actionable feedback about them.<\/p>\n<ul>\n<li><a href=\"http:\/\/media.ch9.ms\/ch9\/03b0\/7fbdd110-0b81-41bc-827f-d8e3bd2803b0\/7diagnostics_Source.wmv\">How Do I video: get crash reports when in-app purchasing failed<\/a> [2mins]<\/li>\n<\/ul>\n<p>It&#8217;s especially important to get good feedback when in-app purchasing fails. Imagine a customer who wants to pay you money, but a glitch isn&#8217;t letting them &#8211; they&#8217;ll be doubly frustrated. It&#8217;s often better to err on the side of generosity and give them the functionality at least this time around. I also wanted good telemetry for the in-app purchasing because, until the app had been approved in both stores, I was getting strange crashes.<\/p>\n<p>Here&#8217;s how I rewrote PurchaseSpeedBoostAsync to get better feedback:<\/p>\n<p><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Shared<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Async<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Function<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> PurchaseSpeedBoostAsync() <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">As<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">Task<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">If<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> HasSpeedBoost() <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Then<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Return<\/span><br \/> <span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;_HasSpeedBoost = <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Nothing<\/span><br \/> <span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Dim<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> log = <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">CStr<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">(<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">ApplicationData<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">.Current.LocalSettings.Values(<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #a31515;background: white\">&#8220;log&#8221;<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">))<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">If<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> log <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">IsNot<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Nothing<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Then<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: green;background: white\">&#8216; previous run of this app tried to purchase, but didn&#8217;t succeed&#8230;<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">ApplicationData<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">.Current.LocalSettings.Values.Remove(<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #a31515;background: white\">&#8220;log&#8221;<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">)<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SendErrorReport(log)<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _HasSpeedBoost = <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">True<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: green;background: white\">&#8216; so the user can at least use the item<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Return<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">End<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">If<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Try<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; log = <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #a31515;background: white\">&#8220;About to await RequestProductPurchaseAsync&#8221;<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">ApplicationData<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">.Current.LocalSettings.Values(<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #a31515;background: white\">&#8220;log&#8221;<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">) = log<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Dim<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> result = <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Await<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">CurrentApp<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">.RequestProductPurchaseAsync(<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #a31515;background: white\">&#8220;SpeedBoost&#8221;<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">)<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; log &amp;= vbCrLf &amp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">String<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">.Format(<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #a31515;background: white\">&#8220;Finished await. Status={0}, OfferId={1}, TransactionId={2}&#8221;<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">, result.Status, result.OfferId, result.TransactionId)<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">ApplicationData<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">.Current.LocalSettings.Values(<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #a31515;background: white\">&#8220;log&#8221;<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">) = log<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Catch<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> ex <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">As<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">Exception<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; log &amp;= vbCrLf &amp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #a31515;background: white\">&#8220;EXCEPTION! &#8220;<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> &amp; ex.Message &amp; ex.StackTrace<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">ApplicationData<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">.Current.LocalSettings.Values(<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #a31515;background: white\">&#8220;log&#8221;<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">) = log<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SendErrorReport(ex)<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">End<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Try<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">End<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Function<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><\/p>\n<p>This method &#8220;pessimistically&#8221; logs, writing its latest state to LocalSettings every step of the way. Even if it crashes part way through, then at least the log will show how far it got.<\/p>\n<p>Separately, when the method starts, it checks if any previous invocation of the method had left anything in the log. If so, that means the user must have tried to make the purchase but something went wrong. The best thing to do is allow for a problem-report to be sent by email, and give the user the benefit of the doubt by assuming (for this run of the app) that the purchase went through.<\/p>\n<p><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Shared<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Sub<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> SendErrorReport(ex <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">As<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">Exception<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">)<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; SendErrorReport(ex.Message &amp; vbCrLf &amp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #a31515;background: white\">&#8220;stack:&#8221;<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> &amp; vbCrLf &amp; ex.StackTrace)<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">End<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Sub<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Shared<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Async<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Sub<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> SendErrorReport(msg <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">As<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">String<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">)<\/span><br \/> <span style=\"font-size: 9.5pt;font-family: Consolas;color: green;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&#8216; Async Subs are normally bad because the caller can&#8217;t know when the method<\/span><br \/> <span style=\"font-size: 9.5pt;font-family: Consolas;color: green;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&#8216; has finished and can&#8217;t deal with exceptions. But the caller will typically be<\/span><br \/> <span style=\"font-size: 9.5pt;font-family: Consolas;color: green;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&#8216; inside a catch block where they can&#8217;t await. And even if they did get an<\/span><br \/> <span style=\"font-size: 9.5pt;font-family: Consolas;color: green;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&#8216; exception from us what would they do? send an error report?!!!<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Dim<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> md <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">As<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">New<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> Windows.UI.Popups.<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">MessageDialog<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">(<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #a31515;background: white\">&#8220;Oops. There&#8217;s been an internal error&#8221;<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">, <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #a31515;background: white\">&#8220;Bug report&#8221;<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">)<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Dim<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> r <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">As<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Boolean<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">? = <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Nothing<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; md.Commands.Add(<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">New<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> Windows.UI.Popups.<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">UICommand<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">(<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #a31515;background: white\">&#8220;Send bug report&#8221;<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">, <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Sub<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">() r = <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">True<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">))<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; md.Commands.Add(<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">New<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> Windows.UI.Popups.<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">UICommand<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">(<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #a31515;background: white\">&#8220;Cancel&#8221;<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">, <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Sub<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">() r = <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">False<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">))<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Await<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> md.ShowAsync()<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">If<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Not<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> r.HasValue <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">OrElse<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Not<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> r.Value <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Then<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Return<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: green;background: white\">&#8216;<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Dim<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> emailTo = <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #a31515;background: white\">&#8220;my.email@address.com&#8221;<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Dim<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> emailSubject = <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #a31515;background: white\">&#8220;App1 problem report&#8221;<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Dim<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> emailBody = <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #a31515;background: white\">&#8220;I encountered a problem with App1&#8230;&#8221;<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> &amp; vbCrLf &amp; vbCrLf &amp; msg<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Dim<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> url = <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #a31515;background: white\">&#8220;mailto:?to=&#8221;<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> &amp; emailTo &amp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #a31515;background: white\">&#8220;&amp;subject=&#8221;<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> &amp; emailSubject &amp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #a31515;background: white\">&#8220;&amp;body=&#8221;<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> &amp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">Uri<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">.EscapeDataString(emailBody)<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; <\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Await<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> Windows.System.<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">Launcher<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">.LaunchUriAsync(<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">New<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">Uri<\/span>&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">(url))<\/span><br \/><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">End<\/span>&nbsp;&nbsp;<span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Sub<\/span><\/p>\n<h2>Conclusion<\/h2>\n<p>So far in this blog series we&#8217;ve created out app, and implemented most of its functionality &#8211; in-app purchases, local state, and roaming state. All this is already good enough for a great many apps. Tomorrow, though, we&#8217;ll venture into serious games programming &#8211; we&#8217;ll add sound effects using the open-source SharpDX library.<\/p>\n<p>&nbsp;<\/p>\n<p>&#8212; <br \/><em><strong>Lucian<\/strong><\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>This is Part 3 of the &#8220;VB Universal Windows App&#8221; series: Part 1: Setting up the universal Windows app in the Dev Centers, and in VS Solution Explorer Part 2: Sharing XAML, Assets and Code &gt; Part 3: Local and Roaming settings, and In-App purchases Part 4: Sound effects with SharpDX Part 5: How to [&hellip;]<\/p>\n","protected":false},"author":260,"featured_media":8818,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[21,16,195],"tags":[36,99,160,180],"class_list":["post-133","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-im-a-vb","category-vb-universal-windows-apps","category-visual-basic","tag-async","tag-lucian-wischik","tag-universal","tag-windows-phone"],"acf":[],"blog_post_summary":"<p>This is Part 3 of the &#8220;VB Universal Windows App&#8221; series: Part 1: Setting up the universal Windows app in the Dev Centers, and in VS Solution Explorer Part 2: Sharing XAML, Assets and Code &gt; Part 3: Local and Roaming settings, and In-App purchases Part 4: Sound effects with SharpDX Part 5: How to [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/posts\/133","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/users\/260"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/comments?post=133"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/posts\/133\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/media\/8818"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/media?parent=133"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/categories?post=133"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/tags?post=133"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}