Sunday, September 7, 2014

Handling references to images in Xamarin iOS

I recently submitted a minor cosmetic update to an iOS app that I had created, and had a user report that after updating the app the app would crash on a certain screen (which was puzzling, given that it hadn't been affected by the update). I did some investigation and uncovered what is potentially a trap for app developers, so I thought I'd share it.

The app allowed users to take photos and would store them in the app's Documents directory (Environment.SpecialFolder.Personal in Xamarin) waiting to be uploaded to a web server. A SQLite database would maintain a reference to the full path of the documents directory and access that path when the time came to upload the image. The user in question had taken some photos and then updated the app before uploading them, which caused the app to crash. It turns out that when an iOS app is updated, the GUID of the path to the data directory for that app is changed and all of the existing files are moved there, meaning that the paths in the SQLite database were now invalid and caused a crash upon trying to access them.  This scenario, and the workaround for Objective-C apps is outlined on this Stack Overflow question.

Basically, the way to stop this from happening is to not store the full path to the file on disk, but instead store just the filename, and append it the Documents directory each time you access it. In Xamarin I did this via a helper class:



To illustrate it's usage, here is the code used to save the image:

var path = GetFullImagePath.ForFileName(imageFileName);
System.IO.File.Copy (t.Result.Path, path);

Then imageFileName is stored in SQLite, not 'path'.

If you implement this code you may not need the check to see if the path supplied is a full path, however it was necessary in my example because some of our users, including the one that reported the issue, will have the full path stored in the SQLite database - which will now call that helper method.

The moral of the story is: if you store a reference to files stored in your Documents directory in your iOS apps, make sure you don't store the full path or this will cause problems when your app is updated.

Sunday, August 3, 2014

[Video] Introduction to iBeacons with Xamarin

Recently I attended a 'Xamarin Hack Day' organised by Michael Ridland & SSW here in Sydney. It was a great day which started with a few presentations, and led into everyone sitting down and coding away on Xamarin applications.

SSW are taking the concept around the world, so if you're interested in learning more about Xamarin you should check out XamarinHackDay.com

In the morning I gave a presentation on iBeacons and how to use them with Xamarin. I've got a keen interest in beacons and think there are big opportunities for developers that create applications which leverage them. I've spent some time trying out different beacon brands and trying out the iOS and third party Android SDK's. I've also been involved in discussing potential use cases to customers of Envoy as part of our iBeacon software development offering.

SSW recorded and edited the video, and have put it online here on their SSW TV website.

For convenience, here is the youtube video embedded:


And here are the slides:

Saturday, March 29, 2014

Thoughts on Xamarin for iOS development

Recently I had the opportunity to develop an iPad/iPhone application using Xamarin iOS. For those of you that don't know Xamarin are a company that develop cross-platform implementations of the .NET framework. Their two main mobile product are Xamarin.iOS and Xamarin.Android, which are wrappers around the native iOS and Android SDK's. This allows you to write C# code that is compiled into native mobile apps.



The good thing about this is that it allows you to write applications that have a shared 'core' library of platform agnostic code (for instance connections to web services, in-app database, business logic) while the user interface is written individually for each platform, providing an a good user experience while allowing for some code-sharing. This is in contrast to writing the app twice, in either Java for Android, or Objective C for iOS, and also differs from fully cross-platform solutions like PhoneGap, which requires some compromise in terms of the user interface. I often say the benefit of Xamarin is you write your  app 1.5 times instead of 2, while maintaining an optimal user experience.


The project I was tasked with was to create a mobile inspection app for building certifiers which was to replace a JQuery mobile website. The goals of the replacement app were to improve the offline support, which was subject to some limitation in HTML5 offline storage API's on iOS devices, to improve the user interface and to add some extra features like the ability to take photos of defects. Given these requirements, and especially that we really wanted to give a top quality experience for the user, I decided that a native app was the best way to go (note that I'm referring to Xamarin as native apps, which isn't technically correct however the terms native, hybrid and cross-platform are often mixed around. I consider hybrid to be a combination of native UI elements and webviews, others consider Xamarin to be hybrid).

Having decided on a 'native' app, it came down to writing it with XCode and Objective-C, or giving Xamarin a go. Envoy (the company I work for) specialise in .NET development, which is one factor, however I'm a believer in choosing the best tool for the job, and that learning new languages/technologies isn't something to be afraid of. In the end I went with Xamarin because it allows code sharing with a possible future Android version of the app, and because the core library could be built out faster in C#.



The app was finished in around 7 developer-weeks (including back-end work), and is live on the app store. After completing the app, and having worked on Objective-C iOS projects previously, I thought I'd share some of my observations on the current state of Xamarin.

The Good

Xamarin is a high quality product

One concern I had was that if Xamarin goes broke the code we produce is probably useless as the framework and tooling won't get updated for new iOS updates, however they are well funded and have been around for quite a while now in various forms, and just keep getting bigger and bigger. Updates are pushed frequently, documentation is well written and kept up to date, and they even put on a yearly conference that has some great presentations. They also have a partnership with Microsoft, and there's all sorts of rumours about Microsoft possibly buying them.

Our app ended up performing well and I didn't feel my development time was held back by the Xamarin product at all.

C# and Xamarin Studio fit in well with Cocoa Touch

I don't think Objective C is that bad, however there's no doubt that I found C# to be a more productive language, you can use Linq, Async/Await and some great .NET libraries including the SQLite.NET mini ORM. Xamarin Studio, which is their IDE for the Mac worked well, and integration with storyboards in Xcode works well enough.

Growing community

There is a growing community of developers who are making great things in Xamarin, there are open source projects like MVVMCross (which I chose not to use this time, but will look at in the future) that are actively contributed to and user groups around the globe full of developers. There are many blog posts and Stack Overflow questions that are Xamarin specific, which helps to accompany the official documentation.

The Bad

Missing out on iOS open source 

This is the biggest one for me, so many components and UI widgets for iOS are available as open-source drop-ins to your app. Xamarin has a component store where they attempt to make up for this, however it still has a long way to go. For me, if I knew I was creating an app that was only ever going to be on iOS, this factor alone would probably mean I gave Xamarin a miss for that particular project so that I can make use of CocoaPods, however it's pretty rare that you know for certain you are never going to want an android version of an app.

Visual studio integration is flaky

Xamarin has a feature that allows you to write code in Visual Studio and have it remotely compile and launch on a network connected Mac. This was very flaky and slow for me, so I didn't bother with it, Xamarin Studio isn't too bad, and if you like you can develop your core library code as a separate PCL DLL on Windows so you can use NCrunch for increase test driven development productivity and then develop the UI of the app on the Mac.

Extra layer of potential bugs

While the Xamarin team are extremely smart, and have created a great platform, they are not infallible. There is still an extra layer of code between your app and the hardware which could cause bugs, either in the Xamarin code itself, or as a result of you needing to know about how both iOS and the Xamarin garbage collectors/compilation works. After we released the app, we wanted to add some image resizing features, and came across a memory leak (Xamarin ships their own garbage collector in your app) that we had a hard time fixing. After contacting support with a trimmed down app to reproduce the problem they indicated to us they found a bug in Xamarin and were going to push an update shortly. They also gave us a workaround which got us going straight away which was great, however it still cost us a few days of developer time debugging it.

Other things to note

Using Xamarin is not an excuse not to learn Cocoa Touch and bits of Objective C

My earlier point about not being afraid to learn new things applies here as you'll still be reading Objective C code from blog posts and Apple's official documentation. Xamarin just wraps the Cocoa Touch libraries so you'll need to understand how that works - it's different to the web, and different to WPF, so don't think you Xamarin is a choice to help you just use your .NET developer knowledge to ship an iOS app. A great book to get introduced is iOS programming for .NET developers.

License Fees

Xamarin licenses for companies are $999 USD a year, per platform. This isn't cheap, but compared to developers salaries, or some of the common license fees for Microsoft developer products this is as cheap as chips.

Overall

All in all I'm a fan of Xamarin and would definitely use it again in the future, however I wouldn't say it's what you should always use for mobile development, it's a matter of picking the best tool for the job, which may be an Objective C/Android app, a Xamarin app, PhoneGap or a responsive website depending on the project, budget, goals etc. I do however believe Xamarin should definitely be something you consider as a serious option.

Also..
I'd like to give some credit to Vanessa Grixti (@vgrixti) for the visual design/UX work on the Buildaform app, she did a great job working to a tight deadline. Also if you are looking for Xamarin mobile developers in Sydney, get into contact with Envoy, as I'd love to work on some more Xamarin projects. 

Sunday, February 16, 2014

[Revit API] Binding a project parameter to all categories

In a recent project I had the need to create a new project parameter, and then set the value of it on certain elements. This post has great information on creating project parameters, however that post along with much of the Autodesk documentation add certain parameters to the CategorySet for the InstanceBinding method, what I wanted to do was add all of them. Unfortunately adding all categories in document.Settings.Categories throws an error as not all categories can have parameters bound.

There is a simple solution to this, only add categories to the CategorySet if they have their AllowsBoundParameters property set to true. It’s an obvious solution once you know this flag is available.

CategorySet categories = app.Application.Create.NewCategorySet();

foreach (Category category in doc.Settings.Categories)
{
    if (category.AllowsBoundParameters)
    {
        categories.Insert(category);
    }
}

Saturday, January 4, 2014

Setting up node-postgres with a new PostgreSQL installation on OSX

I was getting a PostgreSQL installation setup with NodeJS today on my computer and ran into some difficulty that I thought I'd write a post about in case someone else comes across the issue.

I started off by downloading the PostgreSQL installer from the PostgreSQL website (I had also tried Postgres.app) and running through the installer with mostly default settings.

Once that was done I went to install the node-postgres module in my node project via 'npm install pg', this threw the following error:

gyp: Call to 'pg_config --libdir' returned exit status 127. while trying to load binding.gyp

After some searching I found this Github issue which pointed me to the solution. The problem is that the installer did not add the PostgreSQL binary folder to my PATH. To get around this, I updated my ~/.bash_profile (vim ~/.bash_profile is the easiest way to do this) to add the following line:

export PATH=/Library/PostgreSQL/9.3/bin:$PATH

(be sure to use the version of PostgreSQL you installed. Also, if you already have that line, you should just add '/Library/PostgreSQL/9.3/bin:' after PATH=)

Save that file, restart terminal and you should be able to type pg_config and get some output on your screen. Once you've done that, reinstall the node-postgres module and you should not see the error anymore.

Hope this helps!