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.