Xamarin.Tips – Calling Platform-Specific Code from a Portable Class Library – The Singleton Method

For those who just want code: https://github.com/SuavePirate/Xamarin.HockeyApp.Portable

For those who just want the video: [VIDEO] Xamarin.Tips: Calling Platform-Specific Code from a PCL (Singleton Method)

As we develop our applications to be cross-platform, we try to share as much code between different platforms as possible. Many times, though, we have a need to call platform-specific code from that shared code; whether it be something such as playing a sound file, handling hardware readings, or using a third-party SDK that isn’t abstracted to be shareable.

In these examples, we will look at implementing parts of the HockeyApp SDK that are specific to the platform you are running against such as showing the Feedback control to ask your users to report bugs or give feedback.

There are a few ways to accomplish this, but in this post, we will look at using the Singleton Method.

The Singleton Method is where we create a universal Singleton in our shared code that is initialized in our platform code, and then called from our shared code.

To start, in our shared code, we will create an interface that will be implemented on our platforms:

public interface IHockeyService
{
    void Init();
    void GetFeedback();
}

Then we create our actual Singleton in our shared code:

public class HockeyManager
{
    public static IHockeyService Current;
}

Now in our platform projects, we will implement our IHockeyService:

iOS:

public class HockeyService : IHockeyService
{
    public HockeyService()
    {
    }

    public void GetFeedback()
    {
        BITHockeyManager.SharedHockeyManager.FeedbackManager.ShowFeedbackListView();
    }

    public void Init()
    {
        var manager = BITHockeyManager.SharedHockeyManager;
        manager.Configure("HOCKEY_APP_ID");
        manager.StartManager();
    }
}

Android:

public class HockeyService : IHockeyService
{
    private const string HOCKEYAPP_KEY = "HOCKEY_APP_ID";
    private readonly Android.App.Application _androidApp;
    private readonly Activity _context;

    public HockeyAppService(Activity context, Android.App.Application androidApp)
    {
        _context = context;
        _androidApp = androidApp;
    }

    public void GetFeedback()
    {
        FeedbackManager.ShowFeedbackActivity(_context.ApplicationContext);
    }

    public void Initialize()
    {
        CrashManager.Register(_context, HOCKEYAPP_KEY);
        MetricsManager.Register(_androidApp, HOCKEYAPP_KEY);
        UpdateManager.Register(_context, HOCKEYAPP_KEY);
        FeedbackManager.Register(_context, HOCKEYAPP_KEY);
    }
}

Now we need to initialize our Singleton from our platform-specific code. In iOS, we will do this in our AppDelegate, and in Android – our MainActivity:

iOS

public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
    HockeyManager.Current = new HockeyService();
    global::Xamarin.Forms.Forms.Init();
    LoadApplication(new App());

    return base.FinishedLaunching(app, options);
}

Android:

protected override void OnCreate(Bundle bundle)
{
    TabLayoutResource = Resource.Layout.Tabbar;
    ToolbarResource = Resource.Layout.Toolbar;
    base.OnCreate(bundle);
    HockeyManager.Current = new HockeyService(this, Application);
    global::Xamarin.Forms.Forms.Init(this, bundle);
    LoadApplication(new App());
}

Now we need to initialize the HockeyApp manager from our shared code.

App.xaml.cs

public App ()
{
    HockeyManager.Current.Init();
}

Now that our Singleton is created, we can make calls to it from our Shared code. In this example, we will add a button to a Xamarin.Forms page with a click handler that calls the service:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="YourNamespace.MainPage">

    <Button Text="Get feedback with a singleton!"
            VerticalOptions="Center"
            HorizontalOptions="Center"
            Clicked="Feedback_Clicked"/>

</ContentPage>
public partial class MainPage : ContentPage
{
    public MainPage()
    {
        InitializeComponent();
    }

    private void Feedback_Clicked(object sender, EventArgs e)
    {
        HockeyManager.Current.GetFeedback();
    }
}

Now our results will show that our shared code call to the Singleton successfully shows the HockeyApp UI

simulator-screen-shot-feb-15-2017-1-47-26-pm

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s