Installing Xamarin components

Xamarin components are easy to install, all you have to do is to download a zip, extract the content and to reference the dlls in your project. This would work if you download the component manually from components gallery. Same thing can be done using Visual Studio in a more robust way via ‘Components’ under the targeting platform projects. Either way, the component will be downloaded and installed only for a specific project.

Sometimes it might be useful to keep the component in cache, so it will be available globally. This is where the XAM file extension comes into play. Generally speaking, it is just an archive, you can change the file extension to zip and use it in a regular way, or vice versa change zip to xam.

Regardless of your OS you have to download xamarin-component.exe.
On Windows execute the next command:

xamain.component.exe install <component.xam>

On MacOS execute the next command with the same executable:

mono xamain.component.exe install <component.xam>

If the command executed successfully, you should see the installed component:

Screen Shot 2017-11-14 at 21.20.30

Please note the “Included in this project” and “Installed on this machine”. Components under the second section will be always there unless you will clean the cache. On MacOS the components will be installed under ‘~/Library/Caches/Xamarin’. Please let me know where the cached components are stored on Windows.

Entity Framework DB First and Computed Columns

Imagine you have a lovely DB first approach in place. There is a table “Fruits” with a column “WikiLink”. This column is getting populated on insert, using a trigger on the DB level. Can you spot “the” problem here?

Let’s try to understand how EF returns the DB generated entity Id from the DB right after the insert. The code below demonstrates a standard way to insert a new entity with EF:

var fruit = new Fruit { Family = “Rosaceae”, Name = “Apple” };
dbContext.Fruits.Add(fruit);
await dbContext.SaveChangesAsync();
// fruit.Id is auto-generated on the DB level and accessible after insert
// fruid.WikiLink is null

The Id column marked as identity, therefor it is recognised as a value generated on DB level. If you will use a DB profiler you will actually see:

— T-SQL Pseudocode for -> dbContext.Fruits.Add(fruit);
INSERT INTO [dbo].[Fruits] (Family, Name)
VALUES (“Rosaceae”, “Apple”)
SELECT SCOPE_IDENTITY() as Id;

It is insert and select in one query. Now back to our problem with ‘WikiLink’. What we would like to achieve is:

INSERT INTO [dbo].[Fruits] (Family, Name)
VALUES (“Rosaceae”, “Apple”)
SELECT SCOPE_IDENTITY() as Id, WikiLink;

When you use a code first approach, you have an option of explicitly marking an entity’s property as db generated with an attribute:

[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public string WikiLink { get; set; }

However, with DB first approach you don’t have that option, and since there is a trigger behind this column, there is no way for EF to understand that it is generated on the DB level.

Unfortunately, it is not easily solvable with DB first approach. There are a couple of workarounds we could think about:

  1. We can try to manipulate “manually” the auto-generated edmx file and set the “WikiLink” to db computed. Which is a bad idea, because this change will get lost with the next model update as it is being regenerated on each change.
  2. Another option will be to query the DB right after the insert, to get the full row data:

var fruit = new Fruit { Family = “Rosaceae”, Name = “Apple” };
dbContext.Fruits.Add(fruit);
await dbContext.SaveChangesAsync();
await dbContext.Entry(fruit).ReloadAsync()
// fruid.WikiLink is not null anymore

The disadvantage is obvious – additional db query:

— T-SQL Pseudocode for -> dbContext.Fruits.Add(fruit);
INSERT INTO [dbo].[Fruits] (Family, Name)
VALUES (“Rosaceae”, “Apple”)
SELECT SCOPE_IDENTITY() as Id;

— T-SQL Pseudocode for -> await dbContext.Entry(fruit).ReloadAsync()
SELECT FROM * [dbo].[Fruits]
WHERE Id = 99;

However, it could be good enough for some projects.

If you can modify the DB scheme, the solution is quite simple – replace the trigger by a computed column:

— T-SQL Pseudocode for
alter table [dbo].[Fruits]
add [WikiLink] as concat(N’_ttp://mywiki.net/fruits?id=’, Id )

This way you may gain more performance. Since you may have a ‘RowVersion’ column which will be calculated twice because of the trigger. Not to mention that the DB structure is much more readable, compare to unnecessary trigger.

There might be another workarounds for this issue if you don’t have access or you can’t modify the DB. I would like to hear about your experience, so please share via comments.

Web.API 2 centralised model state validation

Model state validation is easy with DataAnnotations. However, you will find repeating the next line of code very soon:


if(!ModelState.IsValid) return BadRequest(..);

Luckily, there is a pretty simple solution – to use ActionFilter:

All you have to do is to add the ValidateModel attribute to your controller methods that require model state validation.

Entity Framework Database First Generalising Timestamps

Using Entity Framework is extremely easy and straight forward unless you have a large amount of entities and business rules to apply. You are lucky if you have a code first approach, however some times database first approach is in place and there are some limitations. For example, as the DbContext is autogenerated using T4, it is hard to introduce general behaviours, like updating CreatedAt, UpdatedAt and DeletedAt properties globally upon saving.

There could be different solutions for the problem I mentioned earlier, however there is a simple one that may work as well. Since all auto-generated files by EntityFramework marked as partial, we could easily extend them. Lets start!

Continue reading “Entity Framework Database First Generalising Timestamps”

Numeric keyboard with "Done" button on iOS Xamarin.Forms

‘Done’ button on Numeric keyboard on iOS is a very popular clients request, but it does not appear out of the box. Luckily the solution is very easy (as usual), all we have to do is to extend ‘Entry’ control and to add a custom renderer:
 
As you can see all the ‘magic’ is happing in AddDoneButton() method. We create a toolbar and add a ‘Done’ UIBarButtonItem which will hide the keyboard and send a ‘Completed’ event back.
The solution is based on this thread and available as a gist on github.

INotifyPropertyChange without boilerplate code in Xamarin.Forms

Implementing INotifyPropertyChange is pretty straightforward. Usually, you create a base ViewModel class which implements it and which usually contains RaisePropertyChanged method:

public abstract class BaseViewModel : INotifyPropertyChanged
{
    #region INotifyPropertyChanged
    public event PropertyChangedEventHandler PropertyChanged;

    protected void RaisePropertyChanged(
        [CallerMemberNamestring propertyName = )
    {
        PropertyChanged?.Invoke(thisnew PropertyChangedEventArgs(propertyName));
    }
    #endregion
}

Now you can extend the BaseViewModel and use it this way:

public class UserViewModel : BaseViewModel
{
    private string login;
    public string Login
    {
        get
        {
            return login;
        }
        set
        {
            if (login == value)
                return;
            login = value;
            RaisePropertyChanged();
        }
    }
    private string password;
    public string Password
    {
        get
        {
            return password;
        }
        set
        {
            if (password == value)
                return;
            password = value;
            RaisePropertyChanged();
        }
    }
}

For very small applications it can be a good enough approach, however, in bigger applications it turns into a lot of boring boilerplate code. Here is where NotifyPropertyChanged.Fody comes into play! With this nice package our code will turn into:


[ImplementPropertyChanged]
public abstract class BaseViewModel {}

public class UserViewModel : BaseViewModel
{
    public string Login { getset; }
    public string Password { getset; }
}

Easy as it is! I highly recommend to get familiar with the documentation as it contains a lot of useful information about more advanced flows. For example, if you need to RaisePropertyChange for dependent properties or to skip equality comparison.

UIDatePicker Countdown mode bug and solution in Xamarin.Forms

Problem

Show hh:mm:ss picker on iOS using Xamarin.Forms.

Goal

Extend Picker view in order to achieve the next result:

Solution

First I tried to keep it simple: to give up on seconds and use UIDatePicker in UIDatePickeCountDownMode. So the end result will look like this:

I achieved it by extending the DatePicker and it’s DatePickerRenderer and changing the mode as described above. However, I discovered that ‘datePickerValueChanged’ is being called only on a second iteration with the values. The issue was successfully reproduced in Swift, so it’s not a Xamarin bug. The Swift version can be found here.
After spending some time understanding the issue described above, I found an example on StackOverflow, thanks to Mathieu who shared his solution. His example was based on XLabs, so I removed the dependency and shared it with the community.
The code can be found on GitHub.

JSON.net Mastering enums

Problem

Legacy backend API endpoint returns JSON with units in an uncommon manner.
Instead of returning the measurement system “imperial” or “metric” it returns “kgs” or “lbs”.

Goal

Using JSON.net deserialize & serialize “kgs” to “metric” and “lbs” to “imperial” in our front-end app.

Solution

The solution is pretty simple. We have to define an enum, with “EnumMember” attributes on each element and use “StringEnumConverter” as preferred JsonConvertor. Here is the full and working example:

using System;
using System.Runtime.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

namespace JSONnetEnums
{
    class Program
    {
        static void Main(string[] args)
        {
            var deserializedObj = 
                JsonConvert.DeserializeObject<Foo>(“{\”Unit\”:\”kgs\”});
            Console.WriteLine(deserializedObj.Unit);
            // Output: Metric

            var serializedObj = 
                JsonConvert.SerializeObject(new Foo { Unit = Unit.Imperial });
            Console.WriteLine(serializedObj);
            // Output: {“Unit”:”lbs”}
        }
    }

    class Foo
    {
        public Unit Unit { getset; }
    }

    [JsonConverter(typeof(StringEnumConverter))]
    enum Unit
    {
        [EnumMember(Value = kgs)]
        Metric,
        [EnumMember(Value = lbs)]
        Imperial
    }
}

JSON.net snake case notation naming strategy

Communicating with backend in JSON can be challenging.
In case of C# model which by convention should be in CamelCase notation and backend which is using snake_notation we can easily solve the problem with Json.NET.

For example, we have the next model:

public class Model
{
public string FooBar { get; set; }
}

and we want it to be serialised to: { “foo_bar”: “” }
We could use an attribute:

[JsonProperty(PropertyName = "foo_bar")]
public string FooBar { get; set; }

That will work, however, if we want to generalise this strategy we should create a JsonSerializerSettings with DefaultContactResolver which is using SnakeCaseNamingStrategy and to use it while serialisation/deserialization:

public class JsonCoverter : IJsonConverter
{
private static JsonSerializerSettings defaultJsonSerializerSettings =
new JsonSerializerSettings
{
ContractResolver = new DefaultContractResolver
{
NamingStrategy = new SnakeCaseNamingStrategy()
}
};

public T Deserialize(string json) =>
JsonConvert.DeserializeObject(json, defaultJsonSerializerSettings);

public string Serialize(object obj) =>
JsonConvert.SerializeObject(obj, defaultJsonSerializerSettings);

}

Using the JsonConverter globally will solve the different notation problem.

How to debug an iOS app build in Xamarin on a real device for free?

“With Apple’s release of Xcode 7 came an important change for all iOS and Mac developers–free provisioning.”

So all you need is an apple id and to configure your IDE.
There are a lot of guides available out there, so this post is not going to be another one:
– Xamarin Developer Guide
http://stackoverflow.com/a/32249026/1970317

One thing that can be confusing is that first, you need to create a Xcode project with the same “Bundle Identifier” and then download the free provisioning profile. Just pay attention to the uniqueness of your bundle identifier otherwise, it won’t work.