Creating Reusable Plugins for Xamarin and Xamarin.Forms

James Montemagno

Xamarin.Forms enables you to share not only your app’s business logic, but also a shared user interface across iOS, Android, and Windows Phone mobile apps. Using Xamarin.Form’s built-in dependency service, it is extremely easy to get access to the native platform to expose rich functionality unique to the underlying platform. However, what happens once you write this code and want to share it between other apps you are building or with developers all over the world? Using the power of portable class libraries (PCL), and NuGet, sharing this code is also straightforward. Today, I want to show you how easy it is to create your own reusable plugin for Xamarin and Xamarin.Forms.

The Idea

Cross Settings LogoUsually an idea for a plugin comes directly from developing an application. A while back, I ran into the issue of having a common API to save settings across all platforms from shared code. That is how my cross-platform settings plugin was born and published to NuGet. Recently, I wanted to have a way to somehow vibrate the phone from shared code, so let’s see how to build and share this functionality.

The Interface

Our plugin will start with a simple interface inside of a PCL describing the functionality we would like to expose. First, let’s create a new PCL. I prefer to name the solution after the functionality I am exposing and follow this naming scheme:

  • Interface PCL: Plugin.Functionality.Abstractions
  • Implementation PCL: Plugin.Functionality
  • iOS: Plugin.Functionality.iOS
  • Android: Plugin.Functionality.Android
  • Windows Phone: Plugin.Functionality.WinPhone

Creating New PCL

Now we just need to create and populate our interface. We are going to simply define and implement one method that accepts a measure of time for how long to vibrate the device.

public interface IVibrate
{
  /// <summary>
  /// Vibrate the phone for specified amount of time
  /// </summary>
  /// <param name="milliseconds">Time in Milliseconds to vibrate (500ms is default)</param>
  void Vibration(int milliseconds = 500);
}

PCL Implementation

Since we want to create this plugin to work with any Xamarin app with no dependencies on Xamarin.Forms’ dependency service we will create a “bait-and-switch” PCL with shim implementation. This will consist of a new file called **CrossVibrate** and also I have set a conditional compilation flag to PORTABLE.

using Plugin.Vibrate.Abstractions;
using System;

namespace Plugin.Vibrate
{
    public static class CrossVibrate
    {
      static Lazy TTS = new Lazy(() => CreateVibrate(), System.Threading.LazyThreadSafetyMode.PublicationOnly);

      public static IVibrate Current
      {
        get
        {
          var ret = TTS.Value;
          if (ret == null)
          {
            throw NotImplementedInReferenceAssembly();
          }
          return ret;
        }
      }

      static IVibrate CreateVibrate()
      {
#if PORTABLE
        return null;
#else
        return new Vibrate();
#endif
      }

      internal static Exception NotImplementedInReferenceAssembly()
      {
        return new NotImplementedException("This functionality is not implemented in the portable version of this assembly.  You should reference the Xam.Plugins.Vibrate NuGet package from your main application project in order to reference the platform-specific implementation.");
      }
    }
}

Platform Libraries

With the interface in place, we will want to create three new class libraries, one for each project type: iOS, Android, and Windows Phone (silverlight). Once we have our libraries setup, we will need to add the PCL Abstractions that we first created to start implementing our IVibrate interface.

FullSolutionSetup

Important

For the proper swapping of the implementation the following must be done to each of the platform libraries:

  • Matching namespaces of the PCL Implementation: Plugin.Vibrate
  • Matching version numbers
  • Matching assembly names: Plugin.Vibrate
  • A file link to the CrossVibrate file we just created

Android Implementation

The implementation on Android is pretty straight forward. We are able to use Application Context and ask for the VibratorService. After a few checks to make sure no one is passing in low numbers, and that the device has a vibrator, we will execute the vibrate command.

 
public void Vibrate(int milliseconds = 500)
{
  using(var v = (Vibrator)Android.App.Application.Context.GetSystemService(Context.VibratorService))
  {
    if (!v.HasVibrator) {
      Console.WriteLine("Android device does not have vibrator.");
      return;
    }

    if (milliseconds < 0)
      milliseconds = 0;

    try { 
      v.Vibration(milliseconds);
    }
    catch(Exception ex) {
      Console.WriteLine("Unable to vibrate Android device, ensure VIBRATE permission is set.");
    }
  }
}

iOS Implementation

On the iOS side of things, this might be our easiest implementation. Living inside of AudioToolbox is SystemSound, which has a way to vibrate the device. Unfortunately, there is no fine grain control over the length, so we will have to document this in the Readme file of our plugin.

/// <summary>
/// Vibrate device with default length
/// </summary>
/// <param name="milliseconds">Ignored (iOS doesn't expose)</param>
public void Vibration(int milliseconds = 500)
{
  SystemSound.Vibrate.PlaySystemSound();
}

Windows Phone Implementation

Windows Phone also has a simple API to vibrate the device with Microsoft.Devices.VibrateController. We simply need to grab the default VibrateController and call start.

public void Vibration(int milliseconds = 500)
{
  var v = VibrateController.Default;
  if (milliseconds < 0)
    milliseconds = 0;

  v.Start(TimeSpan.FromMilliseconds(milliseconds));
}

Create the NuGet and Test

All that is left to do is to create our NuGet package’s nuspec, which defines what dlls get packaged and deployed for each project type. There is great documentation on how to do this on the NuGet website; however, the important part is that you package your Abstraction library into a PCL and all three platforms. Additionally for iOS, Android, and Windows Phone, you should package each of your platform specific libraries. I tend create and package XML documentation and the pdb file along with the dlls and name the package with the naming scheme of Feature Plugin for Xamarin. Here is what my nuspec looks like for the final plugin that supports iOS, Android, Windows Phone 8, Windows Phone/Store 8.1 RT, and Windows 10 UWP:



   
       Xam.Plugins.Vibrate
       2.0.0
       Vibrate Plugin for Xamarin and Windows
       James Montemagno
       James Montemagno
       https://github.com/jamesmontemagno/Xamarin.Plugins/blob/master/LICENSE.md
       https://github.com/jamesmontemagno/Xamarin.Plugins/Vibrate
       https://devblogs.microsoft.com/wp-content/uploads/sites/44/2019/04/vibrate_icon_large.png
       false
       
         Xamarin and Windows plugin to vibrate your devices. 
         Read the full documentation on the projects page.
       
       
         Xamarin and Windows plugin to vibrate your device.
       
       xamarin, xamarin.forms, android, ios, windows phone, vibrate
   
   
     
     
     
     
     
     
     

     
     
     
     
     
     
     

     
     
     
     
     
     

     
     
     
     
     
     
   
     
     
     
     
     
     
     

     
     
     
     
     
     
     

     
     
     
     
     
     
     

     
     
     
     
     
     
     

     
   

With the NuGet package all ready to go we are now able to create a new Xamarin or Xamarin.Forms project and install our NuGet locally before publishing by going into the NuGet Package Manager and specifying a path to our NuGet Packages that were just generated.

NuGetPackageManager

Distributing

As long as you have a NuGet account created you are now able to externally distribute your NuGet package. Read through the distribution documentation for the few steps that it takes to do this.

Using this simple plugin architecture you are easily able to create highly reusable and shareable plugins across all of your Xamarin and Xamarin.Forms projects. You will find this Vibrate plugin live on NuGet right now and you can browse the full documentation and source code on GitHub. Be sure to browse through all of the Plugins for Xamarin to see more awesome examples of reusable plugins, and learn how to create them with our free Xamarin University course and awesome Plugin for Xamarin Templates for Visual Studio to speed up development.

0 comments

Discussion is closed.

Feedback usabilla icon