Plugins - James Montemagno https://staging.montemagno.com/tag/plugins/ https://staging.montemagno.com/content/images/2017/08/MonogramIcon_Orange_NoBuffer.png Plugins - James Montemagno https://staging.montemagno.com/tag/plugins/ Hugo -- gohugo.io Tue, 13 Oct 2026 20:48:55 GMT 60 Upgrading to Xamarin.Essentials from Plugins https://staging.montemagno.com/upgrading-from-plugins-to-xamarin-essentials/ 5b3ee4e62a21a600bf2b04f5 Wed, 19 Sep 2018 18:52:00 GMT

Xamarin.Essentials is a new official library from Microsoft (that I worked on) that provides developers with over 30 cross-platform APIs for their mobile apps to tap into to access native features. Yes, this may sound similar to Plugins for Xamarin, but it is an evolution that is super optimized for each plaform, provides a consistent API, and is super crazy well documented. And of course it is completely open source on GitHub!

Essentials

Why Upgrade?

A lot of developers have asked me why they should upgrade their apps, that have been using Plugins for a long time, to Xamarin.Essentials. Here is my list:

  1. This is an OFFICIAL package from the Xamarin team at Microsoft.
  2. It is super optimized and Linker Safe!
  3. All of your favorite plugins are there.
  4. Only has 1 assembly to help boost your app's startup time.
  5. Super consistent API across all features.
  6. Because it is awesome and super well tested.

Also because I upgraded one of my apps and it reduced that app's assemblies from 47 to 35 and even reduced the application size from 22.7MB to 22.2MB! Because it is crazy optimized!

With Xamarin.Essentials we started over from the beginning and we were able to craft new APIs for features, which means it wasn't just a copy and paste of plugins out there. We re-thought each and every API, optimized them with new code paths for each platform, integrated unit tests and samples, and documented the heck out of them.

This means if you are moving from Plugins to Essentials there is a tiny bit of work you need to do.

Getting Started

We have a great Getting Started Guide that outlines everything you need to know on how to install the NuGet package that you need. Be aware that since it is a single NuGet package this means on Android we DO NOT automatically add permissions, so read the docs on each API to see what you need to add.

The APIs!

I will try to cover as many of my Plugins as I can, but I am sure I will miss some of them. Here we go!

Settings Settings Icon

My settings plugin was not only my first plugin that I ever created, but it also is my most popular plugin with over 1.4 Million NuGet installs over the years. Xamarin.Essentials replaces and upgrades it with the Preferences API. The APIs are extremely similar, but fixes a lot of small things that had been lingering around in my code. It is a very smooth transition as they both use the same default locations to store preferences and even allow for a specific name to be passed in.

Preferences API Access

  • Plugin: CrossSettings.Current.
  • Essentials: Preferences.

Preferences API

  • GetValueOrDefault -> Get
  • AddOrUpdateValue -> Set

The key difference here is that Set simply is a method void call and saves the value every time.

While the new preferences API saves to the same places it doesn't support all of the value types that the Settings Plugin does like decimals. I should have never supported these as I have to store them as string, but you can convert it easily like this:

public decimal MyDecimal
{
   get
  {
       var savedDecimal = Preferences.Get("mykey",  Convert.ToString(0, CultureInfo.InvariantCulture));
       return Convert.ToDecimal(savedDecimal, CultureInfo.InvariantCulture)
   }
   set { Preferences.Set("mykey", Convert.ToString(value, CultureInfo.InvariantCulture)); }
}

In addition to the core APIs you could also open the app settings page on the device. This can now be done in the AppInfo API of Essentials:

  • CrossSettings.Current.OpenAppSettings(); -> AppInfo.OpenSettings();

Connectivity Plugin connectivity-icon

Oh connectivity plugin... I love you! My second most popular plugin out there that has helped developers detect if there is an internet connection for several years. This is also an easy one as many of the APIs are packed into Xamarin.Essentials Connectivity API. There is a little bit of setup for permissions that you should do if you want to check connection types.

Connectivity API Access

  • Plugin: CrossConnectivity.Current.
  • Essentials: Connectivity.

Connectivity API

  • IsConnected -> NetworkAccess (now returns an enum)
  • ConnectionTypes -> Profiles
  • ConnectivityChanged & ConnectivityTypeChanged -> ConnectivityChanged (all rolled into 1 nice event)

So you can replace this:

if (!CrossConnectivity.Current.IsConnected)
{
    //we are offline
}

with this:

if (Connectivity.NetworkAccess != NetworkAccess.Internet)
{
    //we are offline
}

APIs that don't exist

  • IsReachable & IsRemoteReachable: You can read my full analysis on GitHub as to why we did not include this, but long story short I should have never included these. It really makes no sense to try to ping a site to see if it is there instead of just making the web request.
  • Bandwidth: Never really was a need and super inconsistent.

App Version / Version Tracking version-tracking-icon

I simply love our App Info API that gives you all sorts of info about your application. You may have been using other plugins such as DeviceInfo or VersionTracking, but you can just use AppInfo now:

App Info API Access

  • Essentials: AppInfo.

App Info API

  • Name
  • PackageName
  • VersionString
  • BuildString

There is also a new Version Tracking API that is nearly a 1 to 1 replacement for the old plugin.

Version Tracking API Access

  • Plugin: CrossVersionTracking.Current.
  • Essentials: VersionTracking.

Version Tracking API

  • Track(); -> Track();
  • IsFirstLaunchEver -> IsFirstLaunchEver
  • IsFirstLaunchForVersion -> IsFirstLaunchForCurrentVersion
  • IsFirstLaunchForBuild -> IsFirstLaunchForCurrentBuild
  • CurrentVersion -> CurrentVersion
  • PreviousVersion -> PreviousVersion
  • FirstInstalledVersion -> FirstInstalledVersion
  • VersionHistory -> VersionHistory
  • CurrentBuild -> CurrentBuild
  • PreviousBuild -> PreviousVersion
  • FirstInstalledBuild -> FirstInstalledBuild
  • BuildHistory -> BuildHistory

There are a lot of enhancements to this API including that it just uses the built-in Preferences API instead of serialization and file IO.

Share Plugin share-plugin

The share plugin kept growing and started to add tons of APIs for no good reason including opening the browser or setting text on the clipboard. Don't worry though because Xamarin.Essentials has a Data Transfer, Clipboard, and Browser API built right in!

API Access

  • Plugin: CrossShare.Current.
  • Essentials: Browser.
  • Essentials: Clipboard.
  • Essentials: DataTransfer. (this is Share)

Browser API

  • OpenBrowser -> OpenAsync
  • BrowserOptions -> BrowserLaunchType (no current open to specify colors)

Clipboard API

  • SetClipboardText -> SetText
  • NEW API -> GetTextAsync

Data Transfer API

  • Share -> RequestAsync
  • Pass in a ShareTextRequest which specifies text or a uri.

Device Information device-info-plugin

I loved to hate my Device Info plugin becaues it had a lot of great ideas and a lot of bad ideas such as the original implementation of ID and a bunch of other random methods. This has all been fixed with Xamarin.Essentials and the Device Information API, and the addition of the Device Display API that adds the ability to get information about the device's screen metrics, which is very nifty.

API Access

  • Plugin: CrossDeviceInfo.Current.
  • Essentials: DeviceInfo.

DeviceInfo API

  • Model -> Model
  • Manufacturer -> Manufacturer
  • DeviceName -> Name
  • Version -> VersionString
  • AppVersion -> Now: AppInfo.VersionString
  • AppBuild -> Now AppInfo.BuildString
  • Platform -> Platform
  • Idiom -> Idiom
  • IsDevice -> DeviceType

Geolocator geolocator-icon

Another popular plugin of mine that was originally brought over from the old Xamarin.Mobile code base. Xamarin.Essentials has built this API from the ground up on each platform and really thought about what developers need from this API. That is why there are actually two APIs that developers can use and a standardization on what a Location and Placemark is. So hopefully any other APIs could start using these. The first API is Geolocation which is how to get the cached location or current location on the device. Also Geocoding enables getting the Placemark for a Location. As of right now there is no tracking of location changes, but that is on the roadmap.

API Access

  • Plugin: CrossGeolocator.Current.
  • Essentials: Geolocation.
  • Essentials: Geocoding.

Geolocation API

  • GetLastKnownLocationAsync -> GetLastKnownLocationAsync
  • GetPositionAsync -> GetLocationAsync

Geocoding API

  • GetAddressesForPositionAsync -> GetPlacemarksAsync
  • GetPositionsForAddressAsync -> GetLocationsAsync

Text-to-Speech text-to-speech

My plugin has gone under a lot of changes over the year and I have learned a lot that went into the new Text-to-Speech API in Xamarin.Essentials.

API Access

  • Plugin: CrossTextToSpeech.Current.
  • Essentials: TextToSpeech.

Text to Speech API

  • Speak -> SpeakAsync
  • GetInstalledLanguages -> GetLocalesAsync

Vibratevibrate-icon

Another simple tranisition to the Vibrate API and even adds some new methods. For Android be sure to setup permissions correctly in your Android Manifest.

API Access

  • Plugin: CrossVibrate.Current.
  • Essentials: Vibration.

Vibration API

  • Vibration -> Vibrate
  • NEW API -> Cancel

Battery battery-plugin

When you need to check the battery status of the device the Battery API is for you! We also have a new Power API that will help you detect if the device is in power saver mode too!

API Access

  • Plugin: CrossBattery.Current.
  • Essentials: Battery.

Battery API

  • RemainingChargePercent -> ChargeLevel (0 to 1.0)
  • Status -> State
  • PowerSource -> PowerSource
  • BatteryChanged -> BatteryChanged

Wrapping Up

If you made it this far then I am impressed and want to give you a big hug! Xamarin.Essentials is pretty fantastic and I hope that you see how easy it is to change over from Plugins, that it has the ability to shrink your app size and help with startup time by reducing your total assemblies in your app.

One thing to note is that my plugins aren't going away any time soon. Many of them will go into maintenance mode as I push developers towards Xamarin.Essentials. The key difference is that many of my plugins for better or worse support a lot of different platforms that aren't supported yet in Essentials.

There are also some plugins that I plan on supporting long term as they provide functionality not yet in Essentials such as Permissions and Store Review or features that aren't planned at all such as IniApp Billing.

]]>
Continuous Integration & Delivery for Xamarin & .NET Libraries with Azure DevOps (VSTS) https://staging.montemagno.com/continuous-integration-delivery-for-net-libraries-with-vsts/ 5af5cc81dc592200bfc9400b Mon, 21 May 2018 19:20:00 GMT I build a lot of .NET libraries that include simple .NET Standard libraries to fully cross-platform plugins for Xamarin and Windows that target up to 10 different platforms. When I got started building libraries and shipping them to NuGet I went down a simple path of just building everything locally on my machine and manually uploading them to NuGet. This worked great for a single library, but as soon as I took on a second... third... forth... and so on, things got out of hand and I knew I had to put some sort of CI/CD in place. I went down many paths over the years and have now settled on using Visual Studio Team Services to fully automate the build of every library I create and a full distribution pipe line that goes to MyGet then to NuGet preview, and finally NuGet public release with a click of a button. Now I can develop and let VSTS handle everything for me so I can be productive:

If you look at this screenshot from VSTS it is everything that I wanted for so long in my development cycle. I push code, things are built, and automatically packages are pushed. In this post I am going to show you how I set this up for my projects and how you can too in just a few minutes.

.NET Standard and Multi-Target Projects

Before we start to setup our CI/CD for libraries I highly recommend you move your projects to SDK style projects. You can read my full guide on how to convert a PCL to .NET Standard or how to convert a Xamarin.iOS or Xamarin.Android project to SDK Style.

Everything that I develop now is based on a single .NET Standard 2.0 library or a Multi-Targeted project for plugins. I have previously written on how to convert your PCLs to .NET Standard and also have templates for Visual Studio 2017 to create Multi-Target projects for plugins.

SDKStyle

The reason to use these types of projects is that they include full NuGet packaging including all metadata and dependencies. This also means you can fully delete the .nuspec file that always gets out of sync. It is worth your time to update any and all projects to these types of projects to simplify your life.

If you need to learn more about multi-targeting be sure to check out Oren's amazing MSBuildSdkExtras package which is the core of my templates and all of my projects.

If you are building only an iOS or Android library do not fear as you can still just convert your existing library over to an SDK Style. Take a look at my MonoDroid.Toolkit csproj on GitHub.

Build Definition in VSTS

My builds inside of VSTS are actually really simplistic and only contain 6 steps to fully build my libraries. You can use the Hosted Visual Studio 2017 machines, however I have a small Intel NUC that runs a local VSTS agent so all my NuGets are cached which reduces my build times to seconds instead of minutes.

Empty Definition

Select New and pick your source code that you would like to build. I then like to select Empty process because we can easily fill it in.

Empty

NuGet Steps

Under Phase 1 we are going to add two NUGet steps.

First is the NuGet Tool Installer task and change the Version to 4.5.1

NuGetInstaller

Second will be the regular NuGet task which we will use the restore command on our solution that we are going to build. I like to pick the specific .sln or folder where it lives (no need to build other stuff).

NuGetRestore

Build Steps

I build my libraries twice! That is right twice! Once for a "beta" NuGet and once again for "public" NuGet. They are super quick and all it is really doing is changing the version flags. The reason I do this is for my release definition that will allow me to have a single release that goes from beta to public easily. We will be building the .csproj specifically using the MSBuild task:

MSBuild

We will add it twice so we can build the beta and public releases. Name the first Build Beta and the second Build Public. For each of them set the following:

  • Project: Select the .csproj specifically
  • Configuration: $(BuildConfiguration)

For MSBuild Arguments user the following for Beta:

/t:restore;build;pack /p:PackageVersion=$(Build.BuildNumber)-beta /p:PackageOutputPath=$(build.artifactstagingdirectory)/beta /p:AssemblyFileVersion=$(Build.BuildNumber)

For Public use:

/t:restore;build;pack /p:PackageVersion=$(Build.BuildNumber) /p:PackageOutputPath=$(build.artifactstagingdirectory)/public  /p:AssemblyFileVersion=$(Build.BuildNumber)

This will ensure that the build numbers are configured correctly and copy the artifacts to different folders.

Optionally, you may have some additional unit tests or device runners that may need to be run here.

Copy and Publish

The next thing to add is the Copy Files task to stage the NuGet packages for release.

Set these properties:

  • Source Folder: $(build.sourcesdirectory)
  • Contents: **\bin\$(BuildConfiguration)\**\*.nupkg
  • Target Folder: $(build.artifactstagingdirectory)

Finally, add the Publish Build Artifacts task and set the following:

  • Path to publish: $(build.artifactstagingdirectory)
  • Artifact name: drop
  • Artifact public location: Visual Studio Team Services/TFS

This will pull only .nupkg files that we will distribute into a folder that release can pick up.

All in all the definition should look like:

AllDone

Configure Version Number

Under the Options tab in the build definition I like to format the Build number format such as: 4.5.0$(rev:.r)

This means that the next version would be: 4.5.0.1 and then 4.5.0.2.

Now if you change this to: 5.0.0$(rev:.r) it will reset the revision so it will be 5.0.0.1.

Other things!

You will probably want to setup *Triggers so CI and PR validation are configured. This means that every time master is pushed to a package is generated.

Release Definition in VSTS

Now we have our full build complete it is time to setup our release. Our goal for me was to automatically have every build of master go to MyGet and then manually approve the next release to go to NuGet (beta) and finally another approval to go to NuGet with the public non-beta package.

Battery-CD-1

Head over to the Releases section and create a new release definition with an Empty process. Think of Environments as the stages of release. We can create three of them to define each release of the artifacts. Inside of each environment are a sequence of tasks, just like our build definition, that will be run. For my libraries it is really simple as each has just one task. However, before the NuGet beta and production environments I turn on pre-deployment approval steps.

Push to MyGet

In our first environment we will want to push to MyGet. Add the NuGet task with the following settings:

  • Command: push
  • Path to NuGet package: $(System.DefaultWorkingDirectory)/**/drop/beta/*.nupkg
  • Target Feed: External NuGet server

For this step you will want to configure the feed information from MyGet:

MyGet

Push NuGet Beta

For this step you can select Clone or if you already create the new environment simply add the NuGet task again. The settings will be the same as above:

  • Command: push
  • Path to NuGet package: $(System.DefaultWorkingDirectory)/**/drop/beta/*.nupkg
  • Target Feed: External NuGet server

However, we will now want to select or configure NuGet as our destination:

NuGet

Head back to Pipeline and for this environment we don't want it to automatically trigger, we want to approve this release. You will see a lightning bolt and a person shape on the left side of the environment to configure pre-deployment conditions. I turn on pre-deployment approvals and select myself and turn off the policies since I am a solo developer:

predeploy

There is all sorts of rad stuff you can do here on pre and post-deployment so you should totally look into that for larger projects.

Push NuGet Production

Add or clone another environment for after the Beta environment. This is going to be almost the same as the previous step but we are going to change our Path to NuGet package:

  • Command: push
  • Path to NuGet package: $(System.DefaultWorkingDirectory)/**/drop/public/*.nupkg
  • Target Feed: External NuGet server

Notice I am using public here :)

Add Artifact

Finally, click the big Add artifact button on the left side and select the build definition that you created earlier. Also tap on that little lightning bolt and turn on the Continuous deployment trigger so this flow automatically happens!

CI/CD Pro!

You did it! You are totally a Continuous integration and delivery pro!! Enjoy a seamless deployment of every push to master to MyGet and then approval steps to push to NuGet for any and all of your .NET Libraries. <3 Feel free to ask questions below.

]]>
Converting Xamarin Libraries to SDK Style & Multi-Targeted Projects https://staging.montemagno.com/converting-xamarin-libraries-to-sdk-style-multi-targeted-projects/ 5af9d3b5dc592200bfc94017 Mon, 14 May 2018 22:00:00 GMT If you are like me you may have a lot of standard Xamarin.iOS and Xamarin.Android libraries sitting around. They aren't plugins, but they do extend a single platform with custom functionality and controls. Wouldn't it be great if you could update them to the new SDK Style projects which use Package References, auto-NuGet packaging, and load WAY faster?!?!? It is all crazy simple to do just like converting old PCLs to .NET Standard. If you are setting up CI this is going to be a huge time saver as you can set it up in VSTS in minutes (blog coming this week).

Unload that Project

First things first, we need to get at that raw .csproj madness. Right click on the project and click Unload Project. Then right click again and select Edit *.csproj:

UnloadProject

Delete Everything!

That is right! Delete it all because we don't need it at all!

Replace it with my base project information. It is a bit verbose but based on the type of library you are creating there are some special things that you may want to include such as Android resources.

Note: I like to only compile items that end in .shared.cs, .ios.cs, or .android.cs to keep it tidy, but you can easily change what you compile into your library in the project structure.

Right click and re-load the project!

New-project

Spice it up

Now you can go in and any NuGets you may need with the PackageReference node in the ItemGroup of your choosing. Additionally, you can also turn on Multi-Targeting to generate both an iOS and Android (or whatever else like UWP and netstandard) by change TargetFramework to TargetFrameworks and specifying more frameworks.

Multi-Target

NuGet that Library

What is great about the SDK style projects is that you don't need a .nuspec at all for your NuGet and it can be generated automatically at build time! Whoa! Amazing Yes! You can also see the contents with the NuGet Package Explorer

All you need to do is turn on GeneratePackageOnBuild in the Release property group and then add the following items to the main PropertyGroup for the NuGet's information:

You can read more about these attributes over on the NuGet documentation.

Now when you compile in release mode you get a full NuGet with your library:

NuGet-1

SDK and Multi-Target Everything

If you have multiple libraries like me or building multiple libraries from a single solution you can also look into Directory.Build.props and Directory.Build.targets that enable you to group common properties together for a full solution.

I have gone through just about every project I have created and switched over to this new style of project because CI is so simple with it that I can manage a full CI/CD cycle for all of my libraries from one location:

Release

Check back later this week for my blog on how to take the SDK style projects that we have here and set them up for CI in VSTS.

See Me Convert a Library Live!

Because I love seeing things in action I walk through the exact steps here in this short video:

]]>
Monitoring Android Activity Lifecycle Events: Return of Current Activity Plugin https://staging.montemagno.com/monitoring-android-activity-lifecycle-events-return-of-current-activity-plugin/ 5ac403ec03c88a002224ef90 Wed, 11 Apr 2018 20:18:00 GMT It has been nearly two and a half years since I wrote about how to easily get access to the current Android Activity with just a few lines of code. This code led to the creation of my Current Activity Plugin for Xamarin.Android apps and library creators to easily get access to the current Activity. Since then it has been the core of many of my plugins and has been installed over 600,000 times from NuGet!

CurrentActivity

Times change and it is time for an update to this near perfect library. If you have ever used this library or had it as a dependency then you will remember a magical MainApplication.cs file that would get added to your application. This laid down everything that the plugin needed to track the current Activity state with IActivityLifecycleCallbacks. While this was a really simple use case it sometimes ran into issues when developers already had a custom Application class and more over now that Package References are the default for Visual Studio this file no longer gets added to the project.

Automatic Tracking

Thanks to the mastermind Jon Dick who I am working with on some new libraries and pointed out that instead of having developers write their own custom Application or rely on a magical file that I could just create my own IActivityLifecycleCallbacks and have a simple Init call. On top of that I could preserve backwards compatibility with any installations of 1.0!

How can this be? Well I created my own lifecycle listener and now there is just a tiny bit of setup inside of your existing custom application or main activity:

Main/Base Activity Level

Simply call the Init method on OnCreate:

CrossCurrentActivity.Current.Init(this, bundle);

Application Level

Add a new C# class file in you project called "MainApplication.cs". Override the OnCreate method and call the Init method:

#if DEBUG
[Application(Debuggable = true)]
#else
[Application(Debuggable = false)]
#endif
public class MainApplication : Application
{
    public MainApplication(IntPtr handle, JniHandleOwnership transer)
      : base(handle, transer)
    {
    }

    public override void OnCreate()
    {
        base.OnCreate();
        CrossCurrentActivity.Current.Init(this);
    }
}

Extended API

In version 1.0, I simply returned the current Activity as part of the plugin, but now I expose a new event that is triggered when any activity lifecycle changes and access to the current Context:

void Register()
{
    CrossCurrentActivity.Current.ActivityStateChanged += Current_ActivityStateChanged;
}

private void Current_ActivityStateChanged(object sender, ActivityEventArgs e)
{
    Toast.MakeText(Application.Context, $"Activity Changed: {e.Activity.LocalClassName} -  {e.Event}", ToastLength.Short).Show();
}

ActivityPlugin-1

Try it Today

You can grab a copy of version 2.0 today on NuGet. Throughout the month of April I will be updating all of my plugins to use this new version. I am really excited for it and hope that you find it useful. If you are building a library that depends on CurrentActivity please update to version 2.0 today!

]]>
Connectivity Plugin 4.0: Important and Awesome Changes https://staging.montemagno.com/connectivity-plugin-4-0-important-and-awesome-changes/ 59b1e003d65cfa0022681a47 Fri, 08 Sep 2017 00:47:05 GMT

The Connectivity Plugin for Xamarin is my second most installed NuGet package with nearly 600,000 installs at time of writing this. It is easy to see why as it gives developers the ability to check connectivity on any platform with a single line of code, subscribe to events, and see what the current connection type is, with a complete cross platform API for iOS, Android, macOS, and Windows.

Connectivity

I mean look at this thing, it is beautiful:

if(CrossConnectivity.Current.IsConnected)
{
    //You are connected to the internet!!!
}

However, there is a feature that isn't used as much that let's developers ping a local or remote host to see if the device can connect to it. This is often good to use when you want to see if your web host or API is up and running before making full network calls to pull down data.

This "Ping" support was implemented a few different ways across iOS, Android, and Windows, which lead to a few rare issues based on how the developers were using the API. This has all changed with the standardization of checking for reachability in version 4.0, which is available in pre-release today, and took me a long time and a lot of code to refactor with Frank Krueger. So much that I even tweeted about it.

API Changes

In the past the API wasn't really clear if developers should use:

Task<bool> IsReachable(string host, int msTimeout = 5000);
or
Task<bool> IsRemoteReachable(string uri, int port = 80, int msTimeout = 5000);

In addition, what is with the weird port and what is with timeout in milliseconds! The API is now much cleaner:

Use:

  • IsReachable: to check a hostname such as a machine name or IP address
  • IsRemoteReachable: to check reachability of a full valid URI

They now take in a bit different parameters:

Task<bool> IsReachable(string host, TimeSpan timeout);
Task<bool> IsRemoteReachable(string uri, TimeSpan timeout);
Task<bool> IsRemoteReachable(Uri uri, TimeSpan timeout);

This means that you can simply add the port into the URI or the string, which will be converted to a URI.

Notice that everything now uses TimeSpan for the timeout :) very nice!

Under the hood upgrades

One of the original problems with IsReachable on iOS/macOS was that there is actually no built in APIs to ping a local IP address or hostname. This is why I asked very nicely for our components team to create a C# binding around Apple's SimplePing and push it up to NuGet so I can consume it!

On Android things are even more tricky as the old code only attempted to use Java.Net.InetAddress to check for reachability.... which actually doesn't work with hostnames. Now, it detects if you passed it an IP Address and checks, else simply just attempts to resolve the actual hostname.

When it comes to IsRemoteReachable each platform was using different mechanisms to do the same thing. This is no good! This is .NET and we have Sockets! Every platform now uses Socket Streams as their core.

Test it today

If you are using the Connectivity Plugin with these methods in your application, I encourage you to test it out today and give feedback on GitHub.

]]>
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!

]]>
Unit Testing Plugins for Xamarin https://staging.montemagno.com/unit-testing-plugins-for-xamarin/ 598df8f2c121b60019bf2fce Thu, 06 Apr 2017 15:32:23 GMT So you love unit testing…. said no one ever, but you are forced to write unit tests and you want to use Plugins for Xamarin which are all singletons and need platform specific implementations or they will throw an exception in your tests…. what to do?!?!? Plugins are all interface based, which means all we have to do is use standard practices to not directly call the singleton, and setup our code to return the instance we want. In unit tests we can return a Mock (or Moq) of the interface, and in our standard code the singleton.

Let’s take the Connectivity Plugin (my most popular plugin), which checks for connectivity and event changes. There is no code that is laid down and you are encouraged to use the singleton of CrossConnectivity.Current.IsConnected, but that would be an issue in a unit test project or installed into something else that it isn’t supported. Unless we structure our code a bit differently, like this:

This code is structured pretty well actually, and how I would encourage you to use Plugins, which is to just have a property that returns the single, or returns it from your Dependency Service/IoC. If we need to unit test this puppy all we need to do is change that get property to a get and set property and make it static so we can set it in our unit tests.

Now, all we need to do is simply create a mock that implements IConnectivity and then set it in our unit tests.

There you have it, you can install any plugin into any unit test project, but it may or may not have an implementation… and really you don’t want to rely on the implementation in the unit test project as you want full control. You can roll your own mocking framework or use one that is available. Just think of it as an interface.

]]>
Opening App Store for Ratings on iOS and Android https://staging.montemagno.com/opening-app-store-for-review-on-ios-and-android/ 598df8f2c121b60019bf2fd8 Fri, 20 Jan 2017 19:45:11 GMT Sometimes you want to ask your users to rate your application. There are several components out there that will open a dialog box and prompt for ratings, but sometimes you don’t want to stop the flow of your app and throw it in their face. What I do in my application is simply add a section on my settings page asking if they would like to rate the app. When pressed I launch the app store directly to the review page:

Update!

This is now easier than ever with my Store Review Plugin! Just a single line of code and you are good to go!

Original blog post

This is pretty simple to do for iOS and Android by launching a specific URL scheme. To do this, we will use two differnt plugins:

For iOS you will need to decide what URL you want to use based on the OS versions you support as each have different URLs:

* **Lower than iOS 7:** ``` itms-apps://itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?type=Purple+Software&id=YOUR_APP_ID ```

  • iOS 7:
itms-apps://itunes.apple.com/app/idYOUR_APP_ID
  • iOS 8 or later:
itms-apps://itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?id=YOUR_APP_ID&amp;onlyLatestVersion=true&amp;pageNumber=0&amp;sortOrdering=1&amp;type=Purple+Software

I only target iOS 8 and later so I will use that item. All you need to do is replace the “YOUR_APP_ID” with your actual APP ID from your iTunes connect page.

Update! Recently Apple updated the store to simply append on action=write-review onto the end such as:

var url = $"itms-apps://itunes.apple.com/app/id{appId}?action=write-review";

From the looks of it this works all the way back to iOS 8.

For Android, you will need the URL of your app on Google Play:

https://play.google.com/store/apps/details?id=YOUR_APP_ID

The Code! Let’s do this

It is actually really simple now:

var url = string.Empty;
var appId = string.Empty;

if(CrossDeviceInfo.Current.Platform == Platform.iOS)
{
    appId = "your_id";
    url = $"itms-apps://itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?id={appId}&amp;onlyLatestVersion=true&amp;pageNumber=0&amp;sortOrdering=1&amp;type=Purple+Software"
}
else if(CrossDeviceInfo.Current.Platform == Platform.Android)
{
    appId = "your_id";
    url = $"https://play.google.com/store/apps/details?id={appId}"
}

if(string.IsNullOrWhiteSpace(url))
  return;

await CrossShare.Current.OpenBrowser(url, new BrowserOptions
{
    UseSafariWebViewController = false
);}

Boom, there you have it! The app store for both iOS and Android will open up and you are good to go.

Enjoy!

]]>
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.

]]>
Simplified iOS & Android Runtime Permissions with Plugins! https://staging.montemagno.com/simplified-ios-android-runtime-permissions-with/ 598df8f2c121b60019bf2ff8 Wed, 25 Nov 2015 18:09:38 GMT TLDR; I created a brand new cross-platform Permissions Plugin for Xamarin to enable anyone to query and request common permissions from shared code. You can watch a video here.

Permissions! Blarg!

As an Android developer I have felt pretty spoiled over the last few years when it came to getting access to an API that required a permission. Simply check a checkbox in the project setting and any of the 130+ permissions were mine to have! The user installed my app and automatically granted me every permission my little heart desired. I took a look at what those poor iOS developers (and myself) had to implement in their apps to request a permission, get a callback, and then handle revoking of permissions from users! That looked like no fun at all. Well, Android developers had it too good for too long and now with the release of Android Marshmallow users are back in control with the introduction of Runtime Permissions, and I honestly think it is for the better. However, this means for developers we now have to go off and check permissions on multiple platforms, with different APIs, and no shared code. 

First, let’s take a look at what we would have to do for both iOS and Android to get access to grab the users location.

iOS:

  1. Add NSLocationWhenInUseUsageDescription or  NSLocationAlwaysUsageDescription to info.plist.

  2. Create new CLLocatonManager

  3. Check we have the permission

  4. Request correct permission if needed

  5. Register for callbacks when authorization changes

Here is what it would look like:

void RequestLocationPermission()
{

    var locationManager = new CLLocationManager();

    EventHandler authCallback = null;

    authCallback = (sender, e) =>
        {
            if(e.Status == CLAuthorizationStatus.NotDetermined)
                return;

            locationManager.AuthorizationChanged -= authCallback;
            //do stuff here
        };

    locationManager.AuthorizationChanged += authCallback;

    var info = NSBundle.MainBundle.InfoDictionary;
    if (info.ContainsKey(new NSString("NSLocationWhenInUseUsageDescription")))
        locationManager.RequestWhenInUseAuthorization();
    else if (info.ContainsKey(new NSString("NSLocationAlwaysUsageDescription")))
        locationManager.RequestAlwaysAuthorization();
    else
        throw new UnauthorizedAccessException("On iOS 8.0 and higher you must set either NSLocationWhenInUseUsageDescription or NSLocationAlwaysUsageDescription in your Info.plist file to enable Authorization Requests for Location updates!");
}

Android:

  1. Add correct permissions to AndroidManifest
  2. Check permissions on API 23+
  3. Check if need to show rationale (user revoked or denied)
  4. Request permissions
  5. Do this every single time before you make a call!

Here is what that would look like:

async Task GetLocationCompatAsync()
{
  const string permission = Manifest.Permission.AccessFineLocation;
  if (ContextCompat.CheckSelfPermission(this, permission) == (int)Permission.Granted)
  {
    await GetLocationAsync();
    return;
  }
if (ActivityCompat.ShouldShowRequestPermissionRationale(this, permission))
{
//Explain to the user why we need to read the location
Snackbar.Make(layout, "Location access is required to show coffee shops nearby.", Snackbar.LengthIndefinite)
.SetAction("OK", v => ActivityCompat.RequestPermissions(this, PermissionsLocation, RequestLocationId))
.Show();
return;

}

The Problem

It is pretty clear that this code is pretty tedious to write and it has to be done in the actual iOS or Android projects, which is a complete bummer. While we have been forced to write this code for years, I say NO MORE! Last week I set out on a goal of creating my next Plugins for Xamarin to solve Permissions once and for all. Here was the goal:

  1. Simple Cross-platform Async API that should:

  2. CheckPermisssion - Simply check the permission

  3. ShouldShowRationale - Tell us if the user revoked access on Android

  4. RequestPermissions - Any amount that you would like!

  5. Work on a wide array of iOS and Android permissions that require runtime checks

Today, I am pleased to introduce my latest Plugin that does just this, Permissions Plugin for Xamarin! This will not only simplify permissions on a per platform basis, but also from shared code such as Xamarin.Forms. More importantly though it will enable Library creators to deeply integrate with the SDKs without having to worry about writing all the permission code. Did I mention it is all async??!?!?! 

Permissions I Handle

The nice thing is that there are just 9 “permission groups”  (about 30+ permissions) on Android that have to be checked and about the same on iOS currently. Here is a full listing of everything the library can do:

  1.   Calendar (Android: Calendar, iOS: Events)

  2.   Camera (Android: Camera, iOS: Camera Roll & Camera)

  3.   Contacts (Android: Contacts, iOS: AddressBook)

  4.   Location (Android: Location, iOS: CoreLocation (Always/WhenInUse))

  5.   Microphone (Android: Microphone, iOS: Microphone)

  6.   Phone (Android: Phone, iOS: Nothing)

  7.   Photos (Android: Nothing, iOS: Photos)

  8.   Reminders(Android: Nothing, iOS: Reminders)

  9.   Sensors (Android: Body Sensors, iOS: CoreMotion)

  10.   Sms (Android: Sms, iOS: Nothing)

  11.   Storage (Android: External Storage, iOS: Nothing)

Implementation

All in all I have to say that iOS permission requesting is pretty straight forward. You just have to go in aware that each library has its own way of handling permissions, different enums, and different callbacks to handle. If you read through the documentation for each of these APIs you will see that they are pretty identical except that you have different types of status: AVAuthorizationStatus, ABAuthorizationStatus, EKAuthorizationStatus, CLAuthorizationStatus, and more! Each of these actually have a common type though of Granted, Denied, Restricted, or Unknown. I decided copy most of these when returning a PermissionStatus to you:

  1. Denied

  2. Disabled (feature is disabled, such as locatio)

  3. Granted

  4. Restricted

  5. Unknown

To hand the fact that there is a mixture of Async calls to check the status of these permissions and no way to actually request them async I simply used a TaskCompletionSource on every single call such as:

Task RequestPhotosPermission()
{
    if (PhotosPermissionStatus == PermissionStatus.Granted)
        return Task.FromResult(PermissionStatus.Granted);

    var tcs = new TaskCompletionSource();

    PHPhotoLibrary.RequestAuthorization(status =>
        {
            switch(status)
            {
                case PHAuthorizationStatus.Authorized:
                    tcs.SetResult(PermissionStatus.Granted);
                    break;
                case PHAuthorizationStatus.Denied:
                    tcs.SetResult(PermissionStatus.Denied);
                    break;
                case PHAuthorizationStatus.Restricted:
                    tcs.SetResult(PermissionStatus.Restricted);
                    break;
                default:
                    tcs.SetResult(PermissionStatus.Unknown);
                    break;
            }
        });

    return tcs.Task;
}

Android on the other hand is a bit more tricky. To check a permission this can be done on the activity or the application context, which is what I will use if you are trying this on a background service.

To request a permission you actually need an Activity and then you have to actually override a method on the activity to handle the request. This is obviously an issue because I am writing a library and can’t access the Activity you are on. Well, that used to be the case until I created the CurrentActivity plugin! Enabling you, me, or any library creator to get access to the current activity! 

This means a new MainApplication.cs file will get installed when you install the plugin, so be sure to read all about that! Now that I have the Activity the next issue to overcome is that fact that the API I created takes in my enum of a permission group, but Android requires you request all of the Manifest permissions you have specified for that group. This means that yes you will still need to add the permissions to your manifest, but I do a reverse lookup to see what you have listed in the AndroidManifest and those are what I request! What!!!! Amazing! I know! However, there is one small caveat here, which is whatever Activity you are requesting from you will have to notify my library when the call is returned by simply adding the following lines of code:

public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults)
{
PermissionsImplementation.Current.OnRequestPermissionsAsyncResult(requestCode, permissions, grantResults);
}

If you are supporting more than iOS/Android and have a bunch of Windows apps, do not fear as I added in dummy implementations for all flavors of Windows and .NET so permissions will return true.

In Action

Finally I get to just show you the code! It is actually super straight forward. Let’s say you want to request the location using the Geolocator library (although it does check permissions in the upcoming version 2.0.0).  Here are the calls in a PCL (Xamarin.Forms app hence the DisplayAlerts):

try
{
    var status = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Location);
    if (status != PermissionStatus.Granted)
    {
        if(await CrossPermissions.Current.ShouldShowRequestPermissionRationaleAsync(Permission.Location))
        {
            await DisplayAlert("Need location", "Gunna need that location", "OK");
        }

        var results = await CrossPermissions.Current.RequestPermissionsAsync(new[] {Permission.Location});
        status = results[Permission.Location];
    }

    if (status == PermissionStatus.Granted)
    {
        var results = await CrossGeolocator.Current.GetPositionAsync(10000);
        LabelGeolocation.Text = "Lat: " + results.Latitude + " Long: " + results.Longitude;
    }
    else if(status != PermissionStatus.Unknown)
    {
        await DisplayAlert("Location Denied", "Can not continue, try again.", "OK");
    }
}
catch (Exception ex)
{

    LabelGeolocation.Text = "Error: " + ex;
}

Grab the NuGet & Code

Last week I pushed all the code up to GitHub and made the NuGet packages available for all. I will be integrating the Permissions plugin into all of my other Plugins that require permission checking. I also recorded a Motz Codes Live with a full walkthrough.

]]>
DataBinding Settings in Xamarin.Forms https://staging.montemagno.com/databinding-settings-in-xamarinforms/ 598df8f2c121b60019bf2ffb Wed, 07 Oct 2015 15:12:02 GMT For nearly four years now I have been using my cross-platform settings plugin to save preferences across all the different platforms. Ever since I pushed it up to NuGet it has been extremely popular with over 18,000 installs! The plugin gives you a very simple way of saving out native settings from shared code. Usually, you will create a native UI for each platform and in the case of Android use the PreferenceActivity to automagically create a settings page from XML (which is magical), but what if you are using Xamarin.Forms and want to databind stuff up? This is the exact question I got over on StackOverflow. Of cource you can, let’s do it.

Given this Settings Class:

public static class Settings
{

    private static ISettings AppSettings
    {
        get
        {
            return CrossSettings.Current;
        }
    }

    const string CountKey = "count";
    private static readonly int CountDefault = 0;

    public static int Count
    {
        get { return AppSettings.GetValueOrDefault(CountKey, CountDefault); }
        set { AppSettings.AddOrUpdateValue(CountKey, value); }
    }
}

Approach 1: Essentially you need to create a view model with a public property that you wish to data bind to and then call into settings from there and raise a property changed notification if the value changed. Your Settings.cs can stay the same but you will need to create the viewmodel such as:

public class MyViewModel : INotifyPropertyChanged
{

    public int Count
    {
        get { return Settings.Count; }
        set
        {
            if (Settings.Count == value)
                return;

            Settings.Count = value;
            OnPropertyChanged();
        }

    }

    private Command increase;
    public Command IncreaseCommand
    {
        get
        {
            return increase ?? (increase = new Command(() => Count++));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

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

}

Then you XAML will look like this inside your Content page:

<StackLayout Padding="25">
 <Button Text="Increase" Command="{Binding IncreaseCommand}"/>
 <Label Text="{Binding Count, StringFormat='The count is {0:F0}'}"/>
</StackLayout>

Make sure you set the BindingContext in the xaml.cs of the page:

public partial class MyPage : ContentPage
{
    public MyPage()
    {
        InitializeComponent();
        BindingContext = new MyViewModel();
    }
}

This actually isn’t too much code to actually implement as your ViewModel would have a BaseViewModel that implements INotifyPropertyChanged, so really you are just adding in

public int Count
{
    get { return Settings.Count; }
    set
    {
        if (Settings.Count == value)
            return;

        Settings.Count = value;
        OnPropertyChanged();
    }
}

Approach 2: More magical way

However, using the powers of C# and knowing how Databinding works you could first create a BaseViewModel that everything will use:

public class BaseViewModel : INotifyPropertyChanged
{
    public Settings Settings
    {
        get { return Settings.Current; }
    }
    public event PropertyChangedEventHandler PropertyChanged;

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

Notice my reference to Settings.Current, we will need to implement that now as a singleton, but we will use our BaseViewModel so we don’t have to re-implement INotifyPropertyChanged:

public class Settings : BaseViewModel
{
    static ISettings AppSettings
    {
        get
        {
            return CrossSettings.Current;
        }
    }

    static Settings settings;
    public static Settings Current
    {
        get { return settings ?? (settings = new Settings()); }
    }

    const string CountKey = "count";
    static readonly int CountDefault = 0;

    public int Count
    {
        get
        {
            return AppSettings.GetValueOrDefault(CountKey, CountDefault);
        }
        set
        {
            if (AppSettings.AddOrUpdateValue(CountKey, value))
                OnPropertyChanged();

        }
    }
}

Now of course we will still want to create a unique ViewModel that our XAML view will bind to:

public class MyViewModel : BaseViewModel
{
    private Command increase;
    public Command IncreaseCommand
    {
        get
        {
            return increase ?? (increase = new Command(() => Settings.Count++));
        }
    }
}

Notice that we are now inheriting from BaseViewModel, which means our command can actually just increment Settings.Count! But now we must adjust our Xaml just a bit as to what we are actually data binding to for our label:

<StackLayout Padding="25">
 <Button Text="Increase" Command="{Binding IncreaseCommand}"/>
 <Label BindingContext="{Binding Settings}" Text="{Binding Count, StringFormat='The count is {0:F0}'}"/>
</StackLayout>

Notice I am setting the BindingContext to our Settings, which is in our BaseViewModel for the Label, this must be done because that is where it is located now. And there you have it.

]]>
Coffee Filter: A C# Powered Android App in 2 Days https://staging.montemagno.com/coffee-filter-a-c-powered-android-app-in-2-days/ 598df8f2c121b60019bf3011 Thu, 05 Mar 2015 17:45:58 GMT I love coffee. You will normally find me riding my bike around Seattle stopping from coffee shop to coffee shop indulging in a 8oz quad lattes, strong black coffee, or probably a shot in the dark. So when I set out to blog about the new Google Maps Lite API it was pretty obvious what I needed to do… create an app showing me the closest coffee shops around me. In that moment Coffee Filter was born! What was interesting to me and hopefully to you was how I was able to think up Coffee Filter, design, implement, test, and ship to Google Play in under 48 hours. More than half of those hours I was either asleep or on a plane! Let’s take a look at how it was created.

Material Design First

I immediately knew I wanted to use AppCompat and leverage material design as much as I could. I followed my own blog post on how to integrate Support v7 into my app and re-used all of the styles and colors xml. This was pretty tedious to setup and made me question why there aren’t project templates for these…. aka I know what I am doing this weekend :) 

Next was choosing my material palette and integrating different assets. I immediately went to http://www.materialpalette.com/, which is an amazing resource to help you put some colors together for your app. Then I headed over to the Android Asset Studio, every Android developers #1 bookmark, to generate a few icons for the app. If you are looking for some inspiration be sure to check out http://www.materialup.com for awesome material designs.

Tight Code Challenge

Monday night couldn’t have ended better. I got to sit down at my favorite restaurant, Thai Tom, to indulge in a Pad Thai Chicken with one my best friends Frank Krueger. I told Frank about Coffee Filter and my current UI design with Google Maps Lite and I could tell ideas were igniting in his brilliant mind. He enhanced my currenty UI idea with a new enhancement of flipping through coffee locations with a map hiding behind them. The UI would mostly be informational with nice large fonts telling me where to go get coffee. However, what Frank said next was very interesting, which was that he challenging me to write Coffee Filter in as little lines of code as possible. That meant no big MVVM framework, not over architected, just go go go. 

I took this challenge mostly to heart and didn’t introduce any data binding or IPropertyChanged notifications. I still separated out my Models and View Models into a nice re-usable section, but just didn’t add any framework into the mix. The entire app is actually around 650 lines of code including using statements and comments, which to me is very impressive.

Plugins for Xamarin

The reason for nice tight code was actually because of plugins. Plugins abstract away a bunch of cross platform functionality, which is where most of the code actually lives, so I didn’t have to write it. When I started writing plugins for Xamarin a while back I didn’t know how often I would actually use my own, but I found immediate use of three:

Get the App & the Code

My favorite part of Android development is being able to package up an app and have it on Google Play within two hours. This means that yes, Coffee Filter is available right now: https://play.google.com/store/apps/details?id=com.refractored.coffeefilter. Of course you know I love open source, so you can grab the code for Coffee Filter on GitHub: https://github.com/jamesmontemagno/Coffee-Filter. It even includes some brand new Xamarin.UITests that can be run on a simulator or Test Cloud, which is pretty awesome. I am not done yet with Coffee Filter though as I will be adding more details to each coffee shop, refactoring, taking feedback, fixing bugs, and of course leveraging my shared code with iOS.

]]>