Jekyll2020-08-14T04:23:59+00:00https://tomsoderling.github.io/feed.xmlMobile as MuseA Xamarin mobile development blog with picturesHow to do a clean reinstall of Visual Studio for Mac2020-08-13T01:23:00+00:002020-08-13T01:23:00+00:00https://tomsoderling.github.io/Clean-VSforMac-Install<p>Sometimes you just need a new start.<br />
Here’s an easy way to wipe out all the bits from an existing Visual Studio for Mac install so you can do a clean reinstall.</p>
<p>You may want to save any code snippet files you’ve created. Copy this folder to a safe place so it doesn’t get axed: <code class="language-plaintext highlighter-rouge">~/Library/VisualStudio/7.0/Snippet</code></p>
<h2 id="wipeout">Wipeout</h2>
<p>Run the first command on line 1 by itself first. You’ll be prompted for your password.</p>
<p>Then you can copy all the other commands and run them together.</p>
<script src="https://gist.github.com/TomSoderling/4732a9a26e81e9f2c0828313c1a68b1c.js"></script>
<p>All clean! You can now download the <a href="https://visualstudio.microsoft.com/vs/mac">Visual Studio for Mac installer</a> and begin your fresh new start.</p>
<p>Please reach out to me on twitter if you have any comments or feedback.</p>tomSometimes you just need a new start. Here’s an easy way to wipe out all the bits from an existing Visual Studio for Mac install so you can do a clean reinstall.Code Snippet for Xamarin Month2020-06-06T01:23:00+00:002020-06-06T01:23:00+00:00https://tomsoderling.github.io/Unit-Test-Code-Snippet<p>Thanks to Luis Matos for organizing this Xamarin Month on the topic of Code Snippets! Check out the <a href="https://twitter.com/hashtag/xamarinmonth">twitter hashtag to find more posts</a> or see the <a href="https://luismts.com/code-snippetss-xamarin-month">monthly calendar of all posts here</a>.</p>
<p>This Xamarin Month was especially interesting to me because I love code snippets! They save lots of time by stubbing in repetitive code with just a few keystrokes. The snippet I’m posting is one I use almost every day and helps provide a consistent name and outline when writing unit tests.</p>
<h2 id="its-all-in-the-name">It’s All in the Name</h2>
<p>We write our unit tests using NUnit and follow the <a href="https://docs.microsoft.com/en-us/dotnet/core/testing/unit-testing-best-practices#best-practices">Microsoft naming convention</a> for all tests so anyone on the team can quickly understand the intent of the test and get all the necessary info just by reading its name. That convention breaks the name into three parts:</p>
<ul>
<li>The name of the method or unit under test</li>
<li>The scenario or state under which it’s being tested</li>
<li>The expected behavior or result when the scenario is invoked</li>
</ul>
<p>These parts are sometimes hard for me to remember, so this snippet gives me some clues to jog my memory.</p>
<h2 id="outline">Outline</h2>
<p>We also structure every unit test we write using the same basic outline, so anyone on the team can more easily get up to speed on an unfamiliar test and understand what it’s doing. That outline is known as the Triple-A (AAA) Pattern: Arrange, Act, Assert. You can <a href="https://docs.microsoft.com/en-us/dotnet/core/testing/unit-testing-best-practices#arranging-your-tests">read more about that here.</a></p>
<h2 id="using-it">Using It</h2>
<p>I set up this snippet to use the shortcut <code class="language-plaintext highlighter-rouge">test</code>, so by typing that and pressing tab twice, voila! The whole unit test is stubbed out for me:<br />
<img src="/images/XamarinMonthCodeSnippets/InUse1.png" style="width: 600px;" /></p>
<p>The snippet gives me a clue on what the first part of the name should be, <code class="language-plaintext highlighter-rouge">UnitUnderTest</code>. This snippet uses variables, so I can enter the first part of the name and press tab to move on to the other 2 parts of the name:<br />
<img src="/images/XamarinMonthCodeSnippets/InUse2.png" style="width: 600px;" /></p>
<h2 id="the-code">The Code</h2>
<p>I’ll provide the snippet in two formats.</p>
<ol>
<li>
<p>The first one you can copy/paste into Visual Studio for Mac by going to Preferences > Text Editor > Code Snippets > C# group, and creating a new code snippet.<br />
<img src="/images/XamarinMonthCodeSnippets/VSForMacSnippetScreen.png" style="width: 800px;" /><br />
<script src="https://gist.github.com/TomSoderling/06cbd9dd3800c1e4beae988c3847d2f9.js"></script></p>
</li>
<li>
<p>The 2nd format is the entire snippet file as VS for Mac saves it. Just drop the file here: <code class="language-plaintext highlighter-rouge">~/Library/VisualStudio/7.0/Snippets</code> and you’re good to go. (You may have to restart VS)<br />
<script src="https://gist.github.com/TomSoderling/1de12a7669f4fa339d31ac2574ce3de1.js"></script></p>
</li>
</ol>
<p>That’s it! Hope this saves you a little time and typing! Please reach out to me on twitter if you have any comments or feedback.</p>tomThanks to Luis Matos for organizing this Xamarin Month on the topic of Code Snippets! Check out the twitter hashtag to find more posts or see the monthly calendar of all posts here.Clean Up Old Xcode Archives Automatically2018-12-18T01:23:00+00:002018-12-18T01:23:00+00:00https://tomsoderling.github.io/Clean-out-old-xcode-archives<p>What’s the best type of cleaning? Cleaning that happens automatically!<br />
About every 6 months or so, I notice that the free space on my Mac’s hard drive is surprisingly low. Have I really been writing that much code?! Even though I use App Center to do all my production, App Store builds, one of the biggest space hogs for a mobile developer are old Xcode archives.</p>
<p>Found a good guide for how to <a href="https://ole.michelsen.dk/blog/schedule-jobs-with-crontab-on-mac-osx.html">create and edit the job, here</a></p>
<p>Here’s the script:
<script src="https://gist.github.com/TomSoderling/2c473b6d65f4cede805077a5cdf3030b.js"></script></p>tomWhat’s the best type of cleaning? Cleaning that happens automatically! About every 6 months or so, I notice that the free space on my Mac’s hard drive is surprisingly low. Have I really been writing that much code?! Even though I use App Center to do all my production, App Store builds, one of the biggest space hogs for a mobile developer are old Xcode archives.Turn Off the iOS Simulator ‘Accept Incoming Network Connections’ Pop-up2018-04-09T01:23:00+00:002018-04-09T01:23:00+00:00https://tomsoderling.github.io/Disable-iOS-simulator-connections-popup<p>Deploying to the iOS simulators is great - so fast and convenient.<br />
What’s <strong>not</strong> convenient and gets pretty downright annoying is being forced to click “Allow” on this pop-up <strong>EVERY SINGLE TIME</strong> I do it.<br />
<img src="/images/DisableiOSSimulatorPopup/iOSSimulatorPopup.png" style="width: 600px;" /><br />
<em>gah! yes, for the love, just allow them already and stop asking me</em></p>
<p>Thankfully, you can use this handy little bash script to help silence this pop-up and deploy without interruption to the simulator. Sometimes, it’s the little things that make a big difference. I think once you stop clicking this button on every deploy, you’ll wonder how you ever got along without this little script.</p>
<h2 id="so-what-does-this-script-do-exactly">So What Does This Script Do, Exactly?</h2>
<p>Yes, before downloading a bash script from the internet and running it on your personal machine, you should probably know what it’s doing. Fear not, everything is on the up and up here.</p>
<p>Your Mac has a firewall. A firewall that doesn’t remember that you’ve clicked “Allow” a thousand times.<br />
What it doesn’t realize is that incoming connections to the Simulator are probably not malicious. In fact, you probably <strong>always</strong> want to allow those connections because you’re writing an app that is designed to make connections with the outside world.</p>
<p>Thankfully this firewall allows you to make exceptions for certain apps, but even though the pop-up says you can change this setting on the Firewall pane, I wasn’t able to do it; hence this script.</p>
<p>We need to make an exception for two apps: the Simulator and Xcode. In order to do that, we need to turn the firewall off for a moment to add these exceptions, and the last statement in the file turns it back on and gives a confirmation. As you can imagine, turning the firewall off/on requires super user access (that’s what the sudo command is for) so terminal will prompt you for you system password.</p>
<p>Here’s the script:
<script src="https://gist.github.com/TomSoderling/9b3d582c4c895dde4ed1eac3f987b764.js"></script></p>
<h2 id="how-to-use-this-script">How to Use This Script</h2>
<ol>
<li>Copy the script above and save it to a new file with a .sh extension</li>
<li>You’ll need to change the permissions on the file so you can execute the script, otherwise you’ll get a “Permission denied” message if you try. You’ll only need to do this once. In terminal, run the command:
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>chmod u+x [the path to your new script file.sh]
</code></pre></div> </div>
<p>This grants you the user (u) execution permission (x) on this script file.</p>
</li>
<li>Then just drag the file into terminal and hit enter to run it. You’ll be prompted to enter your system password for sudo access.</li>
</ol>
<p>For whatever reason, these two firewall exceptions will be reset whenever you restart your Mac, so put this script in a handy place because you’ll need to run it again.</p>
<p><br />
That’s it! Hope this saves you a little time and clicks. Don’t forget to share this script with you fellow mobile developers!</p>tomDeploying to the iOS simulators is great - so fast and convenient. What’s not convenient and gets pretty downright annoying is being forced to click “Allow” on this pop-up EVERY SINGLE TIME I do it. gah! yes, for the love, just allow them already and stop asking meXamarin.Forms Code You Can Delete Today! (part 1)2018-03-06T01:23:00+00:002018-03-06T01:23:00+00:00https://tomsoderling.github.io/Xamarin-Forms-code-you-can-delete-today-1<div>
<div style="display: inline-block; width: 77%; vertical-align: top;">
What's more fun than writing code?
<br /><br />
Deleting it!
<br /><br />
Your Xamarin.Forms app definitely contains some code that you can delete. Code that is causing you a performance hit. Code you can delete today, right now, pronto, with no risk. <b>Seriously</b>
<br /><br />
Let's get philosophical for a moment. <br />
As much as we as developers really love to solve problems by writing code - <i>deleting</i> code, (or writing less of it in the first place) should be a fundamental desire of mature developers who recognize that each line of code written is a trade-off: is this code worth the potential bugs and the cost of care and feed (maintenance) down the road? <br />
</div>
<div style="display: inline-block;" align="top">
<img src="/images/XFCodeYouCanDelete/Anti-code.png" style="width: 200px;" />
</div>
</div>
<h2 id="good-news-for-deleters">Good News for Deleters</h2>
<p>This tip comes from the now-famous Optimizing App Performance with Xamarin.Forms talk that Jason Smith gave at the 2016 Xamarin Evolve conference. Even though the talk was given nearly 2 years ago, I/we/apps are still breaking many of the cardinal Xamarin.Forms no-no’s and needlessly paying the price in performance.</p>
<p>Here are the detailed steps to delete this hurtful code from your app:</p>
<ol>
<li>Go to Visual Studio and search for LayoutOptions.Fill in your entire Xamarin.Forms solution</li>
<li>Delete all those lines of code. (I like to use cmd+x)</li>
</ol>
<p><img src="/images/XFCodeYouCanDelete/FindLayoutOptions.Fill.png" style="width: 450px;" /></p>
<p>That’s it! Hasta la visa, baby!</p>
<h2 id="but-why">But Why?</h2>
<p>This code may seem innocuous, not really hurting anything - but there are 2 reasons why you need to delete this code from all your Xamarin.Forms apps ASAP.</p>
<ol>
<li>
<p>The default value of a view’s HorizontalOptions and VerticalOptions properties <a href="https://developer.xamarin.com/guides/xamarin-forms/user-interface/layouts/layout-options/#Overview">are <strong>already</strong> LayoutOptions.Fill</a>, so it’s completely unnecessary to set this.</p>
</li>
<li>
<p>Every time you set it, your app is taking an unnecessary performance hit on the chin. Even though you’re setting those properties to what they already were, it comes with a cost, so <strong>just don’t do it</strong>. In addition, the Xamarin docs say changing these properties “consumes memory, even when setting them to the default values”</p>
</li>
</ol>
<hr />
<p>Now that your app will benefit from this change, do your team a favor and point out this necessary code-ectomy in your next PR. We’re all learning to be better Xamarin.Forms developers.</p>
<h2 id="resources">Resources</h2>
<ul>
<li><a href="https://www.youtube.com/watch?v=RZvdql3Ev0E">Optimizing App Performance with Xamarin.Forms, by Jason Smith</a></li>
<li>Kent Boogart put together this <a href="https://kent-boogaart.com/blog/jason-smith%27s-xamarin-forms-performance-tips">really great, easily accessible summary</a> that’s helpful as a reference</li>
<li><a href="https://developer.xamarin.com/guides/xamarin-forms/deployment-testing/performance/#Optimize_Layout_Performance">Optimize Layout Performance</a> from Xamarin docs</li>
</ul>tomWhat's more fun than writing code? Deleting it! Your Xamarin.Forms app definitely contains some code that you can delete. Code that is causing you a performance hit. Code you can delete today, right now, pronto, with no risk. Seriously Let's get philosophical for a moment. As much as we as developers really love to solve problems by writing code - deleting code, (or writing less of it in the first place) should be a fundamental desire of mature developers who recognize that each line of code written is a trade-off: is this code worth the potential bugs and the cost of care and feed (maintenance) down the road?Let Your App Use all the Extra Screen Space on iPhone X2018-01-20T01:23:00+00:002018-01-20T01:23:00+00:00https://tomsoderling.github.io/Use-all-the-space-on-iPhone-X<div>
<div style="display: inline-block; width: 80%; vertical-align: top;">The iPhone X has been out since early November (2017) and it is easily the best phone I've ever used. <br />
Great size, glass on glass on stainless steel design, wireless charging using Qi standard, fantastic gesture-based navigation, IP67 water resistant, convenient face ID, and the best camera I've ever owned. But topping the list is the screen; gorgeous, highly color accurate OLED that makes you think you're touching the very pixels. <br /> <br />
With that nice screen comes some extra space. Space that all my old apps don't understand how to make use of. I've found myself struggling to remember each time how exactly to take advantage of that space, so here are the steps.
</div>
<div style="display: inline-block;" align="top">
<img src="/images/UseAllTheSpaceOniPhoneX/iphone-x.png" width="150" />
</div>
</div>
<div>
<div style="display: inline-block;" align="top">
<img src="/images/UseAllTheSpaceOniPhoneX/unusedSpace.png" style="width: 300px;" />
</div>
<div style="display: inline-block; width: 65%; vertical-align: top;">This app is sad. It doesn't know to use all those extra beautiful iPhone X pixels. <br /> <br />
Most of us are familiar with this screen, where we can specify a Launch Screen image for each device size, type (iPhone, iPad, Apple TV), and screen resolution, like Retina HD 5.5 (iPhone Plus) and Retina HD 4.7 (iPhone 6 and up) <br />
<img src="/images/UseAllTheSpaceOniPhoneX/launchImages.png" style="width: 300px;" />
</div>
</div>
<p>We’d expect it have a spot for the new iPhone X, named something like “Super Retina HD 5.8”, but there isn’t an option for iPhone X here. If you want your app to expand into that new space above and below, you <strong>must</strong> create a Launch Screen Storyboard. For those that are more familiar with Xamarin.Forms apps, this may be foreign, but don’t worry.</p>
<p>As of iOS 8, we’re now able to use a single Unified Storyboard to make a Launch Screen that looks correct in all cases. I’ve just never done it until needing to support iPhone X.</p>
<h1 id="lets-do-it">Let’s Do It</h1>
<p>Start by right-clicking on your project in Visual Studio for Mac and select <strong>Add</strong> > <strong>New File</strong><br />
In the dialog, choose > <strong>iOS</strong> (on the left panel) > <strong>Launch Screen</strong>. The default name “LaunchScreen” is just fine, but can be named anything.</p>
<p><img src="/images/UseAllTheSpaceOniPhoneX/newLaunchScreen.png" style="width: 600px;" /></p>
<p>From here, I’d suggest <a href="https://developer.xamarin.com/guides/ios/application_fundamentals/working_with_images/launch-screens/#storyboard">following steps 2 - 8 in this guide from Xamarin</a>, on how to design the storyboard and place a launch image/icon. Then come back here when they start to talk about constraints.</p>
<p>One tip:</p>
<ul>
<li>If for some reason your app <em>already</em> has a storyboard in it, after creating the new LaunchScreen storyboard, you may not see “LaunchScreen” appear in the Launch Screen dropdown box when editing your Info.plist file. Quit Visual Studio for Mac and relaunch it and open your solution again. It should now appear.<br />
<img src="/images/UseAllTheSpaceOniPhoneX/dropdown.png" style="width: 500px;" /></li>
</ul>
<h2 id="centering-launch-images">Centering Launch Images</h2>
<p>Okay so, you’ve got a basic launch screen storyboard created now.<br />
My launch screens are pretty simple. It’s just my app icon on a solid colored background.</p>
<p>I’ve found an easy way to make your launch image/icon be centered on all device sizes without messing with constraints. Follow these steps:</p>
<ol>
<li>
<p>With your Image View selected.<br />
<img src="/images/UseAllTheSpaceOniPhoneX/centering1.png" style="width: 125px;" /></p>
</li>
<li>
<p>Click the Center and Middle buttons next to <strong>Position in Parent</strong><br />
<img src="/images/UseAllTheSpaceOniPhoneX/centering2.png" style="width: 300px;" /><br />
This will center the image in the middle of your current device view.</p>
</li>
<li>
<p>Click on these red line segments to remove them<br />
<img src="/images/UseAllTheSpaceOniPhoneX/centering3.png" style="width: 300px;" /><br />
Now your image will stay centered on all device sizes</p>
</li>
<li>
<p>If your image is of high enough resolution, you can also click on the dashed arrows inside the box to allow it to be autosized on larger/smaller screen sizes.<br />
<img src="/images/UseAllTheSpaceOniPhoneX/centering4.png" style="width: 300px;" /></p>
</li>
</ol>
<h1 id="the-results">The Results</h1>
<p>Ah, that’s much better! Look at all those good looking pixels being put to use!<br />
<img src="/images/UseAllTheSpaceOniPhoneX/finalProduct.png" style="width: 300px;" /></p>
<h1 id="mind-the-iphone-x-safe-areas">Mind the iPhone X Safe Areas</h1>
<p>The iPhone X is unique in that it features an all new on-screen home indicator bar in place of the physical home button, the “notch” sensor housing, and rounded screen corners. You’ll probably want to check that your layouts are “safe” and make sure that content isn’t being clipped by any of these device-specific features.</p>
<p>See <a href="https://blogs.msdn.microsoft.com/vsappcenter/deliver-better-iphone-x-ux-with-visual-studio-app-center">this great post about it</a> on the VS App Center blog</p>
<p>See these Xamarin blog posts for <a href="https://blog.xamarin.com/making-ios-11-even-easier-xamarin-forms/">Xamarin.Forms apps</a> and <a href="https://blog.xamarin.com/updating-xamarin-ios-apps-for-the-iphone-x/">iOS apps</a></p>tomThe iPhone X has been out since early November (2017) and it is easily the best phone I've ever used. Great size, glass on glass on stainless steel design, wireless charging using Qi standard, fantastic gesture-based navigation, IP67 water resistant, convenient face ID, and the best camera I've ever owned. But topping the list is the screen; gorgeous, highly color accurate OLED that makes you think you're touching the very pixels. With that nice screen comes some extra space. Space that all my old apps don't understand how to make use of. I've found myself struggling to remember each time how exactly to take advantage of that space, so here are the steps.How to Run Automated UI Tests from a VS App Center Build2018-01-17T01:23:00+00:002018-01-17T01:23:00+00:00https://tomsoderling.github.io/AppCenter-Automated-UI-tests-on-build<p>Visual Studio App Center continues to amaze and impress me.<br />
Over Christmas break, I set up CI (Continuous Integration) and Release/App Store builds for all my little app projects - which was truly a delightful experience - and they’ve been humming along smoothly.<br />
It’s surprising how quickly I’ve already taken them for granted. I push code, they build, run the automated launch test on a real device, I get a nice email to install the build on test devices, and can push it to the app stores if it makes the cut. So nice. It’s hard to imagine I used to do it any other way.<br />
<img src="/images/AppCenter-AutomatedUITests/CIBuilds.png" style="width: 700px;" /></p>
<p>Apart from the builds, I think the next most important feature of a good DevOps pipeline is automated testing. We all write unit tests (right???!), which I think is really valuable, but even on my small apps, there are functional areas that I rarely test anymore - now that development of that feature is done.<br />
For example, one of my apps, Pickster, features a ListView of names where you can swipe on any name and be presented with a context action to delete the name. I realized the other day that I haven’t personally tested that functionality for probably 6 months or so. It’s just not part of my regular use. I add names a lot as I’m developing and testing, but hardly ever delete one or use those context actions. This app doesn’t even really do a lot, but has areas that rarely get manual testing love. Think of big apps. Humans just aren’t good at testing everything, or testing it the same way every time.</p>
<p>Enter automated UI tests.</p>
<p>I really like to use the <a href="https://developer.xamarin.com/guides/testcloud/testrecorder/">Xamarin UI Test Recorder</a> to get the inital scaffolding of a UI test built and then tweak it from there. Using the recorder, you simply tap/type/swipe around the app and use it like you normally would, and the test recorder translates that into Xamarin.UITest commands that make up your automated UI test.<br />
<img src="/images/AppCenter-AutomatedUITests/testrecorder.png" style="width: 1000px;" /></p>
<p>More info on how to get started writing and running Xamarin UI tests <a href="https://developer.xamarin.com/guides/testcloud/uitest/">can be found here</a></p>
<p>Okay, so you’ve got some UI tests written and running locally on simulator or device - great. Now we want to run them in Xamarin Test Cloud on that huge collection of real mobile devices they’ve got. 3017 last I heard. The following directions are for an iOS build, but should be similar for Android too.</p>
<h1 id="lets-do-it">Let’s Do It</h1>
<p>Here are the 5 pieces you need to integrate UI tests that run in Xamarin Test Cloud into your App Center builds:</p>
<p><img src="/images/AppCenter-AutomatedUITests/fivePieces.png" style="width: 1000px;" /></p>
<h2 id="pieces-1--2">Pieces #1 & #2</h2>
<p>You have to be authenticated with App Center in order to run the “appcenter test run uitest” command.<br />
Follow <a href="https://docs.microsoft.com/en-us/appcenter/api-docs/">steps 1-9 here</a> to generate an App Center API token.<br />
Using the build configuration settings, create a new build environment variable named “appCenterLoginApiToken” or something. For its value, paste in the token you just generated. This env. variable can now be used in our post-build script.</p>
<h2 id="pieces-4-3-and-part-of-5">Pieces #4, #3, and part of #5</h2>
<p>Go to the Test beacon in App Center<br />
<img src="/images/AppCenter-AutomatedUITests/testBeacon.png" style="width: 200px;" /><br />
and click on the grey Test Series button <img src="/images/AppCenter-AutomatedUITests/testButtons.png" style="width: 200px;" /></p>
<p>With App Center builds, you have the option to run launch app on a real device at the end of a build - just to make sure it’ll launch. That’s a test series App Center creates for you named launch-tests. You’ll want to create and name a new one - like “smoke-tests” or whatever.</p>
<p>Next, create a new test run by clicking on the New Test Run button. It guides you through picking your devices, the framework the test are written in (Xamarin.UITest for me), and generates the command to run the tests in App Center, filling in some of the info for you.</p>
<p><img src="/images/AppCenter-AutomatedUITests/generatedCommand.png" style="width: 900px;" /></p>
<p>This really only gets you part of the way there though. After I copied that generated command, it took me exactly <strong>34</strong> builds before I had the UI tests working at all as part of my CI build. <strong>Thirty.</strong> <strong>Four.</strong> And that was <em>with</em> the help of App Center support. (Which is pretty great. They have a nice on-page chat window that you can paste screenshots into, and responses were usually quick). So hopefully this blog post will save you a bit of time.</p>
<p>For whatever reason, the directions from in App Center state to run the command in terminal on your LOCAL machine to run the tests in App Center. Well that is incredibly <strong>L-A-M-E</strong>. We don’t want to do stuff. We want the machines to do the stuff for us. Ya know, automation?</p>
<p>Good news - that command can be run as part of any Debug build pipeline by writing a tiny post-build bash script. It really only needs to contain that one line, and with the help of a guy that failed <strong>33</strong> times at it, you have nothing to worry about. (Note: for iOS, Xamarin UI tests are usually run on Debug builds.)</p>
<h2 id="piece-5">Piece #5</h2>
<p>Here is the App Center CLI (Command Line Interface) command that I used in my script. Entire script file is included at the bottom of this post.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>appcenter <span class="nb">test </span>run uitest <span class="nt">--app</span> <span class="s2">"tomso/Pickster"</span> <span class="nt">--devices</span> <span class="s2">"tomso/top-devices"</span> <span class="nt">--app-path</span> <span class="nv">$APPCENTER_OUTPUT_DIRECTORY</span>/Pickster.ipa <span class="nt">--test-series</span> <span class="s2">"smoke-tests"</span> <span class="nt">--locale</span> <span class="s2">"en_US"</span> <span class="nt">--build-dir</span> <span class="nv">$APPCENTER_SOURCE_DIRECTORY</span>/Pickster.UITests/bin/Debug <span class="nt">--uitest-tools-dir</span> <span class="nv">$APPCENTER_SOURCE_DIRECTORY</span>/packages/Xamarin.UITest.<span class="k">*</span>/tools <span class="nt">--token</span> <span class="nv">$appCenterLoginApiToken</span>
</code></pre></div></div>
<p>Note that this command has 8 parameters, instead of the wimpy 6 that App Center generated for you. The extras are crucial, and are:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">--uitest-tools-dir</span>
</code></pre></div></div>
<p>and</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">--token</span>
</code></pre></div></div>
<p>Let’s break down what each of these 8 parameters are. I’ll try to explain what they are and what values you’ll probably want to use for each.</p>
<h3 id="parameters-1--2">Parameters 1 & 2</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">--app</span> <span class="s2">"tomso/Pickster"</span>
<span class="nt">--devices</span> <span class="s2">"tomso/top-devices"</span>
</code></pre></div></div>
<p>These first 2 are generated for you and should be pretty straight-forward. Using App Center analytics I found the top 3 devices that users were running my app on, picked those devices when I created my new test run, and saved that device set under the name “top-devices”. A device set is the combination of devices and OS versions, and you can make whatever combination you’d like.<br />
1 of 34 builds spent on these.</p>
<h3 id="parameter-3">Parameter 3</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">--app-path</span> <span class="nv">$APPCENTER_OUTPUT_DIRECTORY</span>/Pickster.ipa
</code></pre></div></div>
<p>First tricky parameter. This is the file path to the .ipa file your build produces. Yes, even though it’s a Debug build, it still creates an .ipa file if you’ve chosen to do Device Builds. Make sure you have in your App Center build configuration settings.<br />
<img src="/images/AppCenter-AutomatedUITests/buildType.png" style="width: 500px;" /><br />
App Center has a environment variable that points to the folder that holds the artifacts of the build. Reference it in your bash script as $APPCENTER_OUTPUT_DIRECTORY + whatever your .ipa file name is.<br />
5 of 34 builds spent on this.</p>
<h3 id="parameters-4--5">Parameters 4 & 5</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">--test-series</span> <span class="s2">"smoke-tests"</span>
<span class="nt">--locale</span> <span class="s2">"en_US"</span>
</code></pre></div></div>
<p>Last two easy ones. They’re both generated for you. The first is the name of the Test Series you created and named earlier in App Center, and I have no idea what the second one is for. I speak english, so I just left it there. ¯_(ツ)_/¯<br />
1 of 34 builds spent on these.</p>
<h3 id="parameter-6">Parameter 6</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">--build-dir</span> <span class="nv">$APPCENTER_SOURCE_DIRECTORY</span>/[your Xamarin UI Test project name]/bin/Debug
</code></pre></div></div>
<p>The generated command simply suggests “pathToUITestBuildDir” for this parameter value. Yes, make no mistake, this is really the UI test project build directory. Your Xamarin UI Test project MUST be built as part of your App Center build, so that meant for me, I had to chose to <strong>build the app solution file in my App Center CI build</strong> - not simply the iOS project like I normally would. When built, the output goes into the $APPCENTER_SOURCE_DIRECTORY, specifically in the /bin/Debug folder.</p>
<p>12 of 34 builds spent on this. Part of what made this so tricky is that I was missing a compiler symbol in the properties of my iOS project. So far, I had only run the UI Tests on a simulator, so I had to add this compiler symbol to my Debug - iPhone configuration.<br />
<img src="/images/AppCenter-AutomatedUITests/compilerSymbols.png" style="width: 800px;" /></p>
<p>For reference, I’m using the ENABLE_TEST_CLOUD symbol in my AppDelegate to start up Calabash. Could also use DEBUG, probably.<br />
<img src="/images/AppCenter-AutomatedUITests/appDelegateCode.png" style="width: 600px;" /></p>
<h3 id="parameter-7">Parameter 7</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">--uitest-tools-dir</span> <span class="nv">$APPCENTER_SOURCE_DIRECTORY</span>/packages/Xamarin.UITest.<span class="k">*</span>/tools
</code></pre></div></div>
<p>This is the folder where test-cloud.exe lives. You’ll find this in: /packages/Xamarin.UITest.[whatever version number]/tools in $APPCENTER_SOURCE_DIRECTORY.</p>
<p>Notice that I’m using globbing (* character) in place of the version number portion (2.2.1 for example), so that when you update this NuGet package to a new version number it won’t break your script.<br />
7 of 34 builds spent on this.</p>
<h3 id="parameter-8">Parameter 8</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">--token</span> <span class="nv">$appCenterLoginApiToken</span>
</code></pre></div></div>
<p>This is where you put the name of the App Center build environment variable that contains your App Center API token that you generated (piece 1 and 2). It’s best to use an env. variable so you don’t have to check in a sensitive API key into source control.<br />
9 of 34 builds spent on this. I didn’t know this parameter even existed for a long time, and haven’t seen any documentation that mentions it (yet). Thanks to the great App Center support for providing this for me!</p>
<h1 id="final-script-details">Final Script Details</h1>
<p>The post-build script needs to be named exactly “appcenter-post-build.sh”, and checked into your source repository in the same folder your solution (.sln) file lives in, since my App Center build builds my app solution file. You’ll know it’s in the right spot when you see this in your build configuration settings:<br />
<img src="/images/AppCenter-AutomatedUITests/postBuildScript.png" style="width: 550px;" /></p>
<p>Here’s more info on the <a href="https://docs.microsoft.com/en-us/appcenter/build/custom/scripts/">3 types of App Center build scripts</a> you can write.</p>
<h1 id="my-script-file">My Script File</h1>
<p><a href="https://github.com/TomSoderling/VSAppCenter/blob/master/appcenter-post-build.sh">Find it on github here</a></p>
<h1 id="troubleshooting">Troubleshooting</h1>
<p>Even with this guide, things will fail while you’re getting everything right. The most common error is when App Center can’t find a file that you’ve specified. The best advice I can give to troubleshoot that, is to just list out the files of the directory where you think the file is. Chances are, it’s named something you didn’t expect, or in a sub-folder you didn’t know was there.</p>
<p>To list the files in a directory, just add a ls [your folder name] command to the build script file. It will be the best way to track down these types of errors.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>echo "list files in APPCENTER_OUTPUT_DIRECTORY"
ls $APPCENTER_OUTPUT_DIRECTORY
</code></pre></div></div>
<h1 id="enjoy">Enjoy!</h1>
<p>Enjoy sitting back, sipping lemonade while the machines do your bidding.</p>
<p>One final tip; during the App Center trial, testing hours are <strong>UNLIMITED</strong> in Test Cloud for 30 days, so <strong>go nuts!</strong></p>
<p><img src="/images/AppCenter-AutomatedUITests/automatedTests.png" style="width: 700px;" /></p>
<p>Please feel free to contact me on twitter if you have questions or feedback!</p>tomVisual Studio App Center continues to amaze and impress me. Over Christmas break, I set up CI (Continuous Integration) and Release/App Store builds for all my little app projects - which was truly a delightful experience - and they’ve been humming along smoothly. It’s surprising how quickly I’ve already taken them for granted. I push code, they build, run the automated launch test on a real device, I get a nice email to install the build on test devices, and can push it to the app stores if it makes the cut. So nice. It’s hard to imagine I used to do it any other way.Turn your Mac into a BLE Peripheral Device2017-08-17T12:00:00+00:002017-08-17T12:00:00+00:00https://tomsoderling.github.io/Turn-Mac-into-BLE-peripheral-device<p>This guide will show you how to turn your Mac into a Bluetooth Low Energy (BLE) peripheral device for creating your very own BLE services and characteristics.</p>
<p>Steps</p>
<ol>
<li>Check if you have node.js installed already<br />
In Terminal, run this command:
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>node --version
</code></pre></div> </div>
</li>
<li>
<p>Install node.js on your Mac<br />
Go to the <a href="https://nodejs.org">Node.js website</a><br />
Download the installer for the latest LTS version (v6.11.2 LTS at the time of writing)<br />
Follow the installer prompts</p>
</li>
<li>
<p>Download example files from the bleno github repo
<a href="https://github.com/sandeepmistry/bleno/tree/master/examples/echo">Echo example</a><br />
It includes two files: main.js & characteristic.js<br />
Place these 2 files by themselves in a folder somewhere</p>
</li>
<li>
<p>In Terminal, navigate to the folder containing your main.js and characteristic.js files</p>
</li>
<li>Use Node Package Manager (npm) to install bleno in that directory<br />
Run this command in Terminal:
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>npm install bleno
</code></pre></div> </div>
</li>
<li>In Terminal, run the main.js script to start advertising your device
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>node main.js
</code></pre></div> </div>
</li>
<li>Open a BLE app, like LightBlue to view your device, its services and characteristics<br />
<a href="https://itunes.apple.com/us/app/lightblue-explorer-bluetooth-low-energy/id557428110?mt=8">LightBlue for iOS</a><br />
<a href="https://itunes.apple.com/us/app/lightblue/id639944780?mt=12">LightBlue for MacOS</a></li>
</ol>
<p>Any value you write to the Echo Characteristic (UUID: 0xEC0E) on the device should be echoed in the Terminal window</p>
<p><img src="/images/MacAsBLEPeripheral/Devices.PNG" width="250" />
<img src="/images/MacAsBLEPeripheral/EchoService.PNG" width="250" />
<img src="/images/MacAsBLEPeripheral/EchoCharacteristic.PNG" width="250" />
<img src="/images/MacAsBLEPeripheral/WriteValue.PNG" width="250" /></p>
<p>Output in Terminal:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>State: poweredOn
on -> advertisingStart: success
EchoCharacteristic - onUnsubscribe
EchoCharacteristic - onWriteRequest: value = ab
EchoCharacteristic - onReadRequest: value = ab
</code></pre></div></div>
<p>To quit the node program, press Control + C</p>
<p>For more info, see the <a href="https://github.com/sandeepmistry/bleno">bleno github page</a></p>
<p>Enjoy!</p>tomThis guide will show you how to turn your Mac into a Bluetooth Low Energy (BLE) peripheral device for creating your very own BLE services and characteristics.What Every Xamarin.Forms Developer Needs to Know About UWP2017-02-15T01:23:00+00:002017-02-15T01:23:00+00:00https://tomsoderling.github.io/what-every-Xamarin.Froms-developer-needs-to-know-about-UWP<p>Over the last few weeks I’ve noticed that a <strong>lot</strong> happens in your UWP project when you flip the switch from Debug build to Release build mode. At the heart of it, has been this little check box on the UWP project build properties: “Compile with .NET Native tool chain”.<br />
<img src="/images/WhatEveryXFDevNeedsToKnowAboutUWP/CompileCheckBox.png" style="width: 500px;" /></p>
<p>There are some good posts about <a href="https://blogs.windows.com/buildingapps/2015/08/20/net-native-what-it-means-for-universal-windows-platform-uwp-developers/#HG2ld3KGHUOiMVQI.97">what it means for UWP.</a><br />
<a href="http://stackoverflow.com/questions/37759125/windows-store-apps-windows-8-vs-uwp">StackOverflow posts here also</a></p>
<p>For me, it means that our app can make the long journey into the Windows Store and none of the code-drawn graphics will be displayed on screen. <strong>Oops</strong>.</p>
<p>We’ve been using the NControl library in this app for a while and it’s been a great tool for drawing custom vector graphics via code. <a href="https://github.com/chrfalch/NControl">NControl</a> is a simple Xamarin.Forms wrapper control around the library that does the drawing, NGraphics.<br />
<a href="https://github.com/praeclarum/NGraphics">NGraphics</a> is a cross platform library for rendering vector graphics on .NET. It provides a unified API for both immediate (display to screen) and retained mode (save .png file to disk) graphics using high quality native renderers.</p>
<p>Here’s a little sample of how to draw something and place it in an NControl:</p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">var</span> <span class="n">width</span> <span class="p">=</span> <span class="m">200</span><span class="p">;</span>
<span class="kt">var</span> <span class="n">height</span> <span class="p">=</span> <span class="m">200</span><span class="p">;</span>
<span class="kt">var</span> <span class="n">frame</span> <span class="p">=</span> <span class="k">new</span> <span class="n">NGraphics</span><span class="p">.</span><span class="nf">Rect</span><span class="p">(-</span><span class="n">width</span><span class="p">/</span><span class="m">2</span><span class="p">,</span> <span class="m">0</span><span class="p">,</span> <span class="n">width</span><span class="p">,</span> <span class="n">height</span><span class="p">);</span>
<span class="kt">var</span> <span class="n">corner</span> <span class="p">=</span> <span class="k">new</span> <span class="n">NGraphics</span><span class="p">.</span><span class="nf">Size</span><span class="p">(</span><span class="m">1</span><span class="p">,</span> <span class="m">1</span><span class="p">);</span>
<span class="kt">var</span> <span class="n">pen</span> <span class="p">=</span> <span class="k">new</span> <span class="n">NGraphics</span><span class="p">.</span><span class="nf">Pen</span><span class="p">(</span><span class="n">NGraphics</span><span class="p">.</span><span class="n">Colors</span><span class="p">.</span><span class="n">Blue</span><span class="p">,</span> <span class="m">0</span><span class="p">);</span>
<span class="kt">var</span> <span class="n">point1</span> <span class="p">=</span> <span class="k">new</span> <span class="n">NGraphics</span><span class="p">.</span><span class="nf">Point</span><span class="p">(</span><span class="m">0</span><span class="p">,</span> <span class="m">0</span><span class="p">);</span> <span class="c1">// these don't seem to have any effect on the gradient</span>
<span class="kt">var</span> <span class="n">point2</span> <span class="p">=</span> <span class="k">new</span> <span class="n">NGraphics</span><span class="p">.</span><span class="nf">Point</span><span class="p">(</span><span class="m">0</span><span class="p">,</span> <span class="m">0</span><span class="p">);</span>
<span class="kt">var</span> <span class="n">brush</span> <span class="p">=</span> <span class="k">new</span> <span class="n">NGraphics</span><span class="p">.</span><span class="nf">LinearGradientBrush</span><span class="p">(</span><span class="n">point1</span><span class="p">,</span> <span class="n">point2</span><span class="p">,</span> <span class="n">NGraphics</span><span class="p">.</span><span class="n">Colors</span><span class="p">.</span><span class="n">Blue</span><span class="p">,</span> <span class="n">NGraphics</span><span class="p">.</span><span class="n">Colors</span><span class="p">.</span><span class="n">Green</span><span class="p">);</span>
<span class="kt">var</span> <span class="n">control</span> <span class="p">=</span> <span class="k">new</span> <span class="n">NControlView</span>
<span class="p">{</span>
<span class="n">DrawingFunction</span> <span class="p">=</span> <span class="p">(</span><span class="n">canvas</span><span class="p">,</span> <span class="n">rect</span><span class="p">)</span> <span class="p">=></span>
<span class="p">{</span>
<span class="n">canvas</span><span class="p">.</span><span class="nf">DrawRectangle</span><span class="p">(</span><span class="n">frame</span><span class="p">,</span> <span class="n">corner</span><span class="p">,</span> <span class="n">pen</span><span class="p">,</span> <span class="n">brush</span><span class="p">);</span>
<span class="p">},</span>
<span class="n">HorizontalOptions</span> <span class="p">=</span> <span class="n">LayoutOptions</span><span class="p">.</span><span class="n">Center</span>
<span class="p">};</span>
<span class="c1">// Then put it on your Xamarin.Forms page</span>
</code></pre></div></div>
<p>And this is the result:<br />
<img src="/images/WhatEveryXFDevNeedsToKnowAboutUWP/SampleNControl.png" style="width: 200px;" /></p>
<p>(Note that the docs on the GitHub page are a bit out of date)</p>
<p>Impressively, NControl currently supports native custom renderers for 6 platforms:</p>
<ul>
<li>iOS</li>
<li>Android</li>
<li>Windows Phone (8, 8.1, and Silverlight 8.1)</li>
<li>Windows Store (Windows 8.1)</li>
</ul>
<p>But was lacking support for UWP (Windows 10). I built this out about 6 months ago and it’s been working really well in our project. Imagine my surprise when it simply didn’t work at all in Release mode :/<br />
When adding UWP support for these libraries, I used a common “monkey-see, monkey-do” approach, not knowing much of the graphic-y bits in the libraries. So naturally, I assumed that the monkey messed something up along the way.</p>
<p>Here’s a comparison of the Live Visual Tree:</p>
<table>
<tr>
<td>Here without .NET Native enabled</td>
<td>And with it enabled. Ta-da! no NControl!</td>
</tr>
<tr>
<td style="vertical-align: top">
<img src="/images/WhatEveryXFDevNeedsToKnowAboutUWP/LVT1.png" alt="NControl is in Visual Tree" style="width: 350px;" />
</td>
<td style="vertical-align: top">
<img src="/images/WhatEveryXFDevNeedsToKnowAboutUWP/LVT2.png" alt="NControl is gone" style="width: 350px;" />
</td>
</tr>
</table>
<h1 id="debugging-net-native">Debugging .NET Native</h1>
<p>Debugging the issue has been a process of examining each component and revisiting the code I wrote, starting at the lowest layer, NGraphics. The good news there is that it works fine when compiled with .NET Native. Sweet! This also gave me the chance to improve things a bit and submit a pull request back to the library (more on that below).</p>
<p>On to NControl then - it contains all the necessary Windows-specific stuff, like a Windows.UI.Xaml.Controls.Canvas, and helpers to convert the NGraphics.Brush to a Windows.UI.Xaml.Media.Brush, but most importantly, a Custom Renderer that renders an NControlView as a Windows.UI.Xaml.Controls.Grid that can be displayed on UWP. Hooking the NControl source to my repro project seemed to be the best approach.</p>
<p>As you may have guessed, debugging a .NET Native compiled app is a little different. Check out my previous <a href="https://tomsoderling.github.io/Debugging-NET-Native">post on this</a> for directions, namely, you will want to debug a non-optimized .NET Native build, and this will show you how to do that.</p>
<p>This confirmed the true issue; the constructor of my NControlViewRenderer was never getting hit, thus all the great code I had added for UWP wasn’t even getting touched :/<br />
I’ve seen this happen before when I forgot to add the assembly attribute above my renderer class.</p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">[</span><span class="n">assembly</span><span class="p">:</span> <span class="nf">ExportRenderer</span><span class="p">(</span><span class="k">typeof</span><span class="p">(</span><span class="n">NControlView</span><span class="p">),</span> <span class="k">typeof</span><span class="p">(</span><span class="n">NControlViewRenderer</span><span class="p">))]</span>
</code></pre></div></div>
<p>but that wasn’t the issue here. It’s almost like Xamarin.Forms was totally oblivious of this custom renderer… But why? Why?<br />
Why…<br />
So I searched all the places I usually look: Google, Xamarin Forums/Bugzilla/Docs (<em>is that the best order?</em>), pdf copies of books, GitHub issues. Zero.</p>
<p>It was then that I hit the point that I often hit when troubleshooting development issues</p>
<p><strong><em>This problem can’t be this huge.</em></strong></p>
<p>If no 3rd party library’s custom renderers work in Xamarin.Forms apps in the Windows Store, that would be a HUGE deal. It can’t be that hundreds of Xamarin developers around the globe are having this issue, can it? It’d have turned up in a search somewhere, right? Someone has got to be writing UWP apps for the Windows Store, right? (maybe not…)</p>
<h1 id="leave-curious">Leave Curious</h1>
<p>So I left work curious (I’d recommend it), and decided to Google just a bit on the bus ride home. I think the small keyboard on my phone encouraged me to keep the search terse; just the essential keywords of my problem: <strong>UWP “.NET Native” ViewRenderer</strong></p>
<p>And then I found it.</p>
<p>One line in an unrelated library’s FAQ section about license keys:</p>
<blockquote>
<p>“For .NET Native compilation, you have to tell Xamarin.Forms which assemblies it should scan for custom controls and renderers”</p>
</blockquote>
<p>AH! That makes so much sense!</p>
<p>Now there have been a few UWP-specific Xamarin.Forms <em>intricacies</em> like this that I think could be documented better. Turns out, there is a special, nearly secret, overload of the Forms.Init method just for UWP where you can pass in an IEnumerable called rendererAssemblies:</p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#if WINDOWS_UWP
</span> <span class="k">public</span> <span class="k">static</span> <span class="k">void</span> <span class="nf">Init</span><span class="p">(</span><span class="n">IActivatedEventArgs</span> <span class="n">launchActivatedEventArgs</span><span class="p">,</span> <span class="n">IEnumerable</span><span class="p"><</span><span class="n">Assembly</span><span class="p">></span> <span class="n">rendererAssemblies</span> <span class="p">=</span> <span class="k">null</span><span class="p">)</span>
<span class="cp">#else
</span></code></pre></div></div>
<p>And what does it do with these assemblies?</p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#if WINDOWS_UWP
</span> <span class="n">Registrar</span><span class="p">.</span><span class="n">ExtraAssemblies</span> <span class="p">=</span> <span class="n">rendererAssemblies</span><span class="p">?.</span><span class="nf">ToArray</span><span class="p">();</span>
<span class="cp">#endif
</span>
<span class="n">Registrar</span><span class="p">.</span><span class="nf">RegisterAll</span><span class="p">(</span><span class="k">new</span><span class="p">[]</span> <span class="p">{</span> <span class="k">typeof</span><span class="p">(</span><span class="n">ExportRendererAttribute</span><span class="p">),</span> <span class="k">typeof</span><span class="p">(</span><span class="n">ExportCellAttribute</span><span class="p">),</span> <span class="k">typeof</span><span class="p">(</span><span class="n">ExportImageSourceHandlerAttribute</span><span class="p">)</span> <span class="p">});</span>
</code></pre></div></div>
<p>And why would you want to register these extra assemblies?</p>
<blockquote>
<p>“Xamarin.Forms may be unable to load objects from those assemblies (such as custom renderers).”</p>
</blockquote>
<p>But the <a href="https://developer.xamarin.com/guides/xamarin-forms/platform-features/windows/installation/universal/#Troubleshooting">little snippet of “documentation”</a> is a little murky here - there are directions to use this UWP-specific overload, but it’s described as a fix for the “Target Invocation Exception” when using “Compile with .NET Native tool chain”. I wasn’t seeing any exceptions, so the entire section under this heading wasn’t on my radar at all. The app ran great. Blissfully unaware that my NControlView should be displayed on the screen.</p>
<p>In fact, I found that this is a requirement for <strong>ALL custom renderers that live in a 3rd party library</strong>. For example, our app has a custom renderer for playing videos. It has an implementation for each platform (iOS & UWP) that lives in its respective platform-specific projects and this renderer works great - so that threw us off for a bit. By contrast, in addition to NControl, we’re also using the popular 3rd party Xamarin Image Circle <a href="https://github.com/jamesmontemagno/ImageCirclePlugin">plugin</a> and it also wasn’t working correctly in .NET Native builds, leaving the images square.</p>
<p>So what other assemblies do we have to include?<br />
You may notice if you look at the Xamarin Evolve <a href="https://github.com/xamarinhq/app-evolve/blob/master/src/XamarinEvolve.UWP/App.xaml.cs#L92">source code</a> that James seems to add everything and the kitchen sink here. Not sure if all that is needed.<br />
The only answer I’ve heard from Xamarin was from James: “<em>Mostly you just need third party ones. I just did them all lol cause I wasn’t sure to be honest</em>”</p>
<h1 id="the-fix">The Fix</h1>
<p>Here’s the bit of code that corrected it. This goes in the App.xaml.cs file in your UWP head project:</p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// For .NET Native compilation, you have to tell Xamarin.Forms which assemblies it should scan for custom controls and renderers</span>
<span class="kt">var</span> <span class="n">rendererAssemblies</span> <span class="p">=</span> <span class="k">new</span><span class="p">[]</span>
<span class="p">{</span>
<span class="k">typeof</span><span class="p">(</span><span class="n">NControl</span><span class="p">.</span><span class="n">UWP</span><span class="p">.</span><span class="n">NControlViewRenderer</span><span class="p">).</span><span class="nf">GetTypeInfo</span><span class="p">().</span><span class="n">Assembly</span><span class="p">,</span>
<span class="k">typeof</span><span class="p">(</span><span class="n">ImageCircle</span><span class="p">.</span><span class="n">Forms</span><span class="p">.</span><span class="n">Plugin</span><span class="p">.</span><span class="n">UWP</span><span class="p">.</span><span class="n">ImageCircleRenderer</span><span class="p">).</span><span class="nf">GetTypeInfo</span><span class="p">().</span><span class="n">Assembly</span>
<span class="p">};</span>
<span class="c1">// Then call Init with these assembiles</span>
<span class="n">Xamarin</span><span class="p">.</span><span class="n">Forms</span><span class="p">.</span><span class="n">Forms</span><span class="p">.</span><span class="nf">Init</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">rendererAssemblies</span><span class="p">);</span>
</code></pre></div></div>
<p>Even though I was calling the Init methods on these libraries:</p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">ImageCircleRenderer</span><span class="p">.</span><span class="nf">Init</span><span class="p">();</span>
<span class="n">NControl</span><span class="p">.</span><span class="n">UWP</span><span class="p">.</span><span class="n">NControlViewRenderer</span><span class="p">.</span><span class="nf">Init</span><span class="p">();</span>
</code></pre></div></div>
<p>Without the above code, you get nothing in UWP with .NET Native builds. No exceptions are thrown. Nothing in the debug output window. Nothing on screen. Silent failure.</p>
<p><strong>I feel that this should be documented much better.</strong> Hence this blog post (and I’ve reached out to the Xamarin docs team).</p>
<p>If you are interested in using NControl or NGraphics on UWP, check out the pull requests <a href="https://github.com/praeclarum/NGraphics/pull/63">here</a> and <a href="https://github.com/chrfalch/NControl/pull/71">here</a>.</p>
<p>I’d love it if you would<br />
1.) try it out<br />
2.) give any feedback on how it could be improved.<br />
I’m really excited about this, my first PR to an open source library, so let’s work together people!</p>tomOver the last few weeks I’ve noticed that a lot happens in your UWP project when you flip the switch from Debug build to Release build mode. At the heart of it, has been this little check box on the UWP project build properties: “Compile with .NET Native tool chain”.Wired Debugging on a Surface Tablet? Yes You Can!2017-02-03T12:00:00+00:002017-02-03T12:00:00+00:00https://tomsoderling.github.io/Wired-Debugging-on-Surface<div>
<div style="display: inline-block;" align="top">
<img src="/images/WiredSurfaceDebugging/SurfacePro3USBPort.png" width="150" />
</div>
<div style="display: inline-block; width: 80%; vertical-align: top;">From a mobile developer's perspective, debugging on a Surface tablet is weird. Really weird.
The first time I picked up the Surface and spotted the USB port on the side, I figured, cool - I'll just plug it into my laptop and run something! <br />
Ah.... no. <br />
Sorry. <br />
It's not <i>that</i> kind of USB port. You can't just stick anything in there, man.
</div>
</div>
<p>To debug on a Surface (or devices that do not have Visual Studio installed) you must install the Visual Studio Remote Debugger client app on the device and then wirelessly communicate with it to debug from Visual Studio on your laptop. The version of the remote client app MUST match the version of Visual Studio you’re using (update 1, 2, 3, etc.). Directions to do that is <a href="https://msdn.microsoft.com/en-us/library/y7f5zaaa.aspx">here</a><br />
<img src="/images/WiredSurfaceDebugging/RemoteDebuggerClient.png" width="400" /></p>
<p><br />
There is a <strong>major</strong> issue with this plan, however:<br />
More and more apps we’re building need to be offline capable. So how are you supposed to debug in an offline scenario with wireless debugging? That’s where that USB port is going to come in handy.</p>
<p>Also, another benefit of debugging over a wired connection is that it’s a bit more reliable and faster to get the app running after each build.</p>
<p>One thing to note: like a lot of mobile developers, I work all day on a MacBook Pro and use <a href="http://www.parallels.com">Parallels</a> that runs a Windows 10 Virtual Machine so I can use all my Windows tools side by side - so this post is written from that perspective.</p>
<h1 id="hardware-needed">Hardware Needed</h1>
<p>In order to debug over a wired connection, you’ll need a few things:</p>
<ul>
<li>2 USB to Ethernet dongles. You can find them for pretty cheap on <a href="https://www.amazon.com/gp/product/B00ET4KHJ2/ref=oh_aui_detailpage_o08_s00?ie=UTF8&psc=1">Amazon</a>.</li>
<li>A length of cat 5 cable to connect the two dongles together.</li>
</ul>
<p><br /></p>
<p>What won’t work here is one of those fancy (and 3x more expensive) lightning to Ethernet dongles plugged into my Mac, because my Windows VM doesn’t recognize it. The USB adapter is the one Windows understands.<br />
<img src="/images/WiredSurfaceDebugging/thunderboldToEthernetAdapter.png" width="250" /></p>
<div>
<div style="display: inline-block; width: 50%; vertical-align: top;" align="top">
Connect the dongles together with the ethernet cable, and plug one dongle into your laptop and the other into the Surface. <br />
Here's what it should look like when it's all hooked up.
</div>
<div style="display: inline-block;">
<img src="/images/WiredSurfaceDebugging/WiredSetup.jpg" width="450px" />
</div>
</div>
<h1 id="debugging-online-and-offline">Debugging Online and Offline</h1>
<p>For our Xamarin.Forms app, we need to be online the first time a user logs in and syncs data with the server, but then we want to disconnect from the internet to test offline scenarios after that first login.</p>
<p>The trickiest part was getting my laptop to share its internet connection with the Surface over my wired ethernet connection. When you first connect your Surface to your laptop, if you turn off the Surface WiFi connection you’ll see an icon indicating that there is no internet connection.</p>
<p>Thankfully, there’s a nice Windows feature that allows you to do that called Adapter Bridging.<br />
Here’s how to do it:</p>
<ol>
<li>Open <strong>Network Connections</strong> on Windows</li>
<li>Locate the adapter that is supplying your internet connection. With Parallels this is done by an Ethernet adapter</li>
<li>Select both the adapter from step #2 and the one for your plugged in USB dongle</li>
<li>Right click and select <strong>Bridge Connections</strong><br />
<img src="/images/WiredSurfaceDebugging/BridgeConnections.png" width="400px" /><br />
The internet connection will now be shared over the ethernet cable to your Surface device</li>
</ol>
<p><strong>Start debugging while online:</strong></p>
<ol>
<li>Bridge adapters<br />
OR<br />
You can always simply unplug the USB adapter dongle from the Surface and turn WiFi back on.</li>
<li>Open browser on Surface to check for connectivity</li>
<li>Get the Surface’s IP address (cmd > ipconfig)</li>
<li>Enter the IP address in the Remote Machine textbox in Visual Studio. Format is xxx.xxx.xxx.xxx:[Port Number]</li>
<li>Run on Remote device</li>
</ol>
<p><strong>Then offline:</strong></p>
<ol>
<li>Select adapters, right click, select Remove from Bridge</li>
<li>Wait for Surface to get new IP</li>
<li>Type it in the Remote Machine textbox in VS</li>
</ol>
<h1 id="tips">Tips</h1>
<ul>
<li>
<p>When Un-Bridging. The Surface will show that the internet connection is lost right away and long before it gets a new IP, so wait for the USB Ethernet adapter to show that it has a new (different) IP before trying to debug to it in Visual Studio.</p>
</li>
<li>
<p>Generally, you’ll have your Solution build configuration set to deploy the UWP head project to your device each time you start debugging the app. That means the app will be installed over the old one on each deploy and that can be undesirable when testing offline behavior, so don’t forget to uncheck that if needed after the initial deploy of the app to the device.<br />
<img src="/images/WiredSurfaceDebugging/SolutionConfig.png" width="800px" /></p>
</li>
<li>I always turn on these two options in the VS Remote Debugger app running on the Surface (under <strong>Tools</strong> menu > <strong>Options</strong>):
<ol>
<li><strong>No Authentication</strong><br />
Turning this off seems to alleviate a lot of the hassle of trying to get the debugger to connect to the remote client app. I debug on a private or wired network and only have the remote client running when I need to debug, so the lack of security doesn’t concern me here.</li>
<li><strong>Allow any user to debug</strong><br />
I use this setting because don’t log into my Windows 10 VM via Parallels so I’ve had an issue with that. I also use this when my coworker needs to debug on the Surface.<br />
<img src="/images/WiredSurfaceDebugging/AuthMode.png" width="300px" /></li>
</ol>
</li>
<li>If you find yourself switching from connected in disconnected frequently, it’s a pain to keep typing in the same 2 IP addresses over and over in the Remote Machine textbox. Undo (Ctrl + Z) works inside that textbox.</li>
</ul>
<h1 id="guiding-principles">Guiding Principles</h1>
<ul>
<li>
<p>Don’t live or die by what the <strong>Remote Connections</strong> dialog is able/unable to find. It’s nice when it finds your device, but often it doesn’t. So if you’ve got things hooked up correctly, just type the IP + Port in the address box manually. Remember to use the correct format: ip<strong>.</strong>addr<strong>.</strong>goes<strong>.</strong>here<strong>:</strong>[port number]<br />
<img src="/images/WiredSurfaceDebugging/ConnectionFound.png" width="350px" /></p>
</li>
<li>
<p>You must have the Visual Studio 2015 Remote Debugger app running on the Surface at all times. That app will close automatically after a certain period of inactivity.</p>
</li>
</ul>
<h1 id="common-errors">Common Errors</h1>
<p><strong>Error:</strong> Unable to connect to the Microsoft Visual Studio Remote Debugger named ‘10.211.55.5:4020’. The Visual Studio Remote Debugger on the remote computer is running as a different user.</p>
<p><strong>Fix:</strong> On the Surface, in the menu for the VS 2015 Remote Debugger app, go to Tools > Options, and check the <strong>Allow any user to debug</strong> option, under the <strong>No Authentication</strong> radio button.</p>
<h1 id="resources">Resources</h1>
<ul>
<li><a href="https://msdn.microsoft.com/en-us/windows/uwp/debug-test-perf/deploying-and-debugging-uwp-apps">https://msdn.microsoft.com/en-us/windows/uwp/debug-test-perf/deploying-and-debugging-uwp-apps</a></li>
</ul>tomFrom a mobile developer's perspective, debugging on a Surface tablet is weird. Really weird. The first time I picked up the Surface and spotted the USB port on the side, I figured, cool - I'll just plug it into my laptop and run something! Ah.... no. Sorry. It's not that kind of USB port. You can't just stick anything in there, man.