Wednesday, June 20, 2012

It's Been A While

I knew it had been a few months since my last post.  As it turns out, it's been almost a year!  Ugh.  I've been working on some very cool MVC projects, learning HTML5, and dabbling in mobile development.  What have I NOT been doing?  Blogging about it!  Let's change that....

New Discovery 

The only 2 viable mobile platforms right now are Android and iOS. (OK - maybe Windows mobile, maybe).  Of course, what that means is to write an app for both platforms means writing an app in Java for 'Droid and porting it to ObjectiveC (or the other direction).

There are ways to avoid this - Monotouch lets you write your code in C# and compile to your target platform. Monotouch is not cheap - $1000 for each platform! Yikes!

I recently discovered another tool that allows people to write once and run everywhere - PhoneGap.

PhoneGap lets a developer create HTML5 pages, add them as the content to their phone app, compile and run.  Wow.

This has so many advantages:
1. We already know HTML and Javascript
2. Did I mention that PhoneGap is FREE?
3. Testing is a breeze now - in fact, you can write your HTML/Javascript code once, and test it in a mobile browser, desktop browser, and in your apps.

There are very clear directions on how to write an app using PhoneGap, so I won't bore you by re-writing a how-to.  I wrote a very simple app using jQuery Mobile and Google maps.

All this app does is get your current location and create a 'pin' in a Google map. 

Below is the HTML5 code I wrote.  Give it a shot!  :-)  I think PhoneGap is a great tool that really simplifies creating mobile apps.  By the way - I also took advantage of the jQuery Mobile layout tool to generate the HTML and CSS.  What it generates is pretty generic (for example, I had to completely rewrite the code that communicates with Google Maps), but it's a good starting point.

     

<title>  
     </title>  
     <link href="http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.css" rel="stylesheet"></link>  
     <link href="my.css" rel="stylesheet"></link>  
     <style>  
       #mapcontainer {  
       height: 300px;  
       width: 95%;  
       border:3px solid #eaeaea;  
       }  
 </style>  
     <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js">  
 </script>  
     <script src="http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.js">  
 </script>  
     <script src="http://www.google.com/jsapi">  
 </script>  
     <script src="http://maps.google.com/maps/api/js?sensor=false">  
 </script>  
     <script charset="utf-8" src="cordova-1.8.1.js" type="text/javascript">  
 </script>  
     <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" type="text/javascript">  
 </script>  
     <script src="modernizr.js" type="text/javascript">  
 </script>  
     <script type="text/javascript">  
       $().ready(function(){  
         if ( Modernizr.geolocation ) {  
           navigator.geolocation.getCurrentPosition(  
           function(pos) {  
           $("#lat_field").val(pos.coords.latitude);  
           $("#long_field").val(pos.coords.longitude);  
           var coords = new google.maps.LatLng(pos.coords.latitude, pos.coords.longitude);  
           var mapOptions = {  
             //zoom level, between 0 to 21.  
             zoom: 15,  
             //center to the user location  
             center: coords,  
             //add map type controls.  
             mapTypeControl: true,  
             //navigation control options  
             navigationControlOptions: {  
               style: google.maps.NavigationControlStyle.SMALL  
             },  
             //default map type  
             mapTypeId: google.maps.MapTypeId.ROADMAP  
           };  
           // Create the map, and place it in the mapContainer div  
           map = new google.maps.Map(  
             document.getElementById("mapcontainer"), mapOptions  
           );  
           // Place the initial marker  
           var marker = new google.maps.Marker({  
             position: coords,  
             map: map,  
             title: "Your current location!"  
           });  
           }  
           );  
         }  
         else{  
           alert("Error");  
         }  
       });  
 </script>  
     <div data-role="page" id="page1">  
 <div data-role="header" data-theme="a">  
 <h3>  
           Where Am I  
 </h3>  
 </div>  
 <div data-role="content" id="mapcontainer" style="padding: 15px;">  
 </div>  
 </div>  
 
    

Thursday, August 11, 2011

Little Gotcha in VS 2010

If you have a class library, and you want to write a Console app to test your class lib with, you might find you get a compile error that doesn't make sense:

The type or namespace name 'MyClassLib' could not be found (are you missing a using directive or an assembly reference?) 

This could be caused by the target framework being set to "client"

Here's how to fix it:
  1. Right click the console app project, and select Properties (at the bottom of the menu).
  2. Select the Application tab on the Property page
  3. Check the Target Framework - make sure it is NOT .Net Framework 4.0 (or 3.5, if that's what you are using).
  4. If it is client, you can just select the correct framework - in my case .Net Framework 4.0
  5. When you select the new Framework, you will get a warning about unloading the project.  Who cares, it's wrong anyway!  :-)

Monday, August 8, 2011

How To Tell If a Request Is An AJAX Request (Microsoft MVC)

There might be times when you want to handle an AJAX http request differently than a "normal" http request.

It's really quite simple - just check the request header!

if (Request.Headers["X-Requested-With"] != null
    && Request.Headers["X-Requested-With"] == "XMLHttpRequest"){
   // if here this is an AJAX Request
}


The point is, take a look at the Headers attribute of the Request and check using the code above.

Hope this post saves someone some time!

Tuesday, August 2, 2011

APIs and Method Deprecation

One of my current projects requires the use of a Library for document conversion and manipulation.  This company has some very good products and they are in a complicated space - one that's always changing.  Like most library vendors, they are looking for ways to improve their offering.  With improvements, comes change...

That said, they are not very experienced at .Net.  Most of their libraries are unmanaged DLLs and their support for .Net clients is with a managed DLL that is a thin adapter around the unmanaged DLL.

Consider this call:  lib.DoSomething(string FileName, int Param);
In earlier versions of their libraries, I would pass in a file name and the param and all was good in the world.

In the newest version, the signature has not changed, but you are not supposed to pass in a file name!  You should only pass "" (an empty string).

In other words, the only valid way to call this method is
 lib.DoSomething("", myInt); 

To add insult to injury, this silently changed between versions!  

There are a lot of things wrong with this approach:
  1. They are causing runtime errors for anyone who doesn't change their code
  2. No one would think about changing their code unless they just happened to catch the change on page 43 of their doc. (and we *all* read the doc, right?) :-)
  3. The method signature doesn't really match the intent.  (Why should I have to pass a parameter when only one value is ever valid - especially when it's a null value?) 
For all intents and purposes, they really want to deprecate this method, but they were not quite sure how to go about it.

What is the right way to deprecate a method in an API in .Net?

You should not kill a method right away.  Give your customers time to change their code to match your changes.  Honestly, if you can avoid deprecation, you should.  In the cases where it is unavoidable, you should use this pattern.

First, mark your deprecated method with the [obsolete] attribute.
[Obsolete("This method is obsolete; use method DoSomething2 instead. This method will become unsupported in version x.y")]
public void DoSomething(string Filename, int Param)


Create the replacing method - it should have a different signature.
public void DoSomething2(int Param)

With this pattern, there is no chance that your changes will cause a runtime error!  Instead, your customers will see compiler-time errors/warnings which is definitely preferable.