Aside

VSTS and Xamarin CI & CD

In Evolve 2016 Visual studio team services (VSTS) team has made an awesome presentation about managing Xamarin apps with VSTS . This talk inspired me to try this new experience. In this post we are going to configure build pipeline for Xamarin iOS and will add to that the integration with HockeyApp and Xamarin Test Cloud.

Steps

Configure build agent 

Microsoft has rebuilt VSTS build and release agent. This will be replacing/combining the existing closed source windows build agent and the existing xplat agent supported on Windows, OSX, Ubuntu and Red Hat written for the .NET Core CLR as one code base in C#.

There is a prerequisite  for VSTS agent which is .Net core. The instruction below will go through how we can install it.

Installing .Net Core

  1. brew update
  2. brew install openssl
  3. brew link –force openssl

Check here if you have installation issues.

Installing VSTS agent for Mac

  1. We need to add VSTS build account to the proper roles, please follow steps written here.
  2. Follow instruction here for downloading /installing VSTS agent.
  3. If you want to run agent as a service, follow following steps:
    1. Navigate to where you have extracted agent and then run the command below.
    2. ./svc.sh install (will configure agent as service)
    3. ./svc.sh start (will start agent)

For troubleshooting check here

Agent up and running

 

Create a new build definition for our app

We are going to configure VSTS build pipeline for our app as below:

I believe you maybe now asking why our build is failing. After investigating this issue, it seems there is a bug  in the build definition because locally build is succeeding. It turns out that msbuild is trying to build our portable class library against iPhone configuration not AnyCpu, which is not there and this was causing build to fail.

Build Error:
 /Library/Frameworks/Mono.framework/Versions/4.4.1/lib/mono/xbuild/12.0/bin/Microsoft.Common.targets: error : ‘OutputPath’ property is not set for this project. Usually this is caused by invalid Configuration/Platform combination. Original values: Configuration: Release Platform: iPhone.
Screenshot_2016_07_10_15_42_17@2xBuild failure from VSTS console log 

 


<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhone' ">

<Optimize>true</Optimize>

<OutputPath>bin\iPhone\Release</OutputPath>

<ErrorReport>prompt</ErrorReport>

<WarningLevel>4</WarningLevel>

<ConsolePause>false</ConsolePause>

</PropertyGroup>


Hooray green build

Xamarin Test Cloud

In this section we are going to publish our app to Xamarin Test Cloud and run UI automation tests. VSTS made this task very easy, we just need to add Xamarin test cloud task as following.

Publishing app to  HockeyApp

Finally  we are going to publish our app to HockeyApp. HockeyApp is going to be our store, which means testers can download new versions from the app through the HockeyApp application. HockeyApp is doing a great job here by easing mobile DevOps experience. So for configuring build pipeline check the steps below.

Well done VSTS team you have done great job here. I’ve done the same pipeline before with Bamboo and Fake  and I can tell you that experience wasn’t that good. But today it’s very easy using VSTS.

 

References

Xamarin – WebView Calling C# Code From JS

I’m writing this post to document how can we trigger c# code from javascript in (Android & iOS) WebView applications, each different platform has a different way for handling this scenario as following:

Scenario:

We have a hybrid app that needs to mark  page as favourite a link is clicked inside a WebView.

iOS:

We need to add url handler so for e.g. assume we have a page we need to mark this page as favourite from JS will be calling a url like this one “myapp://favourite?pageId=1,value=true” and this url will be handled in C# as below sample:

Android:

We need to create a C# class that will be called from javascript and it needs to inherit from Java.Lang.Object and implement Java.Lang.IRunnable as below:

After this we need to add this class to the WebView:

Finally we can call this function from javascript:

JS

HTML