Friday, November 14, 2014

My bipolar approach when recommending a mobile device (phones)

Recommending a new device to somebody else requires a lot of analysis, first of all, they will think you are trying to push your own preferences. And that could be true, at least up to a certain point. For me, however, recommending a device becomes a more complex thing. As a developer I work with and own a lot of them: iPhone, iPad, Android phones and tablets, Windows tablets, both "RT" and regular x86. And while my own device is a Windows Phone (Lumia 925) the right device for you depends on a lot of factors.



First, the Phones


Let's compare the three platforms, but only phones for now, we'll be talking about tablets later. So we have iOS (iPhone), Android and Windows Phone. At some point the discussion must be about a specific brand, but at the end we will have to sort results by platform.

Apps

Most likely the app you need is available for both iOS and Android. There is a huge app gap, as well as a huge number of low quality apps in some stores, so my recommendation is for you to check if the apps that you need are available and if they worth it. For example I don't have Candy Crush on my Windows Phone (yes: I can live without it) but the Instagram app on WP is way better than those on other platforms, and it will let you have multiple profiles, more editing features, regram, etc. You will in fact need several apps to accomplish the same result on iOS. In any case, considering the number of apps available alone:
  1. Android:1.3M (source
  2. iOS: 725K  (1.2M total with 475K iPad-specific source)
  3. Windows Phone: 300K (source)

Maps
Second only to phone calling, texting and LOL-ing, FB-ing, etc, there are the maps...And while we can  all have Google Maps on all devices and iOS even having their own, my recommendation goes to the HERE Suite. This suite of products was named after Nokia some time ago; but it actually works on any Windows Phone and is going to be released for iOS and Android. The suite contains HERE  Maps, HERE Drive+ with voice and turn by turn navigation, offline maps, and the HERE Transit app . So when it comes to maps:
  1. Windows Phone
  2. Android
  3. iOS
Camera
Do you like to take pictures with your phone? Do you take a lot of them? Do you try to take pictures in a club at night? Suffering from those blurry photos? Do you have to use flash all the time? Ok, here we can't compare OSes, We need to talk about the actual devices.  So we can check iPhone 6 vs Galaxy S5.  or Nokia Lumia 1520 vs iPhone 6+, or we can bring into the fight devices like the Lumia 830, 925, 930, or the 41 MP Lumia 1020. So if we try to sort platforms by selecting  the best cameras to represent  them, would be like this:
  1. Windows Phone (because of the Lumias with PureView technology)
  2. Android (some Samsung and Sony models )
  3. iOS (iPhone 6+ is the only one with OIS and only 8MP)
Durability
Here again it's very hard to decide unless we talk about specific models. Since some Samsungs are IP67 certified, they look like the clear winners. Lumias (and Nokias in general) are known to be tough devices (remember the 3310?)  The Lumia series of polycarbonate and gorilla glass turn out to be extremely resistant devices. You can actually smash other phones with a Lumia without  having a scratch, and even without an IPxx certification, I have put some of them in water and they are still working. So my ranking would be this one:
  1. Android  
  2. Windows Phone (a close second)
  3. iOS (iPhone is one of the most fragile devices ever created, especially the iPhone 6+ )


Accessories
The winner here is the iPhone. You can find almost any compatible toy, tool, sensor, reader, drone, home automation system and fashion cover out there for it. Android is a second option here, with Windows Phone being a distant third, so:
  1. iOS
  2. Android
  3. Windows Phone
Security
Have you heard about the recent celebrity leaks? Well, security is something important on modern devices, not only because some private photos might be exposed, but also because we keep a lot of information on them, we perform online purchases, access our bank accounts, and reserve plane tickets. When it comes to security, Windows Phone has the edge, and they are the most secure smartphones out there. Android, in the other hand, is the most insecure one due to lot of fake apps in third party app stores, spyware and many security issues. It is in fact the only one where you actually need an antivirus. 
  1. Windows Phone
  2. iOS
  3. Android
Here is the full Kaspersky report. See below how 98.5% of the mobile malware targets Android.


Also check this 2014 Pwn2Own.


Design (Hardware)
I could not sort devices in general by this aspect, since judging a  device by its design it's a subjective task and each person has its own preferences. I would say iPhone 5S has a good design, then the HTC One M8 and Lumia 830, 930 and 925.

Design (UI)
Well, are you tired of icons? I am. Decades of icons it's enough. But don't take my word for it. Let's just show an image I took in the skytrain at DFW airport. Notice they used an iPhone-ish style for the hardware but the inside design is "modern UI" like Windows Phone and Windows 8 (formerly "metro"). Sadly the app itself is not available for Windows Phone (talking about app gap, right?)

The ad shows a modern UI design inside an iPhone case; however the app is not available for Windows Phone.
Clearly, a preference over design is most likely subjective and not possible to measure, however we can notice that even iOS and Android are flattening their UIs to make it more "modern". What do we get from that?

So, what should I get?
It's up to you... What is the most important thing for you? At the end we are talking about phones, and all of them can make phone calls and messaging. So that extra thing that you want will make the difference.

Here's my order of priorities:  Security,  Camera, Maps and Durability, and that's how I ended up with a Lumia 925 and probably will get a 1020 successor when it comes out.

So now tell me: what's in your pocket?


Tuesday, August 12, 2014

From AsyncCompleted to async await

Since we got the magic of async/await on C# things got much easier on the developer front. Working with Tasks is the key to it, but we also have two older approaches in .NET framework that we need to deal with.
  1.  APM (Asynchronous Programming Model) The pair of Being/End methods.
  2.  EAP (Event-based Asynchronous Programming) The MethodAsync/MethodCompleted pair.
Converting from APM to Tasks is achieved by means of the  System.Threading.Tasks.TaskFactory  class and its generic counterpart.

Now converting from EAP to Tasks  requires us to use the TaskCompletionSource<T> class and notify of the state of the task as it goes. See the example of a "handshake" operation in a WCF service. I am also using the approach from my older post regarding events and anonymous methods. The return type of the WCF operation is WrappedResultOfString, and that will be the actual generic parameter of the Task<T> that the HandshakeAsync method will produce.

 public Task<WrappedResultofString> HandshakeAsync(Credentials credentials)
        {
            var tcs = new TaskCompletionSource<WrappedResultofString>();
            var client = _serviceFactory.Invoke(); //get a WCF client instance
            EventHandler<HandshakeCompletedEventArgs> callback = null;
            callback = (s, e) =>
            {
                client.HandshakeCompleted -= callback;
                 if (e.Error != null)
                    tcs.TrySetResult(new WrappedResultOfstring
                    {
                        Value = null,
                        IsFailed = true,
                        Error =  e.Error
                    });
                 else if (e.Cancelled)
                    tcs.TrySetResult(new WrappedResultOfstring
                    {
                        Value = null,
                        IsFailed = true,
                        Error = "Operation Cancelled"
                    });
                    tcs.TrySetResult(e.Result);

            };
            client.HandshakeCompleted += callback;
            client.HandshakeAsync(credentials.UserName, credentials.Password);
            return tcs.Task;
        }

//then this is ready to be used with async/await

public async void LoginMethod()
{
   var credentials = //build your credentials;
  //now we can use 'await'
   var handshake = await this.HandshakeAsync(credentials);
}


This is particularly useful when dealing with WCF proxies in silverlight or windows phone apps where we only get EAP-based operations.


Thursday, June 05, 2014

The uncatchable exceptions in WCF clients

Did you ever have a problem with a WCF client throwing exceptions you can't catch?

If you have used WCF clients from Windows Phone, Silverlight or Xamarin.iOS, you might have noticed that it is not possible to create Synchronous or Task-Based operations; the functionality is reduced to the Event-based Asynchronous Pattern (EAP). That means that the way to call a WCF method and get the response is usually as follows:

var client = new MyWCFClient();
client.DownloadDataCompleted += (sender, e) =>
{
 try
 {     
     //accessing e.Result here might raise an exception in another
     //thread, that will not be captured by the 'catch' below.
 }
 catch(Exception ex)
 {
 }
};
client.DownloadDataAsync(url);


Our results are wrapped in an auto-generated class that inherits from AsyncCompletedEventArgs, this class has a property Error of type Exception, that will carry information about the error and a property Result with our expected return value.

Accessing the property Result after a failed operation call, might cause cause an exception like this one: "An exception of type 'System.ServiceModel.CommunicationException' occurred in System.ServiceModel.ni.dll but was not handled in user code", you will also realize there is no place in your code that you could place a try-catch to capture it, and your application crashes...


The cause of the problem

The behavior is partially "by design". A quick look at the client  generated  code and you will find the root of the problem. The implementation of DownloadDataCompletedEventArgs contains this code:

 public MyTest.WrappedResultOfstring Result {
            get {
                base.RaiseExceptionIfNecessary();
                return ((MyTest.WrappedResultOfstring)(this.results[0]));
            }
        }
So they actually planned to throw an exception if there is something wrong with the operation, which is a good approach actually. However the exception is raised  in another thread.

The solution 

You must first check if the operation failed, and if it did, don't read the property Result, if you do it, then the exception will rise in another thread and it won't be possible to catch it, causing your application to fail. And in the case of Windows Phone and the other mobile apps, that means getting your app rejected from the store. Here is how you should always handle responses from WCF clients.

client.DownloadDataCompleted += (sender, e) =>
{
    if (e.Error != null)
            {
                //...
                //handle the error
                //but never even read from e.Result
            }
            else
            {
                // do something with e.Result
            }
};
 

Why the exception is raised in another thread is beyond me, however the solution to prevent it just implies a bit of good programming practices and nothing more.

Thursday, May 01, 2014

Get-ChildItem vs Dir in PowerShell

Batch as usual

Recently I was in the need of modifying a huge amount of files across a network share. After installing Serviio media streaming service I noticed that it will crash "randomly". After checking the logs it was clear that ffmpeg was crashing when trying to open subtitle files that were not in the encoding indicated by the Serviio console. I needed a quick way to update all subtitle files to a common encoding, so I decided to convert all files to UTF8.

Since I use a windows environment I went directly to PowerShell and wrote this.

 Get-ChildItem -path .\ -filter *.srt -file  | ForEach-Object { (get-content $_.FullName) | Out-File $_.FullName -encoding utf8 }

This worked almost right except for files with "[" or "]" (among other symbols) on the name or path. To solve it, just added the "-LiteralPath" switch to tell powershell not to consider any wildcards on the path name and just use it exactly as it is.

 Get-ChildItem -path .\ -filter *.srt -file  | ForEach-Object { (get-content -LiteralPath $_.FullName) | Out-File -LiteralPath $_.FullName -encoding utf8 }

And done! All subtitles files in my media server are now in UTF-8 and Serviio will work without crashing. 

Too slow?

Performance however was a concern, I noticed this was a bit slower that it should, considering a fast network, small size of the subtitle files (avg<100kb) and how simple the process is. This single-line script has only 2 parts:

(get the files)  then for each file (convert it)

I started to dig a little bit into Get-ChildItem I found that there have been complains about its performance for some time, but it is much better now than in previous versions. Anyway I tried a different way to do that same first part of getting the files and compared it against Get-ChildItem.

Using "cmd /c" executed "dir /s /b <pattern>" and did some tests, local and over the network. See the image below for an example measuring the search for .exe files in another drive.



Both over the network and locally, the "dir" version worked faster, of course it grabs less information than Get-ChildItem, which actually creates an object around the file returned.

For a final test I then changed the original script to: 

cmd /c dir /s /b *.srt  | foreach { (Get-Content -LiteralPath $_) | Out-File -LiteralPath $_ -Encoding UTF8 }

It works 100% like the original script and a bit faster. Although since the big chunk of  execution time belongs to the conversion of the files encoding, the jump in speed is not that big in this particular case. However, when I need to do search and filtering of files in the terms of thousands I no longer use Get-ChildItem.

Hope this is useful for you all.

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.