<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Tutorials Archives - HangZone</title>
	<atom:link href="https://hangzone.com/category/tutorials/feed/" rel="self" type="application/rss+xml" />
	<link>https://hangzone.com/category/tutorials/</link>
	<description>Mobile App and Game Development</description>
	<lastBuildDate>Tue, 31 Mar 2020 14:49:42 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://hangzone.com/wp-content/uploads/2022/04/cropped-HZ-Logo-32x32.png</url>
	<title>Tutorials Archives - HangZone</title>
	<link>https://hangzone.com/category/tutorials/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>How to Make a Location Check-In App in Xamarin.Forms Part One</title>
		<link>https://hangzone.com/how-to-make-a-location-check-in-app-in-xamarin-forms-part-one/</link>
		
		<dc:creator><![CDATA[Tyler Bandy]]></dc:creator>
		<pubDate>Tue, 31 Mar 2020 14:49:42 +0000</pubDate>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Tutorials]]></category>
		<guid isPermaLink="false">https://hangzone.com/?p=2093</guid>

					<description><![CDATA[<p>It’s been about ten years since Foursquare launched their mobile check-in app. In case you missed out on that trend, the original Foursquare app was all about checking into locations ...</p>
<p>The post <a href="https://hangzone.com/how-to-make-a-location-check-in-app-in-xamarin-forms-part-one/">How to Make a Location Check-In App in Xamarin.Forms Part One</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>It’s been about ten years since Foursquare launched their mobile check-in app. In case you missed out on that trend, the original Foursquare app was all about checking into locations to earn badges. Whoever logged the most activity at a location over a trailing month earned the title of mayor. Sometimes restaurants gave special offers to the mayor, like free guacamole on a burrito, so this was serious business!</p>
<p>These were the early days of gamification of mundane activities, so there was a pretty low bar to get people excited. Eventually, people got tired of having to check-in everywhere, and the app lost popularity.</p>
<h2>Let’s Bring it Back</h2>
<p>They say fads come in cycles though. Maybe it’s time to bring the check-in trend back to the masses. Let’s start with your immediate group of friends anyway. We’ll pick one place you guys all like to go. Everyone will have the ability to check-in once every 12 hours. Whoever has the most check-ins is the mayor. We’ll build the app with Xamarin.Forms. This will be a two part series. We’ll handle the location based functionality in part one. We’ll take care of the server functionality in part 2.</p>
<h2>Start a Xamarin Forms Project</h2>
<p>Fire up Visual Studio. I’m using a Windows computer, but feel free to use a Mac. Some of the menus will be a bit different though. Create a new project. Select a Xamarin.Forms template. I’m going to call this project &#8220;Mayor&#8221;. Go with the blank template option, and select Android and iOS for the platforms.</p>
<h2>Set-up Location Libraries and Permissions</h2>
<p>For starters, the Xamarin Essentials NuGet package houses all of the location functionality that we need. Fortunately, it’s already added to our project by default, along with the necessary start-up code.</p>
<p>That just leaves us with permissions. We’ll start with Android. Open up your AndroidManifest.xml file. It’s in the Properties folder in case you can’t find it. Inside the manifest node, add the following code.</p>
<pre><code>&lt;uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /&gt;
&lt;uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /&gt;
&lt;uses-feature android:name="android.hardware.location" android:required="false" /&gt;
&lt;uses-feature android:name="android.hardware.location.gps" android:required="false" /&gt;
&lt;uses-feature android:name="android.hardware.location.network" android:required="false" /&gt;
</code></pre>
<p>Now let’s do iOS. Right click your Info.plist and select View Code. Inside the dictionary, add the following key value pair.</p>
<pre><code>&lt;key&gt;NSLocationWhenInUseUsageDescription&lt;/key&gt;
&lt;string&gt;We need to verify your location when you check-in.&lt;/string&gt;
</code></pre>
<p>This will show the user a prompt for why we’re requesting to track their location.</p>
<h2>The Interface</h2>
<p>Let’s put together a basic interface now. We want a label that shows how many times you’ve checked-in during the past month. We also want a button to check-in. Finally, we want a label that displays a confirmation or error code for your check-in attempt.</p>
<p>Open up MainPage.xaml and remove the default label inside of the StackLayout. Let’s put our own interface elements inside of the StackLayout.</p>
<pre><code>&lt;Label
    x:Name="MessageLabel"
    HorizontalOptions="Center"
    HorizontalTextAlignment="Center"
    Text="Remember to Check-In!"
    VerticalOptions="EndAndExpand" /&gt;
&lt;Button
    x:Name="CheckInButton"
    Margin="10"
    HorizontalOptions="Center"
    Text="Check-In"
    VerticalOptions="CenterAndExpand" /&gt;
&lt;Label
    x:Name="CountLabel"
    HorizontalOptions="Center"
    HorizontalTextAlignment="Center"
    Text="Check-In Count: 0"
    VerticalOptions="StartAndExpand /&gt;
</code></pre>
<p>It’s a pretty simple layout, but it will do. The top label has a generic instructional message as a filler for now. When the user attempts to login, we’ll replace the text in this label with a success or error message. The label at the bottom will show the total number of check-ins. Go ahead and give the code a run. Your screen should look like this.</p>
<p><a href="https://hangzone.com/wp-content/uploads/2020/03/Check-In-Layout.png"><img decoding="async" class="alignnone size-medium wp-image-2100" src="https://hangzone.com/wp-content/uploads/2020/03/Check-In-Layout-139x300.png" alt="Check In Layout" width="139" height="300" srcset="https://hangzone.com/wp-content/uploads/2020/03/Check-In-Layout-139x300.png 139w, https://hangzone.com/wp-content/uploads/2020/03/Check-In-Layout-473x1024.png 473w, https://hangzone.com/wp-content/uploads/2020/03/Check-In-Layout.png 1125w" sizes="(max-width: 139px) 100vw, 139px" /></a></p>
<h2>The Check-In Code</h2>
<p>Normally, I would put the check-in code in a ViewModel and set-up binding with our labels and button. In the interest of keeping this demo simple, let’s just do our work in the code-behind. Open MainPage.xaml.cs. At the top of the page, add a line to access the Xamarin Essentials library.</p>
<pre><code>Using Xamarin.Essenetials;
</code></pre>
<p>Now, below the MainPage constructor, add a new function.</p>
<pre><code>private async Task CheckIn()
{
    try
    {
        var request = new GeolocationRequest(GeolocationAccuracy.Medium);
        var userLocation = await Geolocation.GetLocationAsync(request);

        if (userLocation != null)
        {
            try
            {
                var locations = await Geocoding.GetLocationsAsync("3330 Cumberland Blvd Suite 500, Atlanta, GA 30339");

                var clientLocation = locations?.FirstOrDefault();
                if (clientLocation != null)
                {
                    double kilometers = Location.CalculateDistance(userLocation, clientLocation, DistanceUnits.Kilometers);
                    if (kilometers &lt; 0.6) { // the accuracy should be good within 500 meters await Device.InvokeOnMainThreadAsync(() =&gt; MessageLabel.Text = "You successfully checked-in!");
                    }
                    else
                    {
                        await Device.InvokeOnMainThreadAsync(() =&gt; MessageLabel.Text = "You need to be closer to check-in.");
                    }
                }
            }
            catch (FeatureNotSupportedException fnsEx)
            {
                // Feature not supported on device
                await Device.InvokeOnMainThreadAsync(() =&gt; MessageLabel.Text = "The check-in feature is not supported on your device.");
            }
            catch (Exception ex)
            {
                // Handle exception that may have occurred in geocoding
                await Device.InvokeOnMainThreadAsync(() =&gt; MessageLabel.Text = "We are unable to retrieve the client's location.");
            }
        }
     }
     catch (FeatureNotSupportedException fnsEx)
     {
         // Handle not supported on device exception
         await Device.InvokeOnMainThreadAsync(() =&gt; MessageLabel.Text = "The check -in feature is not supported on your device.");
    }
    catch (FeatureNotEnabledException fneEx)
    {
        // Handle not enabled on device exception
        await Device.InvokeOnMainThreadAsync(() =&gt; MessageLabel.Text = "The check-in feature is not enabled on your device.");
    }
    catch (PermissionException pEx)
    {
        // Handle permission exception
        await Device.InvokeOnMainThreadAsync(() =&gt; MessageLabel.Text = "You need to grant location permission for the check-in feature to work on your device.");
    }
    catch (Exception ex)
    {
        // Unable to get location
        await Device.InvokeOnMainThreadAsync(() =&gt; MessageLabel.Text = "We are unable to retrieve your location.");
    }
}
</code></pre>
<p>Let me break down what’s going on here. We’re constructing a GeolocationRequest object with medium accuracy. That should allow check-in accuracy within 100 to 500 meters on Android and within 100 meters on iOS. Next we get the user’s location. Note that GetLocationAsync is an asynchronous call, as are many of these location functions, so our CheckIn function must be asynchronous. There are two significant consequences. One, we should probably use a spinner on the interface in case these calls take long. Since this is just a demo, I’ll skip that. Two, we need to remember to switch back to the main thread when we’re ready to update the interface.</p>
<p>Moving further into the code, we use GetLocationsAsync to convert an address into an IEnumerable of Locations, of which we’ll grab the first object in the list. This is how I’m converting an address to a set of latitude and longitude coordinates. I’m using the address of HangZone. I don’t think you can beat me for Mayor of HangZone, so choose whatever other location you’d like!</p>
<p>Finally, we do our distance test within 0.6 kilometers, since the medium accuracy is good within 500 meters at worst. If the user is close enough, we update the MessageLabel for a successful check-in. If not, we tell the user to move closer. We also address a bunch of potential errors—everything from internet errors to location permission errors.</p>
<h2>Hook it Up to the Check-In Button</h2>
<p>We should probably test this out to make sure everything is working correctly. We’ll have to hook up our button first, though. Go back to MainPage.xaml. Add a clicked property to the Button.</p>
<pre><code>Clicked="CheckInButton_Clicked"
</code></pre>
<p>Now go back to the code-behind and implement it. The function may have been auto-populated when you filled out the xaml, but make sure to make the function asynchronous.</p>
<pre><code>private async void CheckInButton_Clicked(object sender, EventArgs e)
{
    await Task.Run(CheckIn);
}
</code></pre>
<p>Now give it a run.</p>
<p><a href="https://hangzone.com/wp-content/uploads/2020/03/Check-In-Missing-Permissions.png"><img decoding="async" class="alignnone size-medium wp-image-2101" src="https://hangzone.com/wp-content/uploads/2020/03/Check-In-Missing-Permissions-139x300.png" alt="Check In Missing Permissions" width="139" height="300" srcset="https://hangzone.com/wp-content/uploads/2020/03/Check-In-Missing-Permissions-139x300.png 139w, https://hangzone.com/wp-content/uploads/2020/03/Check-In-Missing-Permissions-473x1024.png 473w, https://hangzone.com/wp-content/uploads/2020/03/Check-In-Missing-Permissions.png 1125w" sizes="(max-width: 139px) 100vw, 139px" /></a></p>
<h2>Prompt the User for Location Permission</h2>
<p>Well, apparently my iPhone still needs location permission. What’s the deal with that? No worries. This is a good chance to point out a pesky issue with this library that might trip you up. The Xamarin Essentials library will automatically prompt the user to give the app location permission if you call GetLocationAsync without having the proper permission. Unfortunately, we’re running our check-in code on a background thread. While that makes sense for all of these asynchronous location calls, it prevents the library from being able to display the permission request on the UI.</p>
<p>The easiest fix is just to execute our CheckIn function on the main thread. Within the CheckInButton_clicked function, wrap our call to the CheckIn function like so.</p>
<pre><code>Await Device.InvokeOnMainThreadAsync(() =&gt; CheckIn());
</code></pre>
<p>Try to check-in again. You should see a pop-up asking to use your location. Cool! Now it works!</p>
<p><a href="https://hangzone.com/wp-content/uploads/2020/03/Check-In-Permissions.png"><img decoding="async" class="alignnone size-medium wp-image-2102" src="https://hangzone.com/wp-content/uploads/2020/03/Check-In-Permissions-139x300.png" alt="Check In Permissions" width="139" height="300" srcset="https://hangzone.com/wp-content/uploads/2020/03/Check-In-Permissions-139x300.png 139w, https://hangzone.com/wp-content/uploads/2020/03/Check-In-Permissions-473x1024.png 473w, https://hangzone.com/wp-content/uploads/2020/03/Check-In-Permissions.png 1125w" sizes="(max-width: 139px) 100vw, 139px" /></a></p>
<p>Note that while this solution is alright for a demo, we really would rather run the CheckIn function on a background thread. Ideally, we could check for location permission before calling the CheckIn function, then let it do its work on a background thread. That’s just something to think about for when you do this in a real app!</p>
<h2>Count the Check-ins</h2>
<p>Ultimately, we would like to track total check-ins on a server. That way, we know how all of your friends are doing, and we can assign a mayor. For part 1 of this tutorial, we’re skipping the server. Therefore, we’ll store the value locally in Preferences. You get access to the Preferences functionality as part of the Xamarin Essentials library, which we’ve already included for the location code. We’ll also use a local int to keep track of the check-in number.</p>
<p>At the top of your MainPage class definition, just above your constructor, add the following code.</p>
<pre><code>private int CheckInCount;
</code></pre>
<p>Inside the MainPage constructor, add the following below InitializeComponenet().</p>
<pre><code>CheckInCount = Preferences.Get("checkInCount", 0);
CountLabel.Text = "Check-In Count: " + CheckInCount;
</code></pre>
<p>This will ensure that our app loads the check-in count from our previous session. If there wasn’t a previous session, we default to zero total check-ins.</p>
<p>Now inside the CheckIn function, find the if statement that ensures the check-in is within 0.6 meters of the location. Right after we update the MessageLabel, add the following lines.</p>
<pre><code>CheckInCount++;
await Device.InvokeOnMainThreadAsync(() =&gt; CountLabel.Text = "Check-In Count: " + CheckInCount);
Preferences.Set("checkInCount", CheckInCount)
</code></pre>
<p>This increments our total check-ins, updates the label, and puts the value in persistent storage so we’ll have it next time we open the app.</p>
<p>Run the app, and save your first check-in!</p>
<p><a href="https://hangzone.com/wp-content/uploads/2020/03/Check-In-Success.png"><img decoding="async" class="alignnone size-medium wp-image-2103" src="https://hangzone.com/wp-content/uploads/2020/03/Check-In-Success-139x300.png" alt="Check In Success" width="139" height="300" srcset="https://hangzone.com/wp-content/uploads/2020/03/Check-In-Success-139x300.png 139w, https://hangzone.com/wp-content/uploads/2020/03/Check-In-Success-473x1024.png 473w, https://hangzone.com/wp-content/uploads/2020/03/Check-In-Success.png 1125w" sizes="(max-width: 139px) 100vw, 139px" /></a></p>
<h2>Limit Check-In Frequency</h2>
<p>Alright. So far so good. You arrive at the location, you tap the button, and you’re checked-in. But what happens if you tap the button again? Egads! You’ve checked-in twice! This will compromise the integrity of the mayorship if users take advantage of this exploit!</p>
<p>Let’s put a 12 hour limit on how often you can check-in to a location. We can store a timestamp whenever you successfully check-in. On subsequent attempts, we’ll just make sure the current time is at least 12 hours later than the last time. If it is, we’ll process the check-in and update the timestamp.</p>
<p>We’ll update the CheckInButton_Clicked to look like this.</p>
<pre><code>private async void CheckInButton_Clicked(object sender, EventArgs e)
{
    var lastTimeStamp = Preferences.Get("lastTimeStamp", new DateTime(2010,1,1));

    if ((DateTime.Now - lastTimeStamp).TotalHours &gt;= 12)
    {
        await Device.InvokeOnMainThreadAsync(() =&gt; CheckIn());
    }
    else
    {
    await Device.InvokeOnMainThreadAsync(() =&gt; MessageLabel.Text = "You haven't waited 12 hours since your last check-in.");
    }
}
</code></pre>
<p>We also need to add the code for updating the timestamp on successful check-ins. Inside the CheckIn function, add the following code just below where we saved CheckInCount in Preferences.</p>
<pre><code>Preferences.Set("lastTimeStamp", DateTime.Now);
</code></pre>
<h2><a href="https://hangzone.com/wp-content/uploads/2020/03/Check-In-Frequency-Limit.png"><img decoding="async" class="alignnone size-medium wp-image-2099" src="https://hangzone.com/wp-content/uploads/2020/03/Check-In-Frequency-Limit-139x300.png" alt="Check In Frequency Limit" width="139" height="300" srcset="https://hangzone.com/wp-content/uploads/2020/03/Check-In-Frequency-Limit-139x300.png 139w, https://hangzone.com/wp-content/uploads/2020/03/Check-In-Frequency-Limit-473x1024.png 473w, https://hangzone.com/wp-content/uploads/2020/03/Check-In-Frequency-Limit.png 1125w" sizes="(max-width: 139px) 100vw, 139px" /></a></h2>
<h2>Conclusion</h2>
<p>You’ve got a fully functional check-in app! It’s really only effective as a sort of one-player game at the moment, since you’re not competing against anyone else on the server. We’ll add that code another time. For now, perhaps you can use it to track how often you go the gym. Keep an eye open for part two! Until then, thanks for reading the HangZone blog.</p>
<p>The post <a href="https://hangzone.com/how-to-make-a-location-check-in-app-in-xamarin-forms-part-one/">How to Make a Location Check-In App in Xamarin.Forms Part One</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Custom Renderers in Xamarin.Forms Part 2</title>
		<link>https://hangzone.com/custom-renderers-xamarin-forms-part-2/</link>
		
		<dc:creator><![CDATA[Judson Bandy]]></dc:creator>
		<pubDate>Wed, 27 Nov 2019 18:25:13 +0000</pubDate>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Tutorials]]></category>
		<guid isPermaLink="false">https://hangzone.com/?p=2056</guid>

					<description><![CDATA[<p>In part 2 of our custom renderer blog post, we will continue to look at uses for custom renderers in Xamarin.Forms. In part 1, we made a navigation page in ...</p>
<p>The post <a href="https://hangzone.com/custom-renderers-xamarin-forms-part-2/">Custom Renderers in Xamarin.Forms Part 2</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>In part 2 of our custom renderer blog post, we will continue to look at uses for custom renderers in Xamarin.Forms. In part 1, we made a navigation page in Xamarin.Forms. The toolbar item on the page used an icon from <a href="http://material.io">material.io</a> for the Android version and used a system icon for the iOS version. We were able to use the system icon thanks to a custom renderer. If you have not read it, you can find part 1 <a href="https://hangzone.com/custom-renderers-xamarin-forms-part-1/">here</a>. We will start this project where part 1 left off.</p>
<h2>Extending an Element</h2>
<p>Let’s continue with the same Xamarin.Forms solution, which I named CustomRendererSample. The next thing that we want to add is a gradient underneath the toolbar. A shadow can be added to the Android project by adding an elevation property definition under the Resources-&gt;layout-&gt;Toolbar.axml file. This is not what we’re after though. We are going to add a loud, slightly obnoxious gradient on both iOS and Android under the toolbar.<span class="Apple-converted-space"> </span></p>
<p>The Xamarin.Forms control that we want to use is the BoxView. Unfortunately, we only have the ability to give it a single uniform color. To add our desired functionality, we will subclass BoxView and add additional properties to our new control. Then, we will create custom renderers for iOS and Android that will tell the system how to use our new properties. Hopefully, it won’t be too hard.</p>
<h2>Create our Custom BoxView</h2>
<p>Let’s start by creating our new BoxView class. Right click on the Shared Project and select Add-&gt;New Item… Add a new class called GradientBoxView.cs. We could create our properties simply as public properties, but instead, we are going to use BindableProperty. This will allow us to set these properties in a style. Styles do not make much sense if you are only using them once, but they can be quite helpful for maintaining and updating your code if objects with the same appearance are used multiple times.</p>
<p>Add the following code to your GradientBoxView class.</p>
<pre><code>public class GradientBoxView : BoxView
{
    public static readonly BindableProperty StartColorProperty = BindableProperty.Create("StartColor", typeof(Color), typeof(GradientBoxView), Color.Transparent);
    public static readonly BindableProperty EndColorProperty = BindableProperty.Create("EndColor", typeof(Color), typeof(GradientBoxView), Color.Transparent);
    public static readonly BindableProperty IsVerticalProperty = BindableProperty.Create("IsVertical", typeof(bool), typeof(GradientBoxView), true);

    public Color StartColor
    {
        get { return (Color)GetValue(StartColorProperty); }
        set { SetValue(StartColorProperty, value); }
    }

    public Color EndColor
    {
        get { return (Color)GetValue(EndColorProperty); }
        set { SetValue(EndColorProperty, value); }
    }

    public bool IsVertical
    {
        get { return (Color)GetValue(IsVerticalProperty); }
        set { SetValue(IsVerticalProperty, value); }
    }
}</code></pre>
<p>You can see that the class inherits from BoxView, so that we retain all of the functionality of that class. Then, we added variables for StartColor, EndColor, and IsVertical. As the names suggest, these will define the starting color, ending color, and direction of the gradient.</p>
<h2>Implementing the GradientBoxView</h2>
<p>Now, let’s head over to App.xaml to create a style. Like we said, a style is nice in case we want to use the same gradient on a number of pages. In the Application.Resources section, add the following code.<span class="Apple-converted-space"> </span></p>
<pre><code>&lt;ResourceDictionary&gt;
    &lt;Style x:Key=“AwesomeGradientStyle” TargetType=“customrenderersample:GradientBoxView”&gt;
        &lt;Setter Property=“StartColor” Value=“DarkBlue”/&gt;
        &lt;Setter Property=“EndColor” Value=“#10FFFFFF”/&gt;
        &lt;Setter Property=“IsVertical” Value=“True”/&gt;
        &lt;Setter Property=“HeightRequest” Value=“10”/&gt;
    &lt;/Style&gt;
&lt;/ResourceDictionary&gt;</code></pre>
<p>As you can see, a style is added that sets all of our properties for the GradientBoxView. App.xaml will have to add “xmlns:customrendersample=“clr-namespace:CustomRendererSample” so that GradientBoxView will be imported into this class.</p>
<p>Now, we can jump over to MainPage.xaml to add GradientBoxView to the page. Change the ContentPage.Content to look like this.</p>
<pre><code>&lt;ContentPage.Content&gt;
    &lt;Grid&gt;
        &lt;Grid.RowDefinitions&gt;
            &lt;RowDefinition Height="auto"/&gt;
            &lt;RowDefinition Height="*"/&gt;
        &lt;/Grid.RowDefinitions&gt;
        &lt;customrenderersample:GradientBoxView Style=“{StaticResource AwesomeGradientStyle}”/&gt;
        &lt;Label Grid.Row="1" x:Name="SearchLabel" Text="Search" VerticalOptions="Center" HorizontalOptions="Center"/&gt;
    &lt;/Grid&gt;
&lt;/ContentPage.Content&gt;</code></pre>
<p>You can see that we adjusted our grid to put the gradient underneath the toolbar at the top of the page, and our SearchLabel is still in the middle. Again, we need the same CustomRendererSample definition and prefix to use the class. That wraps up the code in our Shared Project. Let’s move on to our custom renderers and set our new GradientBoxView properties in motion.</p>
<h2>iOS Custom Renderer</h2>
<p>Let’s start with the iOS renderer. Its code is a little simpler, so it should be an easier place to begin. Navigate to the iOS project, right click and select Add-&gt;New Item… Choose a class and name it GradientBoxViewRenderer.cs. Click the Add button, and we’re ready to get started.</p>
<p>First, we need to add an assembly line so that this code will be used. Above the line that defines the namespace, add:</p>
<pre><code>[assembly: ExportRenderer(typeof(GradientBoxView), typeof(GradientBoxViewRenderer))]</code></pre>
<p>This line tells our code to use this renderer whenever GradientBoxView occurs in the code. If you get errors in this code, or anywhere else in the custom renderers, you should be able to hover over the error and select for Visual Studio to add the appropriate using directive. Next, we will make this class a subclass of BoxRenderer.</p>
<pre><code>class GradientBoxViewRenderer : <b>BoxRenderer</b></code></pre>
<p>To add our gradient to the boxview, we only need to override one method, the Draw function.</p>
<pre><code>public override void Draw(CGRect rect)
{
    base.Draw(rect);

    var stack = Element as GradientBoxView;
    var topColor = stack.StartColor.ToCGColor();
    var bottomColor = stack.EndColor.ToCGColor();
    var gradientLayer = new CAGradientLayer
    {
        Frame = rect,
        Colors = new CGColor[] { topColor, bottomColor }
    };

    if (!stack.IsVertical)
    {
        gradientLayer.StartPoint = new CGPoint(0, 0.5);
        gradientLayer.EndPoint = new CGPoint(1, 0.5);
    }

    NativeView.Layer.InsertSublayer(gradientLayer, 0);
}</code></pre>
<p>Let’s walk through what is going on. First, we are getting our GradientBoxView and setting it to a local variable, stack. Next, we are getting the start color and end color from it, and converting the colors to CGColors. Then, we create a CAGradientLayer to the size of our BoxView with the gradient colors. Finally, we adjust the direction if horizontal is desired, and we add the gradient to the native iOS BoxView. That’s it! It is fairly straightforward, and just like that, the iOS version is good to go. Now, let’s move to Android.</p>
<h2>Android Custom Renderer</h2>
<p>This custom renderer is a little more involved, but we can do it. Go to the Android project in the Solution Explorer, and add a new class just like we did for the iOS renderer. We will also name this class GrandientBoxViewRenderer.cs. Add the same assembly directive above the namespace definition so that this renderer will be used for all GradientBoxViews when running on Android. Then, add the code so that this class will be a subclass of BoxRenderer. That’s where the same code ends.</p>
<p>First, we’ll add instance variables for our GradientBoxView properties at the top of the renderer class definition and an empty initializer for the class.</p>
<pre><code>public class GradientBoxViewRenderer : BoxRenderer
{
    <b>private Color StartColor { get; set; }
    private Color EndColor { get; set; }
    private bool IsVertical { get; set; }

    public GradientBoxViewRenderer(Context context) : base(context)
    {

    }</b>
}</code></pre>
<p>Then, we will override OnElementChanged. We will use this to set the values of our instance variables.</p>
<pre><code>protected override void OnElementChanged(ElementChangedEventArgs&lt;BoxView&gt; e)
{
    base.OnElementChanged(e);

    if (e.OldElement != null || Element == null)
    {
        return;
    }

    try
    {
        var stack = e.NewElement as GradientBoxView;

        this.StartColor = stack.StartColor;
        this.EndColor = stack.EndColor;
        this.IsVertical = stack.IsVertical;
    }
    catch (Exception ex)
    {
        System.Diagnostics.Debug.WriteLine(@"ERROR:", ex.Message);
    }
}</code></pre>
<p>Now that we have our variables from GradientBoxView, it’s time to do our drawing code to create the gradient on the Android BoxView.</p>
<pre><code>protected override void DispatchDraw(global::Android.Graphics.Canvas canvas)
{
    if (global::Android.OS.Build.VERSION.SdkInt &gt; global::Android.OS.BuildVersionCodes.O)
    {
        var orientation = GradientDrawable.Orientation.TopBottom;

        if (!this.IsVertical)
        {
            orientation = GradientDrawable.Orientation.LeftRight;
        }

        var specialGradient = new GradientDrawable(orientation, new[] { this.StartColor.ToAndroid().ToArgb(), this.EndColor.ToAndroid().ToArgb() });
        ViewCompat.SetBackground(this, specialGradient);
        return;
    }

    global::Android.Graphics.LinearGradient gradient = null;

    if (this.IsVertical)
    {
        gradient = new global::Android.Graphics.LinearGradient(0, 0, 0, Height, this.StartColor.ToAndroid(),this.EndColor.ToAndroid(), global::Android.Graphics.Shader.TileMode.Clamp);
    }
    else
    {
        gradient = new global::Android.Graphics.LinearGradient(0, 0, Width, 0, this.StartColor.ToAndroid(), this.EndColor.ToAndroid(), global::Android.Graphics.Shader.TileMode.Clamp);
    }

    var paint = new global::Android.Graphics.Paint()
    {
        Dither = true,
    };
    paint.SetShader(gradient);
    canvas.DrawPaint(paint);
    base.DispatchDraw(canvas);
}</code></pre>
<p>As you can see, the technique is different for Android versions greater than O. For the newer versions, we simply get our orientation, then create a GradientDrawable with our colors. Then, we set it as the background on the native ViewCompat. For the older Android versions, we create a LinearGradient based on the gradient direction. Then, we DrawPaint the gradient onto the canvas. That’s it for Android and our GradientBoxView. Run the project and see your custom GradientBoxView in action! You can easily change the color, direction, or size if you so desire.</p>
<p><a href="https://hangzone.com/wp-content/uploads/2019/11/Blog-Xamarin-Forms-Custom-Renderer-Finished-App.png"><img decoding="async" class="alignnone size-medium wp-image-2057" src="https://hangzone.com/wp-content/uploads/2019/11/Blog-Xamarin-Forms-Custom-Renderer-Finished-App-188x300.png" alt="Blog Xamarin Forms Custom Renderer Finished App" width="188" height="300" srcset="https://hangzone.com/wp-content/uploads/2019/11/Blog-Xamarin-Forms-Custom-Renderer-Finished-App-188x300.png 188w, https://hangzone.com/wp-content/uploads/2019/11/Blog-Xamarin-Forms-Custom-Renderer-Finished-App-640x1024.png 640w, https://hangzone.com/wp-content/uploads/2019/11/Blog-Xamarin-Forms-Custom-Renderer-Finished-App.png 674w" sizes="(max-width: 188px) 100vw, 188px" /></a></p>
<h2>Conclusion</h2>
<p>Great job! We successfully created a custom control in Xamarin.Forms—a GradientBoxView. This is a nice tool for adding gradients under objects in your projects to further set them off or provide separation of sections. Not only that, but you should now have a good idea of how to create other custom controls using custom renderers. It’s not always simple, but you can usually use custom renderers to accomplish any visual look or action that would natively be available on the platform. As always, thanks for reading the HangZone blog!</p>
<p>The post <a href="https://hangzone.com/custom-renderers-xamarin-forms-part-2/">Custom Renderers in Xamarin.Forms Part 2</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>How to Free Space in Xcode and Android Studio</title>
		<link>https://hangzone.com/free-space-xcode-android-studio/</link>
		
		<dc:creator><![CDATA[Tyler Bandy]]></dc:creator>
		<pubDate>Thu, 31 Oct 2019 19:58:10 +0000</pubDate>
				<category><![CDATA[Developer Insights]]></category>
		<category><![CDATA[Tutorials]]></category>
		<guid isPermaLink="false">https://hangzone.com/?p=2051</guid>

					<description><![CDATA[<p>My 5 year old MacBook recently started complaining about not having enough space. I don’t keep any music on my computer, and I have relatively few pictures. If I go ...</p>
<p>The post <a href="https://hangzone.com/free-space-xcode-android-studio/">How to Free Space in Xcode and Android Studio</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>My 5 year old MacBook recently started complaining about not having enough space. I don’t keep any music on my computer, and I have relatively few pictures. If I go to the About This Mac menu, and click on the Storage tab, the primary culprit is the System type. It takes up over 300 GB of my 500GB hard drive!</p>
<p>If you’ve been developing mobile apps for a few years on the same computer, I suspect you also have a glut of these opaque system files on your machine. Unlike pictures and music, it’s not so obvious how to clean them up. First, we have to identify what these files are, and then we need to figure out a safe way to dispose of them. Be advised that these files reside in the infamous Library folder. Apple hid it for a reason, so be careful!</p>
<h2>Navigating the Library Folder</h2>
<p>If you’re a developer, you’re probably accustomed to opening the Library folder every once in a while. Just in case you’ve forgotten how to get there, open up a Finder window, hold down the option key, and click on the Go menu at the top. Holding down the option key reveals the Library folder. Go ahead and click it.</p>
<p>From here, you can right click any of the folders inside and click Get Info. That will show you how much space each item takes up. As a mobile developer, Xcode and Android Studio are going to be the primary targets for the purge. Feel free to look around and see if you have any other massive file hoards, but we’ll be focusing on the Android and Developer folders.</p>
<h2>Xcode Developers</h2>
<p>Let’s start by dealing with our build-up of Xcode files. Navigate to Library/Developer/Xcode/iOS DeviceSupport. This folder is about 95 GB for me, and it contains symbol files dating back to iOS 6! This is more than a little unnecessary. Keep the folders for the iOS versions you still care about. You can safely delete everything in the folder for the other iOS versions. Even if you accidentally delete the support files for your favorite development device, Xcode will download the appropriate symbol files for that device again the next time you plug it in.</p>
<p>The other major storage hog in the Xcode environment is all of the old simulator data. Go to Library/Developer/CoreSimulator/Devices. I’ve got hundreds of old simulators in here, and they take up about 35 GB of space combined. To make things more complicated, their names are all lengthy strings of seemingly random letters and numbers. I have no easy way of knowing which ones are new and which ones are old.</p>
<p>Fortunately, Xcode tracks which simulators are no longer in use for your current Xcode version. Even better, we can purge them all it once through the Terminal. Open up Terminal and enter the command.</p>
<pre><code>xcrun simctl delete unavailable</code></pre>
<p>You’ll find a much shorter list of simulators in the Devices folder now. Mine take up less than 500 MB now! Between these two maneuvers, I’ve saved over 100 GB of space!</p>
<p>If you were to open Xcode now, you might find some problems. My storyboards turned black, and Xcode showed a vague error. We’re going to remedy this problem by deleting more files! Head over to Library/Developer/Xcode/DerivedData. This is a cache of files created when you build Xcode projects. You can safely delete everything in here. If you do happen to still get an Xcode error, clean your project, close Xcode, delete the DerivedData again, and restart your computer. You should be good as new!</p>
<p>There are other space saving options for Xcode, but they’re less meaningful and some are potentially more dangerous. For instance, you could delete some archives, but you might want them for debugging. I’m going to stop here for now, and call this a win on the Xcode front.</p>
<h2>Android Developers</h2>
<p>Space management on Android is a little more transparent than on Xcode. Considering you manually download which SDKs you want and create individual emulators for testing, you probably have a good idea of what’s taking up space here. Even so, sometimes it’s hard to know exactly how big an SDK or simulator actually is without looking it up. We’ll do that now.</p>
<p>Go to Library/Android/sdk/system-images. This has all of the Android SDKs that you’ve downloaded. Check the size on them. Mine are anywhere from 6 GB to 25 GB. Rather than deleting directly from here, I’ll use Android Studio. Click Configure from the opening dialog, and select SDK Manager. Delete SDKs that you don’t use for testing anymore, particularly if they’re exceptionally large.</p>
<p>Lastly, emulators aren’t going to take up as much space, but head over to the AVD Manager under the Tools menu. Delete the old devices you don’t use, and you’ll be awarded with a few free GB for your effort.</p>
<h2>Conclusion</h2>
<p>I’ve always enjoyed how Xcode downloads everything I need automatically compared to Android Studio forcing me to decide what I need. Of course, the downside is that Xcode will eventually take up a ton of space before you realize it. No worries! You can clean-up everything in a couple of minutes. If you waited as long as I did, you too may have 150 GB of new free space! So much room for activities!</p>
<p>The post <a href="https://hangzone.com/free-space-xcode-android-studio/">How to Free Space in Xcode and Android Studio</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Custom Renderers in Xamarin.Forms Part 1</title>
		<link>https://hangzone.com/custom-renderers-xamarin-forms-part-1/</link>
		
		<dc:creator><![CDATA[Judson Bandy]]></dc:creator>
		<pubDate>Mon, 30 Sep 2019 16:06:38 +0000</pubDate>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Tutorials]]></category>
		<guid isPermaLink="false">https://hangzone.com/?p=2041</guid>

					<description><![CDATA[<p>Xamarin.Forms is a great tool for cross platform app development. It gives you the ability to write shared code that is used by different operating systems. Not only are you ...</p>
<p>The post <a href="https://hangzone.com/custom-renderers-xamarin-forms-part-1/">Custom Renderers in Xamarin.Forms Part 1</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Xamarin.Forms is a great tool for cross platform app development. It gives you the ability to write shared code that is used by different operating systems. Not only are you able to write shared logic, but you are also able to write shared UI code. This allows you to save time in initial development and makes it much more maintainable since there is only one version of the code. Not only this, but Xamarin.Forms is able to use native elements of each platform so that you are still able to get a native look and feel for each device.</p>
<p>Although this shared code is fast and works well, it doesn’t always provide the granularity that we are looking to use for each platform. Sometimes a finer brush is needed to paint our masterpiece. This is no reason to fret, though. Xamarin.Forms allows us to create custom renderers so that we are able to extend controls to take advantage of native specific elements for each platform. In this blog post, we will create a couple of custom renderers in a Xamarin.Forms project to make elements that are more robust than what comes out of the box.</p>
<h2>Create Xamarin.Forms Project</h2>
<p>Let’s start by creating a new Xamarin.Forms project. I am developing on a Windows computer in Visual Studio 2019. You can do this just as well on Visual Studio for Mac. We are are going to write this app to run for both iOS and Android.</p>
<p>First, open Visual Studio, and create a new project. Select Mobile App (Xamarin.Forms), and click Next. Give your project a name, mine is called “CustomRendererSample,” choose a location, and create the project. Select a Blank template, and for platforms, we are doing Android and iOS. You can certainly do UWP as well, but we are only targeting iOS and Android in this example. Press OK, and our project is now created.</p>
<h2>Toolbar Buttons</h2>
<p>For this example, we are going to make an app with a hierarchical navigation scheme. This has the toolbar at the top, and pages are added to and popped off the stack as you navigate. We are only going to have one page for our example, though. With the toolbar at the top, it is common to have toolbar buttons. These can be save, cancel, back, refresh, and so on. You will find these in many of the first party phone apps (like Settings) or pretty much any native enterprise style app. Toolbar buttons can be created through Xamarin.Forms, but as an extension to the control, we are going to have the app use System toolbar buttons on iOS to get a totally native look.</p>
<p>First, let’s get the navigation page set up for the app. Open App.xaml.cs in the Shared Project of your Solution. Make the following edit to the constructor.</p>
<pre><code>MainPage = <b>new NavigationPage(</b>new MainPage()<b>)</b>;</code></pre>
<p>This creates a NavigationPage as the root page of the app, and then adds MainPage as the content of the navigation page. Feel free to go ahead and run the app. You should now see a blank toolbar at the top of your screen, and the Xamarin.Forms welcome label displayed in the middle of it. We’re off to a good start!</p>
<p>Now, open MainPage.xaml. Start by deleting the entire StackLayout and the welcome label that is inside it. We are going to make our own content later.</p>
<pre><code><del>&lt;StackLayout&gt;
    &lt;!-- Place new controls here --&gt;
    &lt;Label Text="Welcome to Xamarin.Forms!"
      HorizontalOptions="Center"
      VerticalOptions="CenterAndExpand" /&gt;
&lt;/StackLayout&gt;</del></code></pre>
<p>Next, we’ll give the page a title to go on the toolbar. Set the title property on ContentPage to “Awesome Page.”</p>
<pre><code>&lt;ContentPage …… <b>Title=“Awesome Page”</b>&gt;</code></pre>
<h2>Android Toolbar Buttons</h2>
<p>We don’t have to add images to our project for iOS since we are using system buttons, but we do need them for Android. We are able to download Android buttons without any problem from the material.io website. All Android icons are open source and are available to be used in any project. We are going to use the search icon in our project. Go to this <a href="https://material.io/resources/icons/?style=baseline">page</a>, select the “search” icon, and download the SVG 24 file.<span class="Apple-converted-space"> </span></p>
<p>I like to open this file in Inkscape (use can use any vector drawing program to edit the file without losing image quality). The image, which is a little larger than 17&#215;17, is designed to be centered on a transparent 24&#215;24 background. Once you do that, we want to change the color of the icon to white, and create 3 different sizes—24&#215;24, 48&#215;48, and 72&#215;72. Now, they are ready to export and add to our project. Please see the image below for what my icons look like.</p>
<p><a href="https://hangzone.com/wp-content/uploads/2019/09/Blog-Xamarin-Forms-Custom-Renderers-Toolbar-Search-Icons.png"><img decoding="async" class="alignnone size-medium wp-image-2045" src="https://hangzone.com/wp-content/uploads/2019/09/Blog-Xamarin-Forms-Custom-Renderers-Toolbar-Search-Icons-300x127.png" alt="Blog Xamarin Forms Custom Renderers Toolbar Search Icons" width="300" height="127" srcset="https://hangzone.com/wp-content/uploads/2019/09/Blog-Xamarin-Forms-Custom-Renderers-Toolbar-Search-Icons-300x127.png 300w, https://hangzone.com/wp-content/uploads/2019/09/Blog-Xamarin-Forms-Custom-Renderers-Toolbar-Search-Icons-1024x435.png 1024w, https://hangzone.com/wp-content/uploads/2019/09/Blog-Xamarin-Forms-Custom-Renderers-Toolbar-Search-Icons.png 1154w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>Let’s go back to Visual Studio. Inside the Android project, open the Resource folder. Drag the 24&#215;24, 48-48, and 72&#215;72 icons into the drawable, drawable-hdpi, and drawable-xxhdpi folders, respectively. All three of my icons are named “searchIconDroid.png.” Now that the icons are created and added to the project, we can return to the code.</p>
<p>On a side note, these drawable folders are currently not working in the Microsoft version of Visual Studio. You can look through the File Explorer and see that the folders do not actually exist. To fix it, simply delete the fake folders that are currently shown, and re-add folders with the same names.</p>
<h2>Create the Toolbar Item in XAML</h2>
<p>Open MainPage.xaml again, and add the following code.</p>
<pre><code>&lt;ContentPage.ToolbarItems&gt;
    &lt;ToolbarItem x:Name="SearchButton"
      Text="Search"&gt;
        &lt;ToolbarItem.IconImageSource&gt;
            &lt;OnPlatform x:TypeArguments="FileImageSource"&gt;
                &lt;On Platform="iOS" Value=""/&gt;
                &lt;On Platform="Android" Value="searchIconDroid"/&gt;
            &lt;/OnPlatform&gt;
        &lt;/ToolbarItem.IconImageSource&gt;
    &lt;/ToolbarItem&gt;
&lt;/ContentPage.ToolbarItems&gt;</code></pre>
<p>This code creates a ToolbarItem named “SearchButton.” We aren’t going to reference the button in this project, but it can still be helpful to give a name to your elements. We set the “Text” to “Search.” This is what our iOS custom renderer is going to use to identify what kind of system bar button should be used. Finally, we set the IconImageSource. We use platform specific code where the Android version is set to the name of the search icon that we created, and the iOS version is left empty. You can run this code on an Android device and see our beautiful search icon, but the iOS version still needs a custom renderer.</p>
<h2>iOS Toolbar Button Custom Renderer</h2>
<p>It’s finally time to create our first custom renderer. Right click on the iOS Project in your Solution and select Add-&gt;New Item… Add a new class called CustomNavigationRenderer.cs. To set up the page, we have to add an assembly directive to the top. This line makes all instances of the Xamarin control referenced flow through this custom renderer. Add the following line (note: many of the lines will require additional using namespaces to be added. Visual Studio should show errors and tell you which namespaces need to be added).</p>
<pre><code>[assembly: ExportRenderer(typeof(ContentPage), typeof(CustomNavigationRenderer))]</code></pre>
<p>You can see that this names ContentPage, which is the page type that we are using in the Shared Project, and the name of this renderer. Next, add that our new renderer class inherits from PageRenderer.</p>
<pre><code>class CustomNavigationRenderer : <b>PageRenderer</b></code></pre>
<p>Now we add the logic to the page.</p>
<pre><code>protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
    base.OnElementChanged(e);
    CreateNativeToolbarItems();
}

private void CreateNativeToolbarItems()
{
    if (this.NavigationController == null)
        return;
    if (this.NavigationController.TopViewController == null)
        return;
    if (this.NavigationController.TopViewController.NavigationItem == null)
        return;
    if (this.NavigationController.TopViewController.NavigationItem.RightBarButtonItems == null)
        return;

    var rightList = new List&lt;UIBarButtonItem&gt;();
    foreach (var item in this.NavigationController.TopViewController.NavigationItem.RightBarButtonItems)
    {
        if (string.IsNullOrEmpty(item.Title))
        {
            continue;
        }
        if (item.Title.ToLower() == "search")
        {
            var newItem = new UIBarButtonItem(UIBarButtonSystemItem.Search)
            {
                Action = item.Action,
                Target = item.Target
            };
            rightList.Add(newItem);
        }
        else
        {
            rightList.Add(item);
        }
    }
    if (rightList.Count &gt; 0)
    {
        this.NavigationController.TopViewController.NavigationItem.RightBarButtonItems = rightList.ToArray();
    }
}</code></pre>
<p>We override the OnElementChanged method, which is defined in the parent class. This is called when the ContentPage is created or changed. We use this method to call our CreateNativeToolbarItems method. After checking that the NavigationController and toolbar pieces exist, we cycle through the toolbar buttons that have been created. If the title is set to “search,” which we did in the xaml code by setting the text property, we create a new UIBarButtonItem. This bar button is the system search icon and we put it into our RightBarButtonItems array instead of the button that was created by the XAML.</p>
<p>Run the project on iOS and you will find a system search icon nestled on the right side of the toolbar. Good job!</p>
<h2>Toolbar Action</h2>
<p>It’s not necessary, but we might as well have something happen when we press the toolbar button. Go back to MainPage.xaml, and add the following property to our ToolbarItem.</p>
<pre><code>Clicked=“SearchButton_Clicked”</code></pre>
<p>We will also add a label to be manipulated when the button is pressed. Below the ToolbarItems code, add the following.</p>
<pre><code>&lt;ContentPage.Content&gt;
    &lt;Grid&gt;
        &lt;Label x:Name”SearchLabel” Text=“Search” VerticalOptions=“Center” HorizontalOptions=“Center”/&gt;
    &lt;/Grid&gt;
&lt;/ContentPage.Content&gt;</code></pre>
<p>Now, let’s go to the MainPage.xaml.cs file to define the click method. Add the following.</p>
<pre><code>private void SearchButton_Clicked(object sender, EventArgs e)
{
    if (SearchLabel.TextColor == Color.Black)
    {
        SearchLabel.TextColor = Color.Green;
    }
    else
    {
        SearchLabel.TextColor = Color.Black;
    }
}</code></pre>
<p>This code will change the color of the label on the middle of the screen each time you click the search icon. Run the code and watch it in action. The label changes to black, then green, then black again on subsequent clicks.</p>
<h2>Conclusion</h2>
<p>Great job! In this tutorial, we put a toolbar item on a page in Xamarin.Forms. For Android, we used icons from <a href="http://material.io">material.io</a>, sized them properly, and added them to our project. For iOS, we used a custom renderer to display system icons in the project. Even though we are using Xamarin.Forms, we were able to display a completely native look on each device. Feel free to further extend our iOS custom renderer to have left side toolbar buttons, different colored toolbar buttons, or anything else you can think of. As always, thanks for reading the HangZone blog.</p>
<p>The post <a href="https://hangzone.com/custom-renderers-xamarin-forms-part-1/">Custom Renderers in Xamarin.Forms Part 1</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>How to Fetch Stock and Currency Quotes for iPhone</title>
		<link>https://hangzone.com/how-to-fetch-stock-and-currency-quotes-for-iphone/</link>
		
		<dc:creator><![CDATA[Tyler Bandy]]></dc:creator>
		<pubDate>Fri, 30 Aug 2019 21:01:41 +0000</pubDate>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Tutorials]]></category>
		<guid isPermaLink="false">https://hangzone.com/?p=2027</guid>

					<description><![CDATA[<p>When I’m not writing apps, I like to follow stocks. I’ve even had the opportunity to combine those interests in the past with quantitative trading strategies. We’ll keep things simple ...</p>
<p>The post <a href="https://hangzone.com/how-to-fetch-stock-and-currency-quotes-for-iphone/">How to Fetch Stock and Currency Quotes for iPhone</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>When I’m not writing apps, I like to follow stocks. I’ve even had the opportunity to combine those interests in the past with quantitative trading strategies. We’ll keep things simple today and just query stock and currency quotes from our iPhone.</p>
<h2>Get an Alpha Vantage API Key</h2>
<p>There are a lot of financial datasources, and many of them cost a good bit of money. That’s no surprise considering the massive budgets successful hedge funds have to spend on these products. Yahoo Finance was traditionally the most popular free source for stock price data, but that’s no longer an option. Fortunately, other free alternatives have emerged to fill the void.</p>
<p>Today, we’ll use Alpha Vantage. They have realtime and historical data for stocks and currencies, including cryptos. The assortment of technical indicator data is also quite robust. <a href="https://www.alphavantage.co">Head on over there and get a free API key</a>, and let’s get started.</p>
<h2>Create an Xcode Project</h2>
<p>Open up Xcode and create a new tabbed app. Call the app <em>Quotes</em>, and set the language as Swift. Open up <em>Main.Storyboard</em>. You should see a tab bar controller and two view controllers. We’ll use one view controller for stocks and the other for currency.</p>
<h2>Stock Storyboard</h2>
<p>The first controller will be for getting stock quotes. In fact, we actually want more than just the current price of the stock. We’d like all sorts of valuable peripherals. You can see I’ve added quite a few labels on my storyboard to cover all the data.</p>
<p><a href="https://hangzone.com/wp-content/uploads/2019/08/Quotes-Storyboard-Stocks.png"><img decoding="async" class="alignnone wp-image-2032 size-medium" src="https://hangzone.com/wp-content/uploads/2019/08/Quotes-Storyboard-Stocks-137x300.png" alt="Quotes Storyboard Stocks" width="137" height="300" srcset="https://hangzone.com/wp-content/uploads/2019/08/Quotes-Storyboard-Stocks-137x300.png 137w, https://hangzone.com/wp-content/uploads/2019/08/Quotes-Storyboard-Stocks.png 388w" sizes="(max-width: 137px) 100vw, 137px" /></a></p>
<p>To recap, the fields are Symbol, Open, High, Low, Price, Volume, Latest Trading Day, Previous Close, Change, and Change Percent. With that in mind, go ahead and drag 20 labels onto your storyboard, positioned in 2 columns of 10. The left column has the field names, and the right column has the values. You won’t actually see those filler names for the values in the app. That’s just for readability in the storyboard. We’ll clear them in the code. Now embed each column of labels into a stack view. Then you can use constraints to get the left stack view away from the top and left edges of the device. Center the right stack view vertically with the left one, and use a standard amount of leading space.</p>
<p>At the bottom of the view controller, I added an instructional label (&#8220;Enter Stock Ticker&#8221;), a text field, and a search button. They’re all centered horizontally with about 40 vertical spacing between each object. Remember to set your text field to capitalize all characters and not autocorrect anything. That&#8217;s important for dealing with stock tickers. You can set those properties in the attributes inspector.</p>
<p>Once you’ve finished with the objects and constraints, tap the tab bar item at the bottom of the view controller, and go to the attributes inspector. Change its title to &#8220;Stocks&#8221;. That takes care of this view controller on the storyboard!</p>
<h2>Currency Storyboard</h2>
<p>The currency view controller is laid out basically the same way, only it has fewer fields. We only need pairs of labels for the following: Currency Code, Currency Name, Exchange Rate, Last Refreshed, Bid, and Ask. Here’s a picture for reference.</p>
<p><a href="https://hangzone.com/wp-content/uploads/2019/08/Quotes-Storyboard-Currency.png"><img decoding="async" class="alignnone size-medium wp-image-2031" src="https://hangzone.com/wp-content/uploads/2019/08/Quotes-Storyboard-Currency-138x300.png" alt="Quotes Storyboard Currency" width="138" height="300" srcset="https://hangzone.com/wp-content/uploads/2019/08/Quotes-Storyboard-Currency-138x300.png 138w, https://hangzone.com/wp-content/uploads/2019/08/Quotes-Storyboard-Currency.png 390w" sizes="(max-width: 138px) 100vw, 138px" /></a></p>
<p>The instructional label should say &#8220;Enter Currency Code&#8221;. The tab bar title will say &#8220;Currency&#8221;.</p>
<h2>Linking Storyboard</h2>
<p>There are quite a few labels to link from out storyboard to the code. Let’s get started. Hook-up the following IBOutlets using the value labels in our stock view controller. These will all link to the code in <em>FirstViewController</em>. Please note that these are from the value column on the right. We don’t need to hook-up the labels on the left.</p>
<pre><code>@IBOutlet weak var stockSymbolLabel: UILabel
@IBOutlet weak var stockOpenLabel: UILabel!
@IBOutlet weak var stockHighLabel: UILabel!
@IBOutlet weak var stockLowLabel: UILabel!
@IBOutlet weak var stockPriceLabel: UILabel!
@IBOutlet weak var stockVolumeLabel: UILabel!
@IBOutlet weak var stockLastTradingDayLabel: UILabel!
@IBOutlet weak var stockPreviousCloseLabel: UILabel!
@IBOutlet weak var stockChangeLabel: UILabel!
@IBOutlet weak var stockChangePercentLabel: UILabel!
</code></pre>
<p>While we’re here, let’s do the text field as well.</p>
<pre><code>@IBOutlet weak var stockTextField: UITextField!
</code></pre>
<p>We need to link the button too, but this one is an IBAction.</p>
<pre><code>@IBAction func stockSearchTapped(_ sender: Any) {

}
</code></pre>
<p>The pattern is similar for the currency view controller. These storyboard objects will link with <em>SecondViewController</em>.</p>
<pre><code>@IBOutlet weak var currencyCodeLabel: UILabel!
@IBOutlet weak var currencyNameLabel: UILabel!
@IBOutlet weak var currencyExchangeRateLabel: UILabel!
@IBOutlet weak var currencyLastRefreshedLabel: UILabel!
@IBOutlet weak var currencyBidValue: UILabel!
@IBOutlet weak var currencyAskValue: UILabel!
@IBOutlet weak var currencyTextField: UITextField!
@IBAction func currencySearchButtonTapped(_ sender: Any) {

}
</code></pre>
<h2>Query a Stock Quote</h2>
<p>In <em>FirstViewController</em>, we’ll add a function to query the stock data.</p>
<pre><code>func getStockQuote() {
    let session = URLSession.shared
    
    let quoteURL = URL(string: "https://www.alphavantage.co/query?function=GLOBAL_QUOTE&amp;symbol=\(stockTextField.text ?? "")&amp;apikey=APIKEY")!
    
    let dataTask = session.dataTask(with: quoteURL) {
        (data: Data?, response: URLResponse?, error: Error?) in
        
        if let error = error {
            print("Error:\n\(error)")
        } else {
            if let data = data {
                
                let dataString = String(data: data, encoding: String.Encoding.utf8)
                print("All the quote data:\n\(dataString!)")
                    
                if let jsonObj = try? JSONSerialization.jsonObject(with: data, options: .allowFragments) as? NSDictionary {
                        
                    if let quoteDictionary = jsonObj.value(forKey: "Global Quote") as? NSDictionary {
                        DispatchQueue.main.async {
                            if let symbol = quoteDictionary.value(forKey: "01. symbol") {
                                self.stockSymbolLabel.text = symbol as? String
                            }
                            if let open = quoteDictionary.value(forKey: "02. open") {
                                self.stockOpenLabel.text = open as? String
                            }
                            if let high = quoteDictionary.value(forKey: "03. high") {
                                self.stockHighLabel.text = high as? String
                            }
                            if let low = quoteDictionary.value(forKey: "04. low") {
                                self.stockLowLabel.text = low as? String
                            }
                            if let price = quoteDictionary.value(forKey: "05. price") {
                                self.stockPriceLabel.text = price as? String
                            }
                            if let volume = quoteDictionary.value(forKey: "06. volume") {
                                self.stockVolumeLabel.text = volume as? String
                            }
                            if let latest = quoteDictionary.value(forKey: "07. latest trading day") {
                                self.stockLastTradingDayLabel.text = latest as? String
                            }
                            if let previous = quoteDictionary.value(forKey: "08. previous close") {
                                self.stockPreviousCloseLabel.text = previous as? String
                            }
                            if let change = quoteDictionary.value(forKey: "09. change") {
                                self.stockChangeLabel.text = change as? String
                            }
                            if let changePercent = quoteDictionary.value(forKey: "10. change percent") {
                                self.stockChangePercentLabel.text = changePercent as? String
                            }
                        }
                    } else {
                        print("Error: unable to find quote")
                        DispatchQueue.main.async {
                            self.resetLabels()
                        }
                    }
                } else {
                    print("Error: unable to convert json data")
                    DispatchQueue.main.async {
                        self.resetLabels()
                    }
                }
            } else {
                print("Error: did not receive data")
                DispatchQueue.main.async {
                    self.resetLabels()
                }
            }
        }
    }
    
    dataTask.resume()
}
</code></pre>
<p>Most of this is UI code to update the labels, so don’t get too intimidated by the length. Let’s start at the top and make some sense of this. The URLSession and dataTask code launch the API call. Our API call is spelled out in quoteURL constant. There are 3 properties that we are passing to the server. The first is the function name, &#8220;GLOBAL_QUOTE&#8221;. This is Alpha Vantage’s function for getting stock quotes. The second is the symbol. We’re passing in whatever text the user has entered in the text field. The last parameter is the API key. In the code above, I set the API key equal to &#8220;APIKEY&#8221;. Put your own API key into your code.</p>
<p>All of this effort nets us a JSON package full of data for our requested stock ticker. We’ll convert that JSON into a dictionary. I’ve included a print to the console which helps you visualize the dictionary data. It’s basically a dictionary with one key, “Global Quote”. The value for that key is another dictionary, this time with keys “01. symbol”, “02. open”, “03. high”, “04. low”, etc. There’s one key for each piece of data we’d like. Our code simply checks each of these keys for a value and updates our labels. If there’s an error for whatever reason, most likely due to entering an invalid ticker, we log the error to the console and reset the labels. For a production app, you should show the user some sort of error, but this will be fine for a tutorial.</p>
<h2>Query a Currency Exchange Rate</h2>
<p>In <em>SecondViewController</em>, we need a similar function to query currency. Here it is.</p>
<pre><code>func getCurrencyQuote() {
    let session = URLSession.shared
    
    let quoteURL = URL(string: "https://www.alphavantage.co/query?function=CURRENCY_EXCHANGE_RATE&amp;from_currency=\(currencyTextField.text ?? "")&amp;to_currency=USD&amp;apikey=APIKEY")!
    
    let dataTask = session.dataTask(with: quoteURL) {
        (data: Data?, response: URLResponse?, error: Error?) in
        
        if let error = error {
            print("Error:\n\(error)")
        } else {
            if let data = data {
                
                let dataString = String(data: data, encoding: String.Encoding.utf8)
                print("All the quote data:\n\(dataString!)")
                
                if let jsonObj = try? JSONSerialization.jsonObject(with: data, options: .allowFragments) as? NSDictionary {
                    
                    if let quoteDictionary = jsonObj.value(forKey: "Realtime Currency Exchange Rate") as? NSDictionary {
                        DispatchQueue.main.async {
                            if let code = quoteDictionary.value(forKey: "1. From_Currency Code") {
                                self.currencyCodeLabel.text = code as? String
                            }
                            if let name = quoteDictionary.value(forKey: "2. From_Currency Name") {
                                self.currencyNameLabel.text = name as? String
                            }
                            if let rate = quoteDictionary.value(forKey: "5. Exchange Rate") {
                                self.currencyExchangeRateLabel.text = "$\(rate)"
                            }
                            if let date = quoteDictionary.value(forKey: "6. Last Refreshed") {
                                self.currencyLastRefreshedLabel.text = date as? String
                            }
                            if let bid = quoteDictionary.value(forKey: "8. Bid Price") {
                                self.currencyBidValue.text = "$\(bid)"
                            }
                            if let ask = quoteDictionary.value(forKey: "9. Ask Price") {
                                self.currencyAskValue.text = "$\(ask)"
                            }
                        }
                    } else {
                        print("Error: unable to find quote")
                        DispatchQueue.main.async {
                            self.resetLabels()
                        }
                    }
                } else {
                    print("Error: unable to convert json data")
                    DispatchQueue.main.async {
                        self.resetLabels()
                    }
                }
            } else {
                print("Error: did not receive data")
                DispatchQueue.main.async {
                    self.resetLabels()
                }
            }
        }
    }
    
    dataTask.resume()
}
</code></pre>
<p>This is very similar, so I’ll only touch on the differences. The quoteURL calls a different function, &#8220;CURRENCY_EXCHANGE_RATE&#8221;. In addition to the Api key, there are parameters for &#8220;from_currency&#8221; and &#8220;to_currency&#8221;. I’m only interested in converting to US dollars, so I hardcoded “USD” as the &#8220;to_currency&#8221;. The &#8220;from_currency&#8221; is pulled from our text field. Once we get our data, we unpackage the JSON and update our labels. We don’t need to use all of the data this time, mostly since we’re using a fixed &#8220;to_currency&#8221;.</p>
<h2>Finishing up the Code</h2>
<p>The query code was the heavy lifting. We just need to make everything works gracefully now. It’s time to implement the resetLabels function that we called in case of an error. Here it is for <em>FirstViewController</em>.</p>
<pre><code>func resetLabels() {
    stockSymbolLabel.text = "";
    stockOpenLabel.text = "";
    stockHighLabel.text = "";
    stockLowLabel.text = "";
    stockPriceLabel.text = "";
    stockVolumeLabel.text = "";
    stockLastTradingDayLabel.text = "";
    stockPreviousCloseLabel.text = "";
    stockChangeLabel.text = "";
    stockChangePercentLabel.text = "";
}
</code></pre>
<p>Now go to <em>SecondViewController</em> and add the equivalent code.</p>
<pre><code>func resetLabels() {
    currencyCodeLabel.text = "";
    currencyNameLabel.text = "";
    currencyExchangeRateLabel.text = "";
    currencyLastRefreshedLabel.text = "";
    currencyBidValue.text = "";
    currencyAskValue.text = "";
}
</code></pre>
<p>We also need some code to make sure the keyboard dismisses appropriately and shifts the screen up so we can view what we’re typing. Make sure both of our view controllers are UITextFieldDelegates by adding UITextFieldDelegate at the top of the class.</p>
<pre><code>class FirstViewController: UIViewController, UITextFieldDelegate {
</code></pre>
<p>Here’s the other one.</p>
<pre><code>class SecondViewController: UIViewController, UITextFieldDelegate {
</code></pre>
<p>Put these keyboard functions in both view controllers.</p>
<pre><code>@objc func dismissKeyboard() {
    //Causes the view (or one of its embedded text fields) to resign the first responder status.
    view.endEditing(true)
}

@objc func keyboardWillShow(notification: NSNotification) {
    if let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
        if self.view.frame.origin.y == 0 {
            self.view.frame.origin.y -= keyboardSize.height
        }
    }
}

@objc func keyboardWillHide(notification: NSNotification) {
    if self.view.frame.origin.y != 0 {
        self.view.frame.origin.y = 0
    }
}
</code></pre>
<p>We need to set up notifications for these functions in viewDidLoad and establish each class as its text field’s delegate. This is also a good chance to clear out the placeholder text in our value labels. Here’s the entirety of viewDidLoad for the stock view controller.</p>
<pre><code>override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.
    resetLabels()
    
    self.stockTextField.delegate = self
    
    let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(UIInputViewController.dismissKeyboard))
    view.addGestureRecognizer(tap)
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: UIResponder.keyboardWillShowNotification, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil)
}
</code></pre>
<p>Click on over to the currency view controller to do something similar.</p>
<pre><code>override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.
    resetLabels()
        
    self.currencyTextField.delegate = self
        
    let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(UIInputViewController.dismissKeyboard))
    view.addGestureRecognizer(tap)
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: UIResponder.keyboardWillShowNotification, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil)
}
</code></pre>
<p>We’d like to fire off queries from either tapping the search button or hitting return on the keyboard. We’ll handle the former by filling out our IBAction functions and the latter is a delegate method for the keyboard. Here’s the code for the stock view controller.</p>
<pre><code>@IBAction func stockSearchTapped(_ sender: Any) {
    getStockQuote()
    dismissKeyboard()
}

func textFieldShouldReturn(_ textField: UITextField) -&gt; Bool {
    getStockQuote()
    self.view.endEditing(true)
    return false
}
</code></pre>
<p>Here’s the equivalent code for the currency.</p>
<pre><code>
@IBAction func currencySearchButtonTapped(_ sender: Any) {
    getCurrencyQuote()
    dismissKeyboard()
}

func textFieldShouldReturn(_ textField: UITextField) -&gt; Bool {
    getCurrencyQuote()
    self.view.endEditing(true)
    return false
}
</code></pre>
<p>That should cover everything! Run the app and check your favorite stock. Check your least favorite stock. How about a currency? Remember to use codes for the currency, like EUR for euro or JPY for yen. You can even do digital currencies likes BTC for bitcoin.</p>
<p><a href="https://hangzone.com/wp-content/uploads/2019/08/Quotes-AAPL.png"><img decoding="async" class="alignnone size-medium wp-image-2034" src="https://hangzone.com/wp-content/uploads/2019/08/Quotes-AAPL-139x300.png" alt="Quotes AAPL" width="139" height="300" srcset="https://hangzone.com/wp-content/uploads/2019/08/Quotes-AAPL-139x300.png 139w, https://hangzone.com/wp-content/uploads/2019/08/Quotes-AAPL-473x1024.png 473w, https://hangzone.com/wp-content/uploads/2019/08/Quotes-AAPL.png 1125w" sizes="(max-width: 139px) 100vw, 139px" /></a></p>
<h2>Conclusion</h2>
<p>We’re just scratching the surface of investment app possibilities. You can fetch all sorts of historical data and technical indicators. Take a look around the documentation at Alpha Vantage and see if anything catches your eye. If you see something you like, just amend the quoteURL in your code and do a test run to see what sort of data you get back. Once you’ve had a look at the structure of the data, you can figure out what keys to use to unpack the dictionaries. Good luck and thanks for reading the HangZone blog!</p>
<p>The post <a href="https://hangzone.com/how-to-fetch-stock-and-currency-quotes-for-iphone/">How to Fetch Stock and Currency Quotes for iPhone</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>How to Add Core Location to our Weather App</title>
		<link>https://hangzone.com/add-core-location-weather-app/</link>
		
		<dc:creator><![CDATA[Tyler Bandy]]></dc:creator>
		<pubDate>Tue, 28 May 2019 14:35:27 +0000</pubDate>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Tutorials]]></category>
		<guid isPermaLink="false">https://hangzone.com/?p=1994</guid>

					<description><![CDATA[<p>It’s been over a year since we tackled weather on the HangZone blog. Longtime readers may recall our original weather app tutorial, followed by our five day forecast tutorial. In ...</p>
<p>The post <a href="https://hangzone.com/add-core-location-weather-app/">How to Add Core Location to our Weather App</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>It’s been over a year since we tackled weather on the HangZone blog. Longtime readers may recall our <a href="https://hangzone.com/build-ios-weather-app-external-api/">original weather app tutorial</a>, followed by our <a href="https://hangzone.com/display-five-day-forecasts-weather-app/">five day forecast tutorial</a>. In those apps, we called the OpenWeatherMap API to get the weather information for our city. Next, we unpacked the JSON results to display the appropriate information on the screen. The end result works…but there’s a catch.</p>
<p>Since we hard-coded a specific city into our API call, the data is only useful if we’re in the right city. If you tend to stay in the same place, no problem! You don’t need to worry about this. Perhaps you find yourself traveling around a bit though. Maybe you’ve even moved to a new city since you originally built your own weather app. Wouldn’t it be nice if your app just automatically detected your location?</p>
<p>Today we’ll use Apple’s Core Location framework to upgrade our 5 day forecast app to automatically query results for the user’s location. Go make a copy of your old weather project, and fire up Xcode.</p>
<h2>Choose the Right Level of Privacy</h2>
<p>In order to track a user’s location automatically, we first have to convince the user to grant our app permission to do so. These days, users are more concerned about privacy than ever, so they don’t want to give apps more information than absolutely necessary. Furthermore, location tracking can drain your iPhone’s battery relatively quickly if you use it constantly. Consequently, users are all the more reluctant to enable location tracking.</p>
<p>Fortunately, Apple has multiple degrees of location tracking that apps can use. Although this can make things more confusing for the developer, the upside is that users shouldn’t have to grant excessive tracking abilities to apps that don’t need them.</p>
<p>For our purposes, <i>When-in-use authorization</i> will suit our needs perfectly, plus it’s more efficient than <i>Always authorization</i>. The names are fairly self-explanatory. The primary difference is that <i>Always authorization</i> can continue to track location data while the app is in the background. Each authorization level supports various Core Location services. <i>Always authorization</i> does support more services, but <i>When-in-use authorization</i> covers the <i>Standard Location Service</i> that we’ll need for this app.</p>
<h2>Set-up info.plist for Core Location</h2>
<p>Now that we’ve decided what sort of tracking we want to do, it’s time to set-up our Core Location code. We’ll start with the <em>info.plist</em> file. In an effort to better educate users on why apps need to infringe on users’ privacy, Apple makes developers offer an explanation for the use of various services, including Core Location.</p>
<p>The key we’re looking for is <i>NSLocationWhenInUseUsageDescription</i>. The more human-readable version of the key displayed in Xcode is <i>Privacy &#8211; Location When In Use Usage Description</i>. You can write whatever you want for the description. I used the following.</p>
<pre><code>We need to check your location in order to let you know the weather forecast.
</code></pre>
<p>Seems like a reasonable request, right? With that out of the way, let’s write some code!</p>
<h2>Request the User’s Location</h2>
<p>The first thing we need to do is get the user’s approval to use their location. Normally, it’s best to wait until you absolutely need whatever data you’re requesting before asking the user for it. Again, users are reluctant to allow anything that seems like overreaching, so it’s nice to onboard them in the app a little bit before asking about a tracking service.</p>
<p>Considering this a weather app and tracking is obviously necessary, we’re going to jump the gun and ask for tracking permission immediately. Open <i>ViewController.swift </i>and make our view controller a Core Location Manager Delegate by adjusting the class line at the top.</p>
<pre><code>class ViewController: UIViewController, CLLocationManagerDelegate {
</code></pre>
<p>Now we can receive callbacks on Core Location events. Let’s go ahead and define the Location Manager, so we can get some events. Put the following constant just below our IBOutlets.</p>
<pre><code>let locationManager = CLLocationManager()
</code></pre>
<p>Now we’ll add some functions to go with it. You can put them anywhere inside the class braces.</p>
<pre><code>func enableBasicLocationServices() {
    locationManager.delegate = self

    switch CLLocationManager.authorizationStatus() {
    case .notDetermined:
        // Request when-in-use authorization initially
        locationManager.requestWhenInUseAuthorization()
        break

    case .restricted, .denied:
        // Disable location features
        clearWeather()
        break

    case .authorizedWhenInUse, .authorizedAlways:
        // Enable location features
        getWeather()
        break
    }
}

func locationManager(_ manager: CLLocationManager,
didChangeAuthorization status: CLAuthorizationStatus) {
    switch status {
    case .notDetermined, .authorizedAlways:
        locationManager.requestWhenInUseAuthorization()
        break

    case .restricted, .denied:
        clearWeather()
        break

    case .authorizedWhenInUse:
        getWeather()
        break
    }
}
</code></pre>
<p>We’ll call our <i>enableBasicLocationServices </i>function manually to get the user’s tracking permission. If we haven’t asked the user before, they’ll get a prompt with our request. Otherwise, we’ll use their previous answer. If they allow us to get their location, we’ll get the weather. Otherwise, we’ll call a new function—<i>clearWeather</i>. We also have a similar switch statement in our <i>locationManagerDidChangeAuthorization</i> function. Users are capable of changing authorization whenever they want through settings, so we have to adjust accordingly.</p>
<p>Go ahead and define clearWeather.</p>
<pre><code>func clearWeather() {
    self.weatherLabel1.text = "Day 1: ?"
    self.weatherLabel2.text = "Day 2: ?"
    self.weatherLabel3.text = "Day 3: ?"
    self.weatherLabel4.text = "Day 4: ?"
    self.weatherLabel5.text = "Day 5: ?"
}
</code></pre>
<p>Five question marks is about the best we can do for a forecast if they won’t give us a location! Now replace the call to <i>getWeather</i> in <i>viewDidLoad</i> with a call to <i>enableBasicLocationServices</i>.</p>
<pre><code>override func viewDidLoad() {
    super.viewDidLoad()

    // Do any additional setup after loading the view, typically from a nib.
    enableBasicLocationServices()
}
</code></pre>
<p>That will set cogs in motion!</p>
<h2>Interpret the Location</h2>
<p>Assuming the user approves location tracking, we still need to get their location and pass it into the OpeanWeatherMap API. Our previous API call used a city name, but we can also use latitude and longitude coordinates. That’s more convenient and precise since we have them readily available with Core Location. Our <i>getWeather </i>function will look the same, other than we now get our <i>weatherURL</i> in the following manner.</p>
<pre><code>var currentLocation: CLLocation!

if( CLLocationManager.authorizationStatus() == .authorizedWhenInUse || CLLocationManager.authorizationStatus() == .authorizedAlways){

    currentLocation = locationManager.location

} else {
    clearWeather()
    return
}

let latitude = currentLocation.coordinate.latitude
let longitude = currentLocation.coordinate.longitude

let session = URLSession.shared

let weatherURL = URL(string: “http://api.openweathermap.org/data/2.5/forecast?lat=\(latitude)&amp;lon=\(longitude)&amp;units=imperial&amp;APPID=XXX")!
</code></pre>
<p>The coordinate property on currentLocation is an optional, so I put in one more check to make sure the user has granted proper authorization. This also covers us if the user reloads the forecast with the onscreen button, which currently calls <i>getWeather</i> without checking on the Core Location authorization. Latitude and longitude are available off the coordinate property, and then all we do is plug them into our slightly modified API string. I replaced my API key with <i>XXX</i>. Use whatever your API key is, just as in the previous iterations of this app.</p>
<p>Run the app and see what happens!</p>
<p><a href="https://hangzone.com/wp-content/uploads/2019/05/Core-Location-Weather-Permission.png"><img decoding="async" class="alignnone size-medium wp-image-1995" src="https://hangzone.com/wp-content/uploads/2019/05/Core-Location-Weather-Permission-139x300.png" alt="Core Location Weather Permission" width="139" height="300" srcset="https://hangzone.com/wp-content/uploads/2019/05/Core-Location-Weather-Permission-139x300.png 139w, https://hangzone.com/wp-content/uploads/2019/05/Core-Location-Weather-Permission-473x1024.png 473w, https://hangzone.com/wp-content/uploads/2019/05/Core-Location-Weather-Permission.png 1125w" sizes="(max-width: 139px) 100vw, 139px" /></a><a href="https://hangzone.com/wp-content/uploads/2019/05/Core-Location-Weather-Forecast.png"><img decoding="async" class="alignnone size-medium wp-image-1996" src="https://hangzone.com/wp-content/uploads/2019/05/Core-Location-Weather-Forecast-139x300.png" alt="Core Location Weather Forecast" width="139" height="300" srcset="https://hangzone.com/wp-content/uploads/2019/05/Core-Location-Weather-Forecast-139x300.png 139w, https://hangzone.com/wp-content/uploads/2019/05/Core-Location-Weather-Forecast-473x1024.png 473w, https://hangzone.com/wp-content/uploads/2019/05/Core-Location-Weather-Forecast.png 1125w" sizes="(max-width: 139px) 100vw, 139px" /></a></p>
<p>Did your message from earlier convince you to grant yourself tracking privileges? I hope so! Try driving a few states over and reloading the data. Pretty nifty, right!</p>
<h2>Conclusion</h2>
<p>This is just a taste of what you can do with Core Location, but it’s a very practical taste and often all you need. Our weather app is moving on up in the world. Maybe we&#8217;ll add another feature to it next year! Until next time, have fun thinking of the crazy things you can do with Core Location’s <i>Always authorization</i>!</p>
<p>The post <a href="https://hangzone.com/add-core-location-weather-app/">How to Add Core Location to our Weather App</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>How to Make Your First Apple TV App</title>
		<link>https://hangzone.com/how-to-make-your-first-apple-tv-app/</link>
		
		<dc:creator><![CDATA[Tyler Bandy]]></dc:creator>
		<pubDate>Fri, 29 Mar 2019 13:20:09 +0000</pubDate>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Tutorials]]></category>
		<guid isPermaLink="false">https://hangzone.com/?p=1975</guid>

					<description><![CDATA[<p>We’ve written extensively on iPhone and iPad development in the past, but never covered the Apple TV. As you may know, you can mirror the screen of your iPhone or ...</p>
<p>The post <a href="https://hangzone.com/how-to-make-your-first-apple-tv-app/">How to Make Your First Apple TV App</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>We’ve written extensively on iPhone and iPad development in the past, but never covered the Apple TV. As you may know, you can mirror the screen of your iPhone or iPad onto your television using Apple TV. That’s a cool way to get your app on the big screen, but what if you want to build something native for Apple TV?<span class="Apple-converted-space">  </span>After all, the Apple TV 4K and Apple TV 4th generation have that fancy Siri Remote that would be fun to utilize. Today, we’ll start with the obligatory Hello World app, and highlight how to program for Apple TV’s unique control scheme.</p>
<h2>Initial Set-up</h2>
<p>I’m going to use an Apple TV 4K with Siri Remote for this tutorial. Fire up Xcode and select <em>tvOS</em> from the template categories. We’ll do a <em>Single View App</em> to keep things simple. I’m calling my project <em>HelloAppleTV</em>. Let’s use Swift for the language. Save the project wherever you like. You’ll see a familiar file structure on your left, similar to a typical iOS project. This is promising!</p>
<p>The next step is to hook up your Apple TV to your Mac so you can deploy apps to a real device. You’ll notice our only deployment options right now are simulators. This step is marginally trickier than hooking up your mobile devices since we can’t use a cable. First, turn on your Apple TV. Open the Settings app, choose <em>Remotes and Devices</em>, then drill down into <em>Remote App and Devices</em>. In Xcode, click the <em>Window</em> drop-down menu, and select <em>Devices and Simulators</em>. Assuming your devices are close enough, you’ll see a prompt on your Mac to pair your Apple TV. Click the pair button and enter the code displayed on your television. Your Mac now knows about your Apple TV!</p>
<p>Go ahead and close the <em>Devices and Simulators</em> window. In addition to the default simulators you can now select your actual Apple TV. Nice work! Let’s code something to celebrate.</p>
<h2>Hello World App</h2>
<p>Despite today’s contentious political climate, at least we can all agree that your first app on a new platform is supposed to display &#8220;Hello World&#8221;. Head over to <em>Main.Storyboard</em>, and you’ll find a blank view. This is basically the same thing you would expect in an iOS storyboard, only this view is shaped like a TV screen. Click the <em>Library</em> button to reveal the list of objects we can use. Drag a label out to the middle of the screen and write “Hello World”.</p>
<p>Sounds like a complete app to me. Go ahead and run the project. Xcode will give you some prompts about registering the Apple TV as a development device, assuming this is your first time using it. Fortunately, Xcode is good about handling these sort of things automatically now. Did you get the classic “Hello World” in black against a white background? Excellent. Time to try some more unique features of the platform.<span class="Apple-converted-space"> </span></p>
<h2>Add Some Buttons</h2>
<p>Normally, you physically tap buttons on an iPhone or iPad. That’s not an option on the TV, so let’s see for ourselves how this activity is handled by default. Add two buttons below your label. For this exercise, you can place them however you like. I placed them at the bottom of the screen, aligned horizontally with each other. I embedded them in a horizontal stack view, then used constraints to center the stack view horizontally and give it standard spacing relative to the bottom of the screen. I also used a constraint to make the buttons’ widths equal to each other. To round off the constraints, I went back and centered our &#8220;Hello World&#8221; label for good measure. In the left button, I set the text to Background. The right one says Text. My storyboard looks like this.</p>
<p><a href="https://hangzone.com/wp-content/uploads/2019/03/Apple-TV-Storyboard.png"><img decoding="async" class="alignnone wp-image-1979 size-large" src="https://hangzone.com/wp-content/uploads/2019/03/Apple-TV-Storyboard-1024x701.png" alt="Apple TV Storyboard" width="800" height="548" srcset="https://hangzone.com/wp-content/uploads/2019/03/Apple-TV-Storyboard-1024x701.png 1024w, https://hangzone.com/wp-content/uploads/2019/03/Apple-TV-Storyboard-300x205.png 300w, https://hangzone.com/wp-content/uploads/2019/03/Apple-TV-Storyboard.png 1496w" sizes="(max-width: 800px) 100vw, 800px" /></a></p>
<p>Now open up <em>Assistant Editor</em> mode, and link your label to <em>ViewController.swift</em> as <em>helloWorldLabel</em>. Link the buttons as actions—<em>backgroundButtonTapped</em> and <em>textButtonTapped</em>. Just use the default options when setting the outlet and actions.</p>
<p>We want to make the background button toggle the background’s color, while the text button toggles the text’s color. Inside <em>backgroundButtonTapped</em>, add the following code.</p>
<pre><code>let colorIndex = Int.random(in: 0 ... 5)

switch colorIndex {
    case 0:
        view.backgroundColor = UIColor.red;
    case 1:
        view.backgroundColor = UIColor.blue;
    case 2:
        view.backgroundColor = UIColor.yellow;
    case 3:
        view.backgroundColor = UIColor.green;
    case 4:
        view.backgroundColor = UIColor.orange;
    case 5:
        view.backgroundColor = UIColor.purple;
    default:
        view.backgroundColor = UIColor.white;
}
</code></pre>
<p>Clicking the button will give us one of 6 random colors for the background. Let’s do something similar inside <em>textButtonTapped</em>.</p>
<pre><code>let colorIndex = Int.random(in: 0 ... 5)

switch colorIndex {
    case 0:
        helloWorldLabel.textColor = UIColor.red;
    case 1:
        helloWorldLabel.textColor = UIColor.blue;
    case 2:
        helloWorldLabel.textColor = UIColor.yellow;
    case 3:
        helloWorldLabel.textColor = UIColor.green;
    case 4:
        helloWorldLabel.textColor = UIColor.orange;
    case 5:
        helloWorldLabel.textColor = UIColor.purple;
    default:
        helloWorldLabel.textColor = UIColor.black;
}
</code></pre>
<p>Give the app a run. You’ll find the you can shift your focus from one button to the other by sliding your thumb left and right on the the remote&#8217;s Touch Surface. You can then tap the Touch Surface to press the button. Perhaps you’ll also find that the blue background with the green text looks pretty nice!<span class="Apple-converted-space"> </span></p>
<h2>Gesture Recognizers</h2>
<p>You’ve got a good feel for the basic user interaction now. Sliding around the focus and tapping buttons is the key to most menus. That Siri Remote has some other buttons on it though. We should make them do something in our app! If we want to harness the action of the Play/Pause button, we can use a tap gesture recognizer.</p>
<p>Add some tap gesture recognizer code in <em>viewDidLoad</em> inside your <em>ViewController.swift</em> file.</p>
<pre><code>let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(tapped))
tapRecognizer.allowedPressTypes = [NSNumber(value: UIPress.PressType.playPause.rawValue)];
self.view.addGestureRecognizer(tapRecognizer)
</code></pre>
<p>Now we need to define the function tapped down at the bottom of <em>ViewController.swift</em>.</p>
<pre><code>@objc func tapped(gestureRecognizer: UITapGestureRecognizer) {
    view.backgroundColor = UIColor.white;
    helloWorldLabel.textColor = UIColor.black;
}
</code></pre>
<p>Whenever the user taps the Play/Pause button, we will reset the background to white and the text to black. Run the app and give it a try!</p>
<h2>Conclusion</h2>
<p>Today we made a Hello World app for Apple TV and learned how to handle basic user interaction. Most of the tools available to you in iOS are also available in tvOS. Now that we’ve demystified the user interaction a bit, you should be off to the races! Look out for more Apple TV tutorials in the future. Until then, thanks for reading the HangZone blog!</p>
<p>The post <a href="https://hangzone.com/how-to-make-your-first-apple-tv-app/">How to Make Your First Apple TV App</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Data Binding and Model-View-ViewModel in UWP Part 2</title>
		<link>https://hangzone.com/data-binding-uwp-part-2/</link>
		
		<dc:creator><![CDATA[Judson Bandy]]></dc:creator>
		<pubDate>Thu, 28 Feb 2019 16:18:48 +0000</pubDate>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Tutorials]]></category>
		<guid isPermaLink="false">https://hangzone.com/?p=1967</guid>

					<description><![CDATA[<p>This tutorial starts where Part 1 leaves off. If you haven&#8217;t read it, you can find it here. As a quick refresher, we are creating an application that highlights data ...</p>
<p>The post <a href="https://hangzone.com/data-binding-uwp-part-2/">Data Binding and Model-View-ViewModel in UWP Part 2</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>This tutorial starts where Part 1 leaves off. If you haven&#8217;t read it, you can find it here.</p>
<p>As a quick refresher, we are creating an application that highlights data binding and the MVVM architectural design pattern in UWP. There is a clear separation of concerns in our code, and data binding is used for the UI to communicate with the data. So far, we have created a model, view, and viewmodel. We will continue to add code (including data binding code) to each of these classes to achieve our desired functionality. Remember, we have a one page application with two pivots. The &#8220;All Foods&#8221; pivot allows you to select your favorite foods from a list of all foods. The &#8220;Favorite Foods&#8221; pivot will then show a list of your favorite foods. Let&#8217;s jump back in by finishing up our view!</p>
<h2>Finishing our View</h2>
<p>Now that we have collections to work with in the viewmodel and some data, let’s go back and complete our view. If you remember, we laid out a simple structure, but we need to finish our pivot sections for all foods and favorite foods.</p>
<p>First, we need to go to the code-behind file of the view to add our viewmodel as the data context for the view. At the top of the FoodView.xaml.cs file, add “using MyFavoriteFoods.ViewModel.”</p>
<p>Next, we will add the viewmodel as an instance variable, and set it as the datacontext in the constructor.</p>
<pre><code><b>public FoodViewModel ViewModel { get; set; } = new FoodViewModel();</b>

public FoodView()
{
    <b>DataContext = ViewModel;</b>
    this.InitializeComponent();
}</code></pre>
<p>Now, back to the .xaml file. We first choose a control that includes ItemTemplate to be used to display the data. ListView, GridView, ListBox, and ItemsControl are all potential options. I will use ItemsControl since it does less manipulation to the view than the other options (no highlighting, selecting, etc). Inside ItemTemplate, we will have a DataTemplate that defines the datatype and the UI layout for each instance of the object. We are using data templates of type FoodModel so we need to add our model namespace to the definitions. In the definitions at the top, add:</p>
<pre><code>xmlns:models=“using:MyFavoriteFoods.Model”</code></pre>
<p>Now, fill in the pivot items as follows.</p>
<pre><code>&lt;PivotItem Header=“Favorite Foods”&gt;
    &lt;ItemsControl ItemsSource=“{x:Bind ViewModel.FavoriteFoods, Mode=OneWay}”&gt;
        &lt;ItemsControl.ItemTemplate&gt;
            &lt;DataTemplate x:DataType=“models:FoodModel”&gt;
                &lt;Grid Height=“40”&gt;
                    &lt;TextBlock VerticalAlignment=“Center” Text=“{x:Bind Name}”/&gt;
                &lt;/Grid&gt;  
            &lt;/DataTemplate&gt;
        &lt;/ItemsControl.ItemTemplate&gt;
    &lt;/ItemsControl&gt;
&lt;/PivotItem&gt;
&lt;PivotItem Header=“All Foods”&gt;
    &lt;ItemsControl ItemsSource=“{x:Bind ViewModel.AllFoods}”&gt;
        &lt;ItemsControl.ItemTemplate&gt;
            &lt;DataTemplate x:DataType=“models:FoodModel”&gt;
                &lt;Grid Height=“40”&gt;
                    &lt;Grid.ColumnDefinitions&gt;
                        &lt;ColumnDefinition Width=“*”/&gt;
                        &lt;ColumnDefinition Width=“auto”/&gt;
                    &lt;/Grid.ColumnDefinitions&gt;
                    &lt;TextBlock VerticalAlignment=“Center” Text=“x:Bind Name”/&gt;
                    &lt;ToggleSwitch Grid.Column=“1” HorizontalAlignment=“Right” VerticalAlignment=“Center” IsOn=“{x:Bind IsFavorite, Mode=TwoWay}”/&gt;
                &lt;/Grid&gt;
            &lt;/DataTemplate&gt;
        &lt;/ItemsControl.ItemTemplate&gt;
    &lt;/ItemsControl&gt;
&lt;/PivotItem&gt;</code></pre>
<h2>Explanation of Data Binding Code</h2>
<p>You will notice that on the data binding for the ItemsControl.ItemSource in the favorite foods section, we used “Mode=OneWay.” Also, for the toggle switch in the all foods section, we used “Mode=TwoWay.” There are three different modes for binding: one time (the default if not specified), one way, and two way. For one way, the view reads the property when the view is created and uses that value going forward. With one way, the view will update its display if the value that it is bound to changes. For two way, the view will update the display if the bound property is changed, like with one way, but it will also update the bound property if the view is manipulated. For instance, if a toggle switch is toggled or a text box changed by the user, the property that is bound to that control will be updated with the information entered by the user.</p>
<p>We need to use one way binding for our favorite foods item source because the bound collection will be modified when we add or remove foods as favorites. The ToggleSwitch.IsOn binding needs two way because the IsFavorite property for the FoodModel object needs to be updated when the user toggles the switch.</p>
<p>Feel free to run the project and take a look at our progress. All of our data and controls should now be displayed correctly. Congratulations! The only problem is that the favorite foods list does not update when the switches are toggled on the all foods pivot.</p>
<h2>Using INotifyPropertyChanged</h2>
<p>With our two way binding, the IsFavorite property on the corresponding FoodModel object is updated when a switch is toggled. We need to be notified when the property is changed so that we can either add or remove the FoodModel from the favorite foods collection. To do this, we need to implement INotifyPropertyChanged for the IsFavorite property in the FoodModel class. Then, we can add code to the FoodViewModel to execute code whenever the property’s value changes.</p>
<p>Go to FoodModel.cs. Add “using System.ComponentModel” to the class. Now, we are going to change the IsFavorite property so that you can subscribe to be notified when the property changes.</p>
<pre><code><del>public bool IsFavorite { get; set; }</del>

private bool _isFavorite;
public bool IsFavorite
{
    get { return _isFavorite; }
    set
    {
        _isFavorite = value;
        RaisePropertyChanged(“IsFavorite”);
    }
}

public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged(string name)
{
    if (PropertyChanged != null)
    {
        PropertyChanged(this, new PropertyChangedEventArgs(name));
    }
}</code></pre>
<p>Now, whenever the IsFavorite property is modified, the PropertyChanged event handler is called. This handler will be used to trigger a method to adjust our favorite foods collection in the viewmodel. Let’s go to the FoodViewModel.</p>
<h2>Subscribing to Property Changed</h2>
<p>We need to subscribe to the PropertyChanged event on each FoodModel in the AllFoods collection so that we can adjust our FavoriteFoods collection. The action is rather simple. First, add “using System.ComponentModel” at the top of the page. In the LoadFoodData method, where we loop through each FoodModel in AllFoods, we add the following line.</p>
<pre><code>foreach(FoodModel eachFood in AllFoods)
{
    <b>eachFood.PropertyChanged += IsFavoritePropertyChanged;</b>
    if (eachFood.IsFavorite)
    {
        FavoriteFoods.Add(eachFood)
   }
}</code></pre>
<p>Now, we define that method to handle the addition or removal of the toggled FoodModel.</p>
<pre><code>public void IsFavoritePropertyChanged(object sender, PropertyChangedEventArgs e)
{
    FoodModel toggledFood = sender as FoodModel;
    if (toggledFood.IsFavorite)
    {
        FavoriteFoods.Add(toggledFood);
    }
    else
    {
        FavoriteFoods.Remove(toggledFood);
    }
}</code></pre>
<p>That’s it. Our code is notified when the IsFavorite property changes for each instance of FoodModel in the viewmodel, and the FavoriteFoods collection is adjusted accordingly. Run the project and see your work in action!</p>
<p><a href="https://hangzone.com/wp-content/uploads/2018/12/Blog-UWP-Data-Binding-Favorite-Foods.png"><img decoding="async" class="alignnone size-medium wp-image-1957" src="https://hangzone.com/wp-content/uploads/2018/12/Blog-UWP-Data-Binding-Favorite-Foods-300x266.png" alt="Blog UWP Data Binding Favorite Foods" width="300" height="266" srcset="https://hangzone.com/wp-content/uploads/2018/12/Blog-UWP-Data-Binding-Favorite-Foods-300x266.png 300w, https://hangzone.com/wp-content/uploads/2018/12/Blog-UWP-Data-Binding-Favorite-Foods.png 980w" sizes="(max-width: 300px) 100vw, 300px" /></a><a href="https://hangzone.com/wp-content/uploads/2018/12/Blog-UWP-Data-Binding-All-Foods.png"><img decoding="async" class="alignnone size-medium wp-image-1956" src="https://hangzone.com/wp-content/uploads/2018/12/Blog-UWP-Data-Binding-All-Foods-300x266.png" alt="Blog UWP Data Binding All Foods" width="300" height="266" srcset="https://hangzone.com/wp-content/uploads/2018/12/Blog-UWP-Data-Binding-All-Foods-300x266.png 300w, https://hangzone.com/wp-content/uploads/2018/12/Blog-UWP-Data-Binding-All-Foods.png 980w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<h2>Conclusion</h2>
<p>In this project, we used data binding and the Model-View-ViewModel pattern to create an application. Our code is nicely segregated so that the view deals only with UI display and the data and logic are handled in the model and viewmodel. Data binding is done to allow the UI to properly communicate with the data to display proper values and relay any user inputs or changes. We use fairly simple binding concepts in this project, but it is a good introduction to how they work. As always, thanks for reading the HangZone blog!</p>
<p>The post <a href="https://hangzone.com/data-binding-uwp-part-2/">Data Binding and Model-View-ViewModel in UWP Part 2</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Data Binding and Model-View-ViewModel in UWP Part 1</title>
		<link>https://hangzone.com/data-binding-uwp-part-1/</link>
		
		<dc:creator><![CDATA[Judson Bandy]]></dc:creator>
		<pubDate>Thu, 31 Jan 2019 17:07:52 +0000</pubDate>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Tutorials]]></category>
		<guid isPermaLink="false">https://hangzone.com/?p=1954</guid>

					<description><![CDATA[<p>Data Binding is a powerful and important tool in Windows development. Whether targeting UWP, WPF, Xamarin.Forms, or something else, binding is crucial to your app design. The idea of binding ...</p>
<p>The post <a href="https://hangzone.com/data-binding-uwp-part-1/">Data Binding and Model-View-ViewModel in UWP Part 1</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Data Binding is a powerful and important tool in Windows development. Whether targeting UWP, WPF, Xamarin.Forms, or something else, binding is crucial to your app design. The idea of binding is simple. It is used to connect a binding target to a binding source. The binding target is typically the property of a control or some type of UI element. This could be the text of a label, whether a switch is on, or a selection in a combo box. The binding source is a property from another class, usually a viewmodel or model. This is the data that tells the binding target what to display.<span class="Apple-converted-space"> </span></p>
<p>Now, we have a high level understanding of data binding, but why are we using it? The main purpose is to decouple our UI code from our non-UI code. This strategy is utilized in Microsoft&#8217;s recommended UI architectural design pattern, Model-View-ViewModel (MVVM), and has a number of benefits. Decoupling different sections of your code creates a separation of concerns. Testing becomes easier since your code is more isolated, different programmers can focus on different parts of the project (front end and back end programmers can simultaneously work on different aspects), and the code is much more maintainable and reusable.<span class="Apple-converted-space"> </span></p>
<h2>Model-View-ViewModel</h2>
<p>Although somewhat self-explanatory, let’s take a quick look at the 3 layers of the MVVM paradigm. The model is the first layer. This houses all of your software’s business data. Core app logic, class definitions, and data can all typically be found here. The view is the user interface of your project. In UWP, which we are using for this project, this is done with XAML files that define your views and controls. Code-behind files can also be used to further define elements of the view. The viewmodel binds and processes information between the model and view classes. Now that we have a quick idea of the elements of MVVM and data binding, let’s jump into a project and see it in action.</p>
<h2>Our Test Project</h2>
<p>Let’s quickly lay out what we want to do for our project. We are going to create a UWP application. It is going to be a single page with tabs on it. One tab will have a list of our favorite foods. The other tab will have a list of all included foods with a toggle switch to tag them as a favorite.</p>
<p>The project will need one model class where we will define our food model, one view class where we layout the UI for the page, and one viewmodel class where we get everything to work together. Let’s get started!</p>
<h2>Create Our Project</h2>
<p>I am going to do this project in Visual Studio on a Windows device targeting UWP. You could easily do this project in Visual Studio for Mac and target Xamarin.Forms, although some of the UI code will be slightly different.</p>
<p>Open Visual Studio and go to File-&gt;New-&gt;Project… Select Windows Universal in the left pane under Visual C#, and select Blank App (Universal Windows). Feel free to name the app anything you want (I’ll call mine MyFavoriteFoods), and click OK. I’m going to target Windows 10, version 1809 and set the minimum version to Windows 10 Creators Update. Press OK. Our project is now created.<span class="Apple-converted-space"> </span></p>
<p>Start by deleting MainPage.xaml and its code-behind file, MainPage.xaml.cs. I want to create my own view file inside a folder to better delineate the layers of the project.<span class="Apple-converted-space"> </span></p>
<h2>Creating our Model</h2>
<p>Right click on the MyFavoriteFoods project, and click Add-&gt;New Folder. Name the folder “Model” and press enter. Right click your new model folder and select Add-&gt;New Item… Select Class and name it FoodModel.cs. Press Add. We will start by just adding the bare bones properties to this class. Make the class public and add properties to make it look like this.</p>
<pre><code><b>public</b> class FoodModel
{
    <b>public string Name { get; set; }</b>
    <b>public bool IsFavorite { get; set; }</b>
}</code></pre>
<p>You can see, we have a string property for the name of the each food and a bool for whether this is a favorite food or not. Let’s move on to our View.</p>
<h2>Creating our View</h2>
<p>Create another folder in the project; this time called View. Create a Blank Page inside the folder named FoodView.xaml.<span class="Apple-converted-space"> </span></p>
<p>Before we make any changes on this page, let’s set this new view as our first page for startup. Open the App.xaml.cs file. At the top, add the view namespace: “using MyFavoriteFoods.View”. Then change the following line to set the first page as our new view, FoodView.xaml.<span class="Apple-converted-space"> </span></p>
<pre><code><del>rootFrame.Navigate(typeof(MainPage), e.Arguments);</del>
rootFrame.Navigate(typeof(FoodView), e.Arguments);</code></pre>
<p>Let’s go back to FoodView.xaml. We’re going to put a large title at the top, and then a pivot to swap between our favorite foods and all foods. Add the following code to the page.</p>
<pre><code>&lt;Grid&gt;
    &lt;Grid.RowDefinitions&gt;
        &lt;RowDefinition Height = “auto”/&gt;
        &lt;RowDefinition Height = “*”/&gt;
    &lt;/Grid.RowDefinitions&gt;
    &lt;TextBlock Text=“Food” FontSize=“30” Margin=“10,0,0,0”/&gt;
    &lt;Pivot Grid.Row = “1”&gt;
        &lt;PivotItem Header=“Favorite Foods”&gt;

        &lt;/PivotItem&gt;
        &lt;PivotItem Header=“All Foods”&gt;

        &lt;/PivotItem&gt;
    &lt;/Pivot&gt;
&lt;/Grid&gt;</code></pre>
<p>As you can see, we created two rows inside our grid. The first has an auto height so that it is allocated the amount of space that its contents need. The second row is set to height “*” so that it is allocated the remaining height of the grid. We use a text block in the first row of the grid to set a title of “Food” for the page. We use a pivot in the second row with two pivot items. The first is given a header of “Favorite Foods” and the second is “All Foods.” Feel free to run the project. You will see what we laid out and be able to select the pivots. We still need to fill out their content. Let’s move on to our viewmodel, and then, we will come back to finish the view.</p>
<h2>Creating Our ViewModel</h2>
<p>We need to create another folder in our project. This one should be called “ViewModels.” Create a new class file inside the folder and call it “FoodViewModel.cs.” This will be the viewmodel for our FoodView class.</p>
<p>Let’s start by creating two instance variables for the class. One will be a list that will house all of the foods that are in our universe. The second will be an ObservableCollection of all of our favorite foods. It is helpful to use an ObservableCollection as the type for our favorite foods because we will be adding and removing foods from this collection. The all foods collection will remain constant as there is currently no way to add new foods while the project is running. The ObservableCollection provides a notification to its binding target when items get added, removed, or when a whole list is refreshed. This is helpful for updating our view as selections get manipulated.</p>
<p>First, we need to add the Model namespace to the class, and another namespace to use ObservableCollection objects. At the top of the page, add the following lines.</p>
<pre><code>using MyFavoriteFoods.Model;
using System.Collection.ObjectModel;</code></pre>
<p>Then, make the class public like this.</p>
<pre><code><b>public </b>class FoodViewModel</code></pre>
<p>Next, create the instance variables in a manner like this.</p>
<pre><code>public List&lt;FoodModel&gt; AllFoods = new List&lt;FoodModel&gt;();

public ObservableCollection&lt;FoodModel&gt; FavoriteFoods = new ObservableCollection&lt;FoodModel&gt;();</code></pre>
<h2>ViewModel Methods</h2>
<p>Now, we need to load initial data into these collections. This data would normally come from either a local or external server, but that is far beyond the scope of this tutorial. We could create a data section to house this data, as well, but again, the purpose of this is to focus on MVVM and binding. We are simply going to load the data in a method in the viewmodel. This is not typical work for a viewmodel in a larger scale project, and if this project was more than one page, we would certainly want to move the data elsewhere. Let’s add a constructor method for the viewmodel and call another method inside it.</p>
<pre><code>public FoodViewModel()
{
    LoadFoodData();
}</code></pre>
<p>Now, let’s define that method to populate data in the collections.</p>
<pre><code>private void LoadFoodData()
{
    AllFoods.Add(new FoodModel()
    {
        Name = “Apple”,
        IsFavorite = false
    };

    AllFoods.Add(new FoodModel()
    {
        Name = “Banana”,
        IsFavorite = false
    };

    AllFoods.Add(new FoodModel()
    {
        Name = “Pizza”,
        IsFavorite = true
    };

    AllFoods.Add(new FoodModel()
    {
        Name = “Spinach”,
        IsFavorite = false
    };

    AllFoods.Add(new FoodModel()
    {
        Name = “Turnip”,
        IsFavorite = false
    };

}

foreach(FoodModel eachFood in AllFoods)
{
    if (eachFood.IsFavorite)
    {
        FavoriteFoods.Add(eachFood);
    }
}</code></pre>
<h2>Conclusion</h2>
<p>Now, we have our collections of data defined and available to use. In part 2 of this tutorial, we will bind these collections to their corresponding pivots so that each collection is displayed in the user interface. On the all foods pivot, you will be able to select whether a particular food is one of your favorites. Upon selecting or unselecting a food, the binding change will alert our code to update the collection of favorite foods. We set up a great MVVM structure in part 1, but there is a lot of exciting coding to look forward to in part 2. As always, thanks for reading the HangZone blog!</p>
<p>The post <a href="https://hangzone.com/data-binding-uwp-part-1/">Data Binding and Model-View-ViewModel in UWP Part 1</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>How to Upload a Xamarin.Forms App To the App Store</title>
		<link>https://hangzone.com/upload-xamarin-forms-app-app-store/</link>
		
		<dc:creator><![CDATA[Tyler Bandy]]></dc:creator>
		<pubDate>Fri, 30 Nov 2018 16:58:47 +0000</pubDate>
				<category><![CDATA[Tutorials]]></category>
		<guid isPermaLink="false">https://hangzone.com/?p=1939</guid>

					<description><![CDATA[<p>We’ve written a few Xamarin.Forms tutorials on the HangZone blog lately. Maybe you’ve even made a Xamarin.Forms app of your own! It’s easy to deploy these apps directly to your ...</p>
<p>The post <a href="https://hangzone.com/upload-xamarin-forms-app-app-store/">How to Upload a Xamarin.Forms App To the App Store</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>We’ve written a few Xamarin.Forms tutorials on the HangZone blog lately. Maybe you’ve even made a Xamarin.Forms app of your own! It’s easy to deploy these apps directly to your device, but what do you do when it’s time to upload to the App Store? The process involves many of the same convoluted steps you know and love from dealing with native iOS apps, but there are some new twists and turns to learn. We’ll cover it all here today! For reference, my instructions are designed for<span class="Apple-converted-space"> use on a Mac.</span></p>
<h2>Apple Developer Account</h2>
<p>The first step is the same as if you were developing a native app in Xcode. You have go to your <a href="https://developer.apple.com">Apple Developer Account</a> and create Distribution Certificate, App ID, and Provisioning Profile. When you arrive on the main Developer Page, click <i>Account</i>, then <i>Certificates, IDs &amp; Profiles</i>. You should see all of the options you need down the left side of the page.</p>
<p>Let’s do the Distribution Certificate first. Click on <i>All</i> on the <i>Certificates</i> category. Do you have a certificate with type <i>iOS Distribution</i> that hasn’t expired? If so, go ahead and move on to the App ID. If not, click the plus button to create a new certificate. Select type <i>App Store and Ad Hoc</i>. On the next page, you’ll find some instructions for creating a CSR file using the program <i>Keychain Access</i>. You should find <i>Keychain Access</i> in the Utilities folder on your Mac. Follow the onscreen instructions to make the CSR file and complete the Distribution Certificate.</p>
<p>Next, click on <i>App IDs</i>. Click the plus button to make a new one. Give your app a name, then give it a bundle ID. If I was making an app called <i>Example</i> the bundle ID would be <i>com.HangZone.Example</i>. Go to the next page and register your App ID.</p>
<p>Finally, go to <i>Distribution </i>under the <i>Provisioning Profile</i> section. Click the plus button, then select the <i>App Store</i> option. Select your App ID, then select your Distribution Certificate on the next page. The last step is to give your provisioning profile a name. For an app named <i>Example</i>, I would go with <i>ExampleAppStore</i>, to distinguish it from a developer provisioning profile or one for ad hoc distribution.</p>
<p>That’s it for your Apple Developer Account!</p>
<h2>App Store Connect</h2>
<p>Now it’s time to head to <a href="https://appstoreconnect.apple.com">App Store Connect</a>. Again, this step is the same as if you were uploading a native app from Xcode. Go to the <i>Apps</i> page, then hit the plus button to create a new app. Select the first option, <i>New App</i>. Check <i>iOS</i> for the platform. Enter your app’s name in the <i>Name</i> field. If you’re reading this blog, you’ll probably go with English for the <i>Primary Language</i>. In the <i>Bundle ID </i>dropdown menu, you should see your bundle ID from earlier. Select it. You can write whatever you want for the SKU, say <i>Example1</i>. Finish things off by setting <i>User Access</i> to <i>Full Access</i>.</p>
<p>Now you have an app listing! You can fill out the rest of the information at your leisure, but this is enough to advance to the next step.</p>
<h2>Xamarin.Forms Project Settings</h2>
<p>Open up Visual Studio. Pull up the <i>info.plist</i> in the iOS section of your project. Enter the appropriate <i>Application Name</i> and <i>Bundle Identifier</i>. The bundle ID should match the one you made earlier. Go with <i>Manual Provisioning</i> for the scheme. I use automatic in Xcode, but Microsoft suggests manual in their Xamarin.Forms documentation (at least as of this writing), and it works fine.</p>
<p>Once you’ve completed those changes in <i>info.plist</i>, right click on the iOS project’s name in the Solution Outline and click <i>Options</i>. Select <i>iOS Build</i> on the left. At the top, change the <i>Configuration</i> to <i>Release</i> and the <i>Platform</i> to <i>iPhone</i>. Set the following options to something like this.</p>
<p><a href="https://hangzone.com/wp-content/uploads/2018/11/Xamarin-Forms-iOS-Build-Settings.png"><img decoding="async" class="alignnone wp-image-1940 size-large" src="https://hangzone.com/wp-content/uploads/2018/11/Xamarin-Forms-iOS-Build-Settings-1024x773.png" alt="Xamarin Forms iOS Build Settings" width="800" height="604" srcset="https://hangzone.com/wp-content/uploads/2018/11/Xamarin-Forms-iOS-Build-Settings-1024x773.png 1024w, https://hangzone.com/wp-content/uploads/2018/11/Xamarin-Forms-iOS-Build-Settings-300x226.png 300w, https://hangzone.com/wp-content/uploads/2018/11/Xamarin-Forms-iOS-Build-Settings.png 1924w" sizes="(max-width: 800px) 100vw, 800px" /></a></p>
<p>Next, click <i>iOS Bundle Signing</i>. Again, Select <i>Release</i> and <i>iPhone</i> at the top. In the <i>Signing Identity </i>dropdown, select your Distribution Certificate. In the <i>Provisioning Profile </i>field, you should find Provisioning Profile available for selection. If the certificate or provisioning profile don’t populate correctly, try closing Visual Studio. Then open Xcode. This should download any missing certificates and provisioning profiles from your Apple Developer Account. Open up Visual Studio again and you should see the missing files.</p>
<h2>Build an Archive</h2>
<p>Along the top bar in Visual Studio, toggle your App from <i>Debug</i> to <i>Release</i>. In the <i>Build</i> menu, choose <i>Archive for Publishing</i>. Once the archive is complete, click the <i>Sign and Distribute</i> button. In the new window, select the <i>App Store </i>distribution option. Choose your provisioning profile on the next page. Finally, publish an IPA of your app. This step might seem weird, as you usually wouldn’t save an IPA file on your computer when publishing with Xcode unless you wanted to distribute your app outside of the App Store. Just roll with it.</p>
<p>Once the IPA is saved on your Mac, you’ll get an option to launch Application Loader. Use your Apple ID to get into the program, then choose the <i>Deliver Your App</i> option. Select the IPA file from your computer, then begin the validation and upload process. If all goes smoothly, you’ll get a successful confirmation! It may still be several minutes or hours until the build shows up in App Store Connect, so don’t worry if you don’t see it immediately.</p>
<h2>Final Thoughts</h2>
<p>You’ve done it! A lot of this was certainly review for seasoned Xcode users, but there are enough oddities about the Visual Studio steps that I wanted to lay out the whole process for a Xamarin.Forms app. With your new build on App Store Connect, you can distribute your app to beta testers via TestFlight, or, if you’re feeling good about it, just go ahead and submit it for worldwide release! Thanks for reading!</p>
<p>The post <a href="https://hangzone.com/upload-xamarin-forms-app-app-store/">How to Upload a Xamarin.Forms App To the App Store</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
