Thursday, March 28, 2013

Cross Mobile Development with Icenium, KendoUI & Azure Mobile Services

,
I have recently spent some time with Telerik's new product offering for cross mobile development called Icenium and I have to say it is quite nice.  Paired with KendoUI Mobile you can't go wrong with a great set of tools for cross mobile platform development if you are an HTML + CSS + JavaScript developer.

In this series, I'll walk through a simple blood pressure tracking application built with Icenium, Kendo UI Mobile and Azure Mobile Services. Here is the outline for the series:

Part 1: Introduction and project setup
Part 2: Creating the UI
Part 3: Adding Azure Mobile Services
Part 4: Authentication using Azure Mobile Services

Icenium

Icenium is a cloud based IDE, there is also a Windows WPF Click-Once app, that allows you as a developer to leverage your existing HTML, CSS and JavaScript skills to develop hybrid cross mobile platform applications.  Assistance of publishing your applications to the Google Play and Apple Store, integrated debugging and development environment, source control integration (including Git) and much more.  See http://www.icenium.com for more information.

I will mention also that the underlying bits of Icenium is PhoneGap (Apache-Cordova) which provides and API through JavaScript (cordova.js) to the device functions such as the camera other hardware capabilities.  For more information on that piece, Jim Cowart (@ifandelse) recently did a blog entry on their blog - "Demystifying Cordova and PhoneGap".

Getting Started

Head over to Icenium.com and click the "Get Started" button. Choose either the browser (cloud) based IDE or download the Windows app.


Once the application is launched select New Project -> Cross Platform Device Application (Kendo UI Mobile). Name the project "MyBloodPressure" and click Ok.

In doing so, Icenium presents the built in "Hello World" type template. Shows how geolocation, transitions, styling using Kendo UI Mobile etc.  If you run the application by either hitting F5 or clicking the "Run" icon atop the IDE you'll also see the awesome tools for viewing the various mobile devices currently supported as well.

After you spend a few minutes playing with the emulators and realizing how cool that all is, we'll rip out some stuff add some sauce to this and get cooking.

Reorganizing the Project for Organization

I'm a very big proponent of being able to look at a project and know what the heck is going without having to hunt down someone or run the code and step through it to find out how it's all composed.  

In a C#/XAML world in I use the MVVM pattern with MVVM Light for my projects. I like to see the view folder, viewmodel folder etc. when developing the app.  For doing so here I will leverage RequireJS  for structuring the organization.  

Removing unnecessary files

Delete the hello-world.js from the scripts folder as we will not be using this for the project.

Folder structure

First, lets create a few folders.  At the root of the project create an app folder that contains view, viewmodel and model.

For any scripts that are 3rd party libraries, I prefer to put those in the scripts folder and any that are related directly to the application specific functionality I organize them within the app folder appropriately.  Given that, I'll move the kendo.mobile.min.js, jquery.min.js and also add require.js to the scripts folder

Next, add a new JavaScript file to the app folder by right clicking and selecting add new file. Name is main.js; this will be the entry point to the application.

Also add a JavaScript file to the app folder named app.js, this will serve as the singelton for exposing the viewmodels and could also be referred to as the view model locator.

First item of business is to tell require.js where to find the modules we either have or will be creating in our application. Add the following to main.js to configure require.js.

require.config({
    paths: {
        jQuery: "../scripts/jquery.min",
        kendo: "../scripts/kendo.mobile.min",
        view: "../app/view",
        viewmodel: "../app/viewmodel",
        app: "../app"
    },
    shim: {
        jQuery: {
            exports: "jQuery"
        },
        kendo: {
            deps: ["jQuery"],
            exports: "kendo"
        }
    }
});

What this is doing, if you are not familiar, is telling require.js that when a module is defined like

define(['viewmodel/bp'], function(bp) { ... } );

it knows to go look for bp.js inside of the "[root]/app/viewmodel" folder and not a relative path etc.  In the shim portion of the code we are stating that kendo has a dependency on jQuery and should wait for that library to load first.  For more information on requirejs and the config method see http://requirejs.org/docs/api.html#config .

Finally in the main.js file add the following to create the app module, put it in scope and init the application.

var app;
require(["app/app"], function (application) {
    console.log('initializing');
    app = application;
    app.init();
});

Last order of business is to add the code to app.js to tell kendo to initialize the mobile application.  Here is the full app.js code for now.

define(["jQuery", "kendo"], function ($, kendo) {
    var _kendoApplication;
    return {
        init: function () {
            console.log('app init');
            _kendoApplication = new kendo.mobile.Application(document.body,
                    { transition: "slide", layout: "mobile-tabstrip" });
        }
    }
});   

The init function is called when the application first fires up setting the transitons of the app the 'slide' and telling kendo what the layout root of the app is; in this case 'mobile-tabstrip'.

Wiring Up Index.html

Now that the scripts, view, viewmodel, entry points etc. are all setup; open index.html.

In the <head> tag remove everything except the references to the .css and cordova.js files and the we need to add the script reference to main and require.js for our entry point.  After that all scripts will be loaded using AMD and require.js . 

    <head>
        <title></title>
        <meta charset="utf-8" />
        <script src="cordova.js"></script>
        <script data-main="app/main" src="scripts/require.js"></script>
        <link href="kendo/styles/kendo.mobile.all.min.css" rel="stylesheet" />
        <link href="styles/main.css" rel="stylesheet" />
    </head>

Also remove the script tag at the bottom of the file that refers to the kendo.mobile.application as we have now moved that to the app.js init function.

Finally, remove all <div> tag sections with a data-role of view other that the first one.  These will be separated into individual html files and stored in the views folder in Part 2 of the series.  The final html document should appear as:

<!DOCTYPE html>
<html>
    <head>
        <title></title>
        <meta charset="utf-8" />
        <script src="cordova.js"></script>
        <script data-main="app/main" src="scripts/require.js"></script>
        <link href="kendo/styles/kendo.mobile.all.min.css" rel="stylesheet" />
        <link href="styles/main.css" rel="stylesheet" />
    </head>
    <body>
        <div data-role="view" id="tabstrip-home" data-title="Hello World!">
            <h1>Welcome!</h1>
            <p>
                Icenium&trade; enables you to build cross-platform device applications regardless of your
                development platform by combining the convenience of a local development toolset with the
                power and flexibility of the cloud.
            </p>
        </div>
     
        <div data-role="layout" data-id="mobile-tabstrip">
            <header data-role="header">
                <div data-role="navbar">
                    <span data-role="view-title"></span>
                </div>
            </header>
            <div data-role="footer">
                <div data-role="tabstrip">
                    <a href="#tabstrip-home" data-icon="home">Home</a>
                    <a href="#tabstrip-uiinteraction" data-icon="share">UI Interaction</a>
                    <a href="#tabstrip-geolocation" data-icon="globe">Geolocation</a>
                </div>
            </div>
        </div>
     
    </body>
</html>

Conclusion

If you run the application you can see that the application still operates as it did in the very beginning, with the exception of the additional views not appearing, but the advantage here is that the overall structure allows for manageability moving forward as complexity is added to the project through data services and additional views. 

If there is something that you would like to see in the series or have a question please add a comment.  I look forward to the next entry. 




Read more →

Monday, March 25, 2013

Custom Routing with IRouteConstraint for ASP.NET Web API

,
I will admit that Regex and I do not speak anymore.  In fact, even when we did it was never a really nice conversation and sometimes ended in me cursing and/or leaving the room.

If you have had this same experience when creating custom routes in ASP.NET MVC then you know what I'm talking about.

IRouteConstraint
IRouteConstraint has been around for some time in MVC, but it is also available in Web API too because of course it is based on the same stack for routing.

Undoubtedly, the most difficult part of routes is debugging or getting the Regex right. I recently re-lived this experience when having to create a custom API route for a project something along the lines of

/api/{controller}/{model}/{road}/{id}

where {model} must exist in a list of valid string values and {road} is a pattern of XX9999 and then obviously the {id} must be an integer for the specific record in the list.

So, initially you start putting the Regex together for the id, "^\d+$", and then the road might be something like   "^[a-zA-Z]{2}\d{4}$".  But how should I handle the in list for the {model} param?

Sure we could put together the Regex for that, but debugging all of this is a pain even in the short term.  Also if the constraint itself is something of an edge case where the value must be a filename that exists, or a guid in memory etc; IRouteConstraint is the answer.

IRouteConstraint requires you to implement one method, Match, which returns a boolean. In the method below we are looking for one of the values being passed in the values[] parameter to a list used in the constructor.


    public class FromValuesListConstraint : IRouteConstraint
    {
        public FromValuesListConstraint(params string[] values)
        {
            this._values = values;
        }
        private readonly string[] _values;
        public bool Match(HttpContextBase httpContext,
            Route route,
            string parameterName,
            RouteValueDictionary values,
            RouteDirection routeDirection)
        {
            // Get the value called "parameterName" from the
            // RouteValueDictionary called "value"
            string value = values[parameterName].ToString();
             // Return true is the list of allowed values contains
            // this value.
            return _values.Contains(value, StringComparer.CurrentCultureIgnoreCase);
        }
    }


In order to use this from the WebApiConfig.cs class, create your route like the following.


config.Routes.MapHttpRoute(
               name: "CustomRouteNoDayOrAction",
               routeTemplate: "dcl/{controller}/{model}/{road}/{id}",
               defaults: null,
               constraints: new
               {
                   ship = new FromValuesListConstraint("ford", "chevy", "dodge", "toyota"),
                   voyage = @"^[a-zA-Z]{2}\d{4}$",
                   id = @"^\d+$"
               }
);

When you run and test your routes, you can now put a break point on the FromValuesListConstraint Match method and debug the routing.




Read more →

Wednesday, February 6, 2013

South Florida Code Camp

,
I will be giving two talks this Saturday at South Florida Code Camp, being held at Nova University in Ft. Lauderdale, Fl.  For directions and more information visithttp://www.fladotnet.com/codecamp/. Schedule for other sessions here.

My Sessions


Read more →

Friday, February 1, 2013

Develop Windows 8 & Windows Phone Apps and Win Cash!

,
From February 1 through June 2013, publish a new Windows 8 or Windows Phone app and enter my sweepstakes page to win up to $1000 in cash prizes.  WHAT?!?!  

Pretty cool right.  Get extra $$ for what you are already doing.  Publish you app in the store the go to http://spboyer.me/appsforcash and submit your app.

3 Winners each month!
$1000
$500
$250

Follow me on twitter @spboyer and let me know when you submit it and I'll personally look at the app and give it a review and let all my friends to give it a look as well for extra exposure.

See official rules here



BONUS POINTS AND AWARDS

FREE NOKIA PHONE

If this is your FIRST Windows Phone App you may qualify for a Free Nokia Lumia Phone.


TELERIK WINDOWS 8 Controls

I will pick 1 Winner each month from the Windows 8 Submissions to receive a free licensed copy of Telerik's Windows 8 Controls

Read more →

Tuesday, January 29, 2013

Nothing great was ever achieved without enthusiasm...

,
Over the past month I have had the opportunity to give some thought to what I wanted to accomplish this year in my life, career, and health. And during those times of thought I have often gone back to a speech I listened or re-listened to by the late Jimmy Valvano.

Jimmy V was a great college basketball coach and was unfortunately diagnosed and later passed away from bone cancer. But shortly before his death he gave a riveting speech at the 1993 ESPN ESPY Awards. There are some great things he said, but one statement lost in many outtakes that stuck with me was

"Nothing great was ever achieved without enthusiasm" ...Ralph Waldo Emerson

I think about that statement and how it relates to life, but also how I approach code, software development and teaching. Enthusiasm is the name of the game.  I'm passionate in how I present it, teach it, talk about it and code it. 

The question I have always wondered is how can the few of us who think this way make that feeling contagious? Spread that disease?

I know how I feel after taking a good 5 mile run or so and beating a goal or my last time thinking, "hell yes!" and that's the same feeling I get when a project is complete or I inspire a developer to do something different or try a new path and then later they tell me "thanks, just what I needed".

Recently, after a .NET User Group meeting I sat and had a beer with a few friends from the group and we had this very discussion and the conversation was really good.  I heard stuff like...

"It's not their project...."

"...making the other guy money, why be passionate"

"...some companies are better at making their devs feel ownership..."

What are your thoughts?  What can make you more enthusiastic or pump up that 9-5'er you know at your office?

Start the conversation....
Read more →
Powered by Blogger.
 
Creative Commons License
TattooCoder.com by Shayne Boyer is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.