Michael Ridland: FreshMvvm – A Mvvm Framework designed for Xamarin.Forms

Now available via Nuget FreshMvvm is a Mvvm framework that’s designed specifically for Xamarin.Forms. The reason I say it’s designed for Xamarin.Forms is because it plays on Xamarin.Forms strengths and fills in ONLY the missing parts. It has a requirement for Xamarin.Forms and therefore is smart and can do thing such as wiring up the […]

The post FreshMvvm – A Mvvm Framework designed for Xamarin.Forms appeared first on Michael Ridland.

Details

Adam Kemp: Taming The Android Activity, Part 2

In part one of this series I covered how to use a Fragment to maintain state through configuration changes. In part two I will cover how to launch a new Activity (in-process or not) and wait for its results using C#’s async/await feature.

Starting Activities

As mentioned in part one, the Activity is designed to let applications reuse pieces of other applications. For instance, if you need to let the user pick a photo then you can construct an Intent object that describes what you want to do (pick a photo), and the OS will find an Activity for one of the installed applications that can satisfy that request. The other Activity may be in another application, but the Intent allows you to send it information about what you want, and then later it can send back the results (through another Intent).

The way the API works is you call StartActivity (a method in Activity) and give it either an Intent object or a Type (which will be used to construct an Intent). When you do that the OS will find the proper Activity, create it (possibly in another process), and then show it the user. Once that Activity is finished (either by the user pressing the back button or the Activity calling Finish()) then your original Activity will resume.

However, that’s only for a simple case: launching a new Activity and ignoring any results. If you actually wanted to get information back from the other Activity then you need to instead call StartActivityForResult. This method is just like StartActivity, but it also takes an int that can be used to identify the request. Then you have to override the OnActivityResult method, which will give you back the request identifier along with a ResultCode and an Intent (for extra information). That basically looks like this:

private const int ImagePickerRequestCode = 1000;

private void LaunchOtherActivity()
{
var intent = new Intent(Intent.ActionGetContent);
intent.SetType("image/*");
StartActivityForResult(intent, ImagePickerRequestCode);
}

public override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
if (requestCode == ImagePickerRequestCode && resultCode == Result.Ok)
{
// Get the image from data
}
}

The Problem

There are several problems with this, and the root of all of them is that all results for any Activity you launch must go through OnActivityResult. This means that any time you launch an Activity and want results you have to put some code in that function to handle the results. This is why you need the annoying int requestCode argument: that is the only way to identify which Activity you were launching so that you know what to do with the results. Now you have to be sure that each type of Activity that you launch in this way uses a different number, which is annoying.

Another problem is that this splits up your code. You start the Activity in one place, and then you handle the results elsewhere. There’s no callback or anything that connects the two. You just have to know to go find that other function to see how the results are handled.

The worst problem is that this makes it very difficult to properly decouple responsibilities between views. What if you want to launch another Activity from a view inside a popup? You still have to handle the results in the Activity itself, and then you somehow have to get the results back to the view inside the popup.

This was my motivation for finding a better way. When you write a large application in Android you might have many different kinds of activities that you want to launch and then gather the results from, and forcing all of that code to go through a single function makes it very difficult to maintain.

Imagine a Better Way

Before we start trying to implement anything let’s first think about what we want the API to look like (always a good first step to avoid APIs like this).

Obviously launching a new Activity and getting results is an asynchronous operation so we’re going to have some kind of asynchronous API. We could do that with callbacks, which would be a huge improvement, but C# has an awesome feature that makes this even better: async/await. Using that feature we could imagine an API that looks like this:

var intent = new Android.Content.Intent(Android.Content.Intent.ActionGetContent);
intent.SetType("image/*");
var result = await StartActivityForResultAsync(intent);
if (result.ResultCode == Result.Ok)
{
// Get the image from data
}

This looks awesome. There’s no request code, and all of the code is in one place. Best of all, there’s not even a callback. This code reads like normal synchronous code.

Gathering Requirements

Now that we know what we want the API to look like let’s think about what we need to accomplish it. One of the benefits of the work we did in part one of this series is that each Activity (and also each Fragment) in our application shares a base class. That provides us with an opportunity to put some bookkeeping in the base class that can help us achieve our goal. Based on the API we have to start with, and the API we are trying to build, we need to keep track of this information:

  1. A request code for each launched Activity. To avoid requiring the caller to give us one we also need to somehow come up with new unique request codes automatically.
  2. A TaskCompletionSource that can be used to provide the results asynchronously to the caller (via its Task property).
  3. A mapping between the request codes and the TaskCompletionSources.

Based on this we can start to see an implementation forming. We can use an auto-incrementing request code (starting at some arbitrary value), and we can use a Dictionary to map between the request codes and the TaskCompletionSources.

While we’re at it we will also solve another challenge that we often face when dealing with these Activity results: OnActivityResult is called before OnResume, which in some cases may be too early to actually deal with the results. Since we’re already handling sending the results back asynchronously we can fix this by also delaying the results until after OnResume, which is far more useful.

Implementation

In the spirit of keeping as much logic in the Fragment instead of the Activity we will be putting this API in the FragmentBase class that we created in part one of this series. This is also important because we don’t want to lose the bookkeeping information if there is a configuration change (like if the user rotates the device after you start the new Activity but before you get the results).

Our FragmentActivity class will be the same as before, but we will add some new code to the FragmentBase class. First, we need an interface for the results returned by our async method:

/// <summary>
/// The information returned by an Activity started with StartActivityForResultAsync.
/// </summary>
public interface IAsyncActivityResult
{
/// <summary>
/// The result code returned by the activity.
/// </summary>
Result ResultCode { get; }

/// <summary>
/// The data returned by the activity.
/// </summary>
Intent Data { get; }
}

Now we need to add our new methods to the FragmentBase class. I have omitted the parts that were unchanged for brevity.

/// <summary>
/// The base class for top-level fragments in Android. These are the fragments which maintain the view hierarchy and state for each top-level
/// Activity. These fragments all use RetainInstance = true to allow them to maintain state across configuration changes (i.e.,
/// when the device rotates we reuse the fragments). Activity classes are basically just dumb containers for these fragments.
/// </summary>
public abstract class FragmentBase : Fragment
{
// This is an arbitrary number to use as an initial request code for StartActivityForResultAsync.
// It just needs to be high enough to avoid collisions with direct calls to StartActivityForResult, which typically would be 0, 1, 2...
private const int FirstAsyncActivityRequestCode = 1000;

// This is static so that they are unique across all implementations of FragmentBase.
// This is important for the fragment initializer overloads of StartActivityForResultAsync.
private static int _nextAsyncActivityRequestCode = FirstAsyncActivityRequestCode;
private readonly Dictionary<int, AsyncActivityResult> _pendingAsyncActivities = new Dictionary<int, AsyncActivityResult>();
private readonly List<AsyncActivityResult> _finishedAsyncActivityResults = new List<AsyncActivityResult>();

#region Async Activity API

public Task<IAsyncActivityResult> StartActivityForResultAsync<TActivity>(CancellationToken cancellationToken = default(CancellationToken))
{
return StartActivityForResultAsyncCore(requestCode => Activity.StartActivityForResult(typeof(TActivity), requestCode), cancellationToken);
}

public Task<IAsyncActivityResult> StartActivityForResultAsync(Intent intent, CancellationToken cancellationToken = default(CancellationToken))
{
return StartActivityForResultAsyncCore(requestCode => Activity.StartActivityForResult(intent, requestCode), cancellationToken);
}

public override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
AsyncActivityResult result;
if (_pendingAsyncActivities.TryGetValue(requestCode, out result))
{
result.SetResult(resultCode, data);
_pendingAsyncActivities.Remove(requestCode);
_finishedAsyncActivityResults.Add(result);
}

base.OnActivityResult(requestCode, resultCode, data);
}

public override void OnResume()
{
base.OnResume();

FlushPendingAsyncActivityResults();
}

private Task<IAsyncActivityResult> StartActivityForResultAsyncCore(Action<int> startActivity, CancellationToken cancellationToken)
{
var asyncActivityResult = SetupAsyncActivity();
startActivity(asyncActivityResult.RequestCode);

if (cancellationToken.CanBeCanceled)
{
cancellationToken.Register(() =>
{
Activity.FinishActivity(asyncActivityResult.RequestCode);
});
}

return asyncActivityResult.Task;
}

private void FlushPendingAsyncActivityResults()
{
foreach (var result in _finishedAsyncActivityResults)
{
result.Complete();
}
_finishedAsyncActivityResults.Clear();
}

private AsyncActivityResult SetupAsyncActivity()
{
var requestCode = _nextAsyncActivityRequestCode++;
var result = new AsyncActivityResult(requestCode);
_pendingAsyncActivities.Add(requestCode, result);

return result;
}

private class AsyncActivityResult : IAsyncActivityResult
{
private readonly TaskCompletionSource<IAsyncActivityResult> _taskCompletionSource = new TaskCompletionSource<IAsyncActivityResult>();

public int RequestCode { get; private set; }

public Result ResultCode { get; private set; }

public Intent Data { get; private set; }

public Task<IAsyncActivityResult> Task { get { return _taskCompletionSource.Task; } }

public AsyncActivityResult(int requestCode)
{
RequestCode = requestCode;
}

public void SetResult(Result resultCode, Intent data)
{
ResultCode = resultCode;
Data = data;
}

public void Complete()
{
_taskCompletionSource.SetResult(this);
}
}

#endregion
}

Now let’s take a quick tour and see how this all works. First, there are two overloads of StartActivityForResultAsync. One takes a type of Activity as a generic argument because it’s very common to want to start a new Activity in-process and just refer to it by its type. The other one takes an Intent, which is more flexible. You will typically use this variant for out-of-process activities.

These methods also take an optional CancellationToken, which can be used to cancel the launched Activity. If the token is cancelled then the code that is waiting on the async result will get a ResultCode that indicates that it was cancelled.

Both of those methods call into the same core routine that sets up the bookkeeping. It is responsible for creating the object that tracks the results and returning the Task that we can wait on.

Once the Activity has been started we return the Task object to the caller, and then we wait for a call to OnActivityResult. If you recall from part one of this series, that method call is actually forwarded to us by our FragmentActivity class (in the Android SDK there is no OnActivityResult method in Fragment, but we added one for this purpose). In OnActivityResult we check to see if the request code is one that is in our Dictionary of pending async activities. If it is then we record the ResultCode and the Intent, add it to a list of finished results, and then remove the item from our Dictionary. Later we will get a call to OnResume, which just goes through the list of finished results and calls the Complete method. That is the method that actually pushes the results into the TaskCompletionSource (by calling SetResult), which unblocks anything waiting on the Task.

And that’s it. Now we have enough to start a new Activity and wait for its result in a single, small function. I have posted a full version of the code with a small example app on GitHub.

Summary

So far in the first two parts of this series I have covered how to preserve state across configuration changes and how to simplify the process of starting new activities and waiting for their results. With those two challenges solved we can avoid a lot of ugly boilerplate code. However, there is still one significant source of tedious boilerplate code: communicating between these activities still has to be done through Intent objects. In the next part of this series I will extend this code even further to allow for directly accessing the new Fragment object for in-process activities.

Details

Matt Ward: Xamarin Components Directory Configuration

One of the new features introduced in Xamarin Studio 5.9 is the ability to configure the directory where Xamarin Components are installed to when they are added to a project.

By default, when a Component from the Xamarin Component store is added to a project, the Component is installed to a Components directory inside the solution’s directory.

Default Components directory for a solution

The project will have references added that refer to assemblies inside this Components directory.

<Reference Include="Microsoft.WindowsAzure.Mobile.Ext">
  <HintPath>..Componentsazure-mobile-services-1.3.1libandroidMicrosoft.WindowsAzure.Mobile.Ext.dll</HintPath>
</Reference>
<Reference Include="Microsoft.WindowsAzure.Mobile">
  <HintPath>..Componentsazure-mobile-services-1.3.1libandroidMicrosoft.WindowsAzure.Mobile.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json">
  <HintPath>..Componentsazure-mobile-services-1.3.1libandroidNewtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System.Net.Http.Extensions">
  <HintPath>..Componentsazure-mobile-services-1.3.1libandroidSystem.Net.Http.Extensions.dll</HintPath>
</Reference>
<Reference Include="System.Net.Http.Primitives">
  <HintPath>..Componentsazure-mobile-services-1.3.1libandroidSystem.Net.Http.Primitives.dll</HintPath>
</Reference>

If a project is shared between multiple solutions then Xamarin Studio can have multiple different Components directories, one for each solution. This can cause Xamarin Studio to modify the hint paths in the project file to use a different Components directory depending on which solution was opened.

A simple way to reproduce this problem is to create one solution with a project that has a Component, then create another solution in a different directory, and add the same project to this new solution. The Component will be downloaded again into the Components directory relative to the new solution and the assembly references in the project file will be modified to use this new Components location.

Now let us take a look at how to solve this problem by configuring the Components directory.

Configuring the Components Directory

To configure the Components directory used by a project you can use a components.config file, as shown below.

<config>
  <add key="cachePath" value="..Components" />
</config>

The path specified in the components.config file can be a full path or a relative path. If it is a relative path then it is relative to the directory containing the components.config file.

The path in the components.config file will be normalized so it contains the correct directory separators on non-Windows operating systems, so you can use either a forward slash or a backslash in the path.

Now let us take a look at how Xamarin Studio finds this components.config file.

Xamarin Studio, when a solution is opened, will check for a components.config file in several locations based on the solution’s directory. If we have a solution in the directory /Users/matt/Projects/MyAndroidApp/ then the full set of locations checked is as follows:

  1. /Users/matt/Projects/MyAndroidApp/.components/components.config
  2. /Users/matt/Projects/MyAndroidApp/components.config
  3. /Users/matt/Projects/components.config
  4. /Users/matt/components.config
  5. /Users/components.config
  6. /components.config
  7. ~/Preferences/Xamarin/Components/components.config

Note that on Windows the last location checked is:

%AppData%XamarinComponentscomponents.config

If you put the components.config file in a directory that is a parent of multiple solutions then all the solutions can use this common components.config file.

If the components.config file is missing or cannot be read then the default Components directory is used, which is inside the solution’s directory.

If there is an error whilst reading the components.config file then the error will be logged by Xamarin Studio and the default Components directory will be used.

The Components directory to be used is cached when the solution is loaded so changes made to the components.config file require the solution to be closed and re-opened before Xamarin Studio will use the new settings.

To help diagnose problems when configuring the Components directory Xamarin Studio will log information in the Components.log file. The Components.log file can be found by selecting Open Log Directory from Xamarin Studio’s Help menu. Two examples taken from the Components.log file are shown below. The first example shows the message logged when a components.config file cannot be found.

[2015-05-10 11:00:29.0] DEBUG: No components.config file found. Using default path. Files checked: /Users/matt/Projects/MyAndroidApp/.components/components.config
/Users/matt/Projects/MyAndroidApp/components.config
/Users/matt/Projects/components.config
/Users/matt/components.config
/Users/components.config
/components.config
/Users/matt/Library/Preferences/Xamarin/Components/components.config

The next example shows the message logged when a components.config file is found.

[2015-05-10 11:10:24.1] DEBUG: Using custom components cache path '/Users/matt/Projects/MyAndroidApp/Components'. components.config file found at '/Users/matt/Projects/MyAndroidApp/components.config'.

Component Restore

The latest version of xamarin-component.exe also supports using the configured Components directory. Its restore command will restore the Components to the directory as specified in the components.config file.

mono xamarin-component.exe restore path/to/solution.sln

xamarin-component.exe will look for the components.config file in the same directories as Xamarin Studio.

Comparison with NuGet

NuGet has similar behaviour to Components in Xamarin Studio. All NuGet packages are downloaded to a packages directory inside the solution directory by default. To override this behaviour you can create a NuGet.Config file. The NuGet.Config file allows the packages directory to be configured through a repositoryPath setting.

<config>
  <add key="repositoryPath" value="../../packages" />
</config>

NuGet will look for this NuGet.Config file in several places. Assuming the solution directory is /Users/matt/Projects/MyAndroidApp/ the NuGet.Config file will be looked for in the locations as shown below:

  1. /Users/matt/Projects/MyAndroidApp/.nuget/NuGet.Config
  2. /Users/matt/Projects/MyAndroidApp/NuGet.Config
  3. /Users/matt/Projects/NuGet.Config
  4. /Users/matt/NuGet.Config
  5. /Users/NuGet.Config
  6. /NuGet.config
  7. ~/.config/NuGet/NuGet.Config (Windows: %AppData%NuGetNuGet.Config)
Details

Xamarin: Android Tips: Hello AppCompatActivity, Goodbye ActionBarActivity

With the latest updates to the Android Support v7 AppCompat Library, revision 22.1, integrating Google’s Material Design has never been easier. If you need to get caught up with AppCompat, we have already covered how to add Material Theming to your apps with AppCompat and how to replace your ActionBar with the new advanced Toolbar […]

The post Android Tips: Hello AppCompatActivity, Goodbye ActionBarActivity appeared first on Xamarin Blog.

Details

Xamarin: Champion San Jose Earthquakes Win with Xamarin.Forms and Xamarin Insights

Avaya Stadium, home to the two-time MLS Cup Champion San Jose Earthquakes, is widely considered to be the best soccer stadium in the U.S. Selected to create a premium app for the new stadium, Xamarin Premier Consulting Partner ArcTouch needed a cross-platform solution to provide an app that would be fun and engaging on game […]

The post Champion San Jose Earthquakes Win with Xamarin.Forms and Xamarin Insights appeared first on Xamarin Blog.

Details

Larry O’Brien: How to: Handoff to a Xamarin iPhone app from Apple Watch

# How to: Handoff to a Xamarin iPhone app from Apple Watch There are two ways to activate the parent (aka container) app from an Apple Watch app. You can either directly activate the container app using WKInterfaceController.OpenParentApplication or you can use Handoff. Using Handoff is a little more complex, so I thought I’d write a […]
Details