Wednesday, October 05, 2016

Converters are bad, so it's good that the AU means fewer are needed #UWPLunch

All this month, I'm taking some time each day to explore (and document) things that are related to UWP development that I haven't fully investigated or used before. While doing it over lunch each day I'm calling it #UWPLunch.

On the surface, converters (implementations of IValueConverter) are powerful tools but I think they're massively overused and encourage doing some things which are actually bad.

The MVVM pattern is great. It's biggest benefits are to enable code reuse and improve the ease of testing. At some point in time, many people confused the pattern and the goals as being based on not writing "code behind". Specifically, they see this as meaning there should be as little as possible code written in the XAML.cs files (ideally none.) Instead, they write more behaviors, converters, or XAML. Here's my issue. Each of these are all code (yes, even XAML) that exists in the UI layer of the app. Just like anything in the code behind file. So my first objection is that there's an artificial distinction between the file or language (XAML vs C#) that UI related code is written in.

But it goes deeper.

If I have a VM that surfaces some data that must be converted before being displayed, I've now got two classes that must be used together. This coupling makes reuse harder. I can't just move one thing around, I need to know that I need another thing with it. Unfortunately, there's no standard way of indicating the VMs dependency. (And I doubt there'd be any benefit in creating such a thing anyway.) Not only do we have two separate but related classes, the business logic for how something should be displayed has been split. This makes testing harder. There's no single item under test in this instance so tests become more complicated. That the logic is in a behavior or a converter also makes it harder to test as it can't be as easily instantiated. It's normally necessary to end up running tests on such objects via the UI. Not only are such tests harder to write they're also slower to run. (UI tests are slower to run than pure code.) Tests that are hard to write or slow to run end up being run less often and eventually abandoned, bringing less benefit and eventually none.

The overuse of something as potentially helpful as a converter can actually undo some of the benefits of the MVVM pattern.

In the past, I've hit issues with performance related to the use of converters. This should no longer be an issue unless they're doing something very complicated or you're using a very large number of them. However, it's made me wary of using them. They also run on the UI thread so can impact performance there.
Generally, I try and avoid the use of converters. Instead I move the logic into the VM itself. All nice and cozy and contained. (Don't worry, I can still encapsulate logic and avoid duplication with this.)
The biggest exception to this is for Visibility. For lots, and lots, of circumstances, it's necessary to make things visible, or not, based on specific (normally boolean) criteria. I have a converter which can take a large number of different inputs (bools, numbers, lists, strings, etc.) and turn them into a Visibility value. It's generally very useful and I use it a lot.

That may not be the case going forward though as in the Anniversary Update, compiled bindings support implicit visibility conversion for booleans.

That means you can put this in the code behind (or associated VM).

 public bool ShowMe { get; set; } = true;
 public bool DontShowMe { get; set; } = false;

And use them to control visibility like this:

 <TextBlock Text="Now you see me" Visibility="{x:Bind ShowMe}" />
 <TextBlock Text="Now you don't" Visibility="{x:Bind DontShowMe}" />

which would only display the first TextBlock.


A couple of points of note.

This only works if the minimum version of the project is the AU.
The implicit conversion only works if the app is running on a machine running the update. The above targeting means that the app will only run on such. In theory, you could include it in code that targets earlier versions and selectively include it if you can detect you're running on a machine with the update but you'd still need to support explicit conversion for when running on older machines and so would require extra code.
The other downside is that you have to bind to booleans for the code to even compile as that's all that's supported. I'll need to keep my own converter around for a bit longer to enable me to do more interesting things like hiding zero length strings or empty lists. Either that or add extra properties to the VM for binding.



Tuesday, October 04, 2016

Displaying GIFs in a UWP app #UWPLunch

All this month, I'm taking some time each day to explore (and document) things that are related to UWP development that I haven't fully investigated or used before. While doing it over lunch each day I'm calling it #UWPLunch.

Displaying GIFs in XAML apps has been notoriously tricky in the past. A mix of licensing issues and a lack of native support meant that complicated workarounds were often needed. The most common solution involved the use of an embedded webbrowser control but it was a far from ideal solution.

With the anniversary update that's changed. GIFs and even animated GIFs are now supported.

Simply drop this in a blank app.

<Image Source="https://api.giphy.com/img/giphy_search.gif" />

and get something that looks like this (minus the animation)

Going a bit further I wanted something that would show a few more animated GIFs at once so I created an app that's pointed at the giphy trending API.


It was just a case of grabbing the API response and serializing it as something suitable

    var json = await new HttpClient().GetStringAsync(new Uri("http://api.giphy.com/v1/gifs/trending?api_key=dc6zaTOxFJmzC", UriKind.Absolute));

    this.DataContext = JsonConvert.DeserializeObject<ApiResponse>(json);

and then displaying it on the view:

        <GridView ItemsSource="{Binding data}" >
            <GridView.ItemTemplate>
                <DataTemplate>
                    <Image Source="{Binding images.original.url}"
                           MaxWidth="200" />
                </DataTemplate>
            </GridView.ItemTemplate>
            <GridView.ItemsPanel>
                <ItemsPanelTemplate>
                    <ItemsWrapGrid Orientation="Horizontal" />
                </ItemsPanelTemplate>
            </GridView.ItemsPanel>
        </GridView>


And voila, a lovely app showing lots of animated gifs:


Apps requiring the display of gifs are no longer an issue. :)



Monday, October 03, 2016

Trying out the new Windows App Development Virtual Machines #UWPLunch

All this month, I'm taking some time each day to explore (and document) things that are related to UWP development that I haven't fully investigated or used before. While doing it over lunch each day I'm calling it #UWPLunch.

At the end of last week, Microsoft (Hi Clint) announced the release of some updated virtual machine images for doing Windows App Development. While I always like having real hardware to run on (it's just faster) I appreciate the need for having a consistent development machine image and it's always good to have a backup. Recently, while preparing to move house and with all other machines packed in boxes my dev machine had a disk failure and I needed to get another dev environment set up quick to create a new release build of an app for a client who needed it ASAP. Using these VMs then might have saved me a lot of faffing around and unpacking.

Knowing these are available is great, but how easy are they to actually use?
Follow along as I see.

I started by going to the Azure portal and searching for a virtual machine that included "Windows SDK".


There's a few there so I selected the first on the list and hit create.


Then it was a case of specifying some details and selecting a machine size and specifying some network settings (which I left as all default values).

Then I just pressed OK and a VM was created for me.

Deployment took a few minutes (8 minutes and 40 seconds to be precise) and then I was able to remotely connect to it via RDP by clicking on the 'connect' link at the top of the screen.

I then entered the credential specified when creating the machine and trusted the certificate when prompted.
And then I had a virtual machine up and running and capable of use as a development environment.

All my favourite project templates are there

and I can create and run new UWP apps.


Yay!

Based on this experience I'll definitely keep a VM around and fully set up for my next UWP project. I never know when I won't have a dev machine handy but need to make a change.I'll also keep an eye out for how updates to the installed tools are handled.


Friday, September 16, 2016

99 developer events

Last month I organised my 99th developer event.
(I've attended and spoken at many more but that was the 99th I'd been primarily, if not solely, responsible for organising.)

These have been as part of DevEvening and then as the 'Window Phone User Group' which was later renamed 'Windows Apps London'. (27 for the first and then 72 for the latter.)


These have mostly been presentation based events on a mid-week evening but have also included:

  • one-day barcamps and mini conferences
  • all-day hackathons
  • workshops
  • coding competitions
  • collaborative coding challenges
  • show-and-tell sessions
  • social events

Through these events, I've met some amazing people and been granted some great opportunities (both in terms of work and personally.)
It's not been just about me . Through these events:
  • friendships have been made
  • businesses have been formed
  • people have found work (and whole new careers)
  • many people have learnt a great deal
  • many apps/products/services/tools have been created and improved
  • attendees have been motivated
  • lessons have been shared and learned
  • people have been encouraged to share what they've learned
  • some of the people who spoke at these meetings for the first time have gone on to become international conference speakers
  • at least five other groups have been started prompted by attendance at one or more meetings
  • lots of people got free phones and tablets
  • I've given away a lot of software, conference passes, t-shirts, badges, stickers, books, pens, cups, and other assorted SWAG (huge thanks to all who donated these.)
  • a lot of burgers and pizza have been eaten. (For events held in pubs this usually meant people buying burgers. For other events this meant ordering pizza--and I'm now very good at ordering large quantities of pizza!)
  • and, of course, much drink has been drunk. (Possibly surprisingly more soft drinks than alcohol and I've also learnt that people really appreciate a variety of drink options.)

It's been an incredible time. 
I started organising these meetings because I wanted to go to them. To meet people with similar interests and learn from their experiences. I've certainly done this and more, even though I'd often miss some of the talks I was keen to hear as I was busy doing organisation related things.

The highlight of eight years of organising events is hearing from people who come to and look forward to these events because they would have had little option to socialise otherwise or at least to meet with other people who share their interests.
It can be tempting to joke about or dismiss a group of geeks or nerds meeting together to talk about technical subjects. (There are even lots of technologies and acronyms discussed that I don't know anything about but others care about passionately--and that's ok.)

While the freebies and trips have been great, the biggest highlight for me and which makes all the organisational effort worth it is one story which almost had me in tears.
Someone who had been coming to meetings on and off for a few years stopped coming for a while. He turned up at one meeting a few months later and after the meeting spoke to me. He said that he was sorry he hadn't been there for a few months. His father had died, his wife had left him and taken their three kids, he'd had to find a new place to live, and get a new job. That night was the first time he'd been out in three months and he was really appreciative of the opportunity to see some friendly faces and spend a few hours doing something for him and enjoy focusing on something pleasant that he like doing. I felt it an honour to be able to help create something and a place that would allow him to feel like that.
In a world where people are increasingly being isolated, it's important to meet with other people with similar interests. Even if it is just to talk about "techy geeky stuff".


What comes next? (Some people have told me that I have to get to 100 events, but 99 seems like just as good a number.)
Right now I honestly don't know what'll be next. Personal circumstances mean it's highly unlikely that I'll be doing any more evening events in the next few months.
Maybe something online - but I've always really valued the difference people meeting in person brings to an event. (see above)
Maybe something during the day....


To all who've attended or otherwise been a part of those 99 events, Thank you. I hope you enjoyed and valued them as much as I did.