Friday, December 20, 2013

Where is Silverlight now?

Time ago I wrote an article about the comparison between of HTML5 and Silverlight. That article was indeed about the "comparison" itself rather than another attempt to compare the two; mainly because I consider that kind of measuring to be pointless. Then again with the pass of time the same question arises: is Silverlight dead?

Before going into trying to answer that, allow me to be clearer than what I was at the time and let me rephrase the question: is the silverlight plugin for browsers dead? Well... the answer is yes, not even a "maybe". But as with any existing software, dead is not actually extinct. We still have people writing code in COBOL, FORTRAN,  DELPHI and VB6. And this is because the enterprise market does not move at the same pace as the consumer market. They invest in infrastructure, they keep it, and they treasure it. And Silverlight was highly adopted in the enterprise for LOB applications. So in that area, Silverlight is going to be there for some time.

So why do people complain? Well the media helped. Panic: Silverlight is dead, go to HTML 5! And when there is a fire, people's first reaction is to scream and run away, instead of finding the origin and trying to do something.

Now, to be honest I was quite disappointed when I saw everybody at Microsoft just jumping off the Silverlight ship. As a C#/XAML developer I felt betrayed, I could not imagine how someone could drop all those really cool, dynamic, responsive and beautiful applications for basic HTML pages. And when they announced that ARM versions of the Surface (the RT) wouldn't run Silverlight I was really mad. But I was short-sighted. It took me a bit until I realized the obvious: I could do the exact same thing that I was doing with a "plugin in a browser" with "an app"; a mobile app, a windows store app, and it would be better fitted for my Windows Phone or my Surface table than any web site. The skills are transferable, and the underlying is similar,it is not a hard task at all. 

And then everything made sense, Microsoft would support HTML5 for the web, pushing the standard along other big guys, and Silverlight was repurposed to fit other roles, and as of today 200.000+ apps in the Windows Phone Store shows that it is not dead.

HTML5 is going to be there, so we have to support it, because it is all we have. Yes, is sad to admit it, more than 20 years later, we have nothing better. HTML is terrible, JavaScript is terrible, and the new potpourri called HTML5, is still terrible. But again, let's face it, there is nothing better

A Windows Store app where you see XAML and .NET is not technically Silverlight, but it will take you no time to convert your Silverlight app into a new one, either a regular WPF, windows phone, or windows store (ARM or x86). A lot of the code can be reused, with little to no modification at all.

Silverlight is not dead, it evolved. You have it on your pocket in your Windows Phone, your Windows tablet, on your Windows computer at home; it is just not constrained anymore to be a hanging plugin at the will of a browser. It does not require a browser anymore. It's transparent to your eyes, you don't see it, and all you see is an app. Because that's all you need.

Monday, October 28, 2013

New updates in apps and games

Just recently updated a couple of apps.

  • Loan Calculator
  • Reversi (both Free and Full editions)

Loan Calculator

First the small "Loan Calculator" app, got a small update.


The UI was simplified and some small glitches were addressed. Is hard to improve an app that is already quite useful yet simple. However new versions will improve it even more and not just cosmetic changes.

Reversi

Reversi got an "almost major" update, with an improved UI (at least over the previous one) and also a new feature that allows the user to see the possibles moves (hints), which of course, you can turn on/off.

Hints are available and optional

In addition to these improvements in the user interface, the internals were also improved a lot, the new game is quite faster than the previous versions and also plays better. Fixing an issue introduced with version 1.2 when the AI was... not so smart.

For next versions...

  • Sounds
  • Statistics board
  • All levels available in the Free edition
  • Custom levels (for geeks)
  • Skins
So stay around and check it out soon.

Monday, September 30, 2013

The invisible property of UIViewController

Popular wisdom says "things happen for a reason". However experience has proved me that when it comes to programmers, that is not always true. Things can just happen for no reason at all. That's why we require feedback, here is one and I assure you is in good spirit. So let's me write about something I found when building an app for iOS using Xamarin/Mono.

The invisible property.

Ranging from windows forms (desktop or Windows Mobile) to WPF, Silverlight/XAML on the web or windows phone. ASP.NET Web Forms or Razor, MVC or classic. One thing I can say for sure: any visual element has a way to check for its visual status.

Call it "Visible" in windows forms, "Visibility" in Silverlight/WPF. There is always an intuitive, simple and trivial way to know if something - that might be visible - it is visible at a particular moment or not. You can't imagine my surprise when I realized that the UIViewController in iOS does not provide such mechanism.

Of course it would not seem necessary because the  UIViewController is not a visible component itself, it is a controller that manages views (root view and subviews) and acts on behalf of them when the user interacts with them. However, in reality we require too often to know if the given "screen" is still visible or not. Examples? asynchronous  callbacks...

Let me add that I am not using the APIs directly with Objective-C, instead I am using Mono to write my app in C#. I checked however, that this is not a deficiency of Mono, it is "by design" or at least it seems so.

So lets explore the alternatives. In order for you to know if a UIViewController (actually its main view) is visible. You can do this:
 
if (this.IsViewLoaded && this.View.Window != null)
   {
    //is visible
   }
   else {
    //not visible
   }

We check first if the current view is already loaded, then we check whether  the parent window is null or not. The reason for the check is to prevent the system from loading the view when asking for its status. And of course that "loading-when-you-ask" is something that is worth an extra discussion but let's skip it today.

But wait, there is more...

The invocation above should be done from the main thread, because we are touching visual components. And we could clean this up a bit and use an extension method. Like this:
 
public static bool IsVisible(this UIViewController view){
   bool value = false;
   view.InvokeOnMainThread (() => {
    value = view.IsViewLoaded && view.View.Window != null;});
   return value;
  }
It's easy, it's not clean, but it works. Now, bad things happen when developers are trying to work around the underlying APIs because something is missing. It might be difficult to accomplish a task, and actually it might be difficult to do it the right way. The code above needed a check in order to prevent the view from being loaded, easy to miss. 

An alternative

If you are using a UINavigationController it might be easier just to check for the VisibleViewController property, this will include views presented in modal mode.

The dirty (don't do it) way

Now the terrible part of workarounds, is when they become something like this:

//the WRONG WAY
//use a field to hold the value
bool isVisible = false;

public override void ViewDidAppear (bool animated)
 {
  base.ViewDidAppear (animated);
  isVisible = true; //and change it when the view appears
 }

public override void ViewDidDisappear (bool animated)
 {
  base.ViewDidDisappear (animated);
  isVisible = false; //or disappears 
 }

I have seen this implementation several times, please don't do it this way, so many things wrong...that I won't enter into details here. Just don't do it. Stick with the other options, until they provide us with a simple property for that.

On the next entry will talk about the virtual keyboard on iOS...!

Thursday, July 25, 2013

The value of your opinion

I have published apps and games for Microsoft Windows Phone, and I update them in a regular basis. Most of the time is because a bug is found, sometimes is a new feature or just because I am trying something new. It helps to keep things moving and people thank you for that.

However, I never had to protect an app or a game from human stupidity. Until now.

Software developers learn  over time how to deal with the final user - in some measure - and I must admit is not easy; as programmers we are not trained to deal with them, is usually another person's job. But when it comes to phone/tablet apps, that individual is you, because as an 'indie' developer you are too close to the complete production line.

I classify the users like this:

  1. The happy mute
  2. The unhappy mute
  3. The fan
  4. The hater
  5. The stupid

The mute ones...

There are always people that either like or don't like your app or website, or tool, but they just don't say anything. This is good and bad, you don't get bad reviews, but that implies you are not getting feedback that is always good. But the worst part is the that the ones that like your app, but are too lazy to upvote it or comment about it, they just don't help either. 

The fan and the hater...

The fans and haters are a necessary part of anything that exist in the planet, but when it comes to technology, they go to the extreme, however they are easy to spot and you can easily bash them, as most of the time they arguments are pointless. Of course, they can hurt you  a bit, mainly because haters are more effusive and active than fans... but hey, there is no such thing as bad publicity right? (or so they say)

Now... the stupid.

This is the kind of user that is impossible to please, and is quite common in the mobile app business. Any app that you find in the Microsoft Store, Apple Store or Google Play, has negative reviews that are written by this type of users. People that downloaded an app, did not read the instructions or have no idea what the app is for but they go and trash the app.

I have seen many cool apps being trashed by this type of pseudo-users, like a torrent download app, that is downvoted because it does not play a song, or downloading an app that does not provide services in the country where the user is located. Even an apps like Flipboard, downvoted by a user that is trying to use it in a hacked phone that barely works, or simply because the user's phone is crashing by itself or  has no space left and is behaving slow.

There are restrictions on what is possible on the phones as in any platform, that's why many apps explicitly say on the description something like:

1) this app can not delete photos from your phone
2) this app can not add videos to your phone
3) this app can not play videos or photos from your SD card
4) this app can not control the Mars Rover

and so on..

Whenever we - the developers - hit a limitation in a platform, we either find a workaround or describe the limitation to the user. If we take the time to do so, we should be able to expect something reciprocal from the users.

The value of your opinion

I think that everybody has the right to give an opinion (even haters), however I am strongly convinced that the value of such opinion has to be taken into consideration. On the internet, there is little room for that. Although many web sites allow people to rate what others say. 

On  websites like MSN you can downvote/upvote a comment on an article - that's a start -and you can also answer to those guys. 

On 'The Code Project' you can answer back and rate with a value (1-5) any answer or comment, you are also forced to justify any score from 1-3. And the system weights the points taken based on the voter's reputation points. The system is not perfect, because some users have a million points just for spending time posting on every forum and making jokes all day, and no points for writing an article or publishing something. But still, better than the model used on the app stores.

On Amazon, people can vote and comment on other's reviews. That seems fair. And I think is simplistic enough to be used on the app stores, and we should definitely move into that direction.

You must earn the value of your opinion.

 (maybe that's why I don't vote in the Oscars)

Friday, January 25, 2013

Events and Multithreading


This is  the second and final part of this series. Will focus now a bit on what happen when we add multithreading to our work with events.

Cleaning Up Events and Context Information


In the previous post I mentioned some issues using lambdas and anonymous methods on events. The unsubscribe problem had a tricky "solution" by declaring a "cleanup" method inside the class that holds the event.
 
public void CleanupSubscribers()
{
    SayHelloCompleted = null;
}

The problem here is obvious since the cleanup method will remove all subscribers from the event. Hence, individually removing listeners from the event gets tricky when using lambdas/anonymous methods. So in this case the recommendations would be:
  1. Do not use lambdas if you need to unsubscribe.
  2. If you do so, use the cleanup method UNLESS your code is multithreaded. 
NOTE: this only applies to the use of lambda expressions and anonymous methods, as for regular named methods you can always remove them easily. 

Race condition, late invocation and more...


Now let's keep with multithreading, because it gets really messy. If we take a look at the previous event invocator OnSayHelloCompleted we will notice the code might seem redundant, right?

   public void OnSayHelloCompleted(HelloEventArgs e)
   {
       var handler = SayHelloCompleted;
       if (handler != null)  
             handler(this, e);
   }

Questions: why hold a reference to the event, then check for null? why not check it for null directly? The reason behind that is that multicast delegates are immutable; so adding/removing subscribers actually creates a new copy. That being said, in line 3, we hold a reference to the list of subscribers into the variable handler, so no matter if SayHelloCompleted event is modified, the local copy will keep the same value through lines 4 and 5.

So we do that to make it "thread-safe", and it worth noticing that both Visual Studio and Resharper pre-populates the invokers this way.

Problem: We can invoke a listener AFTER the the listener itself was removed form the list. WHAT?! yes,.. just like that. We remove the race condition but we get a kind of "unwanted" call problem.

The Bad Optimization


Some people think they "optimize" the code by doing this:
 
//WRONG WAY
public void OnSayHelloCompleted(HelloEventArgs e)
{
   if (SayHelloCompleted!= null)  //is not null at this time
        SayHelloCompleted(this, e); //it can be null if another thread modifies the event
}

This is a clear case of a race condition and you should avoid this.

Alternative...


A suitable alternative could be to always instantiate the event with an empty delegate. Thus, removing the need for a null check.
 
//instantiate with empty delegate
private event SayHello SayHelloCompleted = delegate { };

public void OnSayHelloCompleted(HelloEventArgs e)
{
   //no need for a null-check
   SayHelloCompleted(this, e);
}

Since the event is never accessed from the outside of the class directly, it will never be null.

Controversy: I have read many comments about people complaining that this will cause a "performance" issue, it does not. There is a performance overhead of course, but is minimal, you can do the tests and see for yourself.

Now, don't you think something like this should already be in C# 5.0? I think so...we already have async and await and all that, but events are a bit behind.(IMO)