Wednesday, March 26, 2014

My favorite (critical) developer tools

In addition to pizza, caffeine, and video games, a developer requires a lot of tools, and I mean "a lot". Each one is different so here I want to showcase what I use, and briefly explain why. The idea of this post rather than make any type of advertising (notice there are no links at all) is more to actually find out what other people use and share with you all my experience. So, the profile:  .NET Developer. The usual work:
  • Web applications with ASP.NET (Web Forms and MVC)
  • Windows Forms
  • Windows Presentation Foundation
  • Windows Phone Apps
  • iOS Apps 
Of course, I might code almost every day a bit of JavaScript and some HTML/CSS fixes, along with some other things, but that's not enough to consider it the main course.

The Infrastructure

Before coding, organization and planning is everything, and that means for me 3 things, since I am a SCRUManiac:
  1. Source Control
  2. Issue/Bug tracking
  3. Continuous Integration
For source control, I prefer Git particularly, and use both GitHub and Bitbucket. Keep in mind that the first one is paid for private projects and Bitbucket is free but has a cap on the team size for free projects. I do prefer Bitbucket for personal projects at the end.

YouTrack and TeamCity are two tools that are amazing for sole developers or small teams, the free editions are more than enough for a small team, and YouTrack is magic when it comes to SCRUM. They also integrate pretty well with almost any source code engine out there. You will be able to setup a Build Server linked to a Source Control repository and an Issue Tracker for complete Continuous Integration solution.

NOTE: Its not easy to setup pre-tested commits when using Git, because of its nature, but is totally worth it.
Commit, Build, Test and Report
My recommendation here is to use a Windows VPS to host TeamCity and YouTrack on your own server, that way you (and your customers) have access to the tracking tool from anywhere. A VPS with specs good enough to run these two can be found really cheap online. But you can always use the hosted version of YouTrack and install TeamCity on your local computer or a different box at home or office. You can always opt to install both of them in your local computer.

On the iOS side. 

My preference here is to use Xcode, Xamarin Studio (I also always end up with MonoDevelop as well), with Xamarin.iOS, and MonoTouch.Dialog to help me with the UIs. For source control I used first the built-in support on those IDEs, but I found myself using GitX a lot more lately. 

Extras
  • TestFlight is used for deploying ad-hoc versions of an app during testing. 
  • VNC and Synergy, because having two keyboards when doing tandem developing is not funny at all, so I connect the Mac with the Windows via Synergy and use only one keyboard and mouse. VNC for remote access of course.

On the Windows Side (Web, Desktop, Mobile)

On Windows for a .NET developer: Visual Studio 2013 with Blend. Hands-down. It can do anything you want and usually more, most people I know don't use everything there is to use in Visual Studio. The emulators for Windows Phone and Windows Store development are great, testing, analysis, and more. On the source control side, you can use the built-in plugin/ I use GitExtensions a lot as well on windows mainly because of its Explorer extensions but also because the merging and branching is nicer with it. 

ReSharper colors in a dark background with VS 2013

ReSharper. This well-known Visual Studio plugin requires an especial mention; it is one of the most effective plugins I have ever seen. But it has too many good features to explain them all in one post.

Hyper-V. I run a lot of tests from different environments, so having a way to run Virtual Machines with different configurations is mandatory. Originally I used VMware player for a lot of time, until I got Windows 8 with Hyper-V. 

Extras
  • Telerik. Creating great UIs is difficult, but is less difficult with Telerik components; they have for Web, Desktop and Mobile.
  • Paint.NET. This image editor support layers and it has a huge library of plugins and filters (and it's free)
  • VNC/Synergy, because it's a two-way thing.
  • TuneUp. I know..., why this? Well, it turns out that I need to cleanup, uninstall, install and fix things on a developer computer a lot. This tool helps me keep my pc running smoothly. And its been running smoothly since 2011 and Windows 7.

There is always more.

There are many other tools that we often use, I intentionally left some of them out, like SQL Server Management Studio and others related to databases or Testing Frameworks, or even sketching/mocking tools, but I wanted to mention the most interesting things. Now let me know what's on your side.

Friday, March 14, 2014

Virtual Keyboard in iOS - part 2

One the first entry of this series I covered the issues with the keyboard in iOS not hiding automatically when needed. In this second - and final - entry on the subject I am going to go for the most of annoying issue when creating UIs in iOS.



The keyboard overlaps a focused TextField 


If you have a TextField below the keyboard top edge position, they will be hidden once the keyboard shows up. The keyboard size is 320x216 points* in in portrait mode, so anything below the 264 (iPhone 4/4s) or 352 (iPhone 5/5s) points won’t be visible.  It is so simple that is almost unbelievable, but it happens as you can see in the images. Since this default behavior is inconvenient we are going for the workaround.

The solution is not pretty but it is trivial: we need to place the UI elements inside a UIScrollView  and will use notifications to monitor when the keyboard will Show/Hide and will scroll the content of the container to ensure that views inside are always visible. We are using Xamarin and Xcode to develop this example. The first step is to subscribe to the notifications:

public override void ViewWillDisappear (bool animated)
{
 base.ViewWillDisappear (animated);
 UnregisterNotifications ();
}

public override void ViewWillAppear (bool animated)
{
 base.ViewWillAppear (animated);
 this.scrollView.ContentSize = new SizeF (320, 400);
 RegisterNotifications ();
}

NSObject _keyboardWillShow;
NSObject _keyboardWillHide;

protected  void RegisterNotifications ()
{
 _keyboardWillShow = NSNotificationCenter.DefaultCenter.AddObserver (UIKeyboard.WillShowNotification, WillShow);
 _keyboardWillHide = NSNotificationCenter.DefaultCenter.AddObserver (UIKeyboard.WillHideNotification, WillHide);
}

protected  void UnregisterNotifications ()
{
 NSNotificationCenter.DefaultCenter.RemoveObserver (_keyboardWillShow);
 NSNotificationCenter.DefaultCenter.RemoveObserver (_keyboardWillHide);
}


There is also an outlet called scrollView to access our container and on the ViewWillAppear method we set the ContentSize of the container. You should adjust this value to your specific UI layout.

The NSNotificationCenter it’s a singleton that will allows us to register for notifications, which are essentially events. We will register for two specific notifications on the ViewWillAppear and unregister them on the ViewWillDisapear.

The trickiest part is the WillShow event, in this case the actions are:
  • Get the area above the keyboard.
  • Get the area of the active view.
  • If those areas intersect (meaning is no 100% visible) then we scroll to ensure the active view is completely visible.
protected  void WillShow (NSNotification notification)
{
 var activeView = this.View.FirstResponder ();
 if (activeView == null)
  return;    

 //get keyboard bounds
 var keyboardBounds = UIKeyboard.FrameBeginFromNotification (notification);

 var contentInsets = new UIEdgeInsets (0.0f, 0.0f, keyboardBounds.Size.Height, 0.0f);
 scrollView.ContentInset = contentInsets;
 scrollView.ScrollIndicatorInsets = contentInsets;
    
 //get the are above the keyboard
 var areaVisibleAboveKeyboard = new RectangleF (this.View.Frame.Location,
          new SizeF (this.View.Frame.Width, this.View.Frame.Size.Height - keyboardBounds.Size.Height));

 //get the area of the view we want to ensure its visible
 var areaActiveView = activeView.Superview.ConvertRectToView (activeView.Frame, this.View);   
    
 //if we can't see the full view, then scroll so its visible
 if (!areaVisibleAboveKeyboard.Contains (areaActiveView)) 
 {
  var scrollPoint = new PointF (0.0f, areaActiveView.Location.Y + areaActiveView.Height + 
  scrollView.ContentOffset.Y - areaVisibleAboveKeyboard.Height);
  scrollView.SetContentOffset (scrollPoint, true);
 }
}


The WillHide is far simpler; just reset the scroll the original state.

protected  void WillHide (NSNotification notification)
{
 var activeView = this.View.FirstResponder ();
 if (activeView == null)
  return;         

 //scroll back 
 var animationDuration = UIKeyboard.AnimationDurationFromNotification (notification);
 var contentInsets = new UIEdgeInsets (0.0f, 0.0f, 0.0f, 0.0f);
 UIView.Animate (animationDuration, delegate {
  scrollView.ContentInset = contentInsets;
  scrollView.ScrollIndicatorInsets = contentInsets;
    }
 );
}

Notice that in both the notifications we are checking for an active view, or “first responder” we are using the extensions method from the previous article.

You can get the full code of a working demonstration of both problems and their solutions.
  1. KeyboardMess.zip - full source code
  2. or see all the code above together on a GitHub Gist.


* Points are not pixels, check iPhone Development Guide for more details.

Wednesday, February 05, 2014

Virtual Keyboard in iOS - part 1


When you are a developer for more than one platform, you might find that what is considered basic or pre-built in one, it’s incomplete or completely missing in another one. This entry is about fixing some issues with the virtual keyboard on iOS; especially when it hides your text fields or keeps the input focus. Xamarin Studio/Mono and XCode were used for this example.


Hiding the keyboard

Tapping inside the TextField will show the keyboard, but it won't be possible to get rid of it by tapping outside or pressing “RETURN” on it. This is something pre-built in Silverlight for Windows Phone. Tapping outside of the textbox or hitting the “back” key will hide the keyboard. But well, there is no back key on the iPhone.

So let’s start by creating and extension method that we will use in the rest of the solution. The method will return the view that is the first responder or the “active” one.
public static class Extensions
 {
  public static UIView FirstResponder (this UIView view)
  {
   if (view.IsFirstResponder)
    return view;
   foreach (var child in view.Subviews)
   {
    var fs = child.FirstResponder ();
    if (fs != null)
     return fs;
   }
   return null;
  }

 }
Once it’s done, edit the code of the ViewController where the TextField is located and override the TouchesEnded method with the following implementation.
public override void TouchesEnded(NSSet touches, UIEvent evt)
  {
   var fs = this.View.FirstResponder ();
   if (fs != null)
    fs.ResignFirstResponder ();
  }
Basically the solution is to resign the focus once a touch action finished. But to complete the fix it’s necessary to do the same when the user hits the “return” key, for that a “delegate” [1]  for the TextField must be implemented. In this delegate the method ShouldReturn is overridden to surrender the focus.

public class HideOnEnterDelegate : UITextFieldDelegate
 {
  public override bool ShouldReturn (UITextField tf)
  {
   tf.ResignFirstResponder ();
   return true;
  }
 }
And back into the code of the ViewController preferably in the ViewDidLoad method (you can do it elsewhere)  assign the delegate to your text field.
public override void ViewDidLoad ()
  {
   base.ViewDidLoad ();
   
   //set the delegate for the TextField
   textField.Delegate = new HideOnEnterDelegate ();
  }
At this point the text field behavior is more natural, giving it focus will show the keyboard, taking focus away by tapping outside will now hide the keyboard and so will do the "RETURN" key.

That's it for now, round two will cover the more complicated issue when the keyboard overlays on top of the input text fields. And will include the full source code for this example app.

[1] The term delegate here is not related to C# delegates, but to the objective-C delegation pattern, for more see here.

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)