--- layout: post title: "Improving user experience with the Norsk Tid solution by implementing Xamarin app functionality" author: "Anders Gill" #author-link: "#" #author-image: "{{ site.baseurl }}/images/authors/andersgill.jpg" date: 2017-04-06 categories: [Mobile Application Development with Xamarin, Mobile DevOps] color: "blue" image: "images/NorskTid/feat_teamHacking.jpg" excerpt: Time management supplier Norsk Tid joined Microsoft in a hackfest to implement new app functionality such as geolocation, notification, and a widget, in addition to setting up new DevOps practices. language: [English] verticals: [Professional Services] geolocation: [Europe] permalink: /xamarin/mobile%20devops/2017/04/06/NorskTid.html --- In this Xamarin hackfest, Microsoft teamed up with **Norsk Tid** to hack an existing solution, **tidBANK**. We describe the process and the results here, including implementation of the following Xamarin application functionality: - Geolocation - Notification system - Widget We also included the following practices for DevOps: - Continuous integration - Continuous deployment - Automated tests with Xamarin Test Cloud tidBANK is flexible software for time tracking and time reporting used everywhere from small companies to large, multinational corporations. **Key technologies used** During the hackfest, we primarily used these technologies: - Visual Studio for development (on Mac and Windows) - Xamarin for Visual Studio - Xamarin Test Cloud - BitBucket - Visual Studio Team Services - Git for source control - HockeyApp - Azure Storage Explorer - Microsoft Azure for: - Notification Hubs - Queue storage - Web Apps feature of Azure App Service **Hackfest members** - Øystein Gregers Lindbjør – Developer, Norsk Tid - Anton Shunkov – Technical Evangelist, Microsoft - Anders Gill – Technical Evangelist, Microsoft ## Customer profile [Norsk Tid](http://www.norsktid.no/) is a leading supplier of modern systems for time registration located in Oslo. Norsk Tid also delivers products for time allocation and budgeting. It helps hundreds of Norwegian companies and thousands of users to be more productive and keep track of time, vacation days, and hours worked on a project/budget. ## Focus of the hackfest Norsk Tid is developing a new Xamarin application (**tidBANK**) for both Android and iOS, and would like to expand the possibilities of the application by leveraging more functionality from the Xamarin API to provide a better product for the end users. The focus of the hackfest is to: - Implement geolocation so that users, when tracking time, can provide their locations if they choose. - Implement a notification system into the app so company administrators can send notifications directly to users. - Create a widget for quickly being able to log hours worked without having to actually open the app itself. Norsk Tid is also interested in implementing multiple DevOps practices into their workflow to have a better application deployment and development life cycle. This specifically involves: - Continuous integration - Continuous deployment - Automation testing in Xamarin Test Cloud *Deeply focused team* ![The team hacking]({{ site.baseurl }}/images/NorskTid/teamHacking.jpg) ## Problem statement Norsk Tid is essentially facing two issues with the current application: - Acknowledging the location from where a user is registering hours. - A company's inability to deliver on-the-fly messages to employees using the application to track hours. At the time of this writing, the users are able to record their locations based on wherever they are at. There is no way to accurately check and verify the actual location of the user at the time of reporting. Moreover, a place name can be written in multiple ways and has the potential to clutter the database with low-quality data. For the DevOps part, the main problem is that the deployment of the app to the beta tester is highly connected through a dependency between the developers and their knowledge. Before the hackfest, Norsk Tid did not have a proper distribution model for the beta apps. Implementing the DevOps practices will make it much easier for the developer to get the app to the beta testers (automation), which also makes it much easier to repeat, as well as decoupling the dependency. This allows the next developer on the project to continue on the application development life cycle. Norsk Tid was very interested in implementing continuous integration (CI). CI would allow the developers to check in code directly to a shared repository where each check-in would then be verified by an automation build that in turn would detect problems early on before release. For a deeper breakdown of the different capabilities of a proper build process, read more about [Continuous Integration](https://www.visualstudio.com/team-services/continuous-integration/). As a natural step after having implemented CI, we decided to implement continuous deployment (CD). CD is an approach where you can produce software in short cycles, which in turn allows for faster and more frequent releases. Norsk Tid was very intrigued by the capabilities CD would bring because this step adds transparency between the developer, software quality assurance (SQA), and the stakeholders. Other measurable benefits from the DevOps implementation should be increased release velocity for the tidBANK app. The use of HockeyApp allowed us to distribute the beta version internally with ease. The developers behind tidBANK don't have to be reluctant anymore to make changes that should effectively be put into release. The process is now fully continuous and automatic, and doesn't contain manual steps that increase the overhead of the release. Other benefits from the implementations include: - Reduced time to recover upon failure. - Reduced deployment failures and rollbacks. **Geolocation** By implementing geolocation, you can easily leverage the GPS to track whether an object is leaving a virtual perimeter (designated area), which could be the office where a worker is located during work hours, or simply use the current location when reporting hours. **Notifications** Another important aspect of the application is to allow the company administrators to provide whatever information they would like their employees to know about, on the fly, through a notification system inside the Xamarin app. For this, Azure Notification Hubs will be used in order to send personalized, scalable push-notifications to all target devices. **Widget** The tidBANK app widget will allow users of the app to more easily log hours worked since they no longer have to open up the full application, but can easily use the miniature application view (widget). The widget could also be used to show other relevant information from the app. ### The process We decided to prepare for the four-day hackfest with multiple calls beforehand to discuss architecture and the "need-to-have" functionality. This allowed us to get directly to work on the application when arriving and proved to be very valuable because we had a lot of functionality to implement and only four days of active work to do it in. We discussed each member's strengths in the team and thereafter decided to allocated work based on the specialities of the people involved. Because there was a limited amount of time set for this hackfest, we decided to focus just on the Android version of the app and building stepping stones for Norsk Tid to add these capabilities to their production app. ## Solution, steps, and delivery Three separate tools were created for this hackfest as stepping stones that can be added to the production app: - Web application hosting the web API exposing JSON. - Windows Forms application to connect to the storage account in Azure and create a queue to visualize the messages on the queue. - Android app made in Xamarin that shows a notification when you have checked into a geofenced area. ### Architecture There are essentially two architectures for the tidBANK application. First, there is a prototype architecture that we developed during this hackfest. It consists of: - A web app hosted in Azure. - A notification hub hosted in Azure. - A storage queue hosted in Azure. - A Windows Forms application used for visualization. - The Android Xamarin app itself. The web includes a custom-built API service that exposes the location data (longitude, latitude) for the different offices in JSON format. It also connects to the notification hub that allows us to send notifications to the Xamarin Android app. The app also deserializes the JSON that the web API has exposed, and uses it for the geolocation part. The app then registers a message on the storage queue when a user has entered a geofenced area based on the geolocation data. When the user leaves the geofenced area, the Xamarin app deletes the message on the storage queue. The Windows Forms application connects to the storage queue and looks for messages on the queue. If there are messages on the queue, it shows a green image displaying that the user is inside the geofenced area. As soon as the user leaves, the Windows Forms application recognizes this and changes the image to red, displaying that the user has left the geofenced area. The second architecture that we decided on for the tidBANK application looks like this: The customer has the location data on-premises inside a database. Connected to this database, a tidBANK agent is installed that uses that location data for its location service. This tidBANK web application pings the Azure Function Version Service monthly for the latest version of the tidBANK agent software. Based on the versioning, the tidBANK agent application will update itself or stay idle because it already has the latest updates. The tidBANK agent will be connected to the Azure App Service Mobile App, which has a notifications system and will be used to push notifications out to its users. This service will be connected to Firebase Cloud Messaging for Android push notification. This is again connected to the Xamarin app, and the cycle is complete. **The web app (API)** The web app hosted in Microsoft Azure consists of the example location data that would be stored at the customer's on-premises database. A web API with Swashbuckle Swagger is exposing the data as JSON format and allows other services to fetch this data and deserialize the JSON for their needs. ![Image of web app]({{ site.baseurl }}/images/NorskTid/webapp.gif) The code for the web API: ```cs using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Http; using System.Web.Http; using Swashbuckle.Swagger.Annotations; namespace TidBankWebAppDemo.Controllers { public class LocationsController : ApiController { [SwaggerOperation("GetLocations")] public IEnumerable Get() { return locations; } public class Location { public string ID { get; set; } public string Long { get; set; } public string Lat { get; set; } public string Name { get; set; } } static List locations = new List() { new Location() { ID = "1", Lat = "59.9238397", Long="10.7295549", Name = "Teknologihuset"}, new Location() { ID = "2", Lat = "59.9250158", Long="10.7311643", Name = "Bislett stadion"}, new Location() { ID = "3", Lat = "59.9245263", Long="10.7292303", Name = "Sonans"}, }; } } ``` Download the full code from our [GitHub repo](https://github.com/readyforchaos/Xamarin-Hackfest-2017). **The Windows Forms application (Queue visualization)** The Windows Forms application was created in order to easily pass messages to the storage queue, as well as display the messages on the queue to visualize if the user had entered the fenced perimeter or had left the perimeter. The image on the left in the Windows Forms application visualizes the state of the storage queue. ![Image of Windows Form application]({{ site.baseurl }}/images/NorskTid/winform.gif) The main code for the storage queue: ```cs private async void InitializeQueue(string connectionString, string queueName) //<<< (async) initializes queue, create new or use existing { CloudStorageAccount cloudStorageAccount = CloudStorageAccount.Parse(connectionString); // ^ creates an object from your storage account CloudQueueClient queueClient = cloudStorageAccount.CreateCloudQueueClient(); // < creates a client queue queue = queueClient.GetQueueReference(queueName); try { await queue.CreateIfNotExistsAsync(); } // < creates the queue if it doesn't exist catch (Exception ex) { Console.WriteLine("Could not initialize queue! Error: " + ex.Message); return; } groupBox.Enabled = true; InitTimer(); // < fetches elements from the queue through the timer method (uses the ReadFromQueue(); function) } ``` The code above initializes the queue and creates a queue from the name you entered in the UI if it doesn't exist. The following code fetches the attributes from the queue inside the ReadFromQueue() function. ```cs try { await queue.FetchAttributesAsync(); } // < fetches items from queue(items) catch (Exception ex) { Console.WriteLine("Could not read from queue! Error: " + ex.Message); return; } ``` Download the fully documented code from our [GitHub repo](https://github.com/readyforchaos/Xamarin-Hackfest-2017). **Android App** At the beginning of the hackfest, Norsk Tid had already implemented a Xamarin Android app to simplify the experience for the end users. During the hackfest, Microsoft experts were brainstorming with Norsk Tid to envision how we could further streamline the user experience for customers, making it even easier and more convenient to track their working hours. We came up with three core directions of work for the hackfest: - Push notifications - Geofencing - Widget The improvements listed above will help ensure that employees don't miss a check-in by allowing the back-end system to send reminders to employees via push notifications, allowing automatic check-ins and check-outs based on their presence in the office, and allowing users to check in or out directly from the lockscreen. We were using a lot of the platform-specific things Android can offer to really make a great user experience. ***Push notifications*** For push notifications, we used Azure Notifications Hub. This is the main code for the notification system: ```cs private NotificationHub _notificationHub { get; set; } ``` ```cs _notificationHub = new NotificationHub(Constants.NotificationHubName, Constants.ListenConnectionString, context); _notificationHub.Register(registrationId, tags.ToArray()); ``` In addition, Norsk Tid wanted their customers to have the ability to check in directly from the "reminder notification," so we decided to add the "Action" function to the notification as well: ```cs var notificationBuilder = new Notification.Builder(this) .SetSmallIcon(Android.Resource.Drawable.IcDialogAlert) .SetContentTitle(title) .AddAction(new Notification.Action(Android.Resource.Drawable.SymContactCard, "Check in", PendingIntent.GetService(this, 0, checkinIntent, PendingIntentFlags.UpdateCurrent))) .SetAutoCancel(true) .SetSound(RingtoneManager.GetDefaultUri(RingtoneType.Notification)); ``` Download the full code from our [GitHub repo](https://github.com/readyforchaos/Xamarin-Hackfest-2017). ***Geofencing*** Geofencing combines awareness of the user's current location with awareness of the user's proximity to locations that may be of interest. To mark a location of interest, you specify its latitude and longitude. To adjust the proximity for the location, you add a radius. The latitude, longitude, and radius define a geofence, creating a circular area, or fence, around the location of interest. ![Image of geofenced area]({{ site.baseurl }}/images/NorskTid/geofenceexplained.png) Image from [Android Developers](https://developer.android.com/training/location/geofencing.html). There is a Google Play service running in the background that we connect to in our Xamarin app. This service registers our geofences. When the user either leaves or enters a geofenced area, the service alerts us to this status change as well as which area it was, so that we can react accurately to the alert. Here is the main code for the geofencing: ```cs GeofencingRequest GetGeofencingRequest(IList geofence) { var builder = new GeofencingRequest.Builder(); builder.SetInitialTrigger(GeofencingRequest.InitialTriggerEnter); builder.AddGeofences(geofence); return builder.Build(); } ``` Read the full documentation on [Android Developers: Creating and Monitoring Geofences](https://developer.android.com/training/location/geofencing.html), which was immediately applicable to our application (besides the code that is written in Java). Download the full code from our [GitHub repo](https://github.com/readyforchaos/Xamarin-Hackfest-2017). ***Widget*** The implemented widget allows the users to "check in" and "check out" their current working hours without having to launch the tidBANK app itself. This makes the whole experience more fluid and fast. See how the widget functions below: Here is the main code for the widget: ```xml