NuGet - James Montemagno https://staging.montemagno.com/tag/nuget/ https://staging.montemagno.com/content/images/2017/08/MonogramIcon_Orange_NoBuffer.png NuGet - James Montemagno https://staging.montemagno.com/tag/nuget/ Hugo -- gohugo.io Tue, 13 Oct 2026 20:48:55 GMT 60 Building, testing, & shipping My Cadence for iOS in less than a week https://staging.montemagno.com/building-testing-shipping-my-cadence-for-ios-in-less-than-a-week/ 5fe12e796c10e100399f4eae Thu, 24 Dec 2020 17:43:57 GMT

My holiday hacking came early this year when I decided to build my own DIY spin bike. Soon, after a few rides, my mind started to swirl with app ideas of how to improve my ride. Then when Apple released Apple Fitness+ without support for displaying cadence information from sensors I knew I had to build an app. That app is My Cadence, which connects to a small cadence sensor and displays the current cadence. It is actually packed full of awesome features including custom themes, in-app purchases, store reviews, and more! Best of all it only took me around 12 hours to develop, test, and ship during the last week since I started it. So, today I want to walk through all of the features I put in and how I developed them.

Xamarin.Forms 5

With Xamarin.Forms 5 nearing stable release it was the first thing I updated to when I created the project. I leveraged a lot of new features such as embedded fonts, App Themes for Light/Dark mode, gradient brushes, geometry clipping, and a bunch more! I love how easy it is to react to the mode change on the user's device with a simple line of code.

 <Label Text="The following sensors have been tested with My Cadence."
        TextColor="{AppThemeBinding Dark=White, Light=Black}"/>

Here is a bit of the app themes in action:

Bluetooth

The cadence sensor broadcast over Bluetooth Low Energy. This was actually the first time that I had worked with Bluetooth and I leveraged the Plugin.BLE library to easily detect, connect, and read data from the device. I may upgrade to Shiny in the future, but this was the first one I grabbed and it has been working well.

I fell in love so much with Bluetooth that Frank and I recorded a full Merge Conflict podcast on it!

In-app Purchases

I decided to add a "Pro" mode into the application at the last minute. My thought was that the entire app would be free without restrictions, but to help support the app a user could upgrade to "Pro" to unlock custom theming in the app. I leveraged my InAppBilling plugin and had the upgraded implemented in about 30 minutes. Here is the code from the app if you are interested in how easy it is to implement.

const string productId = "pro";

async Task PurchasePro()
{
    if (IsBusy)
        return;

    IsBusy = true;

    try
    {
        if(Connectivity.NetworkAccess != NetworkAccess.Internet)
        {
            await DisplayAlert("No internet", "Please check internet connection and try purchase again.", "OK");
            return;
        }

        var connected = await CrossInAppBilling.Current.ConnectAsync();

        if (!connected)
        {
            await DisplayAlert("Unable to Connect", "Unable to connect to the app store, check your internet connectivity and try again.", "OK");
            return;
        }

        //check purchases
        var purchase = await CrossInAppBilling.Current.PurchaseAsync(productId, ItemType.InAppPurchase);

        if (purchase == null)
        {
            return;
        }
        else if (purchase.State == PurchaseState.Purchased)
        {
            Settings.IsPro = true;
            SetPro();
            return;
        }

        throw new InAppBillingPurchaseException(PurchaseError.GeneralError);

    }
    catch (InAppBillingPurchaseException purchaseEx)
    {
        var message = string.Empty;
        switch (purchaseEx.PurchaseError)
        {
            // figureout error message
        }

        if (string.IsNullOrWhiteSpace(message))
            return;

        Console.WriteLine("Issue connecting: " + purchaseEx);
        await DisplayAlert("Uh Oh!", message, "OK");
    }
    catch (Exception ex)
    {
        // Handle Exception
    }
    finally
    {
        await CrossInAppBilling.Current.DisconnectAsync();
        IsBusy = false;
    }
}

Store Reviews

On thing that I always forget to put in my app is a way to prompt the user to review the application. Another one of my random plugins comes in to save the day, the Store Review Plugin! In the settings screen I added a button to review the app:

void TextCellReview_Tapped(System.Object sender, System.EventArgs e)
{
    CrossStoreReview.Current.OpenStoreReviewPage("1545730360");
}

Then I also decided to do a prompt for the user to review after they use the app 5 times successfully.

var count = Settings.Usage;
count++;
if(count == 5)
{
    CrossStoreReview.Current.RequestReview(false);
}
Settings.Usage = count;

Custom Controls

I surprisingly I only used 1 custom control in the entire app and it was available directly on NuGet! This control was an advanced color picker and I landed on one built by Dalton Spillman. It is fantastic as it allows full fidelity of color selection and has a built in ViewModel that works great for getting and setting colors.

You can find the code to the control on GitHub.

Xamarin.Essentials

Wow, Xamarin.Essentials continues to make me super productive over and over and over again. I leveraged:

  • Version Tracking
  • Preferences
  • Connectivity
  • MainThread
  • and more!

Every time I thought I was going to need to write some custom code Xamarin.Essetials was there.

CI & CD

In one of my late night code sessions I decided to setup App Center Build/Distribute on the app and I am so glad I did. It took seconds to setup and I had things automatically building, versioning, and distributing to TestFlight in under 10 minutes!

App Center Build & Distribute

More!

There is a lot more that went into this application outside of just the code. I generated a full website and app screenshots from http://apptoolkit.io/, created an app icon from EasyAppIcon.com, & had some amazing tester on Twitter using TestFlight.  

Thanks Dan for Testing!
Thanks Dan for Testing!

Available Now & OSS Code Soon

It is now available in the App Store completely for free! Soon the app is coming to Android as well as I just need to tweak a few Android specific settings and get it through the review process.

If you are looking to get into spinning checkout my full blog on building a DIY spin bike.

Finally, I do plan on putting the full source code online, so be sure to check back when I write up a blog on it.

]]>
5 Must Install NuGet Packages for New Xamarin Projects https://staging.montemagno.com/essentials-nugets-for-new-xamarin-projects/ 5fc80a2879e5440039355a25 Wed, 09 Dec 2020 16:52:18 GMT

Starting your first project can be a bit overwhelming. I mean heck, I wrote nearly 3,000 words breaking down every bit of what to select and what each option means. Oh, and I also have a full video series walking you through it step by step on my YouTube channel. Before I start writing code in my projects I take some time to configure my projects and then install essential NuGet packages that help me be super productive from the start.

Yes, it is true that Xamarin.Forms and Xamarin.Essentials are included "in the box" with your new project, but there is a world of amazing libraries out there from amazing community members. I want to introduce you to my favorite packages that are key in ever app that I have developed. So, let's get started.

MVVM Helpers 🎉

I may be a bit bias with these first 2 NuGet packages because I wrote them, but I think they are super essentials. First is MVVM Helpers (Refractored.MvvmHelpers), a super small library that works in any app that contains nifty classes and utilities that help creating your app from the start. It includes things such as:

  • ObservableObject: A Simple implementation of INotifyPropertyChagned
  • BaseViewModel: The only base view model you will ever need. It implements INotifyPropertyChanged and a bunch of default properties such as Title, SubTitle, Icon, IsBusy, IsNotBusy, CanLoadMore.
  • ObservableRangeCollection: Best way to group items into a Key/Value pair ObservableCollection for managing groups of data.
  • AsyncCommand: An async version of ICommand!

So, now you can just start your project and write code like this:

public class MonkeyViewModel : BaseViewModel
{
	public MonkeyViewModel()
    {
    	Title = "Monkeys";
    }

    public ObservableRangeCollection<Monkey> Monkeys { get; } = new ();

    AsyncCommand doStuffCommand;
    public AsyncCommand DoStuffCommand => doStuffCommand ??= new AsyncCommand(AsyncMethod);

    string name;
    public string Name
    {
    	get => name;
        set => SetProperty(ref name, value);
    }

    public Task AsyncMethod()
    {
    	return Task.CompletedTask
    }
}

Monkey Cache 🐵

This nice little caching library enables you to easily store data objects for set amount of times. For example you may want to cache web results for a few minutes. It integrates directly with the file system, SQLite, or LiteDB so you can write code like this:

public async Task<T> GetAsync<T>(string url, int minutes = 3)
{
    var json = string.Empty;

    if (!Barrel.Current.IsExpired(url))
    {
    	json = Barrel.Current.Get<string>(url);
    }
    else
    {
        json = await client.GetStringAsync(url);
        Barrel.Current.Add(url, json, TimeSpan.FromMinutes(minutes));
    }

    return JsonConvert.DeserializeObject<T>(json);
}

Wow, data caching in 3 lines of code! :)

PancakeView 🥞

My apps can not live without the PancakeView NuGet from Steven Thewissen. It gives your apps a breadth of new life with beautiful gradients, cards, custom rounded corners, and so much more. I mean look at this beautiful thing:

Sharpnado 🦈🌪

Alright, technically Sharpnado is a bunch of smaller libraries, but you get to pick and choose because there is so much awesome from Jean-Marie Alfonsi.

First is Sharpnado.Tabs... fully customizable Tabs that you can put anywhere!

Then there is Sharpnado.Shadows, because you know you need to add lovely shadows to all of your views.

That is just the start as there is a plethora more available including the TaskLoaderView, HorizontalListView, and MaterialFrame. You need these libraries!

Xamarin Community Toolkit 🧰

I am really jazzed about this initiative because it is an official package from the Xamarin team, but a deep collaboration with the community. This toolkit is a collection of controls, Animations, Behaviors, Converters, and Effects for mobile development with Xamarin.Forms. It simplifies and demonstrates common developer tasks building iOS, Android, and UWP apps with Xamarin.Forms. The NuGet is still in pre-release phase for testing, but is packed full of amazing functionality including:

  • Toast
  • Snackbar
  • AvatarView
  • MVVM Helpers (awesome stuff from my library)
  • C# Markup Extensions
  • Tons more!

Even More NuGets

These are just a few of my recommended NuGet packages that you should totally check out. There are a lot more awesome community libraries out there that you should checkout and I have a curated list on my GitHub!

]]>
Add ASP.NET Core's Dependency Injection into Xamarin Apps with HostBuilder https://staging.montemagno.com/add-asp-net-cores-dependency-injection-into-xamarin-apps-with-hostbuilder/ 5cc7df16b2f3d500bff4c9d0 Tue, 18 Jun 2019 21:53:00 GMT

Dependency injection(DI) and inversion of control (IoC), have been a recurring theme in questions that I have received over the last six years. Sometimes it is around using constructor injection(), simple service containers, and often around full frameworks such as Prism or MVVM Light. I will be honest with you, I have never been a fan of DI/IoC when building mobile apps. My main reason is that there has never been any official pattern or recommendations from Google or Apple (or Microsoft/Xamarin) when building Android and iOS apps. Also, I have always been worried around startup performance in my apps and didn't want to introduce another dependency. However, it is 2019 and I think that my concerns have finally been resolved after talking with my friend Glenn Condron, and here is why:

  1. There is a new official library from Microsoft that handles everything for you.
  2. Using this model gives you other powerful features like logging, HTTPClientFactory, and more.
  3. These devices are crazy powerful and the frameworks we use such as Xamarin.Forms, have really matured.

So, what is this magical library? It is the Microsoft.Extensions framework, but specifically the Generic Host framework that lives inside of Microsoft.Extensions.Hosting. It is a platform independent implementation of ASP.NET Core's extensibility framework.

Microsoft.Extenions

The cool part about this library is that if you already have been building ASP.NET Core applications, then you already know exactly how to use the library. Additionally, it means that just about every other library that extends it works with your Xamarin apps like app configuration, logging, HTTPClientFactory, Polly, and more! Let's start with the basics and first setup a HostBuild, which is the base for the Extensions library and then setup some dependency injection with constructor injection.

Installation and Setup

The first thing to do is to install the v3 pre-release Micosoft.Extensions.Hosting NuGet into all of our projects. This will give our projects access to the base foundation and also includes the ability to use the built-in logging framework and application configuration via a json file.

With the library installed we will create two files in our shared code (also if you are building a single iOS/Android app this will also work):

Startup.cs

Will host all of our HostBuilder configuration and setup all of the dependencies in our application. Here is the base foundation for the file with all of the using statements we will need:

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using Xamarin.Essentials;

namespace MyApp
{
    public static class Startup
    {
        public static IServiceProvider ServiceProvider { get; set; }
        public static void Init()
        {

        }

        static void ConfigureServices(HostBuilderContext ctx, IServiceCollection services)
        {

        }
    }
}

appsettings.json

This file will need to be set as an EmbeddedResource and will host configuration properties and settings. Here is a generic default appsettings file:

{
  "Hello": "World",
  "Environment": "Development",
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Debug",
      "System": "Information",
      "Microsoft": "Information"
    }
  }
}

Host Builder setup

The extensions library has a few main concepts to understand:

  1. HostBuilder: Acts as a builder for adding services (logging, app config, etc.) onto the app.
  2. IServiceProvider: Handles all dependency injection & acts as a service locator and comes from the HostBuilder.

Our Init method must be called from either the main Xamarin.Forms or platform specific app startup. We will fill in the Init method by getting a stream to the app settings file so the HostBuilder can read it, configure services, and setup the built in logging service:

var a = Assembly.GetExecutingAssembly();
using var stream = a.GetManifestResourceStream("MyAssemblyName.appsettings.json");

var host = new HostBuilder()
            .ConfigureHostConfiguration(c =>
            {
                // Tell the host configuration where to file the file (this is required for Xamarin apps)
                c.AddCommandLine(new string[] { $"ContentRoot={FileSystem.AppDataDirectory}" });

                //read in the configuration file!
                c.AddJsonStream(stream);
            })
            .ConfigureServices((c, x) =>
            {
                // Configure our local services and access the host configuration
                ConfigureServices(c, x);
            })
            .ConfigureLogging(l => l.AddConsole(o =>
            {
                //setup a console logger and disable colors since they don't have any colors in VS
                o.DisableColors = true;
            }))
            .Build();

//Save our service provider so we can use it later.
ServiceProvider = host.Services;

Configure Dependencies

We have setup our HostBuilder and called ConfigureServices, but we haven't done anything yet. So let's do it!

Let's say we have the following code for a ViewModel and a service that it needs to use:

public interface IDataService
{
    void DoStuff();
}

public class MyDataService : IDataService
{
    // We need access to the ILogger from Microsoft.Extensions so pass it into the constructor
    ILogger<MyDataService> logger;
    public MyDataService(ILogger<MyDataService> logger)
    {
        this.logger = logger;
    }

    public void DoStuff()
    {
        logger.LogCritical("You just called DoStuff from MyDataService");
    }
}

public class MockDataService : IDataService
{
    // We need access to the ILogger from Microsoft.Extensions so pass it into the constructor
    ILogger<MyDataService> logger;
    public MockDataService(ILogger<MyDataService> logger)
    {
        this.logger = logger;
    }

    public void DoStuff()
    {
        logger.LogCritical("You just called DoStuff from MockDataService");
    }
}

public class MyViewModel
{
    IDataService dataService;
    public MyViewModel(IDataService dataService)
    {
        this.dataService = dataService;
    }

    public void DoIt()
    {
        dataService.DoStuff();
    }
}

Here we have a ViewModel that needs access to the IDataService and one of the implementations needs access to a ILogger. This is where the ServiceCollection comes in allowing us to configure all of our dependencies. Let's setup the ConfigureServices method in the Startup.cs again and configure these new classes.

static void ConfigureServices(HostBuilderContext ctx, IServiceCollection services)
{
    // The HostingEnvironment comes from the appsetting.json and could be optionally used to configure the mock service
    if (ctx.HostingEnvironment.IsDevelopment())
    {
        // add as a singleton so only one ever will be created.
        services.AddSingleton<IDataService, MockDataService>();
    }
    else
    {
        services.AddSingleton<IDataService, MyDataService>();
    }

    // add the ViewModel, but as a Transient, which means it will create a new one each time.
    services.AddTransient<MyViewModel>();

    //Another thing we can do is access variables from that json file
     var world = ctx.Configuration["Hello"];
}

HostingEnvironment

Access Dependencies

With our HostBuilder and dependencies configured, we can now access them from anywhere. Since we only went up to the ViewModel level we will need to grab it from the ServiceProvider in the code behind from our page:

public partial class MainPage : ContentPage
{
    public MainPage()
    {
        InitializeComponent();
        BindingContext = Startup.ServiceProvider.GetService<MyViewModel>();
    }

    protected override void OnAppearing()
    {
        base.OnAppearing();
        ((MyViewModel)BindingContect).DoIt();
    }
}

When we call GetService the Microsoft.Extensions framework will handle creating and injecting any dependencies including our IDataService and the ILogger that came for free just by using the library. When we call DoIt in the OnAppering our app ill print out a message to the console using the logger that will have info of what data service it was using.

HTTPClientFactory In Your Xamarin App!

That's right, if you are using Microsoft.Extensions you can use the awesome HTTPClientFactory class that is essentially HTTPClient done right! It handles caching, retries, logging, and all other sorts of awesome! It is really easy to put into your app with just a few lines of code.

First, we will need to install the v3 prerelease Microsoft.Extensions.Http NuGet to get access to HTTPClientFactory. Then in the ConfigureServices method add the following line of code:

services.AddHttpClient();

With this single line of code in place it is now time to get access to the HTTPClientFactory from one of our classes. This is handled like our interface that was passed in as a parameter to the constructor. Microsoft.Extensions takes care of everything for you:

public class MyDataService : IDataService
{
    ILogger<MyDataService> logger;
    HttpClient client;
    public MyDataService(ILogger<MyDataService> logger, IHttpClientFactory httpClientFactory)
    {
        this.logger = logger;
        client = httpClientFactory.CreateClient();
    }

    public void DoStuff()
    {
        logger.LogCritical("You just called DoStuff from MyDataService");
    }
}

If you don't need access to the IHttpClientFactory at all this code can be simplified down to just passing in the HttpClient itself:

ILogger<MyDataService> logger;
HttpClient client;
public MyDataService(ILogger<MyDataService> logger, HttpClient client)
{
    this.logger = logger;
    this.client = client;
}

What is cool now is that when you make any calls with this HttpClient you will automatically get console logging, which is super helpful:

Response

To top it off you can even extend the HttpClient beyond just logging and introduce Polly into the mix with the Microsoft.Extenions.Http.Polly library that will enable you to automatically setup retries and other really cool features. You can find an example of this in my "First App Example" with ASP.NET Core + Xamarin

Platform Specific Dependencies

At this point you are probably like WOW, this is amazing, but what about platform specific implementations that I may need to get access to. Do not fear because it is totally possible and pretty easy to setup. Instead of calling the Init from your shared code, you can call it from your iOS/Android project and pass in a configuration Action like this:

First, let's modify the Init:

public static App Init(Action<HostBuilderContext, IServiceCollection> nativeConfigureServices)
{
    // Resource code

    var host = new HostBuilder()
                    //ConfigureHostConfiguration
                    .ConfigureServices((c, x) =>
                    {
                        //Add this line to call back into your native code
                        nativeConfigureServices(c, x);
                        ConfigureServices(c, x);
                    })
                    // Logging
                    .Build();
}

Then from inside of the Android project's MainActivity and iOS project's AppDelegate you can call this Init method:

Android Example

public class MainActivity : FormsAppCompatActivity
{
    protected override void OnCreate(Bundle savedInstanceState)
    {
        TabLayoutResource = Resource.Layout.Tabbar;
        ToolbarResource = Resource.Layout.Toolbar;

        base.OnCreate(savedInstanceState);

        //setup code

        Startup.Init(ConfigureServices);
        LoadApplication(new App());
    }

    void ConfigureServices(HostBuilderContext ctx, IServiceCollection services)
    {
        services.AddSingleton<INativeCalls, NativeCalls>();
    }
}

public class NativeCalls : INativeCalls
{
    public void OpenToast(string text)
    {
        Toast.MakeText(Application.Context, text, ToastLength.Long).Show();
    }
}

iOS Example

[Register("AppDelegate")]
public partial class AppDelegate : FormsApplicationDelegate
{
    public override bool FinishedLaunching(UIApplication app, NSDictionary options)
    {
        //Init Code:

        Startup.Init(ConfigureServices)

        LoadApplication(new App();

        return base.FinishedLaunching(app, options);
    }

    void ConfigureServices(HostBuilderContext ctx, IServiceCollection services)
    {
        services.AddSingleton<INativeCalls, NativeCalls>();
    }
}

public class NativeCalls : INativeCalls
{
    public void OpenToast(string text)
    {
        var vc = UIApplication.SharedApplication.KeyWindow.RootViewController;
        var okAlert = UIAlertController.Create(string.Empty, text, UIAlertControllerStyle.Alert);
        okAlert.AddAction(UIAlertAction.Create("OK", UIAlertActionStyle.Default, null));
        vc.PresentViewController(okAlert, true, null);
    }
}

Inject The Entire App

As you can see this framework is extremely flexible and allows for optimal extensibility, but you can go even further. As I was trying out this API Glenn challenged me to see how far I could take this dependency/constructor injection madness... so I took it all the way up to the app level. That is right, I injected the entire app, pages, and view models.... because why not! Well maybe you shouldn't do this, but it is pretty cool.

Keeping the same dependencies and view models from above all we need to do is update our MainPage, App, and Init calls:

MainPage

public partial class MainPage : ContentPage
{
    //simply pass in the view model you desire!
    public MainPage(MyViewModel viewModel = null)
    {
        InitializeComponent();
        BindingContext = viewModel;
    }
}

App

There are a few ways to do this. You could pass in the page that you desire into the App constructor or you could have some logic and grab it from the ServiceProvider:

public App()
{
    InitializeComponent();
    MainPage = ServiceProvider.GetService<MainPage>();
}

Update Init

This is where it gets pretty cool, we will create Transient and Singletons of all of the services, view models, pages, and the app itself and have the method return the App intead of being a void method.

public static App Init(Action<HostBuilderContext, IServiceCollection> nativeConfigureServices)
{
    //all of the same code from before
    return ServiceProvider.GetService<App>();
}

static void ConfigureServices(HostBuilderContext ctx, IServiceCollection services)
{
    services.AddHttpClient();
    services.AddSingleton<IDataService, MyDataService>();
    services.AddTransient<MyViewModel>();
    services.AddTransient<MainPage>();
    services.AddSingleton<App>();
}

Then, call Init from the LoadApplication method instead of calling Init randomly in the iOS/Android project:

LoadApplication(Startup.Init(ConfigureServices));

Just like that we dependency injected our entire application and that is crazy! If you want to try it yourself, you can grab my sample project from GitHub that shows off just about everything in this blog post.

Required Versions of Xamarin/VS

As of today, you should be able to develop and debug iOS/Android apps with all these goodies using any version of Visual Studio 2019 or Visual Studio for Mac 2019. However, if you want to use ship your app and turn on the Linker you will need to have a newer version of mono, which ships with Visual Studio 2019 16.2 (preview 2) and Visual Studio for Mac 2019 8.2 (preview). If you are on Windows you can easily install VS 2019 Preview side by side the normal release.

Watch The Build Session

I had the honor of presenting how ASP.NET and Xamarin can come closer in app model with Glenn in a 20 minute theater session. It is available on the Xamarin Developers YouTube channel:

Learn More

This stuff is super fun and I really hope that it takes off and we can encorporate it into user testing, and perhaps one day into the official templates! Until then it is easy to setup and can lead to some really clean and powerful code. Be sure to read through all of the great docs for Generic Host and through any of the extensions documentation. Enjoy!

]]>
Optimizing Xamarin Apps & Libraries with the Linker https://staging.montemagno.com/optimizing-xamarin-apps-libraries-with-the-linker/ 5b398519a4b3dd00bfb1cdad Thu, 13 Jun 2019 20:30:00 GMT The Xamarin linker is one of the most important pieces of technology when building mobile apps, that no one knows exists. It does all of the hard work for you, stripping out all unused code from libraries that you include in your apps. It should only be used in release mode as it takes extra time to compile your app, but means that your app will be smaller:

Capture

The linker has specific implementations for both iOS and Android and is completely customizable.

Linking for App Developers

Before I get to how to optimize libraries, let me go through when the linker actually kicks in and how app developers use it.

For the large majority of developers, all you need to know is turn on Link SDK Assemblies Only when your app is in Release (it is the default). This will only look to link and remove libraries that ship with Xamarin.iOS and Xamarin.Android. The other option is Link All Assemblies, which will look at every assembly and library that your app uses and attempt to link them. I always recommend Link SDK Assemblies Only as it is the safest and easiest to understand. The difference between the two in terms of application size is usually minimal and often when linking everything you can get in trouble as the linker can be aggressive and will remove more than needed, especially if you use reflection.

The linker is pretty customizable and you can tell it to ignore specific libraries in the project settings. For instance if you are building an app with Xamarin.Forms you probably want to leave all of Xamarin.Forms in there so you could add some flags to iOS and Android:

// iOS
 <MtouchExtraArgs>--linkskip=Xamarin.Forms.Platform.iOS --linkskip=Xamarin.Forms.Platform --linkskip=Xamarin.Forms.Core --linkskip=Xamarin.Forms.Xaml --linkskip=Samples</MtouchExtraArgs>

// Android
<AndroidLinkSkip>Xamarin.Forms.Platform.Android;Xamarin.Forms.Platform;Xamarin.Forms.Core;Xamarin.Forms.Xaml;Samples;FormsViewGroup;</AndroidLinkSkip>

You can learn more about this on the iOS and Android documentation.

Linking for Library Creators

For library creators it is super important to understand how the linker works, and how you can optimize your libraries for app developers. You never know when a developer may flip on Link All Assemblies or when the linker may get aggressive and link away some of your library.

Preserve Everything

There are instances where you are creating a library and always want to ensure that NOTHING is ever removed regardless of the linker setting. The [Preserve (AllMembers = true)] can be added to any class in your iOS or Android library and then the linker will ignore that class. I like to always test my library in Link ALL Assemblies mode and if something goes wrong and gets removed then I slap this on the class.

Linker Safe

Sometimes it is really important that unused code in your library is properly removed. This is where the [assembly:LinkerSafe] attribute comes in to inform the linker to include this library in ALL linking modes. This is cool because you are telling the linker that you have done the work to test your library and want it to be treated as if it was part of Xamarin.iOS or Xamarin.Android.

A great example of this is Xamarin.Essentials which is completely optimized with this property. It means that if you only use the Compass then that will be the ONLY chunk of code that is included in the app. This library was built and structured with the linker in mind with very little overlapping code, and each feature is implemented in it's own class.

When I started to look at my other cross-platform libraries I noticed that the PermissionsPlugin was starting to cause people some submission issues on iOS. This was because the library itself checks all sorts of different permissions and since I didn't optimize it for the linker, Apple was detecting usage of the APIs and started to require the info.plist to add permissions that weren't actually being used.

So, I turned on the [assembly:LinkerSafe] and thought everything was going to be fine... until I packaged up an app, extracted the dll from the final package and put it into dotPeek on Windows and found out that NOTHING was getting linked out:

AllItems

This fuzzy photo (sorry about that) shows that even though my code was only requesting one permission, all of the code was still there. Well, let's look at the code:

public async Task<Dictionary<Permission, PermissionStatus>> RequestPermissionsAsync(params Permission[] permissions)
{
    var results = new Dictionary<Permission, PermissionStatus>();
    foreach (var permission in permissions)
    {
        if (results.ContainsKey(permission))
            continue;

        switch (permission)
        {
            case Permission.Calendar:
                results.Add(permission, await RequestEventPermission(EKEntityType.Event));
                break;
            case Permission.Camera:
                results.Add(permission, await RequestAVPermissionStatusAsync(AVMediaType.Video));
                break;
            case Permission.Contacts:
                results.Add(permission, await RequestContactsPermission());
                break;
            case Permission.LocationWhenInUse:
            case Permission.LocationAlways:
            case Permission.Location:
                results.Add(permission, await RequestLocationPermission(permission));
                break;
            case Permission.MediaLibrary:
                results.Add(permission, await RequestMediaLibraryPermission());
                break;
            case Permission.Microphone:
                results.Add(permission, await RequestAVPermissionStatusAsync(AVMediaType.Audio));
                break;
            case Permission.Photos:
                results.Add(permission, await RequestPhotosPermission());
                break;
            case Permission.Reminders:
                results.Add(permission, await RequestEventPermission(EKEntityType.Reminder));
                break;
            case Permission.Sensors:
                results.Add(permission, await RequestSensorsPermission());
                break;
            case Permission.Speech:
                results.Add(permission, await RequestSpeechPermission());
                break;
        }

        if (!results.ContainsKey(permission))
            results.Add(permission, PermissionStatus.Granted);
    }

    return results;
}

At first, you are probably thinking like me that the linker obviously knows what Permission my app is passing in, so it would remove any case that wasn't being used. Nope, that linker is smart, but not that smart. If I call this method at all, the linker will include any method that is being used inside of it. This means that I would need to re-structure the entire library to make it linker safe. James Clancey came up with the amazing idea of breaking the mega method into smaller individual classes that compartmentalized functionality.

This is where the BasePermission came in:

public class BasePermission
{
    protected Permission permission;
    public BasePermission(Permission permission)
    {
        this.permission = permission;
    }

    public virtual Task<PermissionStatus> CheckPermissionStatusAsync() =>
#if __IOS__
        throw new NotImplementedException();
#else
        CrossPermissions.Current.CheckPermissionStatusAsync(permission);
#endif

    public virtual async Task<PermissionStatus> RequestPermissionAsync()
    {
#if __IOS__
        throw new NotImplementedException();
#else
        var results = await CrossPermissions.Current.RequestPermissionsAsync(permission);
        if (results.ContainsKey(permission))
            return results[permission];

        return PermissionStatus.Unknown;
#endif
    }
}

The code looks a little funny, but it has two virtual methods that on iOS have no implementation at all and must be implemented in a parent class. This means that when the linker sees the BasePermission on iOS it wont have any implementation and will get removed. Now, all I needed to do is create classes for each of the permissions such as this:

public class CameraPermission : BasePermission
{
    public CameraPermission() : base(Permission.Camera)
    {

    }
#if __IOS__
    public override Task<PermissionStatus> CheckPermissionStatusAsync() =>
        Task.FromResult(PermissionsImplementation.GetAVPermissionStatus(AVFoundation.AVMediaType.Video));

    public override Task<PermissionStatus> RequestPermissionAsync() =>
        PermissionsImplementation.RequestAVPermissionStatusAsync(AVFoundation.AVMediaType.Video);
#endif
}

public class ContactsPermission : BasePermission
{
    public ContactsPermission() : base(Permission.Contacts)
    {

    }
#if __IOS__
    public override Task<PermissionStatus> CheckPermissionStatusAsync() =>
        Task.FromResult(PermissionsImplementation.ContactsPermissionStatus);

    public override Task<PermissionStatus> RequestPermissionAsync() =>
        PermissionsImplementation.RequestContactsPermission();
#endif
}

On iOS you can see that I am calling into specific implementations for each permission check and request. This now means that even though the library contains 15 different permission classes if the calling app only uses 1 of them then it will be the only code that is included and there will be no more issues with app store submissions!

Some

The linker is pretty complex, but pretty awesome when you figure out how to optimize for it. If you are a library creator I encourage you to flip on this flag for your iOS and Android projects and give it a test drive. This will ensure that you always know if your library will work regardless of any linker setting.

Be sure to read through all the documentation I linked to and also check out [Jon Douglas' blog]9https://www.jon-douglas.com/2017/09/22/linker-analyzer/) on using the linker analyzer for Android. You can also watch me struggle on my live stream from a month back where I figured out all of this.

]]>
Resolving Android Support Library NuGet Installation Issues https://staging.montemagno.com/resolving-android-support-library-nuget-installation-issues/ 5b55f9fd982bf300bf388f92 Wed, 25 Jul 2018 19:15:00 GMT

Xamarin.Essentials has to be my favorite project that I have worked on at Xamarin so far. Bringing together over 30 native platform specific APIs into a single API that creates a linker safe and optimized library that so far has really delighted developers. I did some surveys last week and everyone could not stop saying positive things about the library, which is awesome! One thing stood out though that seems to be causing issues, which is how NuGet handles installing and updating Android Support Libraries.

I recently wrote an article outlining exactly what each of the Android API Levels means. It also highlights why you may see Version conflict detected when installing a library that depends on a support library and how to solve it. My friend Jon Dick took it a step farther and went into low level details on his blog and created an awesome video and we even added troubleshooting to our docs on how to solve this. I figure why not try again one more time on how to solve this if you are having issues installing Xamarin.Essentials, plugins, or other Xamarin.Android libraries.

Compile Against the Latest

Notice that I said COMPILE not Target! When we want to use newer Android Support Libraries we must ensure that we are compiling our android app against the correct version of Android. You can see what version of Android you must compile against to install a NuGet package for Android based on the dependency. Note that Xamarin.Essentials lists MonoAndroid,Version=8.1 aka Android 8.1 SDK 27.

Dependencies

As of today when you install Visual Studio 2017 you will receive Android 8.1 SDK, but if you have an older project you may have it compiling against an older version. Simply right click on your project and under Application you will see Compile using Android version: (Target Framework) and set it to Android 8.1.

Compile

Remember that this is the version of Android we use to COMPILE your application and has no effect over Minimum or Target Android versions, which live in the Android Manifest section of the project properties.

Resolving Version Conflict

I will not go too deep into why or how this is happening because Jon already did this in his post. Just remember that when you attempt to install Xamarin.Essentials or other packages that use Support Libraries you want to ensure that all of your Support Libraries are up to date and use the same version. In the case of my application I had Support version 27.0.2 installed, but Xamarin.Essentials required 27.0.2.1 of CustomTabs and Core.Utils which were not yet in my project so I received:

Version conflict detected for Xamarin.Android.Support.Compat. Reference the package directly from the project to resolve this issue.
 App10.Android -> Xamarin.Essentials 0.8.0-preview -> Xamarin.Android.Support.CustomTabs 27.0.2.1 -> Xamarin.Android.Support.Compat (= 27.0.2.1)
 App10.Android -> Xamarin.Android.Support.Design 27.0.2 -> Xamarin.Android.Support.Compat (= 27.0.2).

This error makes sense because I have 27.0.2 of a Support Library that depends on Support.Compat, but CustomTabs also depends on this library and needs 27.0.2.1 and NuGet doesn't know what to do.

There are a few solutions here:

Option 1: Update All NuGets First

If we know that Xamarin.Essentials needs 27.0.2.1 then just update all of your Support Libraries to this version.

Update

After doing this you will be able to install Xamarin.Essentials.

Option 2: Install Dependencies

One thing to do is not only update your Support Libraries, but also install any of the Support Library dependencies that the NuGet needs. You simply want to match the current version of the other support libraries first or update to 27.0.2.1 and then install both CustomTabs and Core.Utils.

Option 3: Update PackageReferences (My Favorite)

When all else fails or if you are like me and are tired of messing with the NuGet UI then you can just open up your Android projects .csproj and update the PackageReferences to ensure all support libraries are on 27.0.2.1 and also add the other libraries you need. Here is what mine looks like:

<PackageReference Include="Xamarin.Essentials" Version="0.8.0-preview" />
<PackageReference Include="Xamarin.Android.Support.Design" Version="27.0.2.1" />
<PackageReference Include="Xamarin.Android.Support.v7.AppCompat" Version="27.0.2.1" />
<PackageReference Include="Xamarin.Android.Support.v4" Version="27.0.2.1" />
<PackageReference Include="Xamarin.Android.Support.v7.CardView" Version="27.0.2.1" />
<PackageReference Include="Xamarin.Android.Support.v7.MediaRouter" Version="27.0.2.1" />
<PackageReference Include="Xamarin.Android.Support.Core.Utils" Version="27.0.2.1" />
<PackageReference Include="Xamarin.Android.Support.CustomTabs" Version="27.0.2.1" />

When you re-load your project the NuGet packages will re-load and everything will be happy.

Go Code

That is it! We have resolved all of our issues and you can continue coding! Leave comments below if you have any other questions.

]]>
Moving Plugins for Xamarin to .NET Standard https://staging.montemagno.com/plugins-for-xamarin-go-dotnet-standard/ 598df8f2c121b60019bf2fc3 Thu, 29 Jun 2017 17:27:13 GMT I could never imagine the amazing response to Plugins for Xamarin, those amazing little libraries that abstract away all that platform specific code into a lovely cross-platform API for iOS, Android, and Windows. They sure have grown, with hundreds of plugins being generated by the community and with tons of installs. My plugins alone have now hit 3 Million installations! With all this momentum it is a great time to look to the future, simplify plugins, and take the leap to .NET Standard.

Plugins

What is .NET Standard?

Great question! Essentially think of .NET Standard as the defacto way of sharing code across all .NET Platforms including Xamarin, .NET Framework, .NET Core, and others. Essentially all of these .NET Platforms implement a standard set of APIs so you as a developer can just create a library and share it everywhere. They are the evolution, improvement, and replacement for Portable Class Libraries, and I could not be more excited about it.

.NET Standard

I highly recommend you checkout our podcast episode of Merge Conflict, which you should totally listen to:

Merge Conflict 38: One Library to Rule Them All

The Big Move & More Platforms

There are actually two large changes that I have done to my plugins. First, each and every plugin’s “Abstractions” and Core for bait and switch have moved to .NET Standard 1.0. This means that you can easily add them into any .NET Standard library and are 100% backwards compatible with your PCL libraries! The other switch was more on the development side of the plugins, which I have moved fully to Visual Studio 2017 and C# 7. This means that all new versions of my plugins will no longer support Windows Phone 8 Silverlight, Phone 8.1 RT, or Windows Store RT (8.1). I additionally will no longer be accepting any new issues or fixing any bugs for those operating systems in any of my plugins. I don’t have the environment to maintain them so I can’t support them.

What will you support?

With the loss of these platforms comes the rise of other platforms being added into several of my plugins. All plugins today already support iOS, Android, and UWP, and I have done my best to add in macOS, tvOS, and watchOS support to plugins where they make sense, such as Settings, Connectivity, and Text to Speech.

The Brand New IsSupported Boolean!

Previously, when you installed a plugin on a platform that wasn’t supported (or you forgot to install the NuGet in the core project) and you tried to call the method it would simply throw an exception. This is still the case, but I tried to figure out a better way for developers to check to see if an implementation exists before making calls.

You can simply now call CrossPluginName.IsSupported to check if it exists. For instance:

There you have it, super simple way of checking!

Updated Android Support Libraries

In this big move I also took a big risk on deciding to make the break away from defaulting to version 23.3.0 of the Android Support Libraries in a few of my plugins. These libraries are now almost 3 years old and it is simply time to update them to the latest and greatest 25.3.1. Since you can update them now in Xamarin.Forms applications it is time! I even show you how to do it in this small Snack Pack episode of The Xamarin Show

It should be known that I don’t use Support libraries unless I absolutely have to, but if you are using Permissions, Media, Share, or Geolocator then you are going to have to update. Here is what you need to know:

Before you install or update your NuGets, ensure you have Android SDK for API 25 installed. You can watch my video on The Xamarin Show or simply click Tools->Android SDK Manager, deselect everything, and then select Android SDK 25, that is all you will need. Next, you need to go into your Android project settings and under General/Build make sure you select Android 7.0 and then go into your Manifest and set the Target to 25 too!

Set API Android

If you don’t do this you will see an error when trying to install the Android NuGet that you aren’t targeting the correct version of Android. That is what this error means. Go update!

Can I Haz NuGets?

As of the time of writing this article each and every Plugin for Xamarin that I have created now has a pre-release version available that introduces these changes. Over the next two weeks I will be transitioning all of them to the stable branch after a bit more testing and feedback from you!

]]>
Cross Platform Photos with Media Plugin https://staging.montemagno.com/cross-platform-photos-with-media-plugin/ 598df8f2c121b60019bf2fe5 Sun, 30 Oct 2016 23:10:30 GMT After months of work, contributions, code reviews, testing, new operating system releases, and tons of awesome new features the brand new Media Plugin for Xamarin and Windows is ready for mass consumption. Not matter how your developing your applications with Xamarin or Xamarin.Forms you can easily have your users take or pick photos and videos from shared code!

Here is the easiest example of taking a photo and displaying it in a Xamarin.Forms image.

takePhoto.Clicked += async (sender, args) =>
{
    await CrossMedia.Current.Initialize();

    var file = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions
    {
        Directory = "Sample",
        Name = "test.jpg"
    });

    if (file == null)
        return;

    image.Source = ImageSource.FromStream(() =>
    {
        var stream = file.GetStream();
        file.Dispose();
        return stream;
    });
};

Improvements

With this release I really focused on performance, memory optimizations, and adding new features that developers have been asking for. The top of the list has been Image Resizing when taking and picking photos. Now, all you need to do is set the PhotoSize in the Media Options:

PhotoSize = PhotoSize.Medium

This will shrink it in half, or you can simply specify a custom resize ratio:

PhotoSize = PhotoSize.Custom, CustomPhotoSize = 90

Better yet, I have also added a new way of compressing the image quality by just setting another parameter when taking or picking a photo:

CompressionQuality = 92

These can really help when displaying photos to users and when you don’t want a huge 2400x4600 photo saved locally. However, you may want to have the original photo saved to the users gallery, and the Media Plugin has you covered! Simply set:

SaveToAlbum = true

And what do you know the original photo will be saved to the camera roll on each device!

There are a bunch of other new features like specifying cropping on iOS and UWP, new permissions support for iOS 10 and Android N (new fancy File Providers), and even overlay support for iOS:

Optimizations

I have spent a lot of time on optimizing the code especially for Android. This means that photos will be automatically rotated based on Exif information, bitmaps are only loaded into memory when needed for continuous photo taking, and a plethora of other bug fixes that have been reported on the GitHub page. This release also has a nice update to the new Permissions Plugin that you can now get your hands on that has some awesome new features.

I am also really excited for all of the new documentation that I wrote up for this release, documenting just about every feature that I could and even including a lot of nice sample apps in the tests folders to check out.

What’s Next

I would  love to reach a new 3.0 release with some new optimizations including custom photo resizing to a max width and height, but would also love to hear what you want, or is it finally everything that you want :) Let me know on the GitHub Page.

]]>
Build Apps Faster with Plugins for Xamarin! https://staging.montemagno.com/build-apps-faster-with-plugins-for-xamarin/ 598df8f2c121b60019bf2ff7 Tue, 01 Dec 2015 22:03:50 GMT One of my favorite parts of mobile development with Xamarin is that I am not only creating fully native mobile application on iOS and Android, but that I also have 100% API access on those platforms. That means if I want to do something I can do something. However, after four years of mobile development I found myself doing the same things over and over again to access native APIs from shared code. If I wanted to adjust a setting, vibrate the device, or check connectivity I would abstract out an interface and then implent it on each platform. More than likely I would be copying from another application that I had created in the past. My good friend Luke Karrys once said if you ever have to write the same code twice it should be packaged up, and that is how Plugins for Xamarin were born.

A community effort to abstract away common APIs across iOS, Android, and Windows and package them up into small bitesize NuGet packages giving all developers a way to access these native APIs from shared code. In the last years (or so) since we started our original Plugins push nearly 100+ plugins have been created and are out there on NuGet and we have put together a hand currated list to browse through.

On my front I have created and worked on nearly 15 plugins that have gone through a lot of changes over the last year with nearly 100 GitHub issues squashed and plenty of updates along the way. Today, I am happy to announce updates to all of my plugins and some substantial changes that you will find when updating, that I am calling Plugins for Xamarin!

New Plugins!

That is right! In the last few weeks I have worked on a few new plugins and also with some amazing developers to update their plugins to align with the Plugins theming:

  • Compass: Easily access compass heading 0-360 degrees.
  • Local Notifications: Easily show and schedule local notifications.
  • Permissions: Check and request runtime permissions.
  • Share: Easily share text or open a browser.

Updated Plugins

Each and every plugin has been updated with new features, platforms, and yes some breaking changes, which you can read about a bit later on.

Here is a list of what I personally have created and updated:

  • Battery Status: Get battery level, how it is getting charged, and get notified when it changes.
  • Connectivity: See if device is connected to the internet and through what connection type.
  • Contacts: Currently in Beta to gather and query contacts
  • Device Information: Base information about each device such as OS and version.
  • Extended Maps: Launch navigation directions in default map app on each OS
  • Geolocator: Easy way of querying GPS location
  • Media: Take or pick photos/videos
  • Settings: Fully cross platform settings for your application.
  • Text To Speech: Turn your text into a vocal symphony on mobile devices.
  • Vibrate: Make that device rumble!

All of the new and updated plugins have a lot of awesome updates that aim to shorten development time for creating mobile apps. Here are a few enhancements that you will find.

Android Runtime Permissions

Last week I blogged about my new Permissions Plugin, which I beleive is one of my finest pieces of work when it comes to plugins, that solves the problem of checking and request runtime permissons from shared code (all asynce). This plugin was actually created so I could integrate it deeply into all of my other plugins. So now, if any plugin requires an Android runtime permission it will handle automatically requesting it for you, or you can using the Permission plugin to prompt when necessary. This incldes Contacts, Geoloator, and Media are all updated and ready to go.

Windows 10 UWP Support!

Windows 10 hasn’t been out long and Windows 10 Mobile is finally hitting some devices, but demand for plugin support has been high especially with the release of Xamarin.Forms 2.0 and its UWP preview. I am happy to announce that each and every one of my plugins that I have listed have been update with full Windows 10 UWP support in addition to Windows 8.1 RT support!

Lessons Learned

You will notice that all of the udpated plugins are officially 2.0.0! Yes that means there was a major number bump and that is because in the last year I have learned a lot about how developers are using the plugins and how they should have been structured from the beginning.

Don’t require Xamarin.Forms

This might have been the biggest mistakes when I setup the Plugins Templates was that I had the idea that Plugins could be used specifically only with Xamarin.Forms and not with traditional iOS, Android, and Windows apps. This is fine for controls or a specific framework that needs to deeply integrate with Xamarin.Forms, but not for Plugins. Plugins should simply NEVER require Xamarin.Forms. There are easy ways to access the Application Conetxt, ViewControllers, and I even released an amazing Current Activity plugin to get the current Activity in Android!

I have worked already with a few developers to update their plugins to remove the Xamarin.Forms restrictions and open them up to everyone. While it is a breaking change, it is for the best and I encourage everyone to follow suite if you have created a plugin or ping me and I will help out :)

Unified Namespaces

I was so close to perfection when I setup the templates for plugins that you could bring in a plugin and then type out “CrossFEATURE_NAME” to get access to it. However, there was one missign piece, which was that the namespaces for each plugin were completely different. I originally thought that this was a good idea, however talking with Mike James he said wouldn’t it be nice to type in “using Plugin.” and see all the plugins come up. He is right! So I made this change to each and every plugin I had access to :) This means that yes, I have broke all the plugins, but I promise never to do it again, and it is an simple change. I have also update the templates to reflect this.

Required Permissions by Default

This is a very small one, but in general I used to have a readme file with each plugin (still do for some) that told you which permissions you need to set for the different platforms. Little did I know that if a permission is required I should just set it and I can do so from the plugin itself. This means any plugin that requires an Android permission will automatically add itself to your Android Manifest :)

Get The Plugins!

So go forth and update the plugins now that you areaware of the changes as they have all been pushed to NuGet. Or start using some plugins and browse all of Plugins for Xamarin and Windows. In addition, I worked with the Xamarin University team to open up my Guest Lecture on plugins to be FREE for everyone!

Get Involved

If you are a library creator I urge you to take a look at all of the changes I have made to my plugins and make similar updates to really enhance the entire Xamarin development ecosystem. I have updated the Plugins for Xamarin templates with a lot of these changes already and would love to start highlighting even more amazing plugins, so please email or tweet at me about the plugins you have created.

]]>
Add NuGets To All Projects In Xamarin Studio with 1 Click https://staging.montemagno.com/add-nugets-to-all-projects-in-xamarin-studio-with/ 598df8f2c121b60019bf2fff Thu, 27 Aug 2015 23:26:48 GMT I simply love Matt Ward, a wonderful developer who works on NuGet inside of Xamarin Studio. He is always blogging about all of the recent updates to NuGet in XS, so be sure to follow his blog. Matt does so much more though including an awesome add-in for Xamarin Studio to add some awesome new features when using Xamarin Studio. My favorite feature is Solution Level adding of NuGet packages. Why do I love this feature? Well because I use tons of Plugins for Xamarin (and so should you). 

Installing and Using The Add-in

To get started all you need to do is go to the Xamarin Studio Add-in Manager.

You will need to turn on the alpha channel under the Gallery tab by selecting Manage Repositories:

Then turn on Alpha Channel, Hit Close, and then Refresh the list.

You will now see the NuGet Package Manager Extensions available under IDE extensions:

With the add-in installed you can now open up your cross platform native mobile app or create a new one. Now if I want to add my Settings Plugin to all of my projects all I have to do is Right Click on your solution and you will see “Manage Packages”. 

This will bring up an older NuGet package manager (not the new fancy official one), but you can search for a NuGet and then hit Manage to select which projects you want to install them in.

There you have it, easily adding NuGet packages at a solution level to all of your projects. You will then receive all of your normal updates Xamarin Studio offers and still have access to the per platform NuGet Package Manager.

]]>
More Plugins for Xamarin: Vibrate, Device Info, Connectivity, & Battery https://staging.montemagno.com/more-plugins-for-xamarin-vibrate-device-info/ 598df8f2c121b60019bf301a Fri, 26 Dec 2014 23:04:54 GMT I hope that everyone has been having a wonderful holiday season. Over the last month I have had one large goal; to create a plethora of Plugins for Xamarin. This desire to create plugins started a long time ago when I created my very first NuGet packages for cross platform settings. Once I iterated on the plugin and saw how successful and helpful it was I knew right away that I wanted to create more, which is where the idea of a cross platform text to speech plugin came from. I didn’t stop there though as more ideas came to my mind and we even launched a holiday contest with awesome prizes for anyone who also wanted to create a plugin. Here is a recap of the last few weeks:

An Easier Way to Develop

Immediately I realized that setting up projects for iOS, iOS Unified, Android, WP, WP RT, Windows Store, and the PCLs was a big pain if you had to do it all manually, so I wanted to solve this. With a bit of hard work and help from @Kzu I was able to introduce brand new Visual Studio templates for creating plugins and nuspecs. This makes it so you are immediately productive with a full project setup so you can start coding.

Vibrate

Have you ever wanted to tap into the vibration feature of your mobile device from a common API? Well here it is, simply call Vibration(int milliseconds); and you are done! Simple and effective.

Device Info

When using Xamarin.Forms I really enjoyed that I could execute specific functionality by checking the platform type from a PCL or shared code. So why shouldn’t you be able to do this normally? Device Info was born and also brought to the table the ability to get firmware version, device model, unique Id, and more.

Image Circle Control Plugin

Next up was something a bit different; a control plugin for Xamarin.Forms. I really like circle images, I mean I really like them a lot. In fact, I keep talking about them on dates that I go on and I even blogged about them over on the Xamarin Blog. So the Image Circle control plugin for Xamarin.Forms was introduced so no one else would ever have to write code to create circle images from scratch.

Connectivity

Creating online/offline mobile apps can be a bit tricky and each platform has a different way of figuring out if the device has connectivity. So instead of writing this code over and over again I decided to take it to the next level and create a connectivity plugin so you could just check to see if there is an internet connection. Even better is that you can subscribe to be notified when your user is disconnected!

Battery Status

This plugin started as a fun little project on my plane ride from Seattle to Austin for the holidays and ended up with me coding, testing, and releasing this plugin on Christmas Day! Check the current batter percentage left, the devices power source, and of course register for notifications when anything changes.

I love plugins for xamarin and they don’t just work on iOS and Android they all work on Windows Phone and most work on Windows Store as well. I hope that everyone will find these useful and inspire you to create your own plugin. If you are interested to see how I created these be sure to see the entire source code on my GitHub!

Happy Holidays!

]]>
What Exactly is a Plugin for Xamarin? https://staging.montemagno.com/what-exactly-is-a-plugin-for-xamarin/ 598df8f2c121b60019bf301d Sat, 06 Dec 2014 18:39:04 GMT I am so glad that you asked! I recently blogged about creating reusable plugins for Xamarin.Forms, and it might have caught you a bit off guard. Does Xamarin.Forms or Xamarin itself have plugins? The short answer is YES with the power of PCLs and NuGet.

Component vs. Plugin

For a long time, Xamarin developers have been able to add rich functionality to their mobile applications by adding Components from the Component Store. While you might consider these “plugins” of sorts, let me define what a plugin means to me.

Component When refer to Components, we’re generally talking about a library for Xamarin.iOS or Xamarin.Android that has been packaged for the Xamarin Component Store - similar to how a NuGet is a Library that has been packaged for the NuGet Gallery. Sometimes they have the same API, however sometimes they do not. For instance, Twilio has a great component that has very specific and tight integration with iOS and Android, and requires you to write code in the platform specific project.

Plugin

When I refer to a plugin for Xamarin, I am referring to a special kind of NuGet that adds cross-platform functionality or abstracts platform specific functionality to a common API. These are both completely cross-platform and extremely small (i.e., they do 1 or 2 things really well with minimal to no dependencies). The plugin API can be accessed on each platform; however, most likely you will only use the common API in a Portable Class Library or Shared Code project.

I like to use the name Plugin as it follows the same pattern as MVVMCross. In fact, nearly every single MVVMCross Plugin could be turned into a Plugin for Xamarin & Windows with a small amount of work so any Xamarin developer could take advantage of it.

I created my Vibrate and Settings Plugins specifically to provide simple examples of Plugins for Xamarin & Windows - but another great source for model plugins would be nearly anything that comes from Paul Betts, such as Akavache.

Xamarin.Forms or Xamarin plugin?

If you read my earlier blog post about creating plugins specifically for Xamarin.Forms, you might be wondering if you should create them for only Xamarin.Forms or if you should create a more platform independent Xamarin plugin. This is a great question as well and just remember that any “Xamarin plugin” would work in a Xamarin.Forms project. So, it really only depends on what you are trying to accomplish. If you intend to leverage some of the functionality that is built into Xamarin.Forms, or to create custom controls for Xamarin.Forms, then your plugin should be a “Plugin for Xamarin.Forms”.

If you are not using anything that explicitly depends on Xamarin.Forms, then you should really strive to make it completely platform independent, and leverage the Bait & Switch approach to target iOS, Android, and Windows Platforms. I tend to always attempt to target iOS, Android, and Windows Phone at minimum in all of my plugins to ensure compatibility with Xamarin.Forms.

Naming

After taking a few swings at this, I’ve found that following this naming scheme works pretty well:

  • Xamarin.Forms only:
  • Feature Plugin for Xamarin.Forms
  • Xamarin.iOS/Android/Mac:
  • Feature Plugin for Xamarin
  • Xamarin + Windows Platforms:
  • Feature Plugin for Xamarin and Windows

Replacing “Feature” with what your plugin does :)

If you want to learn more about creating plugins, be sure to check out my full repo on GitHub.

]]>
Xamarin Studio + NuGet PCL Support! https://staging.montemagno.com/xamarin-studio-nuget-pcl-support/ 598df8f2c121b60019bf303e Sun, 15 Dec 2013 22:05:10 GMT From @SharpDevelop comes a long awaited update to the Xamarin Studio NuGet Manager Plugin. I wrote about this plugin before, but with this update brings updated support for NuGet including PCLs for Xamarin.Android and Xamarin.iOS. It is extremely easy to add this functionality to Xamarin Studio and I made a short video to get you going.

Unable to display content. Adobe Flash is required.

]]>
NuGets Everywhere! VS or XS! https://staging.montemagno.com/nugets-everywhere-vs-or-xs/ 598df8f2c121b60019bf304b Wed, 21 Aug 2013 17:58:00 GMT Alright so a quick follow up to that huge blog I just wrote about PCLs. So PCLs are great for your core, but are also great because you can share PCLs with people and they will work everywhere. On Visual Studio there is a great Nuget Package Manager already that you can grab and install. If you are using Xamarin Studio you have a pretty great option as well with THIS Addin

Our team here at Ceton does a bit of cross development on both Mac and on Visual Studio. If you are doing WP or Windows Store apps then this is a must. I prefer to create all of my base solutions and projects inside of VS first. Get some Nugets going with the nuget manager and the most important part is to ENABLE NUGET PACKAGE RESTORE!!! Simply right click on your project and say… Enable Nuget Package Restore. This will allow you to sync up your nugets over on XS.

Alright so let’s say you got all your packages up and running in VS how do you sync them over in Xamarin Studio???

The first thing you will need to do is go into the .nuget folder that VS has created and you will find Nuget.targets. For some reason if you have nugets it will try to auto update them, if this is works for you then great, however XS has ALWAYS thrown an error for me, so I say hey let’s just do it manually. So a bit down you sill see somethign that says “NuGet command” after the platform specific code. Well let’s NOT let this run unless we are on windows so add “ Condition=” ’$(OS)’ == ‘Windows_NT’“ to that Property group

Alright awesome!!

So now you will have to create a script over on your MAC to update your Nugets.. This is kind of a pain but you only have to do it every once in a while.

1.) In terminal go to your_project/.nuget

2.) Make script executable "chmod 755 osxnuget.sh”

3.) Fill in the script: it should be something like this:

mozroots --import --sync
mono --runtime=v4.0.30319 NuGet.exe
mono --runtime=v4.0.30319 NuGet.exe install ../project.core/packages.config -Output ../packages
mono --runtime=v4.0.30319 NuGet.exe install ../project.test/packages.config -Output ../packages
mono --runtime=v4.0.30319 NuGet.exe install ../project.ui.android/packages.config -Output ../packa

4.) Run it with “./osxnuget.sh”

If XS was open simply restart it.

Boom you are good to go again!

]]>