Weather Forecast

Porting Weather Forecast from Windows Phone to Qt

Weather Forecast is a Qt application that has been ported from Windows Phone. The goal of the app is to present weather forecast data retrieved from a web service. The functionality of both versions is very similar, however the approaches to accomplish it are quite different. Here you can find the details of the porting process.

1. Porting the UI using Qt Quick

Both versions of the application were designed to keep their platform look & feel and that's why the UI varies quite much between these both implementations. You can compare the UIs in the on figures below. The WP7 version is on the left and the Qt version on the right.

Main page in WP7 Main page in Qt Forecast page in WP7 Forecast page in Qt

As you can see, there are two main views in the application - Main Page and Forecast Details Page. On both platforms there is a similar concept of an application page that represents one separate screen of the application. WP7 uses thePhoneApplicationPage class, whereas Qt theQML Page element. One of the problems when porting from WP7 to Qt for Symbian is that Symbian devices do not have a physical back button, but WP7 devices do. To solve the problem, theQML ToolBarLayout element containing a back button was used. You can see it on the bottom of each page. In addition, two other buttons were added to navigate from Main Page to the Settings and About pages. Navigation between pages is very easy both on WP7 and in QML. To navigate to a particular page, WP7 uses theNavigationService object:

this.NavigationService.Navigate(new Uri("/ForecastPage.xaml?City=" +
                    curCity.CityName + "&Latitude=" + curCity.Latitude + "&Longitude=" +
                    curCity.Longitude, UriKind.Relative));

The QML equivalent is thePageStack element:

window.pageStack.push(Qt.resolvedUrl("ForecastPage.qml"),
                                      { cityName: city ,
                                        testMode: testModeEnabled });

The main control on both pages is a scrollable list of visual items. TheQML ListView element was used to implement the list. In this case, porting was very straightforward, sinceListBox used in WP7 version has a very similar functionality. You can see that the layout of list items differs between both versions, but it is mostly due to the fact that different weather forecast services were used and they provide different sets of data.

The Qt version has two more pages, a Settings page and an About page, which extends the functionality in comparison to WP7.

2. Network Interface

The Weather Forecast application retrieves data from the internet, which means that establishing an internet connection and sending web requests are crucial.

On WP7HttpWebRequest is used for accessing data from the internet. All you need to do is a build request url, create aHttpWebRequest object from the url, and run theBeginGetResponse() function to register the response callback method and send the request. The framework takes care of establishing the network connection.

// form the URI
UriBuilder fullUri = new UriBuilder("http://forecast.weather.gov/MapClick.php");
fullUri.Query = "lat=" + latitude + "&lon=" + longitude + "&FcstType=dwml";

// initialize a new WebRequest
HttpWebRequest forecastRequest = (HttpWebRequest)WebRequest.Create(fullUri.Uri);

// start the asynchronous request
forecastRequest.BeginGetResponse(new AsyncCallback(HandleForecastResponse),
forecastState);

But that's only the first step. The response still needs to be handled correctly. The data received from the weather service is in XML format, so the response needs to be parsed to retrieve the needed data. On WP7 the response is parsed usingLINQ queries. It is the developers responsibility to iterate over XML nodes to find and parse ones that contain the data he or she is interested in, which means that some work is needed to achieve this functionality. The following example shows how to query for a particular node value:

xmlCurrent = xmlWeather.Descendants("conditions-icon").First();

foreach (XElement curElement in xmlCurrent.Elements("icon-link"))
{
    try
    {
         newForecastList.ElementAt(elementIndex).ConditionIcon =
         (string)(curElement.Value);
     }
     catch (FormatException)
     {
         newForecastList.ElementAt(elementIndex).ConditionIcon = "";
      }

      elementIndex++;
}

In Qt there is a very useful QML element - XmlListModel. It is a specific list model that handles both fetching an XML feed over the internet and parsing the feed into roles defined by XPath queries. It can be used directly as a model for ListView?. See the example:

XmlListModel {
    id: xmlModel
    xml: xmlData
    query: "/data/weather"

    XmlRole { name: "date"; query: "date/string()" }
    XmlRole { name: "weatherCode"; query: "weatherCode/string()" }
    XmlRole { name: "tempMax"; query: "tempMaxC/string()" }
    XmlRole { name: "tempMin"; query: "tempMinC/string()" }
    XmlRole { name: "windspeed"; query: "windspeedKmph/string()" }
    XmlRole { name: "precip"; query: "precipMM/string()" }
}

However, XmlListModel has a limitation. It is not possible to parse data from nodes from the same or a higher level in the XML tree than set in the query property. However, theXmlHttpRequest is more flexible when parsing the response. When using bothXmlListModel andXmlHttpRequest, the internet connection is established automatically so that you do not need to worry about it.

3. Model View

Both implementations use the Model View pattern that separates data from the visual layer. The separation of functionality introduced by this architecture provides greater flexibility to customise the presentation of items, and provides a standard model interface to allow a wide range of data sources to be used with existing item views.

The standard practice for Windows Phone software design is MVVM, or Model-View-ViewModel?, which separates the data (Model), views, and control (ViewModel?). The essential part of the pattern is data binding between ViewModel? and View. The bindings are simple to construct by setting a ViewModel? object as the DataContext? of a view (in code behind) and using the {Binding ...} syntax in XAML:

<TextBlock x:Name="PageTitle" Text="{Binding CityName}"/>

When a binding is established and the model data changes, the UI elements that are bound to the data can reflect changes automatically. Similarly, changes made by the user in a UI element can be reflected in the data object.

Qt offers a similar pattern calledMVC (Model-View-Controller). A model is a set of data, and a view is a GUI component that can present a visual representation of the model to the user. A controller defines the way the user interface reacts to user input and modify model data. In the Weather Forecast application we only needed to present the data to the user without the possibility of modifying it, so the controller was not necessary. The model in our case is theXmlListModel object - see how to use it in the snippet from the Network Interface paragraph. Once the model is created, its values have to be bound to the properties of visual controls so that they can reflect data changes. Here is an example of such a binding:

date: model.date

As you can see, Model View concepts are quite similar for both platforms, which makes porting relatively easy.

Attachments

Nokia Developer aims to help you create apps and publish them so you can connect with users around the world.

京ICP备05048969号  © Copyright Nokia 2011 All rights reserved