Posts in Category: Xamarin

Validation in Xamarin.Forms Enterprise Apps 

animation We released an eBook this past May on Enterprise Application Patterns using Xamarin.Forms. The eBook focuses on core patterns and architectural guidance for developing Xamarin.Forms enterprise apps that are easier to test, maintain, and evolve. Guidance is provided on how to implement the Model-View-ViewModel (MVVM) pattern, dependency injection, navigation, validation, and configuration management, while maintaining loose coupling. In addition, there’s also guidance on performing authentication and authorization with IdentityServer, accessing remote data from containerized microservices, and unit testing.

This blog post explores validation in Xamarin.Forms enterprise apps. There are, of course, many approaches that can be taken to validation. What’s presented here is the validation approach taken in the eShopOnContainers mobile app, which is extensible, easily unit testable, and supports data binding and property change notification.

Introduction

Any app that accepts input from users should ensure that the input is valid. An app could, for example, check for input that contains only characters in a particular range, is of a certain length, or matches a particular format. Without validation, a user can supply data that causes the app to fail. Validation enforces business rules, and prevents an attacker from injecting malicious data.

In the context of the Model-ViewModel-Model (MVVM) pattern, a view model or model will often be required to perform data validation and signal any validation errors to the view so that the user can correct them. The eShopOnContainers mobile app performs synchronous client-side validation of view model properties and notifies the user of any validation errors by highlighting the control that contains the invalid data, and by displaying error messages that inform the user of why the data is invalid. The following diagram shows the classes involved in performing validation in the eShopOnContainers mobile app:

View model properties that require validation are of type ValidatableObject<T>, and each ValidatableObject<T> instance has validation rules added to its Validations property. Validation is invoked from the view model by calling the Validate method of the ValidatableObject<T> instance, which retrieves the validation rules and executes them against the ValidatableObject<T> Value property. Any validation errors are placed into the Errorsproperty of the ValidatableObject<T> instance, and the IsValid property of the ValidatableObject<T> instance is updated to indicate whether validation succeeded or failed.

Property change notification is provided by the ExtendedBindableObject class, and so an Entrycontrol can bind to the IsValid property of the ValidatableObject<T> instance in the view model class to be notified of whether or not the entered data is valid.

Specifying Validation Rules

Validation rules are specified by creating a class that derives from the IValidationRule<T>interface, which is shown in the following code example:

 

public interface IValidationRule<T>
{
    string ValidationMessage { get; set; }
    bool Check(T value);
}

 

This interface specifies that a validation rule class must provide a boolean Check method that is used to perform the required validation, and a ValidationMessage property whose value is the validation error message that will be displayed if validation fails.

The following code example shows the IsNotNullOrEmptyRule<T> validation rule, which is used to perform validation of the username and password entered by the user on the LoginView when the eShopOnContainers mobile app is configured to use mock services:

 

public class IsNotNullOrEmptyRule<T> : IValidationRule<T>
{
    public string ValidationMessage { get; set; }
    public bool Check(T value)
    {
        if (value == null)
        {
            return false;
        }
        var str = value as string;
        return !string.IsNullOrWhiteSpace(str);
    }
}

 

The Check method returns a boolean indicating whether the value argument is null, empty, or consists only of whitespace characters.

Adding Validation Rules to a Property

In the eShopOnContainers mobile app, view model properties that require validation are declared to be of type ValidatableObject<T>, where T is the type of the data to be validated. The following code example shows an example of one such property:

 

public ValidatableObject<string> UserName
{
    get
    {
        return _userName;
    }
    set
    {
        _userName = value;
        RaisePropertyChanged(() => UserName);
    }
}

 

For validation to occur, validation rules must be added to the Validations collection of the ValidatableObject<T> instance, as demonstrated in the following code example:

 

private void AddValidations()
{
    _userName.Validations.Add(new IsNotNullOrEmptyRule<string> 
    { 
        ValidationMessage = "A username is required." 
    });
}

 

This method adds the IsNotNullOrEmptyRule<T> validation rule to the Validations collection of the ValidatableObject<T> instance, including a value for the ValidationMessage property, which specifies the validation error message that will be displayed if validation fails.

Triggering Validation

Validation can be triggered manually for a view model property. For example, this occurs in the eShopOnContainers mobile app when the user taps the Login button on the LoginView, when using mock services. The command delegate calls the MockSignInAsync method in the LoginViewModel, which invokes validation by executing the Validate method, which in turn invokes the ValidateUserName method:

 

private bool ValidateUserName()
{
    return _userName.Validate();
}

 

The ValidateUserName method performs validation of the username entered by the user on the LoginView, by invoking the Validate method on the ValidatableObject<T> instance. The following code example shows the Validate method from the ValidatableObject<T> class:

 

public bool Validate()
{
    Errors.Clear();
    IEnumerable<string> errors = _validations
        .Where(v => !v.Check(Value))
        .Select(v => v.ValidationMessage);
    Errors = errors.ToList();
    IsValid = !Errors.Any();
    return this.IsValid;
}

 

This method clears the Errors collection, and then retrieves any validation rules that were added to the object’s Validations collection. The Check method for each retrieved validation rule is executed, and the ValidationMessage property value for any validation rule that fails to validate the data is added to the Errors collection of the ValidatableObject<T> instance. Finally, the IsValid property is set, and its value is returned to the calling method, indicating whether validation succeeded or failed.

Validation is also automatically triggered whenever a bound property changes. For more information, see Triggering Validation when Properties Change.

Displaying Validation Errors

The eShopOnContainers mobile app notifies the user of any validation errors by highlighting the control that contains the invalid data with a red line, and by displaying an error message that informs the user why the data is invalid below the control containing the invalid data. The following screenshot shows part of the LoginView in the eShopOnContainers mobile app when a validation error is present:

Highlighting a Control that Contains Invalid Data

The LineColorBehavior attached behavior is used to highlight Entry controls where validation errors have occurred. The following code example shows how the LineColorBehavior attached behavior is attached to an Entry control:

 

<Entry Text="{Binding UserName.Value, Mode=TwoWay}">
    <Entry.Style>
        <OnPlatform x:TypeArguments="Style"
          iOS="{StaticResource EntryStyle}"
          Android="{StaticResource EntryStyle}"
          WinPhone="{StaticResource UwpEntryStyle}"/>
    </Entry.Style>
    ...
</Entry>

 

The Entry control consumes an explicit style, which is shown in the following code example:

 

<Style x:Key="EntryStyle"
       TargetType="{x:Type Entry}">
    ...
    <Setter Property="behaviors:LineColorBehavior.ApplyLineColor"
            Value="True" />
    <Setter Property="behaviors:LineColorBehavior.LineColor"
            Value="{StaticResource BlackColor}" />
    ...
</Style>

 

This style sets the ApplyLineColor and LineColor attached properties of the LineColorBehaviorattached behavior on the Entry control. When the value of the ApplyLineColor attached property is set, or changes, the LineColorBehavior attached behavior executes the OnApplyLineColorChanged method, which adds or removes the EntryLineColorEffect class to the Entry‘s Effects collection. For more information about the EntryLineColorEffect class, see Highlighting a Control that Contains Invalid Data.

The Entry control also has a DataTrigger added to its Triggers collection. The following code example shows the DataTrigger:

 

<Entry Text="{Binding UserName.Value, Mode=TwoWay}">
    ...
    <Entry.Triggers>
        <DataTrigger 
            TargetType="Entry"
            Binding="{Binding UserName.IsValid}"
            Value="False">
            <Setter Property="behaviors:LineColorBehavior.LineColor" 
                    Value="{StaticResource ErrorColor}" />
        </DataTrigger>
    </Entry.Triggers>
</Entry>

 

This DataTrigger monitors the UserName.IsValid property, and if it’s value becomes false, it executes the Setter, which changes the LineColor attached property of the LineColorBehaviorattached behavior to red.

Displaying Error Messages

The UI displays validation error messages in Label controls below each control whose data failed validation. The following code example shows the Label that displays a validation error message if the user has not entered a valid username:

 

<Label Text="{Binding UserName.Errors, Converter={StaticResource FirstValidationErrorConverter}"
       Style="{StaticResource ValidationErrorLabelStyle}" />

 

Each Label binds to the Errors property of the view model object that’s being validated. The Errors property is provided by the ValidatableObject<T> class, and is of type List<string>. Because the Errors property can contain multiple validation errors, the FirstValidationErrorConverter instance is used to retrieve the first error from the collection for display.

Summary

Enterprise Application Patterns using Xamarin.Forms focuses on core patterns and architectural guidance for developing Xamarin.Forms enterprise apps that are easier to test, maintain, and evolve. The eBook also ships with a sample application, the eShopOnContainers mobile app, which performs synchronous client-side validation of view model properties and notifies the user of any validation errors by highlighting the control that contains the invalid data, and by displaying error messages that inform the user why the data is invalid.

The post Validation in Xamarin.Forms Enterprise Apps appeared first on Xamarin Blog.

Posted by Andrew Tierney Friday, August 18, 2017 10:41:00 PM Categories: C# Xamarin

Adding Storage to Mobile Apps with OneDrive for Business 

Every app needs storage, whether it’s for storing a collection of the same type of records in Azure Mobile Service with Easy Tables, or a SQL Database exposed via Web Services. When the data is unstructured, NoSQL with Azure DocumentDB can be used. For scalability and high availability, Azure CosmosDb can be used in both the cases. In enterprise situations, however, where different types of documents need to be stored and shared with colleagues, the best solution is OneDrive for Business. OneDrive for Business is part of Office 365 and provides easy access across multiple Office 365 services. We learned previously how to integrate OneDrive for Business in mobile apps developed using Xamarin.

Since then, there have been changes to APIs and SDKs that have made this integration simpler. We’ll take a look at those changes in this blog post. You can find the repo for this post on GitHub.

Step 1: App Registration

To integrate OneDrive for Business with mobile apps, the app needs to be registered with the Azure Active Directory service. This will authenticate and authorize users while providing access to the resources. The process is the same as registering any other app with Azure Active Directory.

Visit https://apps.dev.microsoft.com/ and click on Add an app to get started. Name your app and continue, making sure you note the Application Id. Click on Add Platorm and select Native Application.

Ensure you define Delegated Permissions for the application to be able to access files stored on OneDrive for Business:

  • Files.Read
  • Files.Read.All
  • Files.Read.Selected
  • Files.ReadWrite
  • Files.ReadWrite.All
  • User.Read

Step 2: Calling APIs

Once the app is registered, create a Blank Xamarin.Forms application with the PCL code sharing strategy. Make sure that the profile selected for PCL is set to Profile7 by right-clicking the PCL project and selecting Properties > Build > General. Add two NuGet packages: Microsoft.Identity.Client and Microsoft.Graph.

Use the Microsoft Authentication Library (MSAL) to authenticate the user in the code-behind in App.xaml.cs.

 

using Microsoft.Identity.Client;
...
public static PublicClientApplication IdentityClientApp = null;
public static string ClientID = "4f91166f-c946-438f-8d07-33792251026d";
public static string[] Scopes = { "User.Read", "User.ReadBasic.All", "Files.Read", "Files.Read.All", "Files.ReadWrite", "Files.ReadWrite.All" };
public static UIParent UiParent = null;
public App()
{
   InitializeComponent();
   MainPage = new XamarinDrive.MainPage();
   IdentityClientApp = new PublicClientApplication(ClientID);
   MainPage = new NavigationPage(new MainPage());
}

 

After the authentication process is complete, create a GraphServiceClient object which will be responsible for further requests in the code-behind for MainPage.xaml.cs.

 

using Microsoft.Graph;
using Microsoft.Identity.Client;
...
private async Task CreateGraphClientAsync()
{
   try {
      Client = new GraphServiceClient("https://graph.microsoft.com/v1.0",
               new DelegateAuthenticationProvider(
               async (requestMessage) =&gt; {
                         var tokenRequest = await App.IdentityClientApp.AcquireTokenAsync(App.Scopes, App.UiParent).ConfigureAwait(false);
                         requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", tokenRequest.AccessToken);
                }));
                Me = await Client.Me.Request().GetAsync();
                Username.Text = $"Welcome {((User)Me).DisplayName}";
                return true;
       }
       catch (MsalException ex){
            await DisplayAlert("Error", ex.Message, "OK", "Cancel");
            return false;
       }
}

 

Using this GraphServiceClient and Graph Model, traverse through the Drive and get a list of items (files and folders) within the drive. Assign this list of items to the listview control in ListPage.xaml.cs.

 

using Microsoft.Graph;
...
var client = new GraphServiceClient("https://graph.microsoft.com/v1.0",
                new DelegateAuthenticationProvider(
                async (requestMessage) =&gt;
                {
                   var tokenRequest = await App.IdentityClientApp.AcquireTokenSilentAsync(App.Scopes, App.IdentityClientApp.Users.FirstOrDefault());
                   requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", tokenRequest.AccessToken);
                }));
var data = await client.Me.Drive.Root.Children.Request().GetAsync();
var list = data.ToList();
FileList.ItemsSource = list;

 

This list of DriveItems will then be displayed on ListPage using the binding with ListView. When a user clicks on an item inside List, the file will be opened as requested. This can be achieved with the OnItemTapped event.

 

var item = ((DriveItem) e.Item);
   if (item.Folder != null)
      await DisplayAlert("Type", "Selected Item is a Folder!", "Ok");
   else
      Xamarin.Forms.Device.OpenUri(new Uri(item.WebUrl));

 

Just like any Xamarin.Forms app is required to implement platform-specific functionality differently, follow the guide for each individual platform to implement authentication from here.

Step 3: Running the App

Run the app on a device or simulator and log in with your Office 365 credentials. The app will ask for appropriate permissions. Once those permissions are granted, the app will display the list of files.

Wrapping Up

OneDrive for Business, which is part of Office 365, allows users to store, share, and collaborate with different types of documents. Using Microsoft Graph Client Libraries and Microsoft Authentication Library, it’s easy to integrate various Office 365 services such as OneDrive. As usual, you can find the sample used in this blog post on GitHub.

The post Adding Storage to Mobile Apps with OneDrive for Business appeared first on Xamarin Blog.

Posted by Andrew Tierney Friday, August 18, 2017 10:39:00 PM Categories: C# Xamarin

Getting Started with C# 7 

The releases of Visual Studio 2017 and Visual Studio for Mac introduced two spectacular new IDEs to develop mobile applications, cloud workloads, and introduced us to a world of powerful new C# features with the release of C# 7. I recently blogged about my favorite new feature, expression bodied members, and even recorded an entire podcast about how awesome C# 7 is. In this blog post, I’ll show you how to get started with C# 7 and some of features that you can take advantage of right away in your mobile apps.

Tuples!

When you want to return multiple values from a function, Tuples are the way to go. C# 7 provides rich syntax and functionality that make Tuples a first class citizen with the introduction of the System.ValueTuple NuGet package. After installing the NuGet, we’re ready to start using Tuples as lightweight data structures with full IntelliSense.

Tuple Declaration

We can now create Tuples in several ways:

 

var names = ("James", "Montemagno");

 

As you can see, this automatically creates a Tuple with members of Item1 and Item2, but we can do better!

 

(string First, string Last) names = ("James", "Montemagno");

Or…

var names = (First: "James", Last: "Montemagno");
// accessed with:
var first = names.First;

 

Returning Tuples

Now that we know how to declare tuples, we can use them in a method:

 

static (string First, string Last) GetName(int index)
{
   var first = string.Empty;
   var last = string.Empty;
   // Go to database and get names
   var person = GetPersonFromDatabase(index);
   first = person.FirstName;
   last = person.LastName;
   return (first, last);
}

 

Then we can simply call the method:

 

var name = GetName(1);
Console.WriteLine($"My name is {name.First} {name.Last}.")

Or…

(string first, string last) = GetName(1);
Console.WriteLine($"My name is {first} {last}.")

 

You can also use full async/await support with Tasks!

 

static async Task<(string First, string Last)> GetName(int index)
{
   var first = string.Empty;
   var last = string.Empty;
   // Go to database and get names
   var person = await GetPersonFromDatabaseAsync(index);
   first = person.FirstName;
   last = person.LastName;
   return (first, last);
}

 

More Expression-Bodied Members

I can’t talk about C# 7 without mentioning my favorite feature, expression-bodied members, which were introduced in C# 6 and greatly enhanced in C# 7. Here’s how they improved our code in C# 6, using our good friend OnPropertyChanged as an example.

 

public void OnPropertyChanged(string name)
{
  var changed = PropertyChanged;
  if(changed == null)
    return;
  changed(this, new PropertyChangedEventArgs(name));
}

 

Now, with expression-bodied members we can write this:

 

public void OnPropertyChanged(string name)=>
  PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));

 

Amazing! However, in C# 7 things get even better. Take a look at the standard get and set accessors that I use all the time:

 

public string Subtitle
{
  get { return subtitle; }
  set { SetProperty(ref subtitle, value); }
}

 

Look at all of those { and }, well no more! Here is some C# 7 for you:

 

public string Subtitle
{
    get => subtitle;
    set => SetProperty(ref subtitle, value);
}

 

They can now also be applied to constructors, finalizers, and indexers!

 

public ExpressionMembers(string label) => this.Label = label;

 

Pattern Matching

I love expression-bodied members, but I have to admit Pattern Matching is an absolutely delightful feature when using switch and is expressions. At its core, it enables us to inspect an object and determine if it satisfies a specific pattern that we’re expecting.

The most simple example is when you receive an Object type and need to figure out what it is. Let’s say we have a base class of Animal with several derived classes from it for specific animal types:

 

bool LikesBananas(object item)
{
   var monkey = item as Monkey;
   if(monkey != null)
      return monkey.LikesBananas;
   // or perhaps this way:
   if(item is Animal)
   {
      var animal = (Animal)item;
      return animal.FavoriteFood == "Banana";
   }
   return false;
}

 

Now, we can simplify this by combining pattern matching and the code expression and casting the item in line:

 

bool LikesBananas(object item)
{
   var monkey = item as Monkey;
   if(item is Monkey monkey)
      return monkey.LikesBananas;
   if(item is Animal animal)
     return animal.FavoriteFood == "Banana";
   return false;
}

 

Pattern Matching doesn’t stop there, as we can use it in switch cases as well:

 

int TotalAnimalsThatLikeBananas(IEnumberable values)
{
   int count = 0;
   foreach(var item in values)
   {
      switch(item)
      {
         case Monkey monkey:
            count += (monkey.LikesBananas ? 1 : 0);
            break;
         case IEnumberable subList:
            count += TotalAnimalsThatLikeBanans(subList);
            break;
         case Animal animal:
            count += (animal.FavoriteFood == "Banana" ? 1 : 0);
            break;
         case null:
            // maybe throw an exception?
            break;
         case default:
            break;
      }
   }
   return count;
}

 

Awesome out variables

This one is pretty straight-forward, but also extremely powerful. When using a method that has an out variable, you always have to declare it ahead of time, as such:

 

int result = 0;
if (!int.TryParse(input, out result))
{
    return null;
}
return result;

 

Not anymore! Now we can simply declare the variable inline and use it anywhere!

 

if (!int.TryParse(input, out int result))
{
    // result can be accessed here if we needed to
    return null;
}
return result;

 

Learn More

These are just a few of the new features that can be found in C# 7, which you can start using today in Visual Studio 2017 and Visual Studio for Mac. Be sure to read through the entire C# 7 documentation to learn more about all of the other exciting new features available to you right now.

The post Getting Started with C# 7 appeared first on Xamarin Blog.

Posted by Andrew Tierney Friday, August 4, 2017 10:40:00 PM Categories: .NET Xamarin

“Xamarin University Presents” Webinar Recordings 

Thousands of developers have attended this year’s Xamarin University Presents webinar series, and we’ve had a great time introducing developers to the breadth of apps they can build with Xamarin Tools for Visual Studio. We’ve just wrapped up FIVE NEW webinars, covering topics that range from building your first cloud-connected game with SpriteKit to adding intelligent APIs with Machine Learning. Combined with the earlier videos, these new webinar recordings help provide you with everything you need to ship amazing mobile apps using the IDE, language, and code you know and love.

Two of our most popular webinars in this second round of topics were Introduction to Xamarin.Forms for Visual Studio 2017 and SkiaSharp Graphics for Xamarin.Forms with Charles Petzold, which you can find in full below. Head to the full playlist here to access all of the Xamarin University Presents webinar recordings, including the first five in the series and the other three from last month, Building games for iOS, macOS, and tvOS with Visual Studio and AzureCustomizing Xamarin.Forms UI, and Introduction to Azure Machine Learning.

Introduction to Xamarin.Forms for Visual Studio 2017

 

 

SkiaSharp Graphics for Xamarin.Forms

 

 

Don’t miss the other eight videos in the Xamarin University Presents series—head to the full playlist to learn about everything from building your first Xamarin.Forms app with Xamarin for Visual Studio to building games for iOS, macOS, and tvOS with Visual Studio and Azure.

 

Full Playlist

 

 

The post “Xamarin University Presents” Webinar Recordings appeared first on Xamarin Blog.

Posted by Andrew Tierney Saturday, July 8, 2017 6:13:00 PM Categories: .NET Xamarin

Going Global with Xamarin and Azure Cosmos DB 

-- The post Going Global with Xamarin and Azure Cosmos DB appeared first on Xamarin Blog.

Imagine that MyTeaCompany is a locally renowned business in Pune, India, supplying tea to the area from their ten shops within the city. They supply a huge variety of teas from Darjeeling to Assam and Thai to Korean, among others. They decide they want to take their business to the next level and create a worldwide presence on the internet.

Today, we’re going to take a look at how utilizing the Azure Cosmos DB database solution in their new Xamarin mobile app can help them leverage a wider customer-base on the global platform.

Building the Azure Cosmos DB solution

Azure Cosmos DB is a scalable, globally distributable solution for all your data requirements. It supports different models, including Graph, Table, and DocumentDb, with APIs available in different technologies, such as .NET, Python and Java. This makes it the perfect solution for all of MyTeaCompany’s data needs.

You can use the Azure Cosmos DB Emulator for developing and testing apps locally. However, for today’s blog post, we’ll use our Microsoft Azure Subscription.

Create an Azure Cosmos DB Account

Head to Azure Portal and create an Azure Cosmos DB account using the ‘+’ sign and navigating to Databases > Azure Cosmos DB. Once created, click on “Keys” and note the details, as those will be required in future steps.

It’s important to decide on the partition key, which helps to span data across servers or partitions, when creating a collection. It’s also important to carefully select your Request Units(RUs), which can play a major role in expected performance. The guide on the Request Unit Calculator is a great resource to help you gauge your requirements.

Xamarin.Forms Mobile App

Since we’re targeting multiple platforms, Xamarin.Forms is the perfect choice for MyTeaCompany, allowing us to maximize code sharing while still being able to use the native controls and features of each individual platform.

Create a Xamarin.Forms Project

In Visual Studio 2017, create a Xamarin.Forms solution by selecting New Project… > Cross-Platform > Cross-Platform App (Xamarin) > Blank / Shared Project. We’ll want to add the Microsoft.Azure.DocumentDB.Core NuGet package to the projects in order to use the package responsible for communicating with the Cosmos DB services.

Define Endpoint Constants

We need to define the endpoints in the Constants.cs file in order to connect the Xamarin.Forms application with Cosmos DB:

 

//copy details from your Keys section here
public static readonly string EndpointUri = "https://my-tea-company.documents.azure.com:443/";
public static readonly string PrimaryKey = "SKAF9lv43HeXicHgH-----------2yiFff7HPBOyFV0A==";
public static readonly string DatabaseName = "my-tea-company";
public static readonly string CollectionName = "my-tea-company";

 

Our model is StoreInfo which represents the MyTeaCompany store details.
StoreInfoManager is the helper class that wraps around IDocumentDBService. This class helps us perform CRUD operations on our data. The DocumentDBService class implements IDocumentDBService and uses the details provided in the Constants.cs file to perform these CRUD operations.

 

class DocumentDBService : IDocumentDBService
{
   DocumentClient client;
   Uri collectionLink;
   public DocumentDBService()
   {
      client = new DocumentClient(new Uri(Constants.EndpointUri), Constants.PrimaryKey);
      collectionLink = UriFactory.CreateDocumentCollectionUri(Constants.DatabaseName, Constants.CollectionName);
   }
...
}

 

Going Global

After MyTeaCompany deploys their app using Azure Cosmos DB and Xamarin, they see a huge opportunity in Seattle, WA. They decide to open a store there and start serving customers through the existing app. With few changes the app can be configured to serve users in that geographic area. First, they needed to replicate the store and product data to the new Azure Regions, which can be done from the Azure Portal.

Once the the data is replicated, using ConnectionPolicy nearest Azure Regions could be set as PreferredLocations to keep the latency low.

 

public DocumentDBService()
{
   ConnectionPolicy connectionPolicy = new ConnectionPolicy();
   connectionPolicy.PreferredLocations.Add(LocationNames.WestUS);
   client = new DocumentClient(new Uri(Constants.EndpointUri), Constants.PrimaryKey, connectionPolicy);
   collectionLink = UriFactory.CreateDocumentCollectionUri(Constants.DatabaseName, Constants.CollectionName);
}

 

By making two simple changes, the entire solution was made available in an entirely new region. Tomorrow, if MyTeaCompany wanted to open a store in Europe, they could expand their reach to the region in just a couple of clicks.

Conclusion

Azure Cosmos DB makes it easy to build globally distributed, scalable, highly available and low latency data solutions, which can be easily integrated with Xamarin mobile apps. You can check out the completed sample described in this post here and the documentation for Azure Cosmos DB can be found here. You can also see our guide on Storing Data in a Document Database for more information.

 

Posted by Andrew Tierney Sunday, July 2, 2017 8:38:00 PM Categories: Xamarin

Xamarin Workbooks 

Overview

Xamarin Workbooks provide a blend of documentation and code that is perfect for experimentation, learning, and creating guides and teaching aids.

Create a rich C# workbook for Android, iOS, Mac, WPF, or Console, and get instant live results as you learn these APIs.

Give it a try and let us know what you think, or if you run into any bugs. We have a forum too!

 

Installation and Requirements

Information on getting Workbooks installed on your Mac or Windows computer.

 

Interactive Workbooks

An introduction to how to use Xamarin Workbooks.

 

Samples

There are a wide variety of sample workbooks available, including those highlighted here.

 

Integration SDK

It is possible to extend Xamarin Workbooks with custom data representations and renderers. Integrations are written with C# and TypeScript/JavaScript.

Posted by Andrew Tierney Wednesday, June 28, 2017 9:35:00 AM Categories: .NET Xamarin

Adding Face Tracking and Live Recognition to your Android App 

Camera apps today can do so much more than just take perfect photos. Whether it’s adding filters to your image or letting you adjust focus and exposures manually, apps can essentially transform you into a professional photographer. While numerous apps in the app store let you do many things with the camera, there are others that do clever manipulation of your images in real time, such as adding a custom mask to your face, manipulating your face to look older or younger, and more. Social media apps today have this intelligence baked in, so you don’t have to open another app to make your selfies look extraordinary before you share them with friends and family.

Whether you’re building a consumer app that provides fun filters or an enterprise app that recognizes receipts, adding intelligent tires like these gives you an edge over others. With services like the Microsoft Cognitive Services API, you can quickly analyze and process your photos by adding just few lines of code.

In this post, you’ll learn how to display a camera within the Android app, add face tracking using Google’s Mobile Vision APIs and recognize the person in front of the camera using Microsoft Cognitive Services’ Face API.

Face Detection

Adding Face Tracking to Your App

Google’s Mobile Vision provides a set of APIs for “Detecting Face”, “Recognizing Text”, and “Scanning Barcodes”. For this example, I’ll be using the Face APIs to detect human faces from the live camera stream within the app.

To get started, add the Xamarin.GooglePlayServices.Vision NuGet package.

To access the camera on Android, you need to request the user’s permission and add the camera feature to your Android manifest:

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

if (ActivityCompat.CheckSelfPermission(this, Manifest.Permission.Camera) == Permission.Granted)

{

    CreateCameraSource();

    //...

}

else

{

Log.Warn(TAG, "Camera permission is not granted. Requesting permission");

 

var permissions = new string[] { Manifest.Permission.Camera };

 

if (!ActivityCompat.ShouldShowRequestPermissionRationale(this,

        Manifest.Permission.Camera))

{

    ActivityCompat.RequestPermissions(this, permissions, RC_HANDLE_CAMERA_PERM);

    return;

}

 

Snackbar.Make(mGraphicOverlay, Resource.String.permission_camera_rationale,

        Snackbar.LengthIndefinite)

        .SetAction(Resource.String.ok, (o) => { ActivityCompat.RequestPermissions(this, permissions, RC_HANDLE_CAMERA_PERM); })

        .Show();

}

 

Create Camera Source

The FaceDetector.Builder instantiates the FaceDetector with the specified properties. In this example, we use the default face detector settings and associate a processor to it.

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

private void CreateCameraSource()

{

 

    var context = Application.Context;

    FaceDetector detector = new FaceDetector.Builder(context)

            .SetClassificationType(ClassificationType.All)

            .Build();

 

    detector.SetProcessor(

            new MultiProcessor.Builder(this)

                    .Build());

 

    if (!detector.IsOperational)

    {

        // Note: The first time that an app using face API is installed on a device, GMS will

        // download a native library to the device in order to do detection.  Usually this

        // completes before the app is run for the first time.  But if that download has not yet

        // completed, then the above call will not detect any faces.

        //

        // isOperational() can be used to check if the required native library is currently

        // available.  The detector will automatically become operational once the library

        // download completes on the device.

        Log.Warn(TAG, "Face detector dependencies are not yet available.");

    }

 

    mCameraSource = new CameraSource.Builder(context, detector)

            .SetRequestedPreviewSize(640, 480)

            .SetFacing(CameraFacing.Front)

            .SetRequestedFps(30.0f)

            .Build();

 

    

}

 

In the above code, a MultiProcessor is used to receive detection results and CameraSource.Builder instantiates a camera source with a specified Preview Size, Camera Facing, and required fps.

Show a Live Stream from the Camera

Now that we have access to the camera and the CameraSource is already built, we can start the preview on a custom SurfaceView; in this case CameraSourcePreview.
GraphicOverlay instance is also passed in so that the face border can be drawn at the time detection.

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

private void StartCameraSource()

{

 

    // check that the device has play services available.

    int code = GoogleApiAvailability.Instance.IsGooglePlayServicesAvailable(

            this.ApplicationContext);

    if (code != ConnectionResult.Success)

    {

        var dlg =

                GoogleApiAvailability.Instance.GetErrorDialog(this, code, RC_HANDLE_GMS);

        dlg.Show();

    }

 

    if (mCameraSource != null)

    {

        try

        {

            mPreview.Start(mCameraSource, mGraphicOverlay);

        }

        catch (System.Exception e)

        {

            Log.Error(TAG, "Unable to start camera source.", e);

            mCameraSource.Release();

            mCameraSource = null;

        }

    }

}

 

The ideal place to call the StartCameraSource() is in the OnResume() of the Activity, while the OnPause()should stop the preview. It will ensure the camera resources are used only when the user is using the app.

Detect Faces

Every image frame received from the camera source may contain multiple faces, and each face corresponds to a distinct face identity which is represented by the Tracker created by the multiprocessor.

Implement IFactory to capture each Face

MultiProcessor requires an implementation of IFactory to callback when a human Face is detected in the camera. In this example, IFactory is implemented within the MainActivity, that has the Create():

 

1

2

3

4

public Tracker Create(Java.Lang.Object item)

{

    return new GraphicFaceTracker(mGraphicOverlay, mCameraSource);

}

 

In the above code, a new instance of GraphicFaceTracker is created for every detected face, and each of it builds a face box graphic object over the video stream using the GraphicOverlay view passed in the constructor.

Below is the implementation of the GraphicFaceTracker

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

class GraphicFaceTracker : Tracker

{

    private GraphicOverlay mOverlay;

    private FaceGraphic mFaceGraphic;

 

    public GraphicFaceTracker(GraphicOverlay overlay)

    {

        mOverlay = overlay;

        mFaceGraphic = new FaceGraphic(overlay);

    }

 

    public override void OnNewItem(int id, Java.Lang.Object item)

    {

        mFaceGraphic.SetId(id);

    }

 

    public override void OnUpdate(Detector.Detections detections, Java.Lang.Object item)

    {

        var face = item as Face;

        mOverlay.Add(mFaceGraphic);

        mFaceGraphic.UpdateFace(face);

    }

 

    public override void OnMissing(Detector.Detections detections)

    {

        mOverlay.Remove(mFaceGraphic);

    }

 

    public override void OnDone()

    {

        mOverlay.Remove(mFaceGraphic);

    }

}

 

The FaceGraphic instance is created when a Face is detected the first time, updated as the face changes, and hidden when the face goes out of the frame.

That’s it; we successfully created face tracking on a custom camera surface within your app! Next, we’ll recognize the person within the frame.

Recognize a Face from the Live Stream

To recognize the face within the live video frame, we capture the image whenever a new face is detected and send it to Microsoft Cognitive Services APIs to identify the person. Face Recognition requires artificial intelligence and highly efficient machine learning algorithms, which are provided to you as a service and free to get started. If you’re new to Cognitive Services, I highly recommend reading the blog post Adding Facial Recognition to Your Mobile Apps.

Capture the Detected Face

To capture the newly detected Face, modify the GraphicFaceTracker to implement the CameraSource.IPictureCallback first.

 

1

2

3

4

class GraphicFaceTracker : Tracker, CameraSource.IPictureCallback

{

//...

}

And modify the OnNewItem() to capture the image frame with the Face

 

1

2

3

4

5

6

public override void OnNewItem(int id, Java.Lang.Object item)

{

    mFaceGraphic.SetId(id);

    if (mCameraSource != null && !isProcessing)

        mCameraSource.TakePicture(null, this);

}

 

Identify the Person in the Captured Frame

Finally, using the Helper Classes ImageAnalyzer and LiveCamHelper (that abstracts the COGs API call), we successfully identify the person in the video stream.

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

public void OnPictureTaken(byte[] data)

{

    Task.Run(async () =>

    {

        try

        {

            isProcessing = true;

 

            Console.WriteLine("face detected: ");

 

            var imageAnalyzer = new ImageAnalyzer(data);

            await LiveCamHelper.ProcessCameraCapture(imageAnalyzer);

        }

 

        finally

        {

            isProcessing = false;

        }

    });

}

Download video: MP4 format

 

Wrapping Up

Face recognition is widely used in many scenarios, including security, natural user interface, robotics, and more. By using a combination of these services and platform APIs, you can build unmatchable mobile apps that are intelligent and provide five-star user experiences. In this blog post, we used Google Mobile Vision APIs to detect human faces from the Video Live Stream and Microsoft Cognitive Services to recognize the person within the frame. For building the same sample on iOS, read How To Display Camera in Your iOS apps and Adding Facial Recognition to Your Mobile Apps.

The sample built and explained in this post was inspired by the Google Developer documentation on Face Tracker.

Download the samples for both iOS and Android from my GitHub repoNote: For this demo, I’ve written the code to recognize a single face in the frame. However, feel free to modify and make it better.

 

Written on June 12, 2017 by
Nish Anil

Posted by Andrew Tierney Wednesday, June 28, 2017 8:44:00 AM Categories: .NET Xamarin

Interactive 3D with UrhoSharp and Workbooks 

Humans live in a three-dimensional world, which we navigate from the time we’re infants. We might, therefore, assume that 3D graphics programming would be an intuitively natural fit to our lifetime of experience; after all, we simply need to translate familiar concepts (left and right, up and down, forward and back) into an X-Y-Z coordinate system.

For most people, however, 3D graphics is quite daunting. It’s hard to get a mental feel for 3D objects and how they move through space, and the mathematics involved can be truly hairy. It’s very common for beginning 3D graphics developers to programmatically define a camera, light source, and a 3D object, and then see nothing at all on the screen.

Imagine if you could then fiddle with the code a bit, perhaps change that positive Z coordinate to a negative, for instance, and immediately see the new result.

This is what the combination of UrhoSharp and Xamarin Workbooks now offers. 3D graphics programming has become more accessible to developers, as well as more enticing, by becoming more interactive.

UrhoSharp is Xamarin’s C# wrapper for the open-source Urho3D cross-platform game engine. This is a powerful, industrial-strength 3D graphics API whose major deficiency is that it has so many features it can seem overwhelming to a 3D newcomer (and to developers who already have some 3D coding experience!).

Xamarin Workbooks are documents that combine text and code. Workbooks allow you to edit and execute code in tiny pieces and get immediate feedback. To get started, download the Workbooks application from the Xamarin Workbooks page, and then begin exploring the almost 100 Workbooks that already exist for a variety of platforms.

Getting Started

If you know some UrhoSharp, it might not seem like the optimal platform for Workbooks. Normally, you create a UrhoSharp application by deriving a class from Application, overriding several methods, and then calling a method named Run. This Run method is blocking; it doesn’t return until the application has completed. Within a Workbook, this application architecture is not conducive to an interactive experience.

For that reason, a new UrhoSharp class has been created specifically for Workbooks. This class is called SimpleApplication. You can simply call the static method SimpleApplication.Show with an optional ApplicationOptions argument within the Workbook, and you’re ready to go.

There are currently eight UrhoSharp Workbooks, with more in the works. Four of these eight are demonstrations of UrhoSharp features, while four others take a more tutorial approach suitable for aspiring 3D graphics programmers. You can run these Workbooks on a PC or Mac directly from the Workbooks page, or you can download the whole Workbooks GitHub repository. The UrhoSharp Workbooks are in the graphics/urhosharp directory.

One of the crucial aspects of 3D graphics programming is defining solid objects in 3D space. UrhoSharp provides several ways to do this. The most professional approach is to use specialized modeling software. UrhoSharp supports numerous model formats. The Animated Model Workbook is the shortest of the Urho Workbooks because it does little more than load in a model of a 3D mutant and animate it:

It’s also possible to create 3D shapes algorithmically by defining or deriving all the 3D vertices right in the Workbook. This approach is demonstrated in two Workbooks: Working with Urho Custom Geometries and Building Polyhedra with UrhoSharp.

The simplest approach, however, can be found in the Urho.Shapes namespace, which contains seven classes that let you make common geometric objects: BoxConeCylinderPlanePyramidSphere, and Torus. This is certainly the fastest way to get up and running with an UrhoSharp Workbook.

Creating The Workbook

To begin creating your own UrhoSharp Workbooks, you’ll want to download the Workbooks GitHub repository. In the directories for the existing UrhoSharp Workbooks, you’ll see three library files: one for the PC (mono-urho.dll), another for the Mac (libmono-urho.dylib), and the third that’s common to both platforms (Urho.dll). You’ll need these files in the same directory as your new Workbook file.

Note: Since we’re copying the library files specifically created for Workbooks, there’s no requirement to add the UrhoSharp library from NuGet.

Using the Workbooks application, create a new Console Workbook. In a code cell, add a reference for the UrhoSharp library and include two using directives:

 

1

2

3

#r "Urho.dll"

using Urho;

using Urho.Shapes;

 

Now create an instance of SimpleApplication:

 

1

SimpleApplication app = SimpleApplication.Show();

 

When that method executes, a window will pop up on your screen to host the UrhoSharp graphics. SimpleApplicationcreates a default camera, a point light source, and a root node. A 3D scene in UrhoSharp is a tree of nodes. This hierarchical node architecture turns out to be quite convenient when you want to reference a whole subset of 3D components with a single object.

Creating Objects

The following code creates a new node and associates it with the Box shape:

 

1

2

Node boxNode = app.RootNode.CreateChild("boxNode");

Box box = boxNode.CreateComponent<Box>();

 

When that code executes, you’ll see a box on the UrhoSharp window:

These simple shapes become much more versatile when you realize that you can apply transforms to them. You can move them around the scene, of course, but you can also apply scaling and rotation that’s different in the three dimensions:

 

1

2

boxNode.Scale = new Vector3(3, 0.25f, 0.25f);

boxNode.Rotation = Quaternion.FromAxisAngle(Vector3.UnitZ, 45);

 

Now the box has become a thin bar that’s no longer constrained to the axes of the 3D coordinate system:

And, of course, you can set a different color or use a bitmap for texturing. These shapes become a fast and easy approach to creating 3D graphics for visualization purpose, as demonstrated by the Charts Workbook, which uses the Box class to create a little bar chart:

You can also combine these basic shapes to create more complex objects. The Creating Compound Shapes Workbook exploits this technique to the max: it starts with a torus, two cylinders that are scaled to a skinny size, and two circles that are squashed to shapes that look like propeller wings:

Now the node hierarchy implemented by UrhoSharp comes in very handy, for nodes can be cloned and can have transforms applied that also impact all child nodes. This technique allows one arm to be cloned into four arms:

The Workbook goes on to describe the animations to make the wings rotate, and then lets you fly the quadcopter around the screen.

The latest Urho Workbook is called Building Polyhedra with UrhoSharp. This one might have a special appeal to anybody who spent at least part of their childhood making 3D figures out of folded cardboard.

The workbook begins with constructing a plain old dodecahedron:

The dodecahedron has 12 faces (as its name suggests), each of which is a pentagon. As a convex regular polyhedron, it’s one of five possible Platonic solids.

But then the Workbook builds upon this figure to make another figure that is certainly related but looks quite different. Each of the pentagon faces in the dodecahedron becomes the center pentagon of a five-pointed star:

This is a process known as stellating the polyhedron, and this particular result is called the small stellated dodecahedron. It’s still considered a regular polyhedron because all of the faces are the same five-pointed star, but it’s definitely not convex any more.

The Workbook then takes another step by replacing the five-pointed stars with pentagons whose vertices are the same as the points of the stars:

This is known as the great dodecahedron, and yes, another step can replace those pentagons with larger five-pointed stars to create the great stellated dodecahedron… but to see that, you’ll have to run the Workbook!

(It’s definitely more fun that way.)

Summary

Workbooks is an incredibly valuable learning tool, and the Workbooks demonstrate the power and versatility of UrhoSharp and the ability to create professional 3D objects and animations. Workbooks allows you to quickly and easily try new ideas, as well as create samples and tutorials for others.

Don’t forget to check out our guides on both Workbooks and UrhoSharp, as well as the Xamarin Workbooks page containing all our sample Workbooks.

Written on June 26, 2017 by
Charles Petzold

Posted by Andrew Tierney Wednesday, June 28, 2017 8:41:00 AM Categories: .NET Xamarin

UrhoSharp - 3D/2D Engine 

Cross Platform 3D/2D Game and Visualization Engine

PDF for offline use
Interactive:

UrhoSharp is a cross-platform high-level 3D and 2D engine that can be used to create animated 3D and 2D scenes for your applications using geometries, materials, lights and cameras.

UrhoSharp is distributed as a NuGet package that can be installed on either Visual Studio or Xamarin Studio on Mac or Windows and can be used to target any of the following platforms: Android, MacOS, iOS, tvOS and Windows.

An Introduction to UrhoSharp

This article provides a high-level overview of UrhoSharp and its capabilities for 3D visualization and for use in simple 3D games.

Using UrhoSharp

In this document we describe the core concepts of UrhoSharp that you would use to build a game or create a 3D visualization for your application.

Urho and Your Platform

These guides describe the setup instructions for Urho on each target platform and describe ways to integrate Urho with your existing Android and iOS applications.

Programming UrhoSharp With F#

This guide walks through the creation of a simple "Hello, World!" UrhoSharp solution using F# and Xamarin Studio.

API Documentation

You can browse the API documentation for UrhoSharp on our web site.

Samples

We have created samples on GitHub illustrating how to use UrhoSharp.

  • FeatureSamples shows more than 40 individual samples that showcase specific features of Urho.

  • SamplyGame is a sample implementation of the Shooty Skies game.

  • FormsSample showcases how to use UrhoSharp in Xamarin.Forms applications.

All the samples run on Android, iOS, Mac and Windows. There are also a number of UrhoSharp Workbooks including Planet Earth and Exploring Coordinates.

Copyright

This documentation contains original content from Xamarin Inc, but draws extensively from the open source documentation for the Urho3D project and contains screenshots from the Cocos2D project.

License

The UrhoSharp license is available at the http://download.xamarin.com/content/licenses/URHO.LICENSE

Posted by Andrew Tierney Wednesday, June 28, 2017 8:38:00 AM Categories: .NET Xamarin

Deep Dive into SkiaSharp with Xamarin.Forms 

Xamarin.Forms is a versatile cross-platform user-interface toolkit that allows a single program to run on iOS, Android, the Universal Windows Platform, and (most recently) macOS.

However, one feature missing from Xamarin.Forms is a graphics system. Sure, Xamarin.Forms can render bitmaps, and you can size and rotate a BoxView for some simple blocky images, but for those of us who love graphics programming, Xamarin.Forms has a big polygon-shaped hole.

But don’t fret! A very compelling solution for Xamarin.Forms graphics is SkiaSharp, Xamarin’s C# library that incorporates Google’s powerful Skia Graphics Engine.Old-school graphics with SkiaSharp.

SkiaSharp is a cross-platform, high-performance 2D API for .NET developers perfect for mobile development. The API is straightforward to work with and can be used to do simple things, like drawing shapes or text, all the way to complex real-time drawing applications. The Xamarin team has even created a WYSIWYG graphics designer that puts out SkiaSharp graphics code.

As a member of Xamarin’s documentation team, I’ve been engaged in writing what I hope to be an extensive series of bite-sized tutorials on using SkiaSharp in Xamarin.Forms. These articles represent a deep dive into SkiaSharp, but one that I hope can also serve as an introduction to 2D graphics for newcomers. SkiaSharp shares many concepts with other 2D graphics drawing systems, so learning SkiaSharp is a terrific way to get a general education in 2D vector graphics.

Most recently, I’ve finished several articles on SkiaSharp Transforms. SkiaSharp supports all the basic graphics transforms found in other graphics systems, including translation, scaling, rotation, and skewing, which tilts graphics objects such as this shadow:

Example of drawing shadows in SkiaSharp.

That image uses an SKPaint object to define the characteristics of the text output. For the shadow (which is drawn first), the code sets a different color and a combination of translation, scaling, and skew to enlarge the text and tilt it to one side:

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

using (SKPaint textPaint = new SKPaint())

{

    textPaint.Style = SKPaintStyle.Fill;

    textPaint.TextSize = screenWidth / 6;

    textPaint.IsAntialias = true;

 

    // Common to shadow and text

    string text = "shadow";

    float xText = 20;

    float yText = screenHeight / 2;

 

    // Shadow

    textPaint.Color = SKColors.Gray;

    canvas.Save();

    canvas.Translate(xText, yText);

    canvas.Skew((float)Math.Tan(-Math.PI / 4), 0);

    canvas.Scale(1, 3);

    canvas.Translate(-xText, -yText);

    canvas.DrawText(text, xText, yText, textPaint);

    canvas.Restore();

 

    // Text

    textPaint.Color = SKColors.Blue;

    canvas.DrawText(text, xText, yText, textPaint);

}

 

SkiaSharp also supports standard matrix transforms, including non-affine transforms, which can achieve perspective and 3D rotation effects, such as the image at the top of this blog.

On mobile platforms and other modern devices, graphics is often intimately related to touch. Xamarin.Forms supports some rudimentary touch events, but not the essential tool of tracking individual fingers. More sophisticated touch tracking for Xamarin.Forms is now available with a Xamarin.Forms effect described in Invoking Events from Effects.

Combining SkiaSharp with touch tracking can result in some fun applications. I’ve recently created a Xamarin.Forms version of SpinPaint, based on a program I first wrote seven years ago for the Microsoft tabletop computer (originally called Surface and later renamed PixelSense).

SpinPaint simulates a rotating disk. Touch it or move your fingers on it, and it draws not only a line corresponding to your finger but three other lines that are mirror images, creating pretty patterns. Here’s SpinPaint running on iOS, Android, and the Universal Windows Platform:

Painting graphics with SkiaSharp

I think what impresses me most about SkiaSharp is its versatility. For example, other 2D graphics systems aren’t in total agreement about the best way to draw an arc, which is a curve on the circumference of an ellipse. Different graphics systems define the arc in very dissimilar ways.

SkiaSharp doesn’t force you into thinking of arcs in a particular way; rather, it supports three different ways to define an arc in a graphics path, so you can use the one that’s best for your particular application:

The angle arc requires that you specify a bounding rectangle for an ellipse, along with start angles and sweep angles:

 

1

path.AddArc(rect, startAngle, sweepAngle);

 

The resultant arc is shown here in red:

Angle arc drawn with SkiaSharp

This is identical to the AddArc and ArcTo methods of the Android Path object, and similar to the AddArc method of the iOS CGPath (although the iOS version is restricted to arcs on the circumference of a circle). This type of arc is great for pie charts.

The tangent arc is similar to the PostScript arct function and the iOS AddArcToPoint method. A radius of a circle is specified that is then fit snugly between two connected lines:

 

1

path.ArcTo(pointCorner, pointDestination, radius);

 

SkiaSharp draws a line and the arc, again shown in red:

Drawing a tangent arc with SkiaSharp.

The tangent arc is ideal for making rounded corners.

Finally, the elliptical arc allows you to specify two radii of an ellipse, as well as a rotation angle. The resultant tilted ellipse can fit between two points in two different ways, resulting in four different arcs between the two points, shown here in four different colors:

Drawing an elliptical arc with SkiaSharp.

You specify which of these four possible arcs you want with two further parameters:

 

1

ArcTo (radii, rotation, largeArcFlag, sweepDirectionFlag, point)

 

This type of arc specification is consistent with the elliptical arc supported by Scalable Vector Graphics (SVG) as well as the ArcSegment supported by XAML-based Windows graphics systems, including the Universal Windows Platform.

If you think arc-drawing is versatile, wait until you see SkiaSharp’s shaders and path effects! The shaders let you specify various gradients for filling in areas, including a linear gradient, radial gradient, conical gradient, sweep gradient, and random patterns called Perlin noise. The path effect can render a dotted or dashed line with any pattern of dots or dashes you want, but also render a line composed of little patterns:

SkiaSharp drawing a patterned texture.

Wrapping Up

There are still more SkiaSharp articles to come, so check the Using SkiaSharp in Xamarin.Forms page often to see what’s new.

Meanwhile, you’ll also want to register for Xamarin University Presents, a series of five must-see webinars in July, including one I’ll be doing on SkiaSharp Graphics for Xamarin.Forms.

Written on May 23, 2017 by
Charles Petzold

Posted by Andrew Tierney Wednesday, June 28, 2017 8:32:00 AM Categories: .NET Xamarin