Introducing Icenium – an Integrated Cloud Environment for Hybrid Mobile App Development

Today is a day that my team and I have been looking forward to for a long time. Today I am happy to announce that Icenium, an Integrated Cloud Environment (ICE) for hybrid mobile app development, is now available to everyone!

Icenium Logo (1416x321, 54k)

The Story Begins

Back in July 2011, I left Microsoft and joined Telerik to take on an ambitious idea. In my time at Microsoft I had spoken with hundreds of developers and was able to witness first-hand the frustration that many of them felt working with Integrated Development Environments (IDEs) – they were big, bloated and most were designed with only one platform, or one platform vendor in mind (e.g. Visual Studio, xCode, etc.). For developers that targeted multiple platforms, using these IDEs meant downloading, installing and managing multiple platform SDKs and two or more separate development environments. For example, targeting the most relevant platforms in the world today – iOS and Android – meant using xCode with Objective C and Eclipse with Java, along with all the SDKs and tools that go along with them. Nearly 3 GB of downloads to install and maintain (not to mention, you have to have a Mac OS X environment, automatically excluding Windows-based developers). I was no different from the developers I talked to. I used these tools all the time. They took up a lot of my time to download and configure, they took up a lot of hard drive space, and they required a powerful development machine.

I also observed that while I was writing code, I was also listening to music from Pandora, saving documents in DropBox, and keeping notes in Evernote. Nearly everything I used daily was not only cloud-connected, but the cloud played a significant role in enabling the technology; that is, the technology wouldn’t have functioned without the cloud. Everything except my development tools (OK, maybe I’d deploy an app to the cloud, but the cloud didn’t aid me in my development efforts).

An ICE Age is Coming

The idea that a development environment required all of the SDKs and platform dependencies to be installed locally on a development machine with massive RAM and a big hard drive felt so antiquated compared to the other apps I used which were light-weight and used the cloud in a meaningful way. This made me want to redefine what a development environment was. I wanted to build something that enabled developers to build across a variety of platforms, and now that cloud connectivity was ubiquitous for developers, it was possible.

I left Microsoft in pursuit of a company that would allow me to chase my crazy idea, and Telerik is just that crazy (talking to you Forte). I didn’t want to build just another IDE. I wanted to build something different; I wanted to build an ICE – an Integrated Cloud Environment. I believed that we could improve cross-platform development by decoupling the gestures of writing code from the platform dependencies required when building apps. Specifically I wanted to decouple coding from the big, bloated SDKs that limited the development experience to one where the coding environment and the target environment required affinity.

The primary objective in building an ICE was to enable developers to build apps that targeted any relevant platform from any development. My theory was that we could extract the SDKs from the local coding environment and turn them into cloud-based services that could still function as part of an integrated workflow for developing apps. In other words, it still had to be an integrated development experience, and the cloud – not your OS and RAM – would become the enabling technology. The experience had to be functional, capable and simple. The age of having to master multiple complex development environments and SDKs is coming to an end. The new ICE age will usher in a new type of development tools, and the dinosaur IDEs will die off soon enough.

Welcome Icenium

Icenium™ is the realization of that vision. Icenium combines the convenience of a modern coding environment with the power and flexibility of the cloud to manage platform dependencies. Icenium enables you to build applications without being limited by the development environment having to be compatible with the run-time environment (e.g. Mac OS X to iOS). It enables you to focus on the content of your application without the headache of managing multiple SDKs and development environments. With Icenium you can use Windows, Mac OS X, Linux, or even device operating systems, like iOS on an iPad, to build hybrid applications that are distributable through the app stores, and run natively on iOS and Android devices.

I believe web developers are looking for ways to move from mobile-optimized web sites to building apps that run on devices, so we built Icenium with web developers in mind. We leverage Apache Cordova (aka PhoneGap) to enable you to use HTML, CSS and JavaScript to build your application. When your project is compiled, we build the iOS and Android native bits in the cloud, which means you don’t have to think about SDKs, Objective C or Java. Just focus on your app and leave the platform dependencies to us.

We also tailored the development experience to web developers. Most web developers (me included) prefer to work with capable, text-based code editors (and not WYSIWYG tools that modify your code without your consent), a browser and some debugging tools, such as WebKit Inspector, so we designed Icenium to work the same way. The Icenium coding environment is a simple text-based code editor, packed with advanced capabilities including syntax coloring and formatting, real-time error detection, refactoring, code navigation, and more.

Iterate quickly on your design with the integrated device simulator.

Each development client (Icenium Graphite for Windows and Icenium Mist in the browser) includes a device simulator that enables you to test your application much like you would test a web app in a browser. The device simulators include options for simulating iPhone, iPad, Android phone and Android tablet, including a geolocation simulator and the ability to rotate and flip the device. The device simulators expose the ability to use WebKit Inspector-based debugging tools – the tools you already know. We have tried to replicate the working style you already use for web apps, making the transition to mobile application development simple and intuitive.

Icenium Graphite™

Icenium Graphite with real-time syntax error detection.

Icenium Graphite is an installable development tool for Windows operating systems. It is a WPF app that provides you with the ability to build a cross-platform mobile application, test it in a device simulator, build the app (in the cloud of course) and deploy it to multiple devices at once. When you are ready, you can switch to a “release” build setting, add your icons and splash screens and package your app for publishing to the Apple AppStore or Google Play.

Icenium LiveSync™

Icenium LiveSync is one of the truly magical features of Graphite. With LiveSync you can build and deploy your app to one or more iOS and Android devices with nothing more than the click of a button. Your app is built in the cloud, and then delivered back to Graphite where it is pushed over USB to all connected devices.

Icenium integrates Apache Cordova to enable cross-platform mobile application development for iOS and Android devices.

I usually have 10 or 11 connected at once, including iPhone 4S, iPhone 5, iPad 1, iPad 3, Google Nexus, Google Nexus 7, Galaxy S2 Skyrocket, Galaxy S3, Galaxy Tab 8.9”, Galaxy Note 10”, HTC One X, and the Kindle Fire.

After the app is on the devices you can test it out and see how it works on different screen sizes and pixel densities (e.g. Retina display), not to mention different form factors (phone and tablets). If you want to make a change, simply add, edit or remove the HTML, CSS or JavaScript in your project and click “Save.” When you do, the changes are saved (in the cloud of course) and immediately pushed down to the running app on all connected devices. That means you can work in rapid iterations and see your changes on the devices in real-time, as you make them.

Icenium Mist™

Icenium Mist is a browser-based development environment..

Icenium Mist is the browser-based sister of Graphite. Mist provides nearly all of the same functionality as Graphite, and works on a variety of platforms. I use Mist on my MacBook Air, and even on my iPad, when I am away from my office. Mist also includes the modern conveniences of Graphite, such as syntax coloring, statement completion, and version control integration, as well as a browser-based device simulator that can render your app on an iPhone, iPad, Android phone and Android tablet.

Since Mist is browser-based, it doesn’t have access to deploy apps to devices via USB. Instead, you can build your app and deploy it to a device by downloading the app and pushing it to your devices manually, or simply scan the on-screen QR code and the app will be downloaded to your device.

LiveSync On-Demand

Whether using Graphite or Mist, we’ve included the option to use LiveSync in an “on-demand” way. If your app is on a device and either you’ve disconnected it from USB (when using Graphite) or you deployed the app manually or with a QR code, you can request an app update easily and the content of the app will be refreshed based on your latest saved changes in either Graphite or Mist. If it’s an iOS device, simply press three fingers to the screen for a couple seconds and you will see the download begin. If it’s an Android device, simply press the context menu and the download will begin. LiveSync on demand means you can see your changes on any device, anytime, anywhere.

Icenium Ion™

Icenium Ion enables you to forget about device provisioning during development.

If you’re familiar with Apple’s iOS development model, you know that in order to deploy an app onto an iOS device you need to first provision that device through the Apple Developer Center. Icenium fully supports working with provisioned devices – in fact Icenium can aid you in creating the Certificate Signing Request required when requesting a device provision. However, if you want to try out your app without provisioning your phone, or you want a stakeholder or beta tester to try out your app and give you feedback, then Icenium Ion is the tool you need. Ion is a development and testing utility (downloadable for free from the AppStore) that enables you to load your app onto any iOS device regardless of whether or not it has been provisioned. Simply scan a QR code provided by Icenium and the app will download and launch inside Ion. Of course, LiveSync on demand works perfectly with Ion too.

Version Control

Icenium Graphite Code Editor with Version Control-Diff Window
Integrated version control means your code is safely stored and versioned in the cloud.

Of course a development tool wouldn’t be complete without integrated version control, and a cloud-based tool better integrate with popular cloud-based version control systems, so we did just that. By default all Icenium projects are connected to an integrated Git repository in the cloud, and you can optionally configure your project to use any URL-based Git repository, including GitHub and BitBucket. Both public and private projects are supported, enabling you to collaborate and version your code safely.

Kick the Wheels (for a while)

As I mentioned, today we have released Icenium for everyone to use. In fact, I don’t want there to be any barrier in your way to trying out Icenium, so I decided to make it free for the next 6-months. We won’t begin charging anyone for Icenium until May 1, 2013. So go to Icenium.com, create an account and start building cross-platform mobile apps today. I’ll bet you can build an app faster than it takes to download xCode.

We Need Developer Tools, Not Platform Development Tools

It’s been almost a year since I left my role at Microsoft as Director of Product Management for Visual Studio. Ever since I left, I’ve had lots of people asking what I am working on now, and I’ve been pretty quiet about it (the running joke is that I am the VP of Black Ops). The truth is that my team and I have been very busy solving what we believe to be one of the biggest challenges facing developers today and building a new product that I believe will dramatically reduce the barrier to entry for developers wanting to build applications that run natively on mobile devices.

I firmly believe that mobile devices are the single biggest opportunity today for developers. Cell phones are ubiquitous, and smartphones are becoming so common place, it’s surprising when someone doesn’t have one. According to the March 2012 U.S. Mobile Subscriber Market Share from comScore 234 million Americans age 13 and older used mobile devices, and more than 106 million people in the U.S. owned smartphones. That’s roughly one-third of the US population, and if you are anything like me, your smartphone is the only computing device you have with you at all times, from the time you wake up, to the time you go to bed. While a smartphone (or tablet) may not be your primary productivity device, it is arguably your primary device –the only one you always have within reach.

From a developer’s perspective, this represents a huge opportunity. While lots of developers have already entered the mobile device development arena, only a fraction of the entire developer population is actively doing development for mobile platforms. As businesses embrace mobile devices and start to extend their line-of-business applications, business-to-business applications and direct to consumer applications, more and more developers will have to transition into mobile platform developers.

While mobile platforms are one of the biggest opportunities for developers, they are also one of the biggest challenges for developers. Like the browser-wars of the 90’s, the mobile platform arena is hugely challenging. Every mobile platform provider has their own SDKs, uses a different programming language, and different tools. In fact, if you want to target all of the mobile platforms out there, you need multiple development machines—one for Mac OS X and one for Windows (at the very least you need a Mac and a BootCamp image of Windows). To build one app that runs natively on all platforms requires significant duplication of effort—essentially building and rebuilding the same app on different platforms. None of the platform providers are eager to solve this problem for you—they don’t make developer tools, they make platform development tools.

When I was at Microsoft, my job was to ensure Microsoft built the best platform development tools possible As a result we created awesome tools for development on the various Windows platforms (client, server and phone). What we didn’t do was build great developer tools—tools that made developing applications easier and more enjoyable regardless of what platform was being targeted. The only way to do that in the Developer Division would be to secede from Microsoft and become an independent software vendor (ISV)…and DevDiv would be a big one. Since that wasn’t going to happen I decided that it was time to find an ISV that had the ability to create great development tools regardless of platform. That quest led me to Telerik, where my team and I have been doing just that.

I’d like to invite you to join the Icenium private beta. Icenium is a work in progress (hence the private beta) and steadily becoming the product that I envisioned—a development tool that makes building applications easier and more enjoyable regardless of platform. With Icenium, we intent to build the worlds first Integrated Cloud Environment (ICE) that combines the power and flexibility of the cloud with the convenience of a local coding environment to massively eliminate the complexity of building cross-platform mobile applications. In its current beta state Icenium enables you to build applications for Apple iOS and Google Android, and more platforms will follow. My team and I are very excited about this beta, and we are looking forward to getting your feedback.

D7

Data Snacking Metro Style: Part 1 Working with Web APIs

In a previous post I discussed the five different types of Metro style apps that are relevant for Windows 8. In this series I will walk you through building a basic data-snacking application.

Topics Covered

  • Windows 8 Metro apps
  • HTML & JavaScript Metro apps
  • Using data from Web APIs
  • Asynchronous calls
  • JavaScript Promises
  • ListView UI control
  • Data binding HTML controls

Get the sample app.

The Scenario

For review, a data snacking app is one that enables users to consume small chunks of information in a hurry, as time permits. These apps are used regularly and repetitively by users during “down-time” (e.g. waiting in a lobby, on the metro (pun intended), before a meeting, etc.). For the purpose of this walk-through I will build a weather app, similar to the Weather app included in the Windows 8 Developer Preview release. This weather app, named “Seven Days,” will show the current weather conditions, plus the forecasts for the next six days (seven days in all, hence the name). In this post I will build the app to get weather data based on a static (aka hard coded) location, and in follow-up posts I will add the ability to get the weather info based on either the current location of the device the app is running on, or through user input of one or more locations.

image

Language Choice

The first consideration is whether to build a XAML/C# app or an HTML/JavaScript app. Ultimately I know that this application is going to revolutionize the weather-data-snacking market, so I want it to reach as many platforms as possible, so I am going with HTML5 and JavaScript. Of course, I know that this choice doesn’t automatically make my app portable, but as a long-time ASP.NET developer, HTML and JavaScript are more familiar to me than XAML (although I do love C#), and using HTML/JavaScript means that I will have some ability to reuse assets (e.g. HTML layouts, CSS styles, base-level JavaScript functions) across device platforms, rewriting only platform-specific code.

Its settled, I will use HTML and JavaScript.

Using Visual Studio 11 Express for Windows Developer Preview, I create a new Fixed Layout project and get to work.

Setting up the UI

I tend to think in user experience first, and prefer to start with my UI layout before anything else. Looking at the screenshot above, there is a basic structure I need to build – three rows (one in the middle row—outlined in a green dashed line below—for the current weather detail, and one in the bottom row—outlined in a red dashed line below—for the forecast) with two grids (the current weather detail grid—outlined in a red solid line—and a forecast grid—outlined in white).

image

Using DIV Elements as Placeholders

The first two rows are pretty straight forward – I’ll use a set of DIV elements for the current temperature and location in the top row, and a TABLE with DIV elements for the current weather detail in the middle row.

<!DOCTYPE html>
<
html
>
<
head
>
<
meta charset
=”utf-8″ />
<
meta name=”viewport” content
=”width=1024, height=768″ />
<
title>Seven Days by Doug Seven</title
>
<!– WinJS references –>
<link rel=”stylesheet” href
=”/winjs/css/ui-dark.css” />
<
script src=”/winjs/js/base.js”></script
>
<
script src=”/winjs/js/ui.js”></script
>
<
script src=”/winjs/js/binding.js”></script
>
<
script src=”/winjs/js/controls.js”></script
>
<
script src=”/winjs/js/animations.js”></script
>
<
script src=”/winjs/js/uicollections.js”></script
>
<
script src=”/winjs/js/wwaapp.js”></script
>
<!– SevenDays references –>

    <
script src=”/js/default.js”></script>
<
link rel=”stylesheet” href
=”/css/default.css” />
</
head
>
<
body
>
<
div data-win-control
=”WinJS.UI.ViewBox”>
<
div class
=”fixed-layout”>
<
div id
=”topRow”>
<
div id
=”currentWeather”>
<
div id
=”currentTemp”>
</
div
>
<
div id
=”currentLocation”>
</
div
>
</
div
>
</
div
>
<
div id
=”middleRow”>
<
div id
=”statusMessage”>
</
div
>
<
div id
=”currentWeatherData”>
<
table
>
<
tr
>
<
td class
=”currentWeatherElement”>
<
div id
=”currentTempRange”
class
=”currentWeatherDataItem”>
</
div
>
High / Low
</td
>
<
td class
=”currentWeatherElement”>
<
div id
=”humidity”
class
=”currentWeatherDataItem”>
</
div
>
Humidity
</td
>
<
td class
=”currentWeatherElement”>
<
div id
=”currentCondition”
class
=”currentWeatherDataItem”>
</
div
>
Current condition
</td
>
</
tr
>
<
tr
>
<
td class
=”currentWeatherElement”>
<
div id
=”feelLike”
class
=”currentWeatherDataItem”>
</
div
>
Feels like
</td
>
<
td class
=”currentWeatherElement”>
<
div id
=”uvIndex”
class
=”currentWeatherDataItem”>
</
div
>
UV Index
</td
>
<
td class
=”currentWeatherElement”>
<
div id
=”wind”
class
=”currentWeatherDataItem”>
</
div
>
Wind
</td
>
</
tr
>
</
table
>
</
div
>
<
div id
=”currentDateTime”>
</
div
>
</
div
>
<
div id=”bottomRow”>

            </
div>
</
div
>
    </div
>
</
body
>
</
html
>

This is pretty straight forward, so I won’t go into any detail on it. I also spent some time on CSS definition, to make it look nice. Nothing surprising in the CSS, and it is available as part of the sample download.

Using a ListView

For the bottom row, I anticipate getting a feed of data from a weather service, and binding that data to a grid layout with a single row of six items. The ListVIew control (WinJS.UI.ListView) works in just that way. I can use the ListView to create a grid layout and use a template to define how the items in the grid will look. In this case, I want a grid where each item shows the date, a weather icon, the high and low expected temperatures and a brief forecast on the conditions of the day.

The ListView is a DIV element with a data-win-control attribute set to WinJS.UI.ListView.

<div id=”forecastGrid”
data-win-control
=”WinJS.UI.ListView”
data-win-options
=”{itemRenderer: template,
layout: {type: WinJS.UI.GridLayout, maxRows:1}}”>
</
div>

I’ve also set the data-win-options attribute to define how I want the ListView to render (use an item template named “template”, layout as a grid (as opposed to a list), and have no more than one row). The use of the template is key; this is what enables me to define the look of each item that is rendered in the grid.

A template is a DIV with the data-win-control attribute set to WinJS.Binding.Template. This enables it to be the template used when data bound to a source (don’t worry, I’ll get to that soon).

<div id=”template”
data-win-control
=”WinJS.Binding.Template”>
<
div class
=”dailyWeather”>
<
div class
=”dayTitle”>
<
span data-win-bind=”innerText: Day” class=”dayPart”></span
>
<
span data-win-bind=”innerText: Date” class=”datePart”></span
>
</
div
>
<
div class
=”weatherIcon”>
<
img data-win-bind=”src: IconUrl; alt: IconAlt”
/>
</
div
>
<
div data-win-bind
=”innerHTML: HighLow”
class
=”highLow”>
</
div
>
<
div data-win-bind
=”innerText: Condition”
class
=”condition”>
</
div
>
</
div
>
</
div>

Inside the template I have defined how I expect the data source to be bound to the UI elements. Using the data-win-bind attribute I define the element attribute to bind, and the data source item’s property to bind to.

<img data-win-bind=”src: IconUrl; alt: IconAlt” />

In the IMG element example, I have specified that the SRC attribute should be bound to the item.IconUrl value and the ALT attribute should be bound to the item.IconAlt value.

Getting Data from a Web API

The next step in building Seven Days is to get some real data. There are a lot of weather Web APIs to choose from, and I’m not here to tell you which one to use. For the purpose of this example I have chosen to use Weather Underground (Wunderground.com) because they provide their results in JSON format, have clear pricing structures (including a free Developer level) and will provide up to 10-days of weather forecasts (many other weather Web APIs only provide 2 or 3 days of forecasts).

The first thing I need to do is add some JavaScript to get the weather data for a predefined location (I won’t add fancy functionality like geolocation lookup, or pick-a-location until I get the basics working). To do this I can use WinJS.xhr, which is an asynchronous wrapper on the XMLHttpRequest object, to make the request, and return the response.

// Query Format: http://api.wunderground.com/api/KEY/FEATURE/%5BFEATURE…%5D/
// q/QUERY.FORMAT
function weatherLookup(loc) {
// Set the date and time info
var d = new Date();
id(“currentDateTime”).innerText = d.toLocaleDateString()
+
“, ”
+ d.toLocaleTimeString();

var apiUrl = http://api.wunderground.com/api/&#8221;
+ apiKey
+ “/geolookup/conditions/forecast10day/q/”
+ loc
+ “.json”;

// WinJS.xhr is an async wrapper for the XMLHttpRequest class.
WinJS.xhr({ url: apiUrl }).then(
processWeather,         // Called when the promise is complete
dataFetchingError       // Called when there is an error
);
}
wunderground.weatherLookup = weatherLookup;

The apiKey value is provided to you when you create an account on wunderground.com, and the loc value is whatever predefined location string you want to use (I am using “WA/SAMMAMISH”).

Working with Promises

The WinJS.xhr object is a “promise” object. There is a proposed JavaScript standard for promises, which enable invoking methods which promise to return a value at a point in the future. The WinJS.Promise object exposes a “then” method (which I have used in this example) which identifies what to do when the promise returns a value. The first argument of “then” is the callback function to invoke when the promise (in this case, sending the HTTP request and getting back the response) completes successfully. The second argument is the callback function to invoke when the promise returns an error. There is a third option for invoking a progress callback, if the promise reports on progress (so far very few promise operations implement the progress callback option).

Anytime you are invoking a method that could take longer than 50-milliseconds, the guidance is to use an asynchronous method, which enables the UI to continue working while the asynchronous method executes. That is exactly what the “promise” object and “then” method enable. When the promise object is invoked, the code flow surrounding the promise continues (e.g. the next line of code is executed) and the asynchronous (promise) method is invoked on another thread. This enables long running operations (like retrieving data from a Web API) to be called without blocking the UI functionality, resulting in a much more responsive (aka “fast and fluid”) application.

Consider the following example, where two asynchronous calls are made to get data from Bing.com using the Promise/Then model. When the application runs, the progress callback is called every time the XMLHttpRequest object being used changes its ready state. Since each of the requests is running asynchronously, the results are intermixed, and the UI is refreshed without blocking any responsiveness.

(function () {
‘use strict’
;
// Uncomment the following line to enable first chance exceptions.
// Debug.enableFirstChanceException(true);

WinJS.Application.onmainwindowactivated =function(e) {
if(e.detail.kind
===
Windows.ApplicationModel.Activation.ActivationKind.launch
) {
// Add an event listener for the button’s click event.
document.getElementById(“myButton”).addEventListener
(
‘click’, onMyButtonClicked,false
);
}
}

function onMyButtonClicked() {
getWebContent
();
}

function getWebContent() {
var bingUrl =http://www.bing.com/search?q=windows+8&#8221;
;
id(“contentDiv”).innerHTML =“Calling xhr (First).<br/>”
;
// WinJS.xhr is an async wrapper for the XMLHttpRequest class.
       
WinJS.xhr({ url: bingUrl }).then(
onComplete,   
// Called when the promise is complete
onError,      
// Called when there is an error
onProgress    
// Called when the promise reports progress
);
id(“contentDiv”).innerHTML +=“Called xhr (First).<br/>”
;

id(“contentDiv”).innerHTML +=“Calling xhr (Second).<br/>”;
WinJS.xhr({ url: bingUrl }).then(

               
onComplete,
               
onError,
               
onProgress2    // Call a different function to show progress.
);
id(“contentDiv”).innerHTML +=“Called xhr (Second).<br/>”
;
}

function onComplete(request) {
id(“contentDiv”).innerHTML +=“Request complete.<br/>”
;
}

function onError(request) {
id(“contentDiv”).innerHTML +=“<p>!!!ERROR!!! “+request.status+“</p>”
;
}

function onProgress(request) {
id(“contentDiv”).innerHTML +=“Progress on First.<br/>”
;
}

functiononProgress2(request) {
id(“contentDiv”).innerHTML +=“Progress on Second.<br/>”
;
}

functionid(elem) {
returndocument.getElementById(elem
);
}

WinJS.Application.start();
})();

image

Connecting the Data to the UI

Now that I have data coming from a Web API, the last thing I need to do to get Seven Days working, so I can see the fruit of my labor, is to populate the UI controls with the appropriate data. The data from the WinJS.xhr() call is returned when the “complete” callback is invoked (i.e. processWeather()).

// WinJS.xhr is an async wrapper for the XMLHttpRequest class.
WinJS.xhr({ url: apiUrl }).then(
processWeather,        // Called when the promise is complete
   
dataFetchingError    // Called when there is an error
);

The processWeather function uses the JSOPN.parse method to create objects from the data returned. To make setting UI attributes easier, I create four objects from the JSON results returned by the Web API.

var forecastList;
function processWeather(request) {
// Clear the forecast list
   
forecastList = [];
// Parse the JSON response into navigatable objects
   
var weatherData = JSON.parse(request.responseText);
var currentObservation = weatherData.current_observation;
var currentForecast = weatherData.forecast.simpleforecast.forecastday[0];
var forecasts = weatherData.forecast.simpleforecast.forecastday;

Each of these objects will be used to populate different parts of the UI.

  • weatherData represents the entire JSON result set.
  • currentObservation represents the current conditions for the specified location, including an array of weather stations nearby and temperature, as well as some, but not all of the details (like UV index, wind chill, condition, humidity, wind direction and wind speed).
  • currentForecast represents forecast data for the current day (the first item in the forecastday array), including expected high and low temperatures.
  • forecasts is an array of forecasts for the current day and the following 9-days (the Web API request specified a 10-day forecast) and will be used to display the lower table of forecasts.

To populate the UI I am using a combination of explicit value setting and data binding. As the app develops, and I add the ability to get weather for multiple cities, I may move to an entirely data binding model, but that is overkill for the app right now.

To do the element value setting (for the top two rows), I am going to steal borrow an id() function from the Windows 8 SDK samples to make setting values easier.

function id(elemName) { return document.getElementById(elemName); }

This enables me to set an element’s innerText or innerHTML value (or any other property) in the following way:

id("currentTemp").innerHTML = tempString + "&deg;";

Using this model, the next section of the processWeather function looks like this:

// Set the values of the current day weather
var tempString = currentObservation.temp_f.toString();
tempString = tempString.indexOf(‘.’) > 0 ?
tempString.substring(0, tempString.length 2) :
tempString;
id(“currentTemp”).innerHTML = tempString + “&deg;”;
id(“currentLocation”).innerText = currentObservation.display_location.full;
var todayHigh = currentForecast.high.fahrenheit;
var todayLow = currentForecast.low.fahrenheit;
id(“currentTempRange”).innerHTML = todayHigh + “&deg; / ” + todayLow + “&deg;”;
id(“feelLike”).innerHTML = currentObservation.windchill_f + “&deg;”;
id(“uvIndex”).innerText = currentObservation.UV;
id(“currentCondition”).innerText = currentObservation.weather;
id(“humidity”).innerText = currentObservation.relative_humidity;
var windSpeed = currentObservation.wind_mph;
var windDir = currentObservation.wind_dir;
id(“wind”).innerText = windSpeed + ” mph ” + windDir;
id(“lastUpdated”).innerText = currentObservation.observation_time + “. Data provided by wunderground.com”;

With the top two rows populated its now time to build the data source for the lower grid and bind the ListView control to the data source. To build the data source I loop through the forecasts object that I created from the JSON results (skipping the first item, which is today’s forecast), and create an array of forecast items with specific properties that will be displayed. Once the loop has iterated six times, I break out of the loop (remember, this app is Seven Days, not Ten Days). The last step is to set the data source of the ListView control to the array that was just created.

// Build the forecast list for the next six days
for (var i = 1, len = forecasts.length; i < len; i++) {
var item = forecasts[i];
var itemHigh = item.high.fahrenheit;
var itemLow = item.low.fahrenheit;
var itemHighLow = itemHigh + “&deg; / ” + itemLow + “&deg;”;
var forecastItem = {
Day: item.date.weekday_short,
Date: item.date.day,
HighLow: itemHighLow,
IconAlt: item.icon,
IconUrl: item.icon_url,
Condition: item.conditions
};
if (i == 1) {
forecastItem.Day = “Tomorrow”;
forecastItem.Date = “”;
}
forecastList.push(forecastItem);
// Once there are six days of weather, stop building the list
if (i >= 6)
break;
}
// Populate the forecastGrid control
forecastGrid.winControl.dataSource = forecastList;
}

To trigger the binding of the UI elements to the data source, I need to invoke WinJS.UI.processAll() which processes all declarative controls so that any that are data bound get processed and the data is rendered on screen. I have this call in the default.js file as the last line of the initialization function.

WinJS.Application.onmainwindowactivated = function (e) {
if (e.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.launch) {
// TODO: startup code here
       
wunderground.weatherLookup(“WA/SAMMAMISH”);
// process the declarative controls
        WinJS.UI.processAll();
}
}

With that, I now have a functioning weather app (there is some CSS styling I didn’t show in this post, but is in the sample code).

Summary

In this post I showed you how to create a basic Metro style app for Windows 8 that asynchronously calls a Web API to get and display some data, both explicitly and with data binding. In follow up posts I will show you how to

  • use the geolocation capabilities of Windows 8 to get actual position data to display weather for
  • how to use local storage to save a list of favorite cities to get weather for
  • how to use the AppBar to expose additional capabilities
  • how change the UI when the device orientation changes.
    In the final set of posts I will show you how to port this application to the iPad and Android tablets to extend the reach of your application.

What About Video

On a final note, the app wouldn’t have the right level of polish without a cool HD video background running in a loop, which can be done easily with the following HTML and CSS (the video is not included in the sample download):

HTML

<video id="vidbg" src="/video/background.mp4" autoplay="autoplay" loop="loop" />

CSS

#vidbg { position: absolute; top: 0px; left: 0px; width: 100%; z-index: -1; }

Language Choice in Windows 8 is Not About Portability

Every time I go to talk to folks about Windows 8, the same questions pop up. I blame this largely on Microsoft’s silence about Windows 8 following the release of a tidal wave of information followed by the Windows 8 Developer Preview at Build in September. C’est la vie. This too shall pass.

One of the topics of conversation that comes up repeatedly is how to choose between using HTML5 + JavaScript or XAML + C#/VB (aka .NET) to build Metro style applications. What are the factors that you should consider before making your choice? Is HTML5 better? Is there a future for XAML? How do you choose?

Inevitably someone in the conversation cites the portability of HTML5 and JavaScript as the answer. It goes something like this…

“You should use HTML5 and JavaScript for Metro style applications because its portable and XAML isn’t. If you build with HTML5 then you can use the same code for your website or other platforms because its standards-based….HTML and JavaScript.”

This couldn’t be further from the truth. The use of HTML5 + JavaScript in Windows 8 is about as proprietary as using XAML + .NET. Consider the “Hello World” of the modern era – an RSS feed reader.

If you are going to build a feed reader into your Metro style application using HTML5 and JavaScript, it would look something like this:

DEFAULT.HTML

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>RssReader</title>
<!-- WinJS references -->
<link rel="stylesheet" href="/winjs/css/ui-light.css" />
<script src="/winjs/js/base.js"></script>
<script src="/winjs/js/ui.js"></script>
<script src="/winjs/js/binding.js"></script>
<script src="/winjs/js/controls.js"></script>
<script src="/winjs/js/animations.js"></script>
<script src="/winjs/js/uicollections.js"></script>
<script src="/winjs/js/wwaapp.js"></script>
<!-- RssReader references -->
<link rel="stylesheet" href="/css/default.css" />
<script src="/js/default.js"></script>
</head>
<body>
  <h1>RSS Reader</h1>
  <div id="downloadStatus"></div>
  <div id="template" data-win-control="WinJS.Binding.Template">
    <div class="postTitle" data-win-bind="innerText: title"></div>
    <div class="postDate" data-win-bind="innerText: date"></div>
  </div>
  <div id="posts" data-win-control="WinJS.UI.ListView"
    data-win-options="{itemRenderer: template,
                       layout: {type: WinJS.UI.ListLayout},
                       selectionMode: 'single',
                       onselectionchanged: selectionChanged}">
  </div>
  <div id="contentTemplate" data-win-control="WinJS.Binding.Template">
    <div class="postTitle" data-win-bind="innerText: title"></div>
    <div class="postDate" data-win-bind="innerText: date"></div>
    <div class="postContent" data-win-bind="innerHTML: content"></div>
  </div>
  <div id="content"></div>
</body>
</html>

DEFAULT.JS

(function () {
  'use strict';
  WinJS.Application.onmainwindowactivated = function (e) {
    if (e.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.launch){
      downloadStatus.innerText = "Downloading posts...";

      var syn = new Windows.Web.Syndication.SyndicationClient();
      var url = new Windows.Foundation.Uri("https://dougseven.com/feed/");
      syn.retrieveFeedAsync(url).then(processPosts, downloadError);

      // Define an event listener for the onselectionchanged event.
      posts.addEventListener("selectionchanged", selectionChanged);
      // Process the declarative controls
      WinJS.UI.processAll();
    }
 
}

  function selectionChanged(e) {
    content.innerHTML = "";
    var selection = posts.winControl.selection;

    if (selection.length) {
      var post = postItems[selection[0].begin];
      var contentTemplate = WinJS.UI.getControl(
        document.getElementById("contentTemplate")
        );

      contentTemplate.render(post).then(function (element) {
        content.appendChild(element);
        });
    }
  }

  var postItems = [];
  function processPosts(feed) {
    // Clear the process indicator
    downloadStatus.innerText = "";
    // Iterate over the items
    for (var i = 0, len = feed.items.length; i < len; i++) {
      var item = feed.items[i];
      var post = {
        title: item.title.text,
        date: item.publishedDate,
        content: item.summary.text,
        };

      postItems.push(post);
    }

    // Populate the ListView control's data source
    posts.winControl.dataSource = postItems;
  }

  function downloadError() {
    downloadStatus.innerText = "Error loading posts.";
  }

  WinJS.Application.start();
})();

The Results

The resulting application creates a simple two column RSS feed reader, with post titles on the left, and post content on the right (in HTML):

image

Now imagine you wanted to use the same code to make your RSS feed reader website. Immediately you have to cut out all references to the WinJS JavaScript files, since WinJS is a JavaScript wrapper around key WinRT functions.

<!-- WinJS references –>
<script src="/winjs/js/base.js"></script>
<script src="/winjs/js/ui.js"></script>
<script src="/winjs/js/binding.js"></script>
<script src="/winjs/js/controls.js"></script>
<script src="/winjs/js/animations.js"></script>
<script src="/winjs/js/uicollections.js"></script>
<script src="/winjs/js/wwaapp.js"></script>

For example, the Metro style RSS feed reader application uses WinJS to manage a lot of the UI look and feel, data binding and how you interact with the application, including controls, animations, etc. All of that functionality will have to be rewritten in non WinJS format.

You are forced to rewrite key functionality, such as the feed syndication capabilities written in JavaScript which leverage Windows.Web.Syndication.SyndicationClient – a WinRT class that manages the network interaction between the client and the feed provider, including the asynchronous calls to get the RSS data and parse and format it correctly.

var syn = new Windows.Web.Syndication.SyndicationClient();
var url = new Windows.Foundation.Uri("https://dougseven.com/feed/");
syn.retrieveFeedAsync(url).then(processPosts, downloadError);

You have to rewrite the data binding of the feed items to the HTML layout.

// Populate the ListView control's data source
posts.winControl.dataSource = postItems;

// Process the declarative controls
WinJS.UI.processAll();

<div id="template" data-win-control="WinJS.Binding.Template">
  <div class="postTitle" data-win-bind="innerText: title"></div>
  <div class="postDate" data-win-bind="innerText: date"></div>
</div>
<div id="posts"
  data-win-control="WinJS.UI.ListView"
  data-win-options="{itemRenderer: template,
                     layout: {type: WinJS.UI.ListLayout},
                     selectionMode: 'single',
                     onselectionchanged: selectionChanged}">
</div>
<div id="contentTemplate" data-win-control="WinJS.Binding.Template">
  <div class="postTitle" data-win-bind="innerText: title"></div>
  <div class="postDate" data-win-bind="innerText: date"></div>
  <div class="postContent" data-win-bind="innerHTML: content"></div>
</div>

That doesn’t feel very portable.

The conclusion is that your language choice when building a Windows 8 Metro style application has next-to-nothing to do with portability.

Before you get on your soap box, yes you can reuse some of the assets from the application. For example, the CSS is reusable between Windows 8 and the web. Some of the JavaScript is likely reusable, if it isn’t tightly coupled to WinJS or WinRT. But that’s it. Most of what makes the app work is dependent on WinRT, so its not portable – WinRT only runs on Windows 8.

Get Comfortable

So what should your language selection be based on? Comfort.

Microsoft architected an application development stack that does what Microsoft does best – provides flexibility and gives YOU choice. If you want to build an application for Microsoft’s upcoming platform, you can choose the language that you are most comfortable with. Microsoft isn’t making you learn an entirely new stack – just learn the new bits – and use the skills you already have.

Choose XAML

If you are a .NET developer currently working in WPF or Silverlight, then XAML+.NET will be right up your alley. Sure you will have to learn WinRT and some new syntax, but most of what you need to know you already do.

Choose HTML

If you are a web-standards developer, familiar with HTML and JavaScript, then use those skills. Use HTML5, JavaScript and learn WinJS and WinRT.

Either way Microsoft has made developing for Windows 8 very approachable. Make your language selection based on your skillset and what is comfortable for you. Don’t feel like you have to lean a new language. Use what you know.

D7