Azure - James Montemagno https://staging.montemagno.com/tag/azure/ https://staging.montemagno.com/content/images/2017/08/MonogramIcon_Orange_NoBuffer.png Azure - James Montemagno https://staging.montemagno.com/tag/azure/ Hugo -- gohugo.io Tue, 13 Oct 2026 23:21:57 GMT 60 Introducing Island Tracker for Animal Crossing New Horizons https://staging.montemagno.com/introducing-island-tracker-for-animal-crossing-new-horizons/ 5eb04dd46c478d00392fb981 Sat, 09 May 2020 17:25:00 GMT

tldr; I built a new iOS & Android app called Island Tracker that enables you to track turnip prices, get predictions, and share them with friends. It is available today.

Get it on: Download on the App Store Android app on Google Play

When Animal Crossing New Horizons launched in late March I fell in love immediately. My wife adopted my Nintendo Switch Lite and we both got copies the night of release. Over on the Nintendo Dispatch podcast, we call it the perfect game at the perfect time. It truly has been for us during this time of staying inside away from all of our closest friends. Each day we dig up fossils, shake trees, give gifts to neighbors, visit islands and collect things for our museum.

However, something is different each Sunday morning at our house. We wake up and race to our Switch to see what price we can buy bundles and bundles of turnips. Then throughout the week we are constantly bugging our friends to see what we can sell them for, in hopes that someone has a huge spike and we can make a mad profit. After a week of text message madness, my must solve everything with a mobile app mind went to work and Island Tracker was born.

Island Tracker screens for sharing turnip prices with friends, tracking prices, weekly predictions, and an island profile

Island Tracker enables you to easily track your turnip purchases on Sunday and then track your prices throughout the week. You can easily get predictions, see if you are up or down, and then share your prices with all of your friends with a click of the button! Through weeks of beta testing with Animal Crossing die hards, I have even added some really cool features such as sharing your Switch Friend Code and nifty calculators to make buying turnips a breeze. After weeks of development, architecting, testing, and getting ready for release, Island Tracker is available right now on Google Play for Android and the Apple App Store for iOS for $2.99. Need some convincing? Here is a full walk through:

The Tech Behind Island Tracker

As you would expect the entire application is completely open source and available on GitHub. The application shares around 98% shared source code between iOS & Android, leveraging Xamarin.Forms for the user interface and C# business logic. There are tons of great libraries that I leveraged to build the app including PancakeView, Sharpnado, Syncfusion, MvvmHelpers, Monkey Cache, App Center, Xamarin.Essentials, and Resizetizer.NT.

For the backend system I leveraged Azure Functions combined with Azure Table Storage. With just a few Tables I was able to achieve some really cool functionality with a full friends system, encryption, and no-signup users.

Diagram of the phone app exchanging data with Azure Functions, which reads and writes Azure Table Storage

If you are interested in how it all works checkout this YouTube video I shot on the entire process.

A Huge Thanks

There is an amazing Xamarin community making awesome libraries that really helped me be productive throughout the process. I built a lot of the app live on my Twitch stream and got tons of great feedback and help. Then there is the hard work of Mike Bryant and Steve aka sparkie108 who ported tons of the predictions code to JavaScript and then to  C# to use in the app, which is awesome! Finally, thanks to all of my awesome beta testers that gave me feedback all throughout the last month really making the app spectacular.

What's Next

Well, it is out! I am super proud of this app and hope that people enjoy it and make tons of bells in Animal Crossing! I will continue to improve the app, add new features, and make it the best Animal Crossing app that I can! Cheers <3

Get it today: Download on the App Store Android app on Google Play

]]>
Deploying an ASP.NET Core app to Linux on Azure App Service https://staging.montemagno.com/aspnet-core-azure-linux-app-service-deployment/ 598df8f2c121b60019bf2fd2 Tue, 28 Feb 2017 22:46:07 GMT You probably wouldn’t expect this blog post from me as I run away from building any web apps, but I have been messing around with ASP.NET Core inside of Visual Studio for Mac. I thought it would be really cool to take our default app for items and deploy it to an Azure Linux based App Service. Because… why not?!?! Also, I will make Hanselman proud.

So, first things first.. The backend.

My Items on ASP.NET Core

If you head over to your Visual Studio for Mac you will see a “Connected App” template. This outputs an iOS and Android app that can talk to a localhost ASP.NET Core application that runs on your macOS machine! Whoa Cool!. Now make sure you have the latest RC4 of .NET Core installed. It isn’t the one on the home page of .NET Core.. it is hidden in a GitHub readme: https://github.com/dotnet/core/blob/master/release-notes/rc4-download.md

If you just want the source code for the app to play around with you can grab it from my GitHub. Now, once we have the source code we can run the site and navigate to /api/item to retrieve the default lists of items:

Linux App Service

Looking good! Next up, Let’s create our Azure App Service that will run on Linux (in preview today). Head to your Azure Portal and hit New -> Web + Mobile + Web App on Linux (preview):

This will go through the standard setup process and bring you in to your standard app service settings. The first thing that we need to do is adjust our Docker Container. We want to select .NET Core v1.0 runtime stack and REALLY REALLY IMPORTANT to set the startup file. This file is the main DLL of our application. We will be uploading our files to the wwwroot.

Build

I decided to throw all of my code in Visual Studio Team Services (VSTS) and do some good DevOps work to make Donovan Brown proud. You could also just put your code on GitHub if you would like and VSTS will also build it. To actually build it, is crazy easy actually, just select ASP.NET Core (PREVIEW).

This literally does everything for you! I have disabled tests and I have my dotnet commands pointing to a subfolder, but that is about it:

Release

Now, let’s publish this thing. The build will give us a zip file to use and normally you would use Web Deploy and done… but that doesn’t work on Linux just yet… and Kudu… not yet.. and all the continuous git stuff… not yet… so let’s FTP the files! In the azure portal you can grab your FTPs user name and password that you will need.

There are 4 steps needed in the release definition:

  1. Stop App Service

  2. Extract Zip File

  3. Upload Files

  4. Start App Service

1, 2, and 4 are easy with minimal config, but #3 you must specify the remote directory of /site/wwwroot

Whoa!! we did it!!

Fun fact… Preview inside of VSTS and the Azure portal in this blog post alone are cased 3 different ways :)

]]>
Going Serverless with Azure Functions: SendGrid https://staging.montemagno.com/going-serverless-with-azure-functions-sendgrid/ 598df8f2c121b60019bf2fde Thu, 22 Dec 2016 18:48:57 GMT A while back I wrote an app called MyShoppe, which served as a sample application that would enable any business owner with multiple locations to build an app to help their customers get store information and leave feedback. This was more than just a sample application as I built the original application for my brother who has several stores in Texas.

The Old Backend

The app isn’t overly complex. I leveraged Azure Mobile Apps (at the time Mobile Services) as a backend to do online/offline sync with an ASP.NET website so I could write everything in C#. The only thing that the backend was really doing was validating an admin app that I had created when Keith logged in and then it would send an email leveraging SendGrid to Keith whenever someone left feedback.

The New Backend

The app was getting out of date and iOS 10 basically broke the UI, so I had to update it. I decided to simplify the application and get rid of my ASP.NET backend (mosty because I didn’t have the code anywhere) and move to a simplified nodejs backend (even though I hate javascript). The issue of course would be that I would need to handle authentication and sending emails via javascript instead of the nice and pretty C# code that I had in my old ASP.NET backend. No worries though as Azure Functions came to the rescue since I could shove any heavy logic off to the C# world.

Azure Functions 101

If you aren’t aware of what Azure Functions are, let me give you a 101 crash course really quick. Basically think of functions as event based or trigger based methods that get invoked that have inputs and outputs. For instance a trigger could be a HTTP Post and the output could be an email via Send Grid, or perhaps the input is someone uploaded something to blob storage and you want to take it as in input and re-scale it. There are tons of great examples. For my needs I thought… well I could literally send a web request to an Azure Function and write all my parsing and SendGrid logic in C# (Function can actually be written in C#, F#, javascript, and a bunch of other languages).

The App Code

The first step a very simple Azure Mobile App and enabled Easy Tables and Easy APIs which leverage nodejs on the backend.

Inside of my Xamarin apps I made the “Store” table a sync table and the “Feedback” table an ‘online’ only table since I only ever want to push data to the server and don’t need to ever sync to my clients. Essentially here is my code from the app:

if(freedbackTable == null)
  feedbackTable = MobileService.GetTable<Feedback> ();

await feedbackTable.InsertAsync(feedback);

With these lines of code the feedback will be sent to my backend and stores in my SQL backend on Azure. I mostly decided to go this route because I want to always have the data backed up instead of just trying to send an email from the app.

The Azure Function Code

Let’s create a function app! So easy, peasy, basically New -> Compute -> Function App. Fill in a bit of information and this Function app contains a suite of functions inside of it. I like to group all functions for an app together.

There are a lot of nice templates to get you started. I went with a simple “HttpTrigger-CSharp” template since I knew that I wanted that to be my input. Essentially I wanted my mobile app backend to call into my Azure function so it is nice and secure and the mobile apps never call the Function directly so it can’t get spammed.

Under the “Integrate” section, you will see an input and output. I deleted the current output and selected a new SendGrid output.

You now need to fill in a bit of information for the output. The most important part here is that the SendGrid API Key doesn’t actually get posted in here, you have to actually add it under your “Function app settings” -> Go to App Service Settings -> Application Settings -> then add a new app setting ->

If you fail to put it in here and if the keys don’t match up it gets all mad. Alright now for the code. This is super easy. I just copied my model into the function, brought in Json.NET and used the SendGrid API. Here is the code:

#r "SendGrid"
#r "Newtonsoft.Json"

using System;
using SendGrid.Helpers.Mail;
using Microsoft.Azure.WebJobs.Host;
using Newtonsoft.Json;
using System.Net;
using System.Collections.Generic;
using System.Linq;

public static Mail Run(HttpRequestMessage req, TraceWriter log)
{

    log.Info($"SendGrid Function Triggered");
    string jsonContent = req.Content.ReadAsStringAsync().Result;

    if(string.IsNullOrWhiteSpace(jsonContent))
    {
        log.Info($"No data");
        return null;
    }

    var f = JsonConvert.DeserializeObject&lt;Feedback&gt;(jsonContent);

    log.Info($"WCSendGrid function processing order: {f.Id}");

    Mail message = new Mail()
    {
        Subject = $"Feedback from {f.Name} {f.VisitDate.ToShortDateString()}!"
    };
    var service = string.Empty;
    switch(f.ServiceType)
    {
        case 0: service = "Billing and Payments";
        break;
        case 1:service = "Device Help";
        break;
        case 2:service = "Upgrade Device";
        break;
        case 3:service = "New to Store";
        break;
        case 4:service = "Other";
        break;
    }

    var callback = f.RequiresCall ? "need a callback" : "do NOT need a call";

    Content content = new Content
    {
        Type = "text/plain",
        Value = $"Feedback from {f.Name}, for their visit on {f.VisitDate.ToLongDateString()} to store: {f.StoreName}: \n\n" +
        $"{f.Text} \n\n" +
        $"Their rating was: {f.Rating} \n\n" +
        $"Their service type was: {service}\n\n" +
        $"Their phone is: {f.PhoneNumber} and they {callback}"
    };

    message.AddContent(content);

     log.Info($"WCSendGrid function processed order: {f.Id}");
    return message;
}

public class Feedback
{
    [JsonProperty(PropertyName = "id")]
    public string Id { get; set; }

    [JsonProperty(PropertyName = "text")]
    public string Text {get;set;} = string.Empty;

    [JsonProperty(PropertyName = "feedbackDate")]
    public DateTime FeedbackDate {get;set;} = DateTime.UtcNow;

    [JsonProperty(PropertyName = "visitDate")]
    public DateTime VisitDate {get;set;} = DateTime.UtcNow;

    [JsonProperty(PropertyName = "rating")]
    public int Rating {get;set;} = 9;

    [JsonProperty(PropertyName = "serviceType")]
    public int ServiceType {get;set;} = 4;

    [JsonProperty(PropertyName = "name")]
    public string Name {get;set;} = string.Empty;

    [JsonProperty(PropertyName = "phoneNumber")]
    public string PhoneNumber {get;set;} = string.Empty;

    [JsonProperty(PropertyName = "requiresCall")]
    public bool RequiresCall {get;set;} = false;

    [JsonProperty(PropertyName = "storeName")]
    public string StoreName { get; set; } = string.Empty;

    [JsonIgnore]
    public string VisitDateDisplay
    {
        get { return FeedbackDate.ToString ("g"); }
    }

    [JsonIgnore]
    public string SortBy
    {
        get { return FeedbackDate.ToString("MMMM yyyy"); }
    }
}

It isn’t overly complex once you realize that the return value of the function is the output and the parameters are the input. Besides that it is just standard C#! Beautiful!

Update Backend Logic

For each of the tables there is some javascript essentially that lives behind it like a controller in ASP.NET that has different inserts/update/deletes. So, my plan here was to write as little code as possible and I don’t really know javascript very well so I went to stack overflow and found this bit of code that I could put into the table code behind:

var request = require('http');
table.insert(function (context) {
	var item = context.item;

	var body = JSON.stringify(item);

	var request = new http.ClientRequest({
	    hostname: "fa.azurewebsites.net",
	    port: 80,
	    path: "/api/WCSendGrid?code=YourCode",
	    method: "POST",
	    headers: {
	        "Content-Type": "application/json",
	        "Content-Length": Buffer.byteLength(body)
	    }
	});

	request.end(body);
    return context.execute();
});

This isn’t too bad even though it tooke me like 30 minutes to debug silly hostname issue, but then someone told me about this crazy awesome javascript library called request, which essentially is the new hottness and turned my code into:

var request = require('request');
table.insert(function (context) {
    request.post("https://fa.azurewebsites.net/api/WCSendGrid?code=YourCode", {body: context.item, json:true});
    return context.execute();
});

And just like that all my logic got placed on to a super cheap Azure Function that I only have to pay per the execution time :) My next steps are to move even more logic to the Azure Function to keep all my costs :)

]]>
Updating Azure Mobile SQLiteStore to 3.0 https://staging.montemagno.com/updating-azure-mobile-sqlitestore-to-30/ 598df8f2c121b60019bf2fe7 Tue, 27 Sep 2016 01:57:10 GMT If you are using Azure Mobile Apps as a backend for your Xamarin and Windows apps you may have seen a very fancy new 3.0 release pop up in NuGet. This is a super important update for the NuGet that brings in the amazing SQLite.raw to ensure compatibility with changes in Android N. So what is new? Well according to the changelog:

Version 3.0.0

Doesn’t seem too crazy, but why the 3.0? Well it is because there is a breaking change with the update to SQLite.raw and how you have to initialize SQLite on multiple operating systems. I highly recommend reading the SQLite.raw README to fully get detail, but here is the short:

UPDATE! 3.0.2 Fixes Everything!

After providing the team with much feedback on the first 3.0 and 3.0.1 release they have fixed the issue I blogged about for the greater good! You can find details here on their blog, but the overview is that you wont have to modify really anything into your app. You should still uninstall the old SQLitePCL and remove the SQLitePCL.Init() that you may have had in the past, but besides that the correct files will be created for you automatically! Yay!

All you need to do is specify your path like this:

var path = "syncstore.db";
path = Path.Combine(MobileServiceClient.DefaultDatabasePath, path);

In the future, I am hoping that you can just specify the path without the combine. I have already filed an issue :)

Below is only for 3.0.1 Reference

Call SQLitePCL.Batteries.Init();

Previously, on iOS you would have to call SQLitePCL.CurrentPlatorm.Init(), but now, you must call into Batteries to initialize it on ALL platforms;

//Call this in each platform before intializing your Mobile Client
SQLitePCL.Batteries.Init();

Android Has a Special Path for Database

For some reason… not sure why, but you have to set a special path for Android specifically. I really think that the library should do this, but it doesn’t so you need to get the path correctly for Android such as:

var path =  "syncstore.db";

#if __ANDROID__
path = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), path);

if (!File.Exists(path))
    File.Create(path).Dispose();
#endif

You won’t be able to do this in your PCL, but if you are using shared code projects this will work, else you will have to pass it up to your PCL.

This means that in your PCL project you should do something like this:

public class MyAzureService
{
  public static string Path {get;set;} = "syncstore.db";
}

Then in your MainActivity before your app starts up simply execute this code:

MyAzureService.Path = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), MyAzureService.Path);

if (!File.Exists(MyAzureService.Path))
    File.Create(MyAzureService.Path).Dispose();

If you want to take it a step further you could create an interface and use the DependencyService or something of this sort to inject it.

See it in action

I just updated my CoffeeCups app to 3.0.1 and also take a look at the new Quick Start guides.

]]>
Azure Mobile Services + Xamarin + PCL https://staging.montemagno.com/azure-mobile-services-xamarin-pcl/ 598df8f2c121b60019bf303f Sun, 15 Dec 2013 02:56:00 GMT You might have noticed that both @ChrisNTR and myself have been on the .NET Rocks Roadshow. We have been talking to awesome devs all over the US about Xamarin, PCL, and Azure all wrapped up into an amazing demo (full source code there). One common question that has come up is that while a lot of people have the demo up and running they are having a hard time getting Azure + PCL integrated into their own project. So let’s set one up from scratch.

Pre-requisites: I am going to be using VS 2013 and making an Android App based on the Azure sample. You should:

  1. Read through the Android Setup Guide for Azure

  2. Ensure your Azure Database is setup

  3. Ensure your Azure Table named “TodoItem” is setup

Step 1: New PCL

Select new project in VS2013 and select Portable Class Library. Name your solution “TodoList” and your project: “TodoList.Portable”:

When prompted to select targets select: .NET 4.5, Windows Store, Xamarin.Android, Xamarin.iOS. *NOTE: Windows Phone is not supported in the Azure Mobile Services PCL.

Step 2: Add Azure Mobile Services Nuget

UPDATE 12/16 Don’t actually use the nuget file here, we want to actually reference our component directly. There are a few reasons for this after talking with Paul Batum from Microsoft.

You will want to go to the component store and download the azure mobile service: https://components.xamarin.com/view/azure-mobile-services and then reference both “Netonsont.Json.dll” and “Microsoft.WindowsAzure.Mobile.dll”. You could reference these from the download component later on as well.

**Don’t do this:

Next up is to add the AMS nuget. Simply right click on References and click “Manage Nuget Packages”. Search for “Azure Mobile Services” and click Install.

Such as: Install-Package WindowsAzure.MobileServices -ProjectName TodoList.Portable -Version 1.1.0

Step 3: TodoItem + AzureWebService

Next up let’s first delete Class1.cs and create the TodoItem.cs:

Now our AzureWebService.cs will have a helper to “GetTodoItems” and “AddTodoItem”:

Make sure you fill in your specific Azure Settings.

Step 4: Android Project Setup

Next add a new Android ICS Project named “TodoList.Droid”. Once the project is created add a reference to you “TodoList.Portable” project. After that right click on the Components folder and hit “Get More Components”. Search for Azure Mobile Services and hit Add to App.

Step 5: Add in the UI

The next part is to add an EditText and Button to the UI that will add new items. Under it will be a ListView that we will populate with all of our TodoItems.

Step 6: Hook it all up

Last thing is to tie into this UI and the Azure Mobile Services. We will create our adapter and then get the current TodoItems. When our user clicks to add a TodoItem we will send it up to Azure and add it to the UI if successful:

There you have it. The same can be done for Xamarin.iOS as well.

Cheers!

]]>