Xamarin Web View

Overview

The easiest way to get into Xamarin framework programming is creating your first webview.

A webview is something that is intended to embed a web browser inside your application.

“Webview allows you to create your own window for viewing web pages (or even develop a complete browser).” – Xamarin

In this article, I will show how to create a working Android application that loads website as a webview within your application.

If you already have a working responsive website, a webview can easily solve your problem for the need of mobile app!

Steps

Create Project

Start a new Cross Platform project in VS 2015. There are many options for the project types, we will pick “Blank Xaml App (Xamarin.Forms Portable)

cap1

Give this project and a name it will create 5 projects in your solution explorer. There will be 1 portable project where we will write most of our cross platform code and the rest of the 4 projects are for 4 individual platforms (Android, iOs,  Windows 10 and Windows Phone). We can even remove the project for the platform that you do not wish to build application for.

The main project will have an “App.cs” file which is the main entry point for our application. We will update this later as per our need later.

Check for Internet Connection

Since our application is going to need internet connection to load webpages, let’s first create a way to check whether or not the mobile has internet connection. As of now, this needs to be done being platform specific. While there are plugins for this, we will create our own mechanism for this purpose using Xamarin Forms Dependency Service.

Let’s create an interface in our main project. The interface is going to look something like this which will be implemented in for every platform.


public interface IPlatformNetworkService
{
bool HasInternetConnection();
}

In our Android prjoect, let’s add it’s implementation which will look like this:


using Xamarin.Forms;
using Android.Net;

[assembly: Dependency(typeof(YamaFriends.CP.WView.Droid.PlatformNetworkService))]

namespace YamaFriends.CP.WView.Droid
{
public class PlatformNetworkService: IPlatformNetworkService
{
public bool HasInternetConnection()
{
ConnectivityManager connectivityManager = (ConnectivityManager)Android.App.Application.Context
.GetSystemService(Android.App.Application.ConnectivityService);
NetworkInfo activeConnection = connectivityManager.ActiveNetworkInfo;
bool isOnline = (activeConnection != null) && activeConnection.IsConnected;
return isOnline;
}
}
}

But before this code can work, we will also need to provide Android project permission to network connectivity status. This should be done in the Android manifest file.

cap3

If we were developing app for iOs as well, we would need to write an implementation for iOs platform too.

XAML Page

Next, add a new Cross Platform item to your main project. Since we will be writing both XAML and C# code for loading web view, we will select Forms Xaml Page.

cap2

Now in our newly created XAML page, let’s put the following code:


<?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="YamaFriends.CP.WView.WebViewMain">

<ContentPage.Padding>
<OnPlatform x:TypeArguments="Thickness"
iOS="10, 20, 10, 0"
Android="10, 0" />
</ContentPage.Padding>

<StackLayout x:Name="mainStack">
<StackLayout Orientation="Horizontal"
x:Name="stack">
<Button Text="⇐"
FontSize="Large"
HorizontalOptions="FillAndExpand"
IsEnabled="{Binding CanGoBack}"
Clicked="OnGoBackClicked" />
<Button Text="⇒"
FontSize="Large"
HorizontalOptions="FillAndExpand"
IsEnabled="{Binding CanGoForward}"
Clicked="OnGoForwardClicked" />
</StackLayout>
</StackLayout>

</ContentPage>

You might have to adjust changes for the namespaces that you have in your project.

The code behind for the XAML page will handle internet conenction checks and back and forward button clicks and also loads the webview.


using System;

using Xamarin.Forms;

namespace YamaFriends.CP.WView
{
public partial class WebViewMain : ContentPage
{
WebView webView;

public WebViewMain()
{
InitializeComponent();

IPlatformNetworkService networkService = DependencyService.Get<IPlatformNetworkService>();

if (networkService.HasInternetConnection())
{
webView = new WebView();
webView.VerticalOptions = LayoutOptions.FillAndExpand;
webView.Source = "http://www.yamafriends.com/";
stack.BindingContext = webView;

mainStack.Children.Add(webView);
}
else
{
var label = new Label();
label.VerticalOptions = LayoutOptions.Center;
label.HorizontalOptions = LayoutOptions.Center;
label.Text = "This application requires internet connection. Please check and try again!";
}

}

void OnGoBackClicked(object sender, EventArgs args)
{
webView.GoBack();
}

void OnGoForwardClicked(object sender, EventArgs args)
{
webView.GoForward();
}
}
}

Set the Source property of the webview in code behind file to your website and run the application on your Android device.

Our webview is ready to go!

Automating Development in ASP.NET MVC

Inspired by rapid development framework Artisan in Laravel for PHP, I am thinking maybe we (.NET developers) can do something similar in our environment as well.

http://laravel.com/docs/5.0/artisan

Basically I am thinking of automating the whole process of creating Repository classes (including required entries for properties and fields), Model classes,  Service layer (layer where you put your business logic) interfaces and classes and maybe even Controllers and Views! Wouldn’t this be real good treat if all of this code writing could be automated!! Unless you have already seen this automation implemented by someone somewhere elsewhere, I am sure you are excited by this idea.

So this is the big idea. How do I plan to achieve this?

Well, I do all my projects in MVC pattern implementing Entity Framework and Unit of Work Pattern for Data Layer and Service Layer. Basically, I keep a project for Data Access Layer where the .edmx file generated by EF stays along with repositories for each Database objects. Then I expose the repositories for each Entities by a central repository using a Unit of Work pattern.

Then I keep another project for Model classes. For every entities generated by EF, I have models in this project.

Then I have third project for Service (or Business Logic) Layer where I have interfaces and their implementations to do all CRUD activities.

Finally for displaying the View to the user, I use a ASP.NET MVC project where I have controllers for each Entities. These controllers receive request from views and process data as per the request using the Interface exposed by Service Layer. The response sent from controllers to View is usually in JSON format.

The big realization is that no matter what type of entities we are dealing with the whole process of creating Repositories, Models, Services, Controllers and even the Views stays the same. The only changes that we will find are in the Members (Properties) of our Entities.

If we are dealing with User entity, we will have properties like Username, Password and Email and if we are dealing with Product entity, we will have properties like ProductName, ProductPrice, Category and so on.

Hence, if we just replace the properties and entity names, everything stays the same. This opens up the possibility for automating this whole process like I mentioned in the beginning of the post. Heck if I am able to automate only 70% of the process and make necessary adjustments for the remaining 30%, I would be more than happy.

I will be giving this a try and will write about it once its done. What are your thoughts on this?

Implementing Unit of Work Repository Pattern and Entity Framework Database First Design

Without getting into the discussion of the advantages/disadvantages of this implementation, I would like to straight away get into the implementation pattern that I have learned from working in a company in Kathmandu.
If you are interested in the discussion whether this is a better approach of implementation as compared to some other “XYZ” approach, feel free to surf the web. I use this implementation in almost all of my projects and am quite comfortable with it.
To begin with, first have your database ready. Have your tables sorted out as per your requirement. To demonstrate a basic sample, here I have one table called “SurveyBuilderHelper” which I am using for my next big project (:D for real). So this is how my table looks:
Fig 1: Sample Table
 
Now, in our visual studio, create a new project class library project. In this project, add a new item. This item is going to be “ADO.NET Entity Data Model”, which will serve as our database entities context. So, create a new .edmx file entity model which you will be generating by providing proper server credentials and pointing to the database that you have just designed. Also, provide a proper name for the entity connection string to be stored in your app.config file. In my case, I have named it as “SurveyBuilderHelperEntities”.
 
 
Now, add a new class to this project and call it “DB.cs”. This class will derive from your entities. It will look something like this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Helper.DataLayer
{
    public class DB : SurveyBuilderHelperEntities
    {      
        public DB() : base() { }      
    }
}
 
Next, we will implement the repository pattern. Add the following interface and class to your project: IRepository and Repository.
 
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
namespace Helper.DataLayer
{
    public interface IRepository : IDisposable
        where T : class
    {
        ///
        /// Gets all objects from database
        ///
        ///
        IQueryable All();
        ///
        /// Gets objects from database by filter.
        ///
        /// Specified a filter
        ///
        IQueryable Filter(Expression<Func<T, bool>> predicate);
        ///
        /// Gets objects from database with filting and paging.
        ///
        ///
        /// Specified a filter
        /// Returns the total records count of the filter.
        /// Specified the page index.
        /// Specified the page size
        ///
        IQueryable Filter(Expression<Func<T, bool>> filter, out int total, int index = 0, int size = 50);
        ///
        /// Gets the object(s) is exists in database by specified filter.
        ///
        /// Specified the filter expression
        ///
        bool Contains(Expression<Func<T, bool>> predicate);
        ///
        /// Find object by keys.
        ///
        /// Specified the search keys.
        ///
        T Find(params object[] keys);
        ///
        /// Find object by specified expression.
        ///
        ///
        ///
        T Find(Expression<Func<T, bool>> predicate);
        ///
        /// Create a new object to database.
        ///
        /// Specified a new object to create.
        ///
        T Create(T t);
        ///
        /// Delete the object from database.
        ///
        /// Specified a existing object to delete.
        int Delete(T t);
        ///
        /// Delete objects from database by specified filter expression.
        ///
        ///
        ///
        int Delete(Expression<Func<T, bool>> predicate);
        ///
        /// Update object changes and save to database.
        ///
        /// Specified the object to save.
        ///
        int Update(T t);
        void Refresh(T entity);
        ///
        /// Get the total objects count.
        ///
        int Count { get; }
    }
}
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
namespace Helper.DataLayer
{
    public class Repository : IRepository
        where TObject : class
    {
        private bool shareContext = false;
        public Repository()
        {
            Context = new DB();
        }
        public Repository(DB context)
        {
            Context = context;
            shareContext = true;
        }
        protected DB Context = null;
        protected DbSet DbSet
        {
            get
            {
                return Context.Set();
            }
        }
        public void Dispose()
        {
            if (shareContext && (Context != null))
                Context.Dispose();
        }
        public virtual IQueryable All()
        {
            return DbSet.AsQueryable();
        }
        public virtual IQueryable Filter(Expression<Func<TObject, bool>> predicate)
        {
            return DbSet.Where(predicate).AsQueryable();
        }
        public virtual IQueryable Filter(Expression<Func<TObject, bool>> filter, out int total, int index = 0, int size = 50)
        {
            int skipCount = index * size;
            var _resetSet = filter != null ? DbSet.Where(filter).AsQueryable() : DbSet.AsQueryable();
            _resetSet = skipCount == 0 ? _resetSet.Take(size) : _resetSet.Skip(skipCount).Take(size);
            total = _resetSet.Count();
            return _resetSet.AsQueryable();
        }
        public bool Contains(Expression<Func<TObject, bool>> predicate)
        {
            return DbSet.Count(predicate) > 0;
        }
        public virtual TObject Find(params object[] keys)
        {
            return DbSet.Find(keys);
        }
        public virtual TObject Find(Expression<Func<TObject, bool>> predicate)
        {
            return DbSet.FirstOrDefault(predicate);
        }
        public virtual TObject Create(TObject TObject)
        {
            var newEntry = DbSet.Add(TObject);
            if (!shareContext)
                Context.SaveChanges();
            return newEntry;
        }
        public virtual int Count
        {
            get
            {
                return DbSet.Count();
            }
        }
        public virtual int Delete(TObject TObject)
        {
            DbSet.Remove(TObject);
            if (!shareContext)
                return Context.SaveChanges();
            return 0;
        }
        public virtual int Update(TObject TObject)
        {
            var entry = Context.Entry(TObject);
            DbSet.Attach(TObject);
            entry.State = EntityState.Modified;
            if (!shareContext)
                return Context.SaveChanges();
            return 0;
        }
        public virtual int Delete(Expression<Func<TObject, bool>> predicate)
        {
            var objects = Filter(predicate);
            foreach (var obj in objects)
                DbSet.Remove(obj);
            if (!shareContext)
                return Context.SaveChanges();
            return 0;
        }
        public void Refresh(TObject entity)
        {
            Context.Entry(entity).Reload();
        }
    }
}
 
Basically what this repository pattern does is that it exposes all the methods that will be used to access our repository.  Now, for every table objects that we have in our database, we have to create a separate repository class inheriting from the above repository. Since, I have only one table right now, I will add a repository for that table by creating the following class file:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Helper.DataLayer
{
    public interface IQuestionEntryRepository: IRepository<QuestionEntry>
    {
    }
    public class QuestionEntryRepository : Repository<QuestionEntry>, IQuestionEntryRepository
    {
        public QuestionEntryRepository(DB context)
            : base(context)
        { }
    }
}
For other tables, you would have similar repositories with their own s.
Next, we implement the unit of work pattern. For this, we will create two interfaces: IUnitOfWork and IManageUnitOfWork.  The IUnitOfWork will inherit from IDisposable and the IManageUnitOfWork will inherit from IUnitOfWork.
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Helper.DataLayer
{
    public interface IUnitOfWork : IDisposable
    {
        int SaveChanges();
    }
    public interface IManageUnitOfWork : IUnitOfWork
    {
       
    }
}
Now, for every repositories we have, we will include a property of that type in our IManageUnitOfWork interface. So, since I have only one table right now, it looks like this for me:
public interface IManageUnitOfWork : IUnitOfWork
    {
        IQuestionEntryRepository QuestionEntries { get;}       
    }
 
 
But when I have my database ready with all other tables, it could look like this:
public interface IManageUnitOfWork : IUnitOfWork
    {
        IParticipantInfoRepository Participants { get; }
        IQuestionRepository Questions { get; }
        IQuestionEntryRepository QuestionEntries { get; }
        ISurveyHeaderRepository SureveyHeaders { get; }
        ISurveySectionRepository SurveySections { get; }
        IAnswerRepository Answers { get; }
        IInputTyperepository InputTypes { get; }
        ISessionTableRepository SessionTables { get; }
        IErrorLogRepository ErrorLogs { get; }
        ISkippedQuestionRepository SkippedQuestions { get; }
        IHouseholdPhotoRepository HouseholdPhotos { get; }
        IMultiTextAnswerRepository MultiTextAnswers { get; }
        IMultiSelectAnswerRepository MultiSelectAnswers { get; }
    }
 
 
What we are doing here is creating a centralized access to all our repositories. All of these repositories can be accessed easily from an implementation of our IManageUnitOfWork interface. Finally now, we will create this implementation and call it ManageUnitOfWork.cs.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Helper.DataLayer
{
    public class ManageUnitOfWork: IManageUnitOfWork
    {
        #regionFields
        private DB dbContext;
        private IQuestionEntryRepository questionEntries;
       
        #endregion
        #regionConstructor
        public ManageUnitOfWork(DB context)
        {
            dbContext = context;
        }
        #endregion
        #regionProperty
        public IQuestionEntryRepository QuestionEntries
        {
            get
            {
                if (questionEntries == null)
                    questionEntries = new QuestionEntryRepository(dbContext);
                return questionEntries;
            }
        }
        #endregion
        #regionUtility
        public int SaveChanges()
        {
            return dbContext.SaveChanges();
        }
        public void Dispose()
        {
            //if (categories != null)
            //    categories.Dispose();       
            if (dbContext != null)
                dbContext.Dispose();
            GC.SuppressFinalize(this);
        }
        #endregion
    }
}
Again, for every repositories, you will have a field and property value set up similar to this one.
This ends the setting up of the Unit of Work, Entity Framework repository pattern. This repository can now be accessed from your other projects in the following way:
using Helper.DataLayer;
using Helper.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Helper.Services.QuestionEntryService
{
    public class QuestionEntryService: IQuestionEntryService
    {
        ManageUnitOfWork context;
        DB db;
        public QuestionEntryService(DB _db)
        {
            db = _db;
            context = new ManageUnitOfWork(db);           
        }
        public int Create(QuestionEntryModel model)
        {
            QuestionEntry questionEntry = new QuestionEntry
            {
                EntryID = model.EntryID,
                SectionHeader = model.SectionHeader,
                SectionNumber = model.SectionNumber,
                QuestionText = model.QuestionText,
                OptionGroup = model.QuestionText,
                InputType = model.InputType,
                HasBranches = model.HasBranches,
                FurtherDesc = model.FurtherDesc
            };
            context.QuestionEntries.Create(questionEntry);
            context.SaveChanges();
            return questionEntry.EntryID;
        }
    }
}
That’s all!!
Thank you for taking time to read through all of this implementation tutorial. I hope it was helpful.

Flat File Splitter

At work the other day, I needed to write a program for splitting a text file (.txt) to smaller pieces. The file that we received from our client was a flat file of size of about 2.5 GB. I needed to import the contents of the file to our SQL Server database.  Since the file was in pipe delimited format with 33 columns of data elements, simply using Import feature of SQL would have solved the case for me. But the import turned out unsuccessful. There were some faulty rows that didn’t match up with the required format of 33 columns. So, I needed to open the file and check where the issue was, however because of the huge size of the file, text editor (notepad) couldn’t open the file. Thus, the following code was developed.
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Text;
namespace FileSplitter
{   
    class Program
    {
        static void Main(string[] args)
        {
            FileSplitter();
            // Suspend the screen.
            Console.WriteLine(“Program completed”);
            Console.ReadLine();
        }       
        /// 
        /// Reads the specified input file one line at a time and creates output file(s)         based upon the required number of lines
        /// to break the file with
        /// 
        public static void FileSplitter()
        {
            int counter = 0;
            int fileLengthLimit = int.Parse( ConfigurationManager.AppSettings[“lineLimit”]);
            int fileCursor = 0;
           
            string filePath = ConfigurationManager.AppSettings[“input”];
            string outputFile = ConfigurationManager.AppSettings[“outputDir”];
            //StringWriter allows to create/write new text files
            var output = new System.IO.StreamWriter(System.IO.Path.Combine(outputFile, string.Format(“1-{0}”, fileLengthLimit)));//output file
            //StringReader allows to read from text files
            var file = new StreamReader(filePath);//read file   
            string line=string.Empty;
            while ((line = file.ReadLine()) != null)
            {
                output.WriteLine(line);
                counter++;
                if (counter == fileLengthLimit)
                {
                    
                    output.Close();
                    fileCursor += counter;
                    Console.WriteLine(“finished processing line: “ + fileCursor);
                    output = new System.IO.StreamWriter(System.IO.Path.Combine(outputFile, string.Format(“{0}-{1}”, fileCursor, fileCursor + fileLengthLimit)));
                    counter = 0;
                }               
            }
            //          
            file.Close();
            output.Close();
        }       
    }   
}
App.Config
<?xml version=1.0?>
<configuration>
  <appSettings>
    <add key=input value=“”/>
    <add key=outputDir value=“”/>
    <add key=lineLimit value=“”/>
  </appSettings>
</configuration>
The code is pretty straight forward. The static method FileSplitter() opens the specified text file and reads one line of text at a time from the file. Then it writes output files with desired number of lines (file length limit) per file.  The input file path, output filepath and line limit needs to be provided from the config file.
I think I used 10000 lines per text file and got about 1200 output files. I forgot the exact numbers. Thankfully, the error with the file was in the last record i.e. in the last line of the file. It had only six elements instead of 33. Since, I looked at the last file output first, so I didn’t need to dig into more than one file.