Some time ago, I started working on a mobile version of the Azure Storage Explorer. The intent of this app was that anything you could do from the ASE app on Windows, MacOS, or Linux, you’d be able to do on Android and iOS. There were a few different reasons I wanted to build this:

  • I wanted to spend time building out a real application using Xamarin.
  • There were a few situations where I thought it would be handy to have access to my storage accounts while away from my computer.
  • I wanted to start auto-backing up any photos I took with my phone to Azure Storage.

Fast forward through several months of working on the app in my spare time (which is to say not very frequently) and I had a number of scenarios around Storage working. What I didn’t have, was a strong use case or motivation to release and support the app. Additionally, after talking with more people, it didn’t seem like there was a very strong use case for the mobile version of ASE. As with many other things, if there wasn’t a customer need, there probably wasn’t going to be much usage, and therefore there wouldn’t be much in the way of support. So rather than releasing an app to the App Store and Google Play and let it languish, I decided it would be better to just open source the app.

Releasing the Souce Code for ASE Mobile

Effective today, you can now access all source code and assets for Azure Storage Explorer for Android and iOS on GitHub. I think this is a great reference app as it details:

  • How to build a semi-sophisticated Xamarin app for Android and iOS.
  • How to use different UI elements depending on the platform (iOS makes use of tabs while Android uses the slide out menu).
  • How to access a number of different Azure Storage capabilities (see below).
  • How to mix usage of Azure REST APIs and libraries.

Credit to Other Devs

I couldn’t have built this without stealing borrowing from many other devs.

  • I heavily referenced the app architecture and patterns from the Xamarin Evolve 2016 Mobile App. James and Pierce did a great job with this app and made it very easy to look through and reuse.
  • I’ll call out James Montemagno again as I made use of a large assortment of the Xamarin plugins he builds and supports.
  • Developers at Realm and Rg.Plugins.Popup for their technical support.
  • Everyone that works on Visual Studio Team Services and Visual Studio App Center. Throughout developement, I used VSTS for continuous integration and App Center to deliver the app to test devices and track errors and analytics.

Outstanding Issues

There are a number of issues I never got around to including:

  • Testing against a large quantity of blobs, table rows, etc.
  • Editing table schema and rows.
  • Any sort of advanced querying of data.
  • Currently the app only works with Classic Storage Accounts due to how I am pulling subscriptions and storage accounts (i.e. the APIs I used). This wouldn’t be very difficult to convert over but I never got to it.

How to Build it?

In order to build and run the application, there are a few things you should do and a few things you need to do:

  • In the src/AzureStorageExplorer/Helpers/Constants.cs class, there are a number of API Keys that need to be set. First is the AuthClientId which is the value you get from Azure Active Directory after you create an app with appropriate permissions. Second is the MobileCenterId which is the value you get after creating an app in Visual Studio App Center (yeah it used to be called Mobile Center). You’ll note that there are different values based off of if you’re in Debug or not as well as if you’re in iOS or Android.
  • If you’re building and running in iOS, you’ll need to create an App ID and all the appropriate bundle identifiers, etc. Because there is certain functionality that requires iCloud access, for the App ID, you’ll need to set up iCloud access (I used iCloud.azurestorageexplorer as the container name).
  • I haven’t compiled against the absolute latest versions of iOS / Android / Xamarin but I don’t anticipate any issues.
  • One thing to keep in mind is that I pulled in the actual code for the Rg.Plugins.Popup library. This is only directly used in the iOS project and was done to alleviate an issue where popups weren’t working if you were too deep down the navigational stack. I believe they’ve fixed this in a preview version of the plugin (v1.1.0-pre1 and beyond) but haven’t tested this yet.

Would you use it?

If you see this and think you’d have use for the app if it was easily available on the App Store and Google Play, please let me know. I left this project because it didn’t seem like there was a solid enough use case for it. I’d love to be wrong about that. If you need any help getting the app built, please reach out or file an issue on the GitHub repo.

GitHub Blogging edit

Six years ago, when I was still using my own custom built blog engine, I switched the comment system over to using Disqus. At the time, this change made a lot of sense. With just a little bit of additional markup per page, Disqus would render all of the comments and the comment form and handle everything for me, including the ability to do moderation. Recently, when I switched over to GitHub, I kept on with Disqus as it was relatively easy and there were instructions on how to integrate. Unfortunately, one of the issues with Disqus is that it loads quite a bit of JavaScript including ads. While the JavaScript is not blocking, I wouldn’t be entirely surprised if the long time for the page to actually finish loading didn’t impact some ratings by a few certain search engines. Plus, the only way to remove the ads (which aren’t even relevant to the material of the site in anyway), is to pay.

A First Replacement: CommentIt

I’d taken a very brief look some months ago about finding a replacement that would work with GitHub pages. Since GitHub pages are generated using Jekyll there isn’t really a backend that can be used to run the comment engine. I was chatting about it with one of my teammates at work and he mentioned he’d recently setup a new site on GitHub pages and had used CommentIt to handle this comments. Once you give CommentIt access to your GitHub repo and put some markdown on your site (to display comments and to put a comment form on the page), everything works. CommentIt runs the backend javascript that actually handles processing comments. Whenever a comment is made, it creates a pull request against your repo. The one big issue both he and I had with CommentIt was that it puts comments into the Front Matter for your blog posts. I’d much rather prefer comments end up in a different file or location.

StaticMan

While looking around further, I stumbled upon this post on mademistakes.com about changing from Disqus or an external site to use StaticMan for comments on GitHub Pages. StaticMan functions similarly to CommentIt except it puts every comment in a separate file in your repo under the /data/comments/[slug] path. Additionally, there is support for replies, notifications, and Captchas. Getting started is quite easy and fully documented. I did go down the route of trying to further customize my rendering and interface similar to what MadeMistakes.com had done and thought it would be good to share some of the implementation details. Of particular importance, I’d look at the following files (on top of the JS and SCSS files):

One of the big things I want to call out because I ran into issues with it multiple times is the ordering of the comments. Specifically, ordering didn’t seem to be the same when running the site locally and when it was showing up in GitHub Pages. I want to share what the comments.html looks like:

{% assign count = 0 %}
{% assign comments = (site.data.comments[page.slug] | where_exp: 'item', 'item.replying_to == ""' | sort: 'date') %} 
{% assign comments = (comments | sort) %}
{% for comment in comments %}              
  {% if comment[1].replying_to == "" %}    
    {% assign index       = (forloop.index | minus: count) %}
    {% assign r           = comment[1].replying_to %}
    {% assign replying_to = r | to_integer %}
    {% assign avatar      = comment[1].avatar %}
    {% assign email       = comment[1].email %}
    {% assign name        = comment[1].name %}
    {% assign url         = comment[1].url %}
    {% assign date        = comment[1].date %}
    {% assign message     = comment[1].message %}
    {% include comment.html index=index replying_to=replying_to avatar=avatar email=email name=name url=url date=date message=message %}
    
  {% else %}
  {% assign count = count | plus: 1 %}
  {% endif %}
{% endfor %}

For some reason, the query where we’re trying to get comments that have nothing in the replying_to field doesn’t work. I’ve seen other examples where they compare against blank as in where_exp: ‘item’, ‘item.replying to == blank’ but that didn’t work for me either. The sorting was very bizarre and didn’t make very much sense as, as near as I could tell, different rebuilds of the site lead to different ordering of the comments.

Importing Disqus Comments

The next step was to export the comments from Disqus which I did with these instructions. From there, I built a program to translate the XML into YML comment files. Once that was done, I just needed to copy the comments over and push them up to my repo. Now all of my comments are showing and their in the correct order.