Integrating with Xamarin Forms Application
Xamarin Forms error handling for the .NET SDK
Working Sample
For the working sample, please look here.
Recommended Rollbar Modules/Packages
Whenever you are trying to integrate Rollbar.NET SDK into an existing Xamarin-based application, the most optimal way is to do it via our Rollbar
module. Optionally, you may want to also use other modules/packages of the SDK: Rollbar.App.Config
or Rollbar.AppSettings.Json
and Rollbar.OfflinePersistence
:
dotnet add package Rollbar
// optionally:
dotnet add package Rollbar.App.Config
dotnet add package Rollbar.AppSettings.Json
dotnet add package Rollbar.OfflinePersistence
Modify your Xamarin Forms Shared Project
Add RollbarHelper.cs
using the following boilerplate code for its content:
namespace Sample.Xamarin.Forms
{
using System;
using System.Threading.Tasks;
using Rollbar;
using Rollbar.DTOs;
using Samples;
/// <summary>
/// Class RollbarHelper.
/// A utility class aiding in Rollbar SDK usage.
/// </summary>
public static class RollbarHelper
{
public static readonly TimeSpan RollbarTimeout = TimeSpan.FromSeconds(10);
/// <summary>
/// Registers for global exception handling.
/// </summary>
public static void RegisterForGlobalExceptionHandling()
{
AppDomain.CurrentDomain.UnhandledException += (sender, args) =>
{
var newExc = new System.Exception(
"CurrentDomainOnUnhandledException",
args.ExceptionObject as System.Exception
);
// report the exception to Rollbar:
RollbarLocator
.RollbarInstance
.AsBlockingLogger(RollbarTimeout)
.Critical(newExc);
};
TaskScheduler.UnobservedTaskException += (sender, args) =>
{
var newExc = new ApplicationException(
"TaskSchedulerOnUnobservedTaskException",
args.Exception
);
// report the exception to Rollbar:
RollbarLocator
.RollbarInstance
.AsBlockingLogger(RollbarTimeout)
.Critical(newExc);
};
}
/// <summary>
/// Configures the Rollbar singleton-like infrastructure.
/// </summary>
public static void ConfigureRollbar()
{
// create valid Rolbar configuration:
RollbarInfrastructureConfig rollbarInfrastructureConfig =
new RollbarInfrastructureConfig(
RollbarSamplesSettings.AccessToken,
RollbarSamplesSettings.Environment
);
// optionally:
RollbarDataSecurityOptions dataSecurityOptions =
new RollbarDataSecurityOptions();
dataSecurityOptions.ScrubFields = new string[]
{
"access_token", // normally, you do not want scrub this specific field (it is operationally critical), but it just proves safety net built into the notifier...
"username",
};
rollbarInfrastructureConfig
.RollbarLoggerConfig
.RollbarDataSecurityOptions
.Reconfigure(dataSecurityOptions);
// optionally:
RollbarPayloadAdditionOptions payloadAdditionOptions =
new RollbarPayloadAdditionOptions();
payloadAdditionOptions.Person = new Person("007")
{
Email = "[email protected]",
UserName = "JBOND"
};
rollbarInfrastructureConfig
.RollbarLoggerConfig
.RollbarPayloadAdditionOptions
.Reconfigure(payloadAdditionOptions);
RollbarInfrastructure.Instance.Init(rollbarInfrastructureConfig);
// optionally, to monitor Rollbar internal events:
RollbarInfrastructure
.Instance
.QueueController
.InternalEvent += OnRollbarInternalEvent;
}
/// <summary>
/// Called when rollbar internal event is detected.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The <see cref="RollbarEventArgs" /> instance containing the event data.</param>
private static void OnRollbarInternalEvent(
object sender,
RollbarEventArgs e
)
{
Console.WriteLine(e.TraceAsString());
RollbarApiErrorEventArgs apiErrorEvent = e as RollbarApiErrorEventArgs;
if (apiErrorEvent != null)
{
//TODO: handle/report Rollbar API communication error event...
return;
}
CommunicationEventArgs commEvent = e as CommunicationEventArgs;
if (commEvent != null)
{
//TODO: handle/report Rollbar API communication event...
return;
}
CommunicationErrorEventArgs commErrorEvent = e as CommunicationErrorEventArgs;
if (commErrorEvent != null)
{
//TODO: handle/report basic communication error while attempting to reach Rollbar API service...
return;
}
InternalErrorEventArgs internalErrorEvent = e as InternalErrorEventArgs;
if (internalErrorEvent != null)
{
//TODO: handle/report basic internal error while using the Rollbar Notifier...
return;
}
}
}
}
Modify your Xamarin Forms UWP Project
Update your App.xaml.cs
like so:
namespace Sample.Xamarin.Forms.UWP
{
using System;
using Windows.ApplicationModel;
using Windows.ApplicationModel.Activation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
using Rollbar;
using xf = Xamarin.Forms;
/// <summary>
/// Provides application-specific behavior to supplement the default Application class.
/// </summary>
sealed partial class App : Application
{
/// <summary>
/// Initializes the singleton application object. This is the first line of authored code
/// executed, and as such is the logical equivalent of main() or WinMain().
/// </summary>
public App()
{
// configure Rollbar:
RollbarHelper.ConfigureRollbar();
// basic senity check:
RollbarLocator.RollbarInstance
.Info("Xamarin.Forms sample: Hello world! Xamarin is here...");
// subscribe to all known unhandled exception events application-wide:
RollbarHelper.RegisterForGlobalExceptionHandling();
this.UnhandledException += App_UnhandledException;
this.InitializeComponent();
this.Suspending += OnSuspending;
}
private void App_UnhandledException(
object sender,
Windows.UI.Xaml.UnhandledExceptionEventArgs e
)
{
// report the exception to Rollbar:
RollbarLocator
.RollbarInstance
.AsBlockingLogger(RollbarHelper.RollbarTimeout)
.Critical(e.Exception);
}
}
}
Modify your Xamarin Forms Android Project
Update your MainActivity.cs
like so:
namespace Sample.Xamarin.Forms.Droid
{
//...
using Rollbar;
//...
[Activity(
Label = "Sample.Xamarin.Forms",
Icon = "@drawable/icon",
Theme = "@style/MainTheme",
MainLauncher = true,
ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation
)]
public class MainActivity
: global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
protected override void OnCreate(Bundle bundle)
{
// configure Rollbar:
RollbarHelper.ConfigureRollbar();
// basic senity check:
RollbarLocator.RollbarInstance
.Info("Xamarin.Forms sample: Hello world! Xamarin is here @MainActivity.OnCreate(...) ...");
//subscribe to all known unhandled exception events application-wide
RollbarHelper.RegisterForGlobalExceptionHandling();
AndroidEnvironment.UnhandledExceptionRaiser +=
AndroidEnvironment_UnhandledExceptionRaiser;
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(bundle);
global::Xamarin.Forms.Forms.Init(this, bundle);
LoadApplication(new App());
}
private void AndroidEnvironment_UnhandledExceptionRaiser(object sender, RaiseThrowableEventArgs e)
{
var newExc =
new System.Exception("UnhandledExceptionRaiser", e.Exception);
// report the exception to Rollbar:
RollbarLocator
.RollbarInstance
.AsBlockingLogger(RollbarHelper.RollbarTimeout)
.Critical(newExc);
}
}
}
Modify your Xamarin Forms iOS Project
Update your AppDelegate.cs
like so:
namespace Sample.Xamarin.Forms.iOS
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Foundation;
using UIKit;
using Rollbar;
// The UIApplicationDelegate for the application. This class is responsible for launching the
// User Interface of the application, as well as listening (and optionally responding) to
// application events from iOS.
[Register("AppDelegate")]
public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
{
//
// This method is invoked when the application has loaded and is ready to run. In this
// method you should instantiate the window, load the UI into it and then make the window
// visible.
//
// You have 17 seconds to return from this method, or iOS will terminate your application.
//
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
// configure Rollbar:
RollbarHelper.ConfigureRollbar();
//subscribe to all known unhandled exception events application-wide:
RollbarHelper.RegisterForGlobalExceptionHandling();
global::Xamarin.Forms.Forms.Init();
LoadApplication(new App());
return base.FinishedLaunching(app, options);
}
/// <summary>
/// Informs the app that the activity of the <paramref name="userActivityType" /> type could not be continued, and specifies a <paramref name="error" /> as the reason for the failure.
/// </summary>
/// <param name="application">To be added.</param>
/// <param name="userActivityType">To be added.</param>
/// <param name="error">To be added.</param>
/// <remarks>To be added.</remarks>
public override void DidFailToContinueUserActivitiy(
UIApplication application,
string userActivityType,
NSError error
)
{
// collect data about the NSError:
IDictionary<string, object> custom = new Dictionary<string, object>();
custom["NSError.Description"] = error.Description;
custom["NSError.DebugDescription"] = error.DebugDescription;
custom["NSError.Code"] = error.Code;
custom["NSError.Domain"] = error.Domain;
custom["NSError.LocalizedDescription"] = error.LocalizedDescription;
custom["NSError.LocalizedFailureReason"] = error.LocalizedFailureReason;
custom["NSError.LocalizedRecoveryOptions"] = error.LocalizedRecoveryOptions;
custom["NSError.LocalizedRecoverySuggestion"] = error.LocalizedRecoverySuggestion;
// capture the user activity type:
string message = "NSError during user activity type: " + userActivityType;
// report the error to Rollbar:
RollbarLocator
.RollbarInstance
.AsBlockingLogger(RollbarHelper.RollbarTimeout)
.Error(message, custom);
base.DidFailToContinueUserActivitiy(application, userActivityType, error);
}
}
}
Updated about 1 year ago