Monday, 2 June 2014

My Favourite Visual Studio Features #myVSUK

It's been really interesting to read some of people's submissions for the Visual Studio Features competition. Quite varied.

I thought I'd add my top 5 into the mix, although I've probably missed the deadline :)

1 - Test Explorer

Test Explorer, Docked Left in my Main Window

I really love having Test Explorer baked in, especially when the XUnit runner is installed. Previously I used to use ReSharper's test manager but now I pretty much only use this. The addition of playlists in VS2013 has also helped.

You can run tests automatically after build, search your tests and group in various ways. One of my most used features.

2 -  Navigate To or as I say Ctrl + T

Finding those Test Types are now just one Key Combo away :)

This is another feature I used to use Resharper extensively for, the ability to quickly find a type by name. Just hit Ctrl+, start typing, instant win :)

3 - Server Explorer with Azure Integration

Managing and Viewing Azure Services is now simple
Before I got VS2013 I was often using 3rd party management tools for viewing my Azure resources, be this storage or just general management of what I use, this used to work well but then I started using Server Explorer and everything changed. Its amazing how just having the tight integration within VS means everything feels much quicker, less context switching etc. Everything is presented well and you can easily add / remove services from within VS no more having to login into the portal.

As much as I love this feature it does have a few issues, for me it seems to constantly forget my login details, so if I happen to have VS crash or have rebooted I have to re login, as my account uses 2-Step Authentication (Which everyone's should ;)) it's a bit of a faff.

4 - Editor Extensions

If only VS could do this.... Oh look an extension...

This may seem like an odd feature to include but I think having Extensions within Visual Studio is a game changer. You have always had the ability to install IDE extensions, Resharper etc however they were always "drawn on top" or didn't feel quite native. Now that the IDE has been redesigned to be fully extensible, the editors. test explorer etc, your experience can be greatly enhanced by some simple extension that is fully integrated.

Personally I wouldn't be without Web Essentials, Productivity Power Tools, Chutzpah, XUnit Runner

I even know friends and colleagues who write extensions just to make their lives easier.


5 - Full VS Colour Schemes

Which theme do I use today...

I debated adding this to my list, I know other's have said Intellisense, IntelliTrace etc which are great features however I think its often underestimated the effect changing the VS Theme has.

I've always changed my editor area theme from the default to often something dark, I've blogged about this before, but now having the full IDE change really reduces the clashes and I think looks better and improves the overall integrated feel. I loved blend having the dark theme so now VS has I'm happy ;)

Depending on how I'm feeling, and more often how my eyes are feeling I sometimes switch between blue and dark.

And there we are 5 of my favourite Visual Studio IDE features :)

Friday, 30 May 2014

The importance of all-age user testing and the UIButton Touch Area

Of late I have been getting various users to try out an iOS app I have been building using Xamarin.iOS, and I got some interesting feedback which I thought I'd share.

The app runs on iPod Touch's / iPhone's so a common platform. One of the areas people commented on was Ease of Use. Interestingly most people commented that the app felt natural and looked easy to use, however about 30% of my responses contained "I struggled to accurately tap the response icons", "I kept missing the buttons and began to get frustrated", "Wearing gloves seemed to make it harder to tap the icons".

My first response to this was "really?", The icons by my standards were fairly large and didn't look too small, in fact I deliberately made them slightly larger than Apple's recommended 44x44 [ref: http://stackoverflow.com/questions/1928991/minimum-sensible-button-size-on-iphone]

So I found out more information from the affected users. Turns out all of my users that struggled to tap the icons were aged 40+ and the majority of which had larger than average hands, note I only did a quick visual, no measurements made :)
The observed problem

This left me with a decision to make, let the users simply get used to the hit area and hope they wont get frustrated and give up, increase the icon sizes further and have to rethink parts of the app design or could I add an error margin on to each icon tap and therefore increase the perceived target area.
The Hit Area I Wanted

I decided simply getting the users to get used to the sizes wasn't an option, so for now I will increase the target area for each icon and leave the visual design alone, I'm sure my designer will thank me later.

This is actually really simple to do.

First of all create a new class that inherits UIButton, I'm calling mine OverhitUIButton, and then override the PointInside method. This method simply takes a point and returns whether the point is within the current UIView (UIButton). I then changed this to see if the point exists within a configurable extended boundary for my UIButton instead of the real boundary. That's it no messing around with the HitTest method or anything, simply test for the point in an extended boundary.


public class OverhitUIButton : UIButton
{
    private int _errorMargin = 30;

    public override bool PointInside(PointF point, UIEvent uievent)
    {
            var bounds = Bounds.Inset(-_errorMargin, -_errorMargin);
            return bounds.Contains(point);
    }
        
    public int ErrorMargin
    {
        get
        {
            return _errorMargin;
        }
        set
        {
            _errorMargin = value;
        }
    }
}
 
It's worth noting I made the error margin configurable as depending on how the icons are spaced I might not want as large a hit area. From my own testing I noticed if had 1 icon in the middle of the screen I didn't need as large as hit area, however if I had a row of icons the ones at the extreme edges of the screen needed a larger hit area. I also used 30 as my default value just as this felt the most accurate without feeling over extended.
 
This update is only going into my next beta so I will report back on whether my users found this made touching my icons easier, based upon my own testing I noticed the difference so I am hoping others will. 

Thursday, 15 May 2014

Using LinqPad to replace my "test" console applications

I've used LinqPad since... well forever :) I've had the free version since the early days and then paid for the full thing when I started out on my own a few years ago. At the beginning I was mainly using it for quick testing DB queries and quick idea jottings without thinking about big architectures etc, basically a scratchpad, and it's always worked well for me. Even more so after I started using it to connect to Azure using the Azure Table Storage driver.

Another thing I have always done, even when I have lots of unit tests, is to often have a console app in most of my API projects. Be this WebApi or older ones using MVC or WCF. These exist to test the client libraries for the API's that I have written which integration easier. These console apps mainly have a few methods that allow me to easily and quickly try out my service api's. Be this querying, uploading / downloading files etc.

These console apps aren't instead of unit tests or integration tests but allow me a quick convenient way to test development / stage / live api end points without firing up VS or having to worry about what credentials I need etc.

Today I almost fell into "lets add a console app into a new project" but I had a brainwave. Why not use LinqPad to write these "apps" and then store them in my solution with source control etc? Thus avoiding unnecessary additional projects, compile times etc. LinqPad allows you to save queries as .linq files and if I create several can be opened by anyone with LinqPad and be ran within seconds. No open project, compile, run etc.

The process is dead simple. First I opened LinqPad and created a new query. I then switched the language from C# Expression to either C# Statements or C# Program. I generally find C# Statements is enough but if I'm trying a few thing out programs are sometimes easier to manage.
1 -Change Language Type

2 - Finding Query Properties
I then needed to reference my "client" libraries. It seems no matter how many times I do this after a week off, or sometimes less; I blame lack of sleep / caffeine depending on the day, I always forget how to do this. It's actually DEAD simple. Simply bring up query properties by either pressing F4, bringing up the context menu within the query editor or by choosing query in the menu and choosing the bottom option.


Once this is loaded you can easily add references by either finding the assemblies on disk or even via nuget directly which is very cool. Once the assemblies are referenced click the additional namespace tab and pull in the namespaces you'll want to use in your script. You can do this later but it often saves time to do this once the window is open.
3 - Choose References, even with Nuget

4 - Write the test script and run
With the query properties now set you can then enter your scripts for testing. You can even async/await which is handy as most things now I write are async.

Finally just save the query into your solution and you can open it when ever you need too.

And that's it, So far I find this quick and easy and it will be great to come back at a later date and know replaying things against stage / live will be one click away.

As a bonus point, whilst writing this post I thought what about using HttpClient to try out new third party client rest api's or client libraries. Simply really quick iterations before writing a concrete implementation with the full test suite etc. Something I will explore properly at a later date.

For today this works fantastic for me but I have thought it might be worth looking into ScriptCS as an alternative however I'm not sure if I prefer having the LinqPad IDE with autocompletion etc. I'll to need to investigate but that is for another day.

Hope this helps.

Tuesday, 13 May 2014

Base64 Images with Xamarin.IOS

Today I was adding the ability to render Base64 encoded image strings to my iOS application which is built using Xamarin.iOS. These images are just small thumbnails and are stored in a small database within my app.

Since iOS 7 it's really easy to render these as UIImage's inside an UIImageView, in objective-c you simply do something along the lines of:


NSData* data = [[NSData alloc] initWithBase64EncodedString:base64String options:0];
UIImage* image = [UIImage imageWithData:data];

With Xamarin.IOS this would translate to:

var image = new NSData(base64image, NSDataBase64DecodingOptions.None);
var uiImage = UIImage.LoadFromData(image);


However running this gives you the following exception:

System.Exception: Could not initialize an instance of the type 'MonoTouch.Foundation.NSData': the native 'initWithBase64EncodedData:options:' method returned nil.


Ouch

As this exception is within the NSData class which is a class that Xamarin generates to map C# to native Objective-C it's fairly safe to say this is a bug. Turns out after a bit of searching it's a known bug and has existed since February 2014. Sounds like it should be fixed by now so I ensured I was up to date, Xamarin.iOS 7.2.3 and alas the issue still occurred.

I was now looking at alternative ways to do this, I could use the NSData.FromUrl method as iOS does recognise the data:image format, the method you use for Base64 Images within HTML Img tags, but it does have a max url length issue which you can quite easily hit with 20+KB images.

Instead I thought lets convert the Base64 string to its byte array representation and then populate NSData from the array.

Simply:

var base64Bytes = Convert.FromBase64String(base64image);
var data = NSData.FromArray (base64Bytes);                            
var uiImage = UIImage.LoadFromData(data);


This works great but I was left thinking, wouldn't it be great if when the bug is resolved the code automatically used the native implementation but for now use the workaround.

To that end I then decided to then use a helper method that would first try the native route and fallback if needed.

Like so:

public static UIImage FromBase64(string base64Data){
  NSData imageData;
  try
   {
      imageData = new NSData(base64Data, NSDataBase64DecodingOptions.None);
   }
   catch (Exception ex)
   {
     if (!ex.Message.StartsWith("Could not initialize an instance of the type 'MonoTouch.Foundation.NSData'"))
     {
       throw;
     }
     var encodedDataAsBytes = Convert.FromBase64String(base64Data);
     imageData = NSData.FromArray(encodedDataAsBytes);  
   }
  return UIImage.LoadFromData(imageData);
  }

Quite simple and does the job.

I've got this in my app currently but I'm unsure if I will leave this in when I finish / publish the app. It hides the bug but at the expense of throwing and catching an exception for each image load who's cost could add up. For now though, until I've proven it to be a performance overhead it's handy workaround that could benefit from a micro-optimisation  :)

Hope this helps.

Tuesday, 23 October 2012

Getting all profile happy with JustTrace

Recently I have been developing a fair size application and so far everything seemed to be "just working" fine. However during testing I noticed a few times the app seemed to stall up. This left me quite unhappy and I knew it was time to relook at some of my "decisions". Initial glances through the code didn't really highlight anything so I thought it about time to profile the application and see what it can find.

In the past I have used Redgate's Ants Profiler and an early version of Telerik's JustTrace. I decided to give Telerik's JustTrace a go again as I have heard alot about it and wanted to see how it's changed / grown.

Alas, my initial attempt to use JustTrace ended quite abruptly, I've been developing on Windows 8 and VS2012 exclusively for about 5 months now and sadly JustTrace didn't support IIS8 or IIS Express 8. I was gutted to find this out but a quick chat to the Telerik Dev Team and Chris Eargle gave me hope as they advised me the Q3 update was right around the corner, 1 week to be exact, and it brought all the new toys into the game,

HURRAH!

So tonight I got it all updated and fired up, and started profiling my app. Profiling is immensely easy to perform, simply enable justtrace in the Telerik menu and hit F5 :) You are asked how you want to profile, i chose to simply [].

You then simply start using your application like normal and JustTrace sits there observing and recording what it is up too. Once you have spent some testing you can really start digging around. The first thing to notice is the Timeline view, this is showing all the CPU activity whilst running through the application. You want to start looking at where you have some peaks, and in particular extended CPU activity.
Timeline View
By clicking on an area of the timeline you get a larger view where you can highlight a time snapshot to view.
Show Snapshot

You can then look at a ton of options to find your issue, by looking at the call trees across all threads, all methods and even look straight into "hot spots". Hot spots are each threads expensive method in terms of time. In my current snapshot Assembly.Load was very expensive, but this was app startup, not what I was noticing.

Hot Spot View


By looking at the other peaks I did find where 3 seconds was going, executing queries against the database. Now this could be down to bad queries, but its more likely to be a bad use of Linq with Entity Framework, and not compiling queries etc. However now I know where to look and it only took me 5 - 10 minutes of profiling to find out. Fantastic, stuff and I've not even touched memory profiling !

My Hot Spot
Hopefully I can do before my trial runs out, but so far it looks worthwhile investing in, here's hoping I can get some BizSpark discount ;)