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)

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.

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.

Michael Ridland: Top 10 Tips for Building an Apple Watch App

Unless you’ve been living under a rock then you already know about the Apple Watch, have ordered one or your wearing one right now. At the moment I’ve been getting my head around how WatchKit apps will work for my the apps of my clients. The truth be told is that not all apps need […]

The post Top 10 Tips for Building an Apple Watch App appeared first on Michael Ridland.

Xamarin: Build 2015: Visual Studio Integration & Developer Celebrations

In addition to achieving the 1 Million developer milestone last week, Xamarin developers also enjoyed a great show at Microsoft Build 2015, with a packed attendee party on opening night, multiple sessions covering mobile development with Xamarin, and the debut of Microsoft’s Visual Studio 2015 Release Candidate with improved Xamarin integration. Kicking Off Build 2015 […]

The post Build 2015: Visual Studio Integration & Developer Celebrations appeared first on Xamarin Blog.

James Montemagno: Generating Android Color Palettes Super Fast with Rev 22.1

Google went on a spree a few weeks back updating all of their support libraries to rev 22.1. If you haven’t read about all the changes be sure to read through the official Android Developer’s blog for a full breakdown. The most drastic change to the support libraries was to v7 AppCompat with the new AppCompatActivity, but there were several other enhancement to the libraries including one of my favorite Palette. If you don’t remember what palette is, it allows you to sample a color palette from any bitmap to theme your application. Here is a simple example of the before and after:

With rev 22.1, available as a NuGet package for your Xamarin.Android applications, the speed in which palettes are now generated are now 5 to 10 times faster! Here are some stats from Chris Banes’ blog:

After you update your NuGets to the latest version (currently 22.1.1.1 as of May 2nd 2015), you may notice that your old Palette methods were deprecated. This is because Google has replaced the older Palette.Generate and Palette.GenerateAsync methods with the tried and true Builder pattern. This will feel very familiar if you have worked with AlertDialogs or Notifications. It is basically a way of chaining property setters in a row (kind of linq style) since java doesn’t really have getters for properties that you could construct. So here is our old code:

In the latter method call the “this” is your current implementation of 

Palette.IPaletteAsyncListener, which will get a callback when the generate has been completed and the new way of generating a palette uses this same interface implementation, but looks a bit different:

Updating to the latest NuGet packages will have some drastic improvements in speed as you saw in Chris’ chart because according to Chris Banes: “In this release, we went back to some old-style optimizations for the colour quantization. Things like less object allocations, more appropriate data structures and a reduction in algorithmic complexity. “

There you have it! You can grab a sample from our Xamarin.Android samples gallery. Now go make things beautiful.