Xamarin.Tip – Adding a Password Toggle Button in Android

Here’s another quick tip to use when building your Android apps whether in Xamarin, or native in Java/Kotlin. Depending on the target audience of your application, you may find it necessary to add a password toggle button to your password EditText to allow users to view and hide their password while typing it.

In this post, we will explore how to do this in Android natively while future posts will cover iOS (which is more involved) as well as building a Xamarin.Forms custom Entry view (no renderer’s required!) to handle the toggling.

There are two places to achieve this in Android – in the xml of the layout resource, or in the code behind where manipulating the view. Luckily, Android (unlike iOS) has this feature built in to the properties of the TextInputLayout control.

We get the ability to show the button as well as apply a custom Drawable if we want!

Using the Layout Resource

Here is an example using the TextInputLayout from the xml side to wrap an EditText:

activity_login.axml

<android.support.design.widget.TextInputLayout
    android:id="@+id/password_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:passwordToggleEnabled="true"
    app:passwordToggleTint="@android:color/white">
    <android.support.design.widget.TextInputEditText
        android:id="@+id/password_editText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:password="true"
        android:hint="Password"
        android:textColor="@android:color/white"
        android:inputType="textPassword" />
</android.support.design.widget.TextInputLayout>

Notice the two properties:

app:passwordToggleEnabled="true"

and

app:passwordToggleTint="@android:color/white"

These are the two that control showing the password toggle. Alternatively, you can set the

app:passwordToggleDrawable="@drawable/someDrawable"

Using Code

If you’re manipulating your TextInputLayout in your code, you can also update these fields very easily:

LoginActivity.cs

public class LoginActivity : AppCompatActivity
{
    protected override void OnCreate(Bundle savedInstance)
    {
        base.OnCreate(savedInstance);
        SetContentView(Resource.Layout.activity_login);

        var editTextLayout = FindViewById<TextInputLayout>(Resource.Id.password_layout);

        editTextLayout.PasswordVisibilityToggleEnabled = true;
    }
}

That’s it!

Results

Take a look for yourself!

Screen Shot 2018-03-15 at 11.04.31 AM
Screen Shot 2018-03-15 at 11.04.40 AM


If you like what you see, don’t forget to follow me on twitter @Suave_Pirate, check out my GitHub, and subscribe to my blog to learn more mobile developer tips and tricks!

Interested in sponsoring developer content? Message @Suave_Pirate on twitter for details.

Advertisements

Xamarin.NuGet – Xamarin.Forms Dynamic Bindable StackLayout

I recently released a component I commonly use in my Xamarin.Forms applications for binding data to a wrapping layout here: Xamarin.NuGet – DynamicWrapLayout Announcement! In the spirit of this type of control, I’ve also released a new NuGet package for a bindable DynamicStackLayout. It’s a simple control that allows you to create a StackLayout and bind an ItemsSource collection and an ItemTemplate. This is useful for smaller, but dynamic collections with the use of the orientation changing of a StackLayout. This means you could have a horizontally scrolling list of cards, bind the orientation or change it to vertical, and play with positioning more easily than using a ListView. I would still highly suggest using a ListView over this control for a standard vertical stack of dynamic content since this control does NOT use any view recycling or virtualization which can cause performance issues with large collections or constantly changing collection.

Get it here

NuGet: https://www.nuget.org/packages/DynamicStackLayout

Github: https://github.com/SuavePirate/DynamicStackLayout

In the end, you get something like this!

Be sure to read the documentation below:

DynamicStackLayout

A Xamarin.Forms layout for creating dynamically wrapped views. Inspired by the WrapLayout example: https://developer.xamarin.com/samples/xamarin-forms/UserInterface/CustomLayout/WrapLayout/

Installation

It’s on NuGet! https://www.nuget.org/packages/DynamicStackLayout/

Install-Package DynamicStackLayout

Be sure to install in all projects that use it.

Usage

There are two key properties that make this control useful – the ItemsSource (like a ListView) and the ItemTemplate (although, you can also just add children to the view – it does both!)
Be sure to wrap it in a ScrollView though

XAML

Add the xmlns:

xmlns:suave=&quot;clr-namespace:SuaveControls.DynamicStackLayout;assembly=SuaveControls.DynamicStackLayout&quot;

Use it in your View:

&lt;ScrollView&gt;
    &lt;suave:DynamicStackLayout ItemsSource=&quot;{Binding Items}&quot; HorizontalOptions=&quot;Fill&quot;&gt;
        &lt;suave:DynamicStackLayout.ItemTemplate&gt;
            &lt;DataTemplate&gt;
                &lt;StackLayout BackgroundColor=&quot;Gray&quot; WidthRequest=&quot;120&quot; HeightRequest=&quot;180&quot;&gt;
                    &lt;Label Text=&quot;{Binding .}&quot; VerticalOptions=&quot;FillAndExpand&quot; HorizontalOptions=&quot;FillAndExpand&quot; VerticalTextAlignment=&quot;Center&quot; HorizontalTextAlignment=&quot;Center&quot; /&gt;
                &lt;/StackLayout&gt;
            &lt;/DataTemplate&gt;
        &lt;/suave:DynamicStackLayout.ItemTemplate&gt;
    &lt;/suave:DynamicStackLayout&gt;
&lt;/ScrollView&gt;

Don’t like data-binding and want to just use child views? You can do that too!

&lt;ScrollView&gt;
    &lt;suave:DynamicStackLayout HorizontalOptions=&quot;Fill&quot;&gt;
      &lt;StackLayout BackgroundColor=&quot;Gray&quot; WidthRequest=&quot;120&quot; HeightRequest=&quot;180&quot;&gt;
          &lt;Label Text=&quot;0&quot; TextColor=&quot;White&quot; VerticalOptions=&quot;FillAndExpand&quot; HorizontalOptions=&quot;FillAndExpand&quot; VerticalTextAlignment=&quot;Center&quot; HorizontalTextAlignment=&quot;Center&quot; /&gt;
      &lt;/StackLayout&gt;
      &lt;StackLayout BackgroundColor=&quot;Gray&quot; WidthRequest=&quot;120&quot; HeightRequest=&quot;180&quot;&gt;
          &lt;Label Text=&quot;1&quot; TextColor=&quot;White&quot; VerticalOptions=&quot;FillAndExpand&quot; HorizontalOptions=&quot;FillAndExpand&quot; VerticalTextAlignment=&quot;Center&quot; HorizontalTextAlignment=&quot;Center&quot; /&gt;
      &lt;/StackLayout&gt;
      &lt;StackLayout BackgroundColor=&quot;Gray&quot; WidthRequest=&quot;120&quot; HeightRequest=&quot;180&quot;&gt;
          &lt;Label Text=&quot;2&quot; TextColor=&quot;White&quot; VerticalOptions=&quot;FillAndExpand&quot; HorizontalOptions=&quot;FillAndExpand&quot; VerticalTextAlignment=&quot;Center&quot; HorizontalTextAlignment=&quot;Center&quot; /&gt;
      &lt;/StackLayout&gt;
      &lt;StackLayout BackgroundColor=&quot;Gray&quot; WidthRequest=&quot;120&quot; HeightRequest=&quot;180&quot;&gt;
          &lt;Label Text=&quot;3&quot; TextColor=&quot;White&quot; VerticalOptions=&quot;FillAndExpand&quot; HorizontalOptions=&quot;FillAndExpand&quot; VerticalTextAlignment=&quot;Center&quot; HorizontalTextAlignment=&quot;Center&quot; /&gt;
      &lt;/StackLayout&gt;
      &lt;StackLayout BackgroundColor=&quot;Gray&quot; WidthRequest=&quot;120&quot; HeightRequest=&quot;180&quot;&gt;
          &lt;Label Text=&quot;4&quot; TextColor=&quot;White&quot; VerticalOptions=&quot;FillAndExpand&quot; HorizontalOptions=&quot;FillAndExpand&quot; VerticalTextAlignment=&quot;Center&quot; HorizontalTextAlignment=&quot;Center&quot; /&gt;
      &lt;/StackLayout&gt;
    &lt;/suave:DynamicStackLayout&gt;
&lt;/ScrollView&gt;

Features

  • Bindable child views
  • Bindable to collections
  • Handles layout changing well (try rotating the device)
  • Doesn’t require custom renderers (All Xamarin.Forms baby!)

Notes

This does not use any native view virtualization, which means performance does not scale well with extremely large data sets.

Coming soon

  • ItemSelected event and SelectedItem bindable property (for now, you can add custom gestures and commands to your DataTemplate and handle the events yourself)
  • Better Collection Updating

 

If you like what you see, don’t forget to follow me on twitter @Suave_Pirate, check out my GitHub, and subscribe to my blog to learn more mobile developer tips and tricks!

Interested in sponsoring developer content? Message @Suave_Pirate on twitter for details.

Xamarin.Tip – Read All Contacts in Android

To follow the posts made for iOS, let’s talk about reading the device contacts in Xamarin.Android.

Since Xamarin hasn’t been working on the Xamarin.Mobile component for a while, and James Montemagno dropped support for his Contacts Plugin, if you want to access the contact APIs on each platform, you might just have to go at it yourself – or just copy this code!

Android

The first thing we need to do is create our shared model to represent a contact on the device. In this example, we’ll focus on just the name and phone number of a given contact:
PhoneContact.cs

public class PhoneContact
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string PhoneNumber { get; set; }
 
    public string Name { get => $"{FirstName} {LastName}"; }
 
}

Now we need to create our service to enable the reading of the contacts on the device. We’ll call it the ContactService.

    public class ContactService_Android
    {
        public IEnumerable<PhoneContact> GetAllContacts()
        {
            var phoneContacts = new List<PhoneContact>();

            using (var phones = Android.App.Application.Context.ContentResolver.Query(ContactsContract.CommonDataKinds.Phone.ContentUri, null, null, null, null))
            {
                if (phones != null)
                {
                    while (phones.MoveToNext())
                    {
                        try
                        {
                            string name = phones.GetString(phones.GetColumnIndex(ContactsContract.Contacts.InterfaceConsts.DisplayName));
                            string phoneNumber = phones.GetString(phones.GetColumnIndex(ContactsContract.CommonDataKinds.Phone.Number));

                            string[] words = name.Split(' ');
                            var contact = new PhoneContact();
                            contact.FirstName = words[0];
                            if (words.Length > 1)
                                contact.LastName = words[1];
                            else
                                contact.LastName = ""; //no last name
                            contact.PhoneNumber = phoneNumber;
                            phoneContacts.Add(contact);
                        }
                        catch (Exception ex)
                        {
                            //something wrong with one contact, may be display name is completely empty, decide what to do
                        }
                    }
                    phones.Close(); 
                }
                // if we get here, we can't access the contacts. Consider throwing an exception to display to the user
            }

            return phoneContacts;
        }
    }

 
In this method, we get access to the Context‘s ContentResolver and query for all contacts’ phone numbers.

We can then iterate over each phone number and read their name and number which is added to the master list of PhoneContacts. This list is what ends up being returned, and we close the query context we opened in the using statement.

There is one more step we need to do in order to access the contacts on the device. In the AndroidManifest.xml we need to add the permission for READ_CONTACTS. This can be added in the XML directly or done in the UI from Visual Studio:
Screen Shot 2017-09-07 at 5.30.01 PM
 
Now that we have access to all the contacts on the device, we can render those in a list through either an Android ListView, RecyclerView, or if in Xamarin.Forms – a Xamarin.Forms.ListView.

Screenshot_1504821136

 Try building some other fun features into your ContactsService or selector!
– Filter the list via search
– Build a more user friendly selector without duplicating contacts
– Gather additional properties for contacts

If you like what you see, don’t forget to follow me on twitter @Suave_Pirate, check out my GitHub, and subscribe to my blog to learn more mobile developer tips and tricks!

Interested in sponsoring developer content? Message @Suave_Pirate on twitter for details.

Xamarin.Tip – Playing Audio Through the Earpiece on Android

Xamarin provides plenty of documentation on how to play audio in Android:

However, this never touches on directing audio through the onboard earpiece for applications such as voicemail or other real-time uses. Here’s a quick and dirty service that can be used in Xamarin.Android to direct audio through either the speaker or the onboard earpiece:

AudioService.cs

    public class AudioService : IAudioService
    {
        public AudioService()
        {
        }

        public void PlaySoundThroughEarPiece()
        {
            var mediaPlayer = new MediaPlayer();

            mediaPlayer.Reset();

            var audioManager = (AudioManager)Android.App.Application.Context.GetSystemService(Context.AudioService);
            mediaPlayer.SetAudioStreamType(Stream.VoiceCall);
            audioManager.Mode = Mode.InCall;
            audioManager.SpeakerphoneOn = false;
            mediaPlayer.SetDataSource(Android.App.Application.Context, Android.Net.Uri.Parse("android.resource://com.suavepirate.audiotest/raw/sample_sound"));
            mediaPlayer.Prepare();
            mediaPlayer.Start();
        }

        public void PlaySoundThroughSpeaker()
        {
            var mediaPlayer = MediaPlayer.Create(Android.App.Application.Context, Resource.Raw.sample_sound);


            var audioManager = (AudioManager)Android.App.Application.Context.GetSystemService(Context.AudioService);
            mediaPlayer.SetAudioStreamType(Stream.Music);
            audioManager.Mode = Mode.Normal;
            audioManager.SpeakerphoneOn = true;

            mediaPlayer.Start();
        }
    }

There are 2 important pieces required to stream it through the earpiece. Certain devices and Android versions only require 1 of the 2, but using both seems to be the best bet.

The first is to use the AudioManager service from the current Context and set SpeakerphoneOn to false as well as set the Mode to Mode.InCall. The second is to take the MediaPlayer object created and set the AudioStreamType to Stream.VoiceCall.

To go back to playing through the full speaker, revert the audio manager Mode to Normal, and set SpeakerphoneOn back to true. Be sure to also set the MediaPlayer.SetAudioStreamType with Stream.Music.

Check out an example of this on my GitHub here in Xamarin.Forms: https://github.com/SuavePirate/XamarinEarpieceAudioTest

If you like what you see, don’t forget to follow me on twitter @Suave_Pirate, check out my GitHub, and subscribe to my blog to learn more mobile developer tips and tricks!

Interested in sponsoring developer content? Message @Suave_Pirate on twitter for details.

Xamarin.Tip – Borderless Inputs

I published multiple posts this week about creating Xamarin.Forms controls without borders using Custom renderers. This post is your one stop shop for all these posts. These are the controls that are used in my repository to create Material Design inputs in Xamarin.Forms that you can find here:
https://github.com/SuavePirate/SuaveControls.MaterialFormControls. These will be talked about in posts to come!
Check the borderless controls out here:

  1. Xamarin.Forms Borderless Entry
  2. Xamarin.Forms Borderless Picker
  3. Xamarin.Forms Borderless DatePicker
  4. Xamarin.Forms Borderless TimePicker
  5. Xamarin.Forms Borderless Editor

And check out how they look here:

BorderlessEntry


BorderlessEditor

BorderlessPicker

BorderlessDatePicker

BorderlessTimePicker

If you like what you see, don’t forget to follow me on twitter @Suave_Pirate, check out my GitHub, and subscribe to my blog to learn more mobile developer tips and tricks!

Interested in sponsoring developer content? Message @Suave_Pirate on twitter for details.

Xamarin.Tip – BottomNavigationView in Xamarin.Android

I previously talked about adding a BottomNavigationView to your native Android apps using Java (Android.Basics – Adding a Bottom Navigation View), but I couldn’t leave my Xamarin buddies out! Consider this phase 1 in moving your tabs to the bottom of your Xamarin apps! In this post, we’ll look at a basic implementation of the new Material Design BottomNavigationView in Xamarin.Android, and in a later post, we’ll implement it in Xamarin.Forms with a custom TabbedRenderer.

Resources

Create a Menu Resource

The BottomNavigationView uses a menu to create the items in the navigation view, so you’ll need to create an xml resource under Resource/menu.

bottom_bar_menu.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/all_puppies"
        android:title="@string/action_all"
        android:icon="@drawable/ic_home_white_24dp" />

    <item android:id="@+id/big_puppies"
        android:title="@string/action_big"
        android:icon="@drawable/ic_dog_white_24dp" />

    <item android:id="@+id/small_puppies"
        android:title="@string/action_small"
        android:icon="@drawable/ic_small_dog_white_24dp" />

    <item android:id="@+id/trained_puppies"
        android:title="@string/action_trained"
        android:icon="@drawable/ic_trained_white_24dp" />

    <item android:id="@+id/active_puppies"
        android:title="@string/action_active"
        android:icon="@drawable/ic_active_white_24dp" />
</menu>


Note that the images I use are from my previous post, and are included in the source code in GitHub linked above.

Update the Layout

Add an android.support.design.widget.BottomNavigationView to your layout, or you can now add it easily in Visual Studio (for Mac) in the design view by selecting it on the right.

main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:id="@+id/textView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:text="All"
        android:textAlignment="center"
        android:gravity="center" />
    <android.support.design.widget.BottomNavigationView
        android:id="@+id/bottomNavigationView"
        android:minWidth="25px"
        android:minHeight="25px"
        android:layout_width="match_parent"
        android:layout_height="56dp"
        android:layout_alignParentBottom="true"
        android:background="@android:color/white"
        app:elevation="6dp"
        app:menu="@menu/bottom_bar_menu" />
</RelativeLayout>

or….

Screen Shot 2017-07-25 at 3.48.02 PM

Just make sure you properly set the layout_width and layout_height to meet the standards and also add elevation to give it the shadow and solid background.

Add Listeners

Xamarin did a great job of wrapping the Java listener with C# events so we can add the event handlers we know and love to handle changes when an item is selected in the BottomNavigationView.

MainActivity.cs

    public class MainActivity : Activity
    {

        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);

            // Set our view from the "main" layout resource
            SetContentView(Resource.Layout.Main);

            var textView = FindViewById<TextView>(Resource.Id.textView);
            var bottomBar = FindViewById<BottomNavigationView>(Resource.Id.bottomNavigationView);
            textView.Text = "All";
            bottomBar.NavigationItemSelected += (s,a) => {
                textView.Text = a.Item.TitleFormatted.ToString();
            };
        }
    }

Things to Remember

Remember that this is part of the AppCompat packages from Google, and is only in version 25+ of the Android Support Design Library. You can install the nuget package for it here: https://www.nuget.org/packages/Xamarin.Android.Support.Design/25.4.0-rc1

Because of this, you also need to set the theme of your Activity to something that is a sub-theme of Theme.AppCompat.

Results

Check it out!

Xamarin_Bottom_Bar

If you like what you see, don’t forget to follow me on twitter @Suave_Pirate, check out my GitHub, and subscribe to my blog to learn more mobile developer tips and tricks!

Interested in sponsoring developer content? Message @Suave_Pirate on twitter for details.

Xamarin.Tip – Fixing the VS for Mac Xamarin.Forms Template Android Issues

Here’s another quick resolution to one of the most annoying issues I’ve faced in working with Visual Studio for Mac…

The Problem

When creating a brand new, out of the box, Xamarin.Forms project, it didn’t work. This has been a common trend for Xamarin/Microsoft over the last year or so as they roll out Xamarin + Visual Studio updates. The latest culprit was that the Android project was never able to actually install the Xamarin.Forms package from nuget. This was not obvious during the actual build, since the project DID load successfully, and the build errors were along the lines of not being able to find Android Support library resources in the styles.xml. This also caused an issue where source files were not loading with intellisense or highlighting, so the error was even less obvious (see Xamarin.Tip – Fixing the Highlighting Drop In Your Xamarin.Android Projects).

When going into the nuget package manager and trying to manually add the Xamarin.Forms package, I was hit with this error:

Could not install package 'Xamarin.Android.Support.v4 23.3.0'. You are trying to install this package into a project that targets 'MonoAndroid,Version=v2.3'
...

The Solution

My first instinct was to check the Android target version in the project options to make sure that they were within the supported SDK range, and they were:
Screen Shot 2017-06-21 at 4.05.17 PM

Unlike Visual Studio 2017 (or any Windows VS with Xamarin), there was no “Compile using Android Version” picker. THIS field is what is really determines the projects target framework level, but VS for Mac doesn’t have it like it should (hope you’re reading this Microsoft!).

Let’s fix it manually:

  1. Unload your Android project by right clicking it in the Solution explorer and clicking “Unload”
  2. Open the Android project .csproj in the editor by right clicking > Tools > Edit.
  3. For each build configuration, add an explicit TargetFrameworkVersion that’s compatible. In my case that was v4.4
  4. Your .csproj should look like this:
    <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    ... 
      <PropertyGroup>
        <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
        <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
        <ProjectGuid>{2BC9AAD5-D311-499E-8B06-A63CCB65C633}</ProjectGuid>
        <ProjectTypeGuids>{EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
        <OutputType>Library</OutputType>
        <RootNamespace>AppName.Droid</RootNamespace>
        <AssemblyName>AppName.Droid</AssemblyName>
        <AndroidApplication>True</AndroidApplication>
        <AndroidResgenFile>Resources\Resource.designer.cs</AndroidResgenFile>
        <AndroidResgenClass>Resource</AndroidResgenClass>
        <AndroidManifest>Properties\AndroidManifest.xml</AndroidManifest>
        <MonoAndroidResourcePrefix>Resources</MonoAndroidResourcePrefix>
        <MonoAndroidAssetsPrefix>Assets</MonoAndroidAssetsPrefix>
        <AndroidUseLatestPlatformSdk>true</AndroidUseLatestPlatformSdk>
        <TargetFrameworkVersion>v4.4</TargetFrameworkVersion> <!-- THIS IS WHAT YOU NEED TO ADD OR CHANGE -->
      </PropertyGroup>
      <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
        <DebugSymbols>true</DebugSymbols>
        <DebugType>full</DebugType>
        <Optimize>false</Optimize>
        <OutputPath>bin\Debug</OutputPath>
        <DefineConstants>DEBUG;</DefineConstants>
        <ErrorReport>prompt</ErrorReport>
        <WarningLevel>4</WarningLevel>
        <AndroidLinkMode>None</AndroidLinkMode>
        <TargetFrameworkVersion>v4.4</TargetFrameworkVersion><!-- THIS IS WHAT YOU NEED TO ADD OR CHANGE -->
      </PropertyGroup>
      <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
        <DebugSymbols>true</DebugSymbols>
        <DebugType>pdbonly</DebugType>
        <Optimize>true</Optimize>
        <OutputPath>bin\Release</OutputPath>
        <ErrorReport>prompt</ErrorReport>
        <WarningLevel>4</WarningLevel>
        <AndroidManagedSymbols>true</AndroidManagedSymbols>
        <AndroidUseSharedRuntime>false</AndroidUseSharedRuntime>
        <TargetFrameworkVersion>v4.4</TargetFrameworkVersion><!-- THIS IS WHAT YOU NEED TO ADD OR CHANGE -->
      </PropertyGroup>
    
    ...
    </Project>
    
  5. Close the .csproj editor
  6. Reload the project by right clicking in the Solution Explorer and selecting Reload
  7. Retry adding the Xamarin.Forms nuget package to the project

Now you should be good to go. Did this not work for you? Leave a comment below and I’d be happy to help you fix this annoying issue as well!

If you like what you see, don’t forget to follow me on twitter @Suave_Pirate, check out my GitHub, and subscribe to my blog to learn more mobile developer tips and tricks!

Interested in sponsoring developer content? Message @Suave_Pirate on twitter for details.