June 16, 2013

Using Raygun for Logging in Windows Phone Applications

There are very good error logging and reporting tools for other platforms. But when it comes to Windows Phone, developers need to depend on their own sources. Luckily, I got to know about Raygun.io and it is one of the best logging framework. In this post, we’ll see how we can use this platform to track, manage and report errors.

Special thanks to Mindscape for providing trial versions and details about this product. This error logging platform is available to other platforms as well like ASP.NET, PHP, JS, .NET, WinRT/WP and what not.

To use this platform, you’ll need to first create a Raygun.IO account. You can opt for a trial version. Once you login, you’ll be asked to create a new app or visit: https://app.raygun.io/application/create

image

Once the application is created, you’ll be taken to the Dashboard. On this dashboard you can see various platforms and your application key. Select Windows Phone platform.

image

Now create a Windows Phone application using Visual Studio

image

Using NuGet PackageManger (Tools > Library Package Manager > Manage NuGet Packages for solution) install Raygun required assemblies in Online category.

image

Now, in your Windows Phone’s App.xaml.cs file, create object of RaygunClient, passing your Application Key. This will require you include referred assemblies. Make a note of highlighted text.

So, the App.xaml.cs will look like:

 using System;  
using System.Diagnostics;
using System.Windows;
using System.Windows.Markup;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using Mindscape.Raygun4Net;
using RaygunForWPDemo.Resources;
namespace RaygunForWPDemo
{
public partial class App
{
public static PhoneApplicationFrame RootFrame { get; private set; }
private readonly RaygunClient _client = new RaygunClient("YOUR APP KEY FROM REYGUN DASHBOARD");
public App()
{
UnhandledException += Application_UnhandledException;
InitializeComponent();
InitializePhoneApplication();
if (Debugger.IsAttached)
{
Current.Host.Settings.EnableFrameRateCounter = true;
PhoneApplicationService.Current.UserIdleDetectionMode = IdleDetectionMode.Disabled;
}
}
#region Application Events
private void Application_Launching(object sender, LaunchingEventArgs e)
{
}
private void Application_Activated(object sender, ActivatedEventArgs e)
{
}
private void Application_Deactivated(object sender, DeactivatedEventArgs e)
{
}
private void Application_Closing(object sender, ClosingEventArgs e)
{
}
private void RootFrame_NavigationFailed(object sender, NavigationFailedEventArgs e)
{
if (Debugger.IsAttached)
{
Debugger.Break();
}
}
#endregion
private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
{
_client.Send(e);
}
#region Phone application initialization
// Avoid double-initialization
private bool phoneApplicationInitialized = false;
// Do not add any additional code to this method
private void InitializePhoneApplication()
{
if (phoneApplicationInitialized)
return;
// Create the frame but don't set it as RootVisual yet; this allows the splash
// screen to remain active until the application is ready to render.
RootFrame = new PhoneApplicationFrame();
RootFrame.Navigated += CompleteInitializePhoneApplication;
// Handle navigation failures
RootFrame.NavigationFailed += RootFrame_NavigationFailed;
// Handle reset requests for clearing the backstack
RootFrame.Navigated += CheckForResetNavigation;
// Ensure we don't initialize again
phoneApplicationInitialized = true;
}
// Do not add any additional code to this method
private void CompleteInitializePhoneApplication(object sender, NavigationEventArgs e)
{
// Set the root visual to allow the application to render
if (RootVisual != RootFrame)
RootVisual = RootFrame;
// Remove this handler since it is no longer needed
RootFrame.Navigated -= CompleteInitializePhoneApplication;
}
private void CheckForResetNavigation(object sender, NavigationEventArgs e)
{
// If the app has received a 'reset' navigation, then we need to check
// on the next navigation to see if the page stack should be reset
if (e.NavigationMode == NavigationMode.Reset)
RootFrame.Navigated += ClearBackStackAfterReset;
}
private void ClearBackStackAfterReset(object sender, NavigationEventArgs e)
{
// Unregister the event so it doesn't get called again
RootFrame.Navigated -= ClearBackStackAfterReset;
// Only clear the stack for 'new' (forward) and 'refresh' navigations
if (e.NavigationMode != NavigationMode.New && e.NavigationMode != NavigationMode.Refresh)
return;
// For UI consistency, clear the entire page stack
while (RootFrame.RemoveBackEntry() != null)
{
; // do nothing
}
}
#endregion
#region InitializeLanguage Code
private void InitializeLanguage()
{
try
{
// Set the font to match the display language defined by the
// ResourceLanguage resource string for each supported language.
//
// Fall back to the font of the neutral language if the Display
// language of the phone is not supported.
//
// If a compiler error is hit then ResourceLanguage is missing from
// the resource file.
RootFrame.Language = XmlLanguage.GetLanguage(AppResources.ResourceLanguage);
// Set the FlowDirection of all elements under the root frame based
// on the ResourceFlowDirection resource string for each
// supported language.
//
// If a compiler error is hit then ResourceFlowDirection is missing from
// the resource file.
FlowDirection flow = (FlowDirection)Enum.Parse(typeof(FlowDirection), AppResources.ResourceFlowDirection);
RootFrame.FlowDirection = flow;
}
catch
{
// If an exception is caught here it is most likely due to either
// ResourceLangauge not being correctly set to a supported language
// code or ResourceFlowDirection is set to a value other than LeftToRight
// or RightToLeft.
if (Debugger.IsAttached)
{
Debugger.Break();
}
throw;
}
}
#endregion
}
}

Now, we’ll add a button to MainPage and in the code behind we’ll write a method which will throw DivideByZeroException.

 private void Button_Click(object sender, RoutedEventArgs e)  
{
int num1 = 1;
int num2 = 0;
int answer = num1/num2;
MessageBox.Show(answer.ToString());
}


If we run the app and click on the button, it will throw an exception. This exception will be logged by Raygun and you can get its details on the dashboard like one shown below. You can see the status marked in Red blocks.


image


Apart from that, you’ll also receive an email with error details as shown below:


image


This platform can help you to track exceptions in your applications, which are already published on the store and used by consumers. This can allow you to fix these exceptions and release updates/patches to your app making your app more successful.


Do give Raygun.IO a try.


Namaste. Happy coding :)

Mayur Tendulkar

June 7, 2013

Building Windows Phone apps for SharePoint

Yes. I love Windows Phone and I (sometimes) hate SharePoint, I’ve my own personal reasons :)

But still, there are many enterprises who use SharePoint for various reasons like collaboration, document management and what not. Providing SharePoint access on mobile devices can result in high productivity for employees. Indeed, SharePoint does have Mobile interface exposed for every site, but look at the web-page and people will simply hate it even more.

 

(Image From TechNet)

So, why not make it beautiful by providing rich user interface? why not make it more productive by building customized SharePoint solutions and mobile application? Yes. We can.

When I tried building Windows Phone apps for SharePoint, the biggest hurdle was authentication as SharePoint gives various options like Claims/Forms/ACE, NTLM, MicrosoftOnline, etc.. And then calling REST APIs every now and then. Wictor Willen has written a nice blog about SharePoint online authentication and you can see how painful it is to make requests here and there just to do the authentication :( <yes, I’m a lazy programmer> :)

But, recently I found out that Microsoft has released an SDK for building such apps. You can download these SDKs as: Microsoft SharePoint SDK for Windows Phone 7.1 & Microsoft SharePoint SDK for Windows Phone 8. Personally, I’ll recommend SDK for 7.1 unless you’re using any specific features from Windows Phone 8.

Once you download and install the SDK, using it is straight forward – just like using SharePoint CSOM. You need to refer following assemblies to use SharePoint APIs in your project:

  • Microsoft.SharePoint.Client.Phone.dll

  • Microsoft.SharePoint.Client.Phone.Runtime.dll

  • Microsoft.SharePoint.Client.Phone.Auth.UI

  • Microsoft.SharePoint.Phone.Application.dll

You can find these assemblies at: %ProgramFiles(x86)%\Microsoft SDKs\SharePoint\v15.0\Phone\%ver.%\

As you refer these libraries, accessing SharePoint list inside a Windows Phone is very simple:

image

In this example, it will show you a mobile authentication page (shown below) as I’m using MicrosoftOnline authentication mode. Else, you can provide login box to get credentials from users.

loginbox

After providing correct credentials, user will be authenticated and Failed/Succeeded callbacks will be sexecuted. Here you can process the results.

image

I hope this blog post will help you to build more SharePoint Mobile apps.

Namaste

Mayur Tendulkar