If you have used ASP.NET in recent years you will probably be familiar with the appSettings.jsonfile and it’s associated, build-specific transformations, e.g. appSettings.development.json and appSettings.release.json.
Essentially these allow developers to define multiple configuration settings which will be swapped out based on the build configuration in play. Common settings are stored in the main appSettings.json file while, for instance, API Endpoint Urls for development and production deployments are stored in the development and release files.
At compile-time any values specified in the deployment version of the file overwrite those in the common version.
Simple – works well and we use it all the time without thinking about it. But what about Xamarin.Forms – it doesn’t have such a mechanism out of the box so how do we achieve this and prevent accidentally publishing an app to the App/Play Stores which are pointing to your development/staging servers?
When I was at NDC London in January I watched a demonstration of the OzCode extension for Visual Studio. Not only was it well presented but it highlighted some of the pinch points we all have to tolerate while debugging.
In return for a scan of my conference pass, i.e. my contact details, I received a whopping 35% discount off a licence and without completing the 30 day trial I was so impressed that I pulled out my wallet (actually the company wallet!).
While I don’t use all of the features every day there are a few that I use all the time – the first one is called ‘Reveal‘.
Consider the following situation:
At this breakpoint I’m looking at collection of View Models – but I knew that already what value am I getting from this window? There are over 600 records here – do I have to expand each one to find what I’m looking for? What if one has a null value that is causing my problem – how will I find it?
When we open Visual Studio and click File > New we are greeted with a huge list of project templates to choose from. Now and then we may opt for a simple Console Application for a quick one off utility, e.g. post processing some .csv files or images.
Similarly we have all used command line utilities which require numerous arguments and switches to ‘tune’ exactly what we want it to do, e.g. git or tar.
Well I’m looking to create a Command Line utility that will allow users to encrypt and decrypt textual messages.
But that’s a bit nasty and relies on each parameter having a value and that it’s been specified in the correct way to allow casting etc. There has to be a better way .. well there is and it comes in the form of a nuget package called, suitably enough, CommandLineParser.
Now, I didn’t find the documentation (the ReadMe.md on the projects Github page) that helpful and it took a lot of trial and error to work out how to use it for my needs. When I got to grips with it though – I was impressed.
After installing the CommandLineParser via nuget I needed to create a new class to define each operation, i.e. GenerateKeys, Encrypt and Decrypt.
So the above code defines the Generate Keys action and provides options for Key Length, Name and Output Folder. Notice that the Key Length will default to 2048 bits if not specified by the user. It is also possible to make options mandatory and the operation will fail if they are not specified.
When the Console Application project was created a Program.cs class was added containing a single method called Main. I’ve modified the signature to return an integer instead of a void as I think it is good practice to return exit codes from command line utility.
To test the configuration I can right-click on the project file, open the Properties page and click on the ‘Debug’ option. Enter suitable values into the ‘Command Line Arguments’ as below
and then run the application (I had a breakpoint on the return statement within the GenerateKeyPair method).
If the parser fails for any reason then it will automatically generate the required output and error ‘gracefully’.
Try dropping the value for one of the options and rerunning the application – below I dropped the DavesMessage value from the -n parameter:
Obviously I want to add another couple of Option configurations and this is easy enough to do – take a look at the sample app in the github repo, in particular the Program.cs file, to see how this is done. Alternatively you can keep track of this application when it hits GitHub as I will be open sourcing the code.
With the most recent update to the FillLPG application (v22.214.171.124) rolling out I will be ceasing all development of this version (unless some horrible bug raises it’s ugly head). But fear not loyal LPG users – that doesn’t mean the the app will be going away – far from it.
Technology moves on at pace and over time new skills are acquired and lessons are learned. The ‘problem’ is that to implement all of this it is easier to start over again – taking advantage of the new framework features, applying the new skills and remembering those sometimes painful lessons.
So, what’s on the horizon?
I suppose the ‘headline’ news is that an iOS version will soon be a reality! After years of focusing solely on the Android version our Apple-using LPG’ers will be getting some love too.
The aim will be to develop an iOS application with feature parity to the current Android version.
Now, don’t fret if you are an Android user – I’m not abandoning all of you who have helped make the app what it is today. The fact that I can essentially develop for two platforms at the same time is due to the advances made in the underlying framework used to develop the app. Previous versions didn’t really lend themselves to the type of mapping that is required for the FillLPG app – but that’s all changed now and mapping is now fairly straightforward to achieve on both platforms whilst sharing the maximum amount of code – which is good for maintainability (fix a bug in one place and it’s fixed for Android and iOS).
With the rest of the application mainly consisting of ‘Forms and Lists’ and these can easily be shared between the new platforms.
The result will be a more modern UI, lower impact on battery life and data usage.
Other planned features include:
Offline price updates (updates will be pushed when your device next has internet access)
“Route Planning” – display stations along a particular route allowing you to plan stops
Enable/Disable update alerts for favorite stations
But there’s more…
The webmaster of the FillLPG website is currently developing a new version with a new and improved webservice – which is how the app communicates with the site. This will expose a lot more data to the app, including:
Flags such as ‘Disabled Friendly’ and ‘SafeFill Capable’
Ability to specify price currency
Obviously I have no control over the timescales for the new website functionality but as soon as it is available I will be including it into the application as quickly as I can.
Please remember though that the FillLPG website and the mobile apps are ‘labours of love’ and that both myself and the site webmaster have other commitments. The website and apps are provided free of charge and with no ads.
Listening to one of my favorite podcast (.Net Rocks) I heard a plug for the Stackify Prefix tool which claims to help the developer fix problems before anyone else sees them – a bold claim. Well as I am currently working on a greenfield development project I decided to give is a whirl – it’s free after all so why not.
Now I was not expecting to find too much wrong with the application and thankfully I was right – but I was getting errors.
Well, looking at the stack trace a little more carefully I see that the exception is being raised by the XmlMediaTypeFormatter when it is creating it’s default serializer. But the WebAPI is returning JSON so why it is spinning up an XML serialiser?
The problem is on line 8 where I’m returning the OK status with the required content – which is an anonymous object that I’ve just put together on the fly. The WebAPI is configured to accept the ‘application/json’ header and to use an appropriate JSON Formatter – which it does.
The problem is that I still have the default XML Formatter in the list and for some reason the framework is trying to use it to serialize my anonymous object – and failing (silently).
So all I need to do is to remove the Formatter during the WebAPI registration – within WebApiConfig.cs in the App_Start folder (see line 12 below).
Now this was fairly trivial but a bug is a bug and as we know – exceptions are expensive. They take time to raise while they pull the required information together and work their way through to the calling code – which in this instance appeared to simply discard it. A small performance hit but if this scaled then it could have become a bigger problem in the future – and probably harder to find.
Prefix highlighted it straight away and the issue is now fixed. It never made it to production, in fact it never made if off my desk – it was Pre-Fixed!
We all know that when you are developing mobile apps there is nothing better than running on an actual device. This is especially useful when wanting to access the device sensors such as GPS and the accelerometer. But we also all know that we have to test against a wider variety of devices than we have in our drawer. That’s where emulators come in – and where the trouble starts in some cases, but I won’t go into Hyper-V here!
Well I’ve been using GenyMotion for a little while and am very happy with it – to the point that I was about to put my hand in my pocket to buy a licence (which I may well still do). However, today I ran into a problem where Visual Studio would refuse to deploy to the emulator.
With the emulator running I selected it as the deployment target in Visual Studio and pressed F5, the build completed successfully and then, just before deployment the emulator disappeared from the list of targets and the deployment failed. I made sure I had the latest version of Genymotion installed (which I did) and that everything else was up to date (which it was).
While I was badgering Xamarin in the forums and via the support email I thought to fire up the Android Debug Bridge (adb) command prompt from within Visual Studio to check what devices the Debug Bridge was actually connected to:
Well, there you have it – it’s a problem with the adb versions ….. wait a minute, how many do I have?
My understanding was that I should only have one – the one that Visual Studio connects to so that it can access the Android devices & emulators. And (I think) I was right on that score – I should only have on running. So what’s with the version clash?
As it happens, Genymotion also ships with a version of the Android Debug Bridge and as it turns out, right now that one and the one shipped with the Xamarin toolset are not the same version.
Comparing versions of adb.exe (from Genymotion and the Android SDK) I found that Genymotion was currently at version 1.0.32 while the Android SDK has 1.0.36.
So what to do?
I suppose I could copy the adb files from the Android SDK into the Genymotion installation – but that frankly smells a bit to me and as it turns out it’s unnecessary.
It is possible, within Genymotion, to set which ADB instance to use for each individual emulator. Simply select the emulator instance and click Settings. Select the ADB tab, click ‘Use Custom Android SDK Tools’ and browse to the SDK location on your system.
Note that the SDK will be in a folder called ‘Android’ within C:Program Files (x86) or C:Users<user>AppDataLocal
Setting this resolved my issues and I am once again enjoying the flexibility of Genymotion and will be buying a licence very shortly.
I’ve been developing with Xamarin for a few years now and most of the time I do so using Visual Studio. Now, as with most technologies, Xamarin is constantly evolving and therefore updates are pushed out fairly frequently – that’s all good, we all like new stuff don’t we?
Well, I’ve always had a problem whereby Visual Studio would prompt me to say that there was an update available and that I should ‘Click Here to Update’ – the only problem being that this doesn’t actually do anything!
In the past I’ve simply opened up Xamarin Studio, checked for and installed updates and then reopened Visual Studio – simple it’s a bit irritating.
Well with Xamarin now being part of Microsoft and after rebuilding my development workstation I find that Xamarin Studio is no longer installed with the rest of the Xamarin components when Visual Studio is installed. So how do I install the updates now?
Well today I decided to start a new Xamarin.Forms project in Visual Studio 2015 but fell at the first hurdle – you would have thought File > New Project would be simpler than this really.
After clicking through all the errors I tried to build the solution which failed as badly as I expected it to – only 28 errors but all pretty severe.
Opening the Package Manager Console resulted in another error which seemed to indicate that a file was missing (nuget.psm1) but it was present, accessible and appeared to be intact.
So what’s the problem here? Well, it’s not actually Xamarin.Forms at fault – if I open Visual Studio with no solution loaded and then open the Package Manager Console I get the same error. I checked for updates and compared all the version numbers against the installation on my laptop (which didn’t have the same issue) and everything seemed in order.
Well after a look (and I mean, a lot!) of Googling I found a cure for the symptom but not for the root cause.
When you open Visual Studio 2015 an instance of the devenv.exe.config file is generated in the following location: C:Users<username>AppDataLocalMicrosoftVisualStudio14.0 with a nice comment header indicating that modifications were subject to being overwritten. Now that’s a bit of a pain because only by editing that file can I get the workstation to open the Package Manager Console correctly and hence generate a Xamarin.Forms project.
Add the following within the assembly binding section of the config file:
Now, the laptop does not have those lines in it’s version of the file and it runs just fine so why the workstation is choking I have no idea – this is a quick and (very) dirty fix at best. From time to time you may need to reedit the file but at least you will be able to continue working.
The thing is I plan to pave this workstation soon and perform a clean installation so I’m not really looking to spend a great deal more time trawling the internet to find which obscure setting is flipped the wrong way and is causing this issue.