Archive

Archive for the ‘Windows Phone 7’ Category

Developing mobile applications with PhoneGap and JQuery Mobile

March 26, 2012 24 comments

Introduction

For a very long time I have avoided learning HTML and ASP.Net and stayed away of applications using it. I didn’t wanted to end up with messy code and hacks to support multiple browsers (read: Internet Explorer 6.0). But as HTML5 and CSS3 are gaining more momentum, I have changed my mind and I have started learning HTML, CSS and JavaScript. Even if these technologies have their annoyances, they are THE way to develop cross platform software applications.

Recently there was a lot of buzz around PhoneGap. This a software framework that allows wrapping HTML5 applications into native applications for various mobile platforms (including iPhone, Android and Windows Phone). The idea of developing a mobile application for multiple platforms with a single code base is very tempting.

During the article I have still used the old name PhoneGap, but the framework has recently been open-sourced and renamed into Cordova (http://incubator.apache.org/projects/callback.html). Adobe will continue to offer a commercial version using the PhoneGap branding (http://phonegap.com/).

During the past days, I have developed a simple Todo Application using the following technologies:

  • PhoneGap to wrap in into a native application.
  • JQuery Mobile for the UI.
  • HTML5 local storage to store the user data.
    The applications consists of 6 screens and runs completely local; it does not require internet access to function. Theoretical it should be able to run on iPhone, Android and Windows Phone, but I was only able to test on a real Windows Phone device and on the desktop versions of Firefox, Safari and Chrome. So although it was not tested on multiple devices, I don’t expect a lot of issues when running it on IOS or Android.

todo1 todo2

PhoneGap & JQuery Mobile

I selected JQuery Mobile for the user interface because I like using JQuery for JavaScript development and thus it seemed the most natural choice for my screens. JQuery Mobile was pleasant and easy to use; in no time I was able to develop my screens using a simple HTML syntax combined with HTML5 data-* attributes.

I tested the application both on local browsers (Firefox, Chrome, etc.) and on the Windows Phone mobile browser. But the issues started when I started wrapping my HTML code into PhoneGap. Suddenly nothing still worked. After some trial and error, I discovered that it was required to add the PhoneGap JavaScript library to the web pages, even if you don’t need to use any special features of PhoneGap.

A second issue that I discovered was that JQuery Mobile and PhoneGap currently don’t work good together on Windows Phone 7. I was using a single HTML file per page, but the only thing that worked was either disabling the AJAX based loading of pages in JQuery Mobile or reverting to multi page HTML files. I choose for the multi page HTML files.

I hope that the page loading issue on Windows Phone will be fixed by either the PhoneGap or the JQuery Mobile developers as it is annoying.

Debugging

Debugging a HTML application wrapped in PhoneGap is not possible. The only option is to test and debug it with the developer tools of desktop browsers. If something goes wrong on the mobile device in PhoneGap, the only thing you can do is using old school console log statements to figure out what is happening.

I solved this issue this by creating two projects: a web application and the phone gap WP7 project. I develop and test with the web application project on a local browser and when I want to run it on a device, I execute a script to put the HTML  and JavaScript code into the WP7 project. Below you can find the synchronization script that I used:

@ECHO OFF

SET sourceDirectory=Html5TodoApp
SET destinationDirectory=Html5TodoApp.WindowsPhone\www

MKDIR %destinationDirectory%\images\

COPY "%sourceDirectory%\*.js" %destinationDirectory%\
COPY "%sourceDirectory%\*.html" %destinationDirectory%\
COPY "%sourceDirectory%\*.css" %destinationDirectory%\
COPY "%sourceDirectory%\images\*.gif" %destinationDirectory%\images\
COPY "%sourceDirectory%\images\*.png" %destinationDirectory%\images\

patch.exe "%destinationDirectory%\index.html" index.patch

The patch of my index.html file is required because for PhoneGap I have to add a reference to the cordova.js file. Something that is not possible in a regular browser. The “index.patch” is a regular patch file that saves me from having to update my index.html manually when I copy the source code to the PhoneGap project.

*** C:\Users\Pieter\Documents\Visual Studio 2010\Projects\Html5TodoApp\Html5TodoApp\index.html    Thu Mar 22 17:15:13 2012
--- C:\Users\Pieter\Documents\Visual Studio 2010\Projects\Html5TodoApp\Html5TodoApp.WindowsPhone\www\index.html    Thu Mar 22 17:20:51 2012
***************
*** 4,9 ****
--- 4,10 ----
<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, maximum-scale=1.0, user-scalable=no;" />
<title>Todo Demo Pieter</title>
<link rel="stylesheet" href="jquery.mobile-1.1.0-rc.1.css" />
+         <script src="cordova-1.5.0.js"></script>
<script src="jquery-1.7.1.js"></script>
<script src="jquery.mobile-1.1.0-rc.1.js"></script>
<script src="todo.logic.js"></script>

Conclusion

Would I recommend developing mobile applications using PhoneGap? It would depend on the application. It was a little bit more difficult to develop and test everything compared to using c# and Silverlight and the performance of the interface was also less “fluent” than a native application on my Nokia Lumia 800. But the big advantage is that my application can run on multiple platforms with almost the same code and this can be important for companies that want to deploy their business application on multiple platforms.

Creating Behaviors for WP7 Silverlight controls

September 29, 2011 1 comment

Behaviors allow you attach custom behavior to Silverlight controls from within the XAML instead of having to add code to the code-behind of the view. Support for behaviors can be added by referencing the assembly “System.Windows.Interactivity” from within your Windows Phone project.

Creating a new behavior is straightforward. All you have to do is extend the generic Behavior class and choosing a Dependency type for the generic parameter T. You can add custom behavior in the “OnAttached” and “OnDetaching” methods.

The following sample is a behavior I created for a search box in Cloudfox. The binding is automatically updated when the user presses enter.

public class UpdateOnSearchBehavior: Behavior<TextBox>
{
    protected override void OnAttached()
    {
        base.OnAttached();

        this.AssociatedObject.KeyDown += new KeyEventHandler(AssociatedObject_KeyDown);
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();

        this.AssociatedObject.KeyDown -= new KeyEventHandler(AssociatedObject_KeyDown);
    }

    private void AssociatedObject_KeyDown(object sender, KeyEventArgs e)
    {
        if (e.Key == Key.Enter)
        {
            BindingExpression binding = this.AssociatedObject.GetBindingExpression(TextBox.TextProperty);
            binding.UpdateSource();

            // Set the focus back to the page instead of the TextBox
            PhoneApplicationPage currentPage = ((PhoneApplicationFrame)Application.Current.RootVisual).Content as PhoneApplicationPage;
            if (currentPage != null)
                currentPage.Focus();
        }
    }
}

The behavior can be added to a TextBox using the following XAML:

<TextBox InputScope="Search" Text="{Binding SearchText, Mode=TwoWay}" Name="searchTextBox">
    <i:Interaction.Behaviors>
        <util:UpdateOnSearchBehavior/>
    </i:Interaction.Behaviors>
</TextBox>

Please note: Don’t forget to add a reference to System.Windows.Interactivity in the XAML of the View:

xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"

My MVVM tombstone pattern

August 25, 2011 4 comments

I am developing an application for Windows Phone 7 and during tombstoning I had to store some data of the view model. Tombstoning is done in the code behind of the view in the “OnNavigatedFrom” and “OnNavigatedTo” methods. This forced me to tightly couple my view model to (the code behind of) my view. As I don’t want this tightly coupling, I came with the following pattern:

Properties in the view model that must be tomstoned are decorated with the “Tombstone” attribute.

[Tombstone]
public SomeSerializableType SomeProperty { get; set; }

All my view then has to contain is the following code.

public MyPage()
{
    // ...
    isNewPage = true;
}

Please note: we need the “isNewPage” variable to differentiate between restoring a tombstoned view or revisiting the view in the current application instance.

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    base.OnNavigatedTo(e);

    if (isNewPage)
    {
        TombstoneHelper.RestoreState(this);

        isNewPage = false;
    }
}

protected override void OnNavigatedFrom(NavigationEventArgs e)
{
    base.OnNavigatedFrom(e);

    TombstoneHelper.SaveState(this);
}

TombstoneHelper uses reflection to find all properties that must be tombstoned. It can be used with any view model and it allows my view models and views to be loosely coupled. The only drawback is that it can only be used for properties with public getters and setters, because reflection on WP7 does not allow developers to access private properties or variables.

/// <summary>
/// Attribute to indicate the ViewModel Property should be tombstoned.
/// </summary>
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class TombstoneAttribute : Attribute
{
}
public static class TombstoneHelper
{
    public static void SaveState(PhoneApplicationPage page)
    {
        foreach (PropertyInfo tombstoneProperty in FindTombstoneProperties(page.DataContext))
        {
            page.State["ViewModel." + tombstoneProperty.Name] = tombstoneProperty.GetValue(page.DataContext, null);
        }
    }

    public static void RestoreState(PhoneApplicationPage page)
    {
        foreach (PropertyInfo tombstoneProperty in FindTombstoneProperties(page.DataContext))
        {
            string key = "ViewModel." + tombstoneProperty.Name;

            if (page.State.ContainsKey(key))
            {
                tombstoneProperty.SetValue(page.DataContext, page.State[key], null);
            }
        }
    }

    // ...

    private static IEnumerable<PropertyInfo> FindTombstoneProperties(object o)
    {
        IList<PropertyInfo> tombstoneProperties = (from p in o.GetType().GetProperties()
                                                        where p.GetCustomAttributes(typeof(TombstoneAttribute), false).Length > 0
                                                        select p).ToList();

        foreach (PropertyInfo tombstoneProperty in tombstoneProperties)
        {
            if (!tombstoneProperty.CanRead || !tombstoneProperty.CanWrite)
            {
                throw new TombstoneException("The getter and the setter of a property that needs to be tomstoned must be declared public.");
            }
        }

        return tombstoneProperties;
    }
}

I also use TomstoneUtility to help tombstoning my controls. I will write more about this in a future blog article.

Frameworks used inside my WP7 application

August 19, 2011 2 comments

A couple of days ago, I have released the first version of my free open source WP7 application “Cloud Fox” to the windows phone market place. It allows Windows Phone 7 users to synchronize their FireFox bookmarks, history and open tabs with their mobile phone.

Developing it was a fun and interesting exercise. I was able to use some of the best .Net open source frameworks available. They allowed me to reduce the development time and they helped me improving the overall quality and user experience.

I wrote this article because I want to share these frameworks with fellow WP7 developers:

  • MVVM Light: One of the best MVVM frameworks available.
  • JSON.Net: Makes parsing JSON data very easy and it is much more standard-compliant then the Microsoft JSON parser.
  • Silverlight Toolkit for Windows Phone: Offers a lot of high quality Silverlight controls. I used the ToggleSwitch implementation.
  • Coding4Fun Windows Phone Toolkit: For the ToastPrompt control.
  • Prism: For the ApplicationBarButtonCommand component, allowing me to bind commands to the application bar buttons
  • Ninject: For gluing everything together 🙂

And a special thanks to NuGet; it made downloading and installing .Net libraries super easy.

Which .Net frameworks are you using for WP7 development? I’d love to know them! 🙂

Adding synchronous methods to WebRequest on Windows Phone 7

May 23, 2011 6 comments

In general, I really like developing for Windows Phone 7. The tools like Visual Studio and Blend are of excellent quality and both Silverlight and XNA are very good frameworks. I only have one big annoyance and that’s the fact WebRequest does not support synchronous method calls. I am completely aware of the fact that you should not do heavy operations on the UI thread and I perform all my REST calls on a background thread, but I don’t like the fact that Microsoft forces me to make these calls asynchronously. As a developer, I would prefer to make this choice myself.

I have created 2 simple extension methods to add synchronous behavior to WebRequest.

public static class WebRequestExtensions
{
	public static WebResponse GetResponse(this WebRequest request)
	{
		AutoResetEvent autoResetEvent = new AutoResetEvent(false);

		IAsyncResult asyncResult = request.BeginGetResponse(r => autoResetEvent.Set(), null);

		// Wait until the call is finished
		autoResetEvent.WaitOne();

		return request.EndGetResponse(asyncResult);
	}

	public static Stream GetRequestStream(this WebRequest request)
	{
		AutoResetEvent autoResetEvent = new AutoResetEvent(false);

		IAsyncResult asyncResult = request.BeginGetRequestStream(r => autoResetEvent.Set(), null);

		// Wait until the call is finished
		autoResetEvent.WaitOne();

		return request.EndGetRequestStream(asyncResult);
	}
}

Please note: using an AutoResetEvent comes with a performance penalty, so this code is less efficient than a real synchronous method implementation.

Plase note 2: I know that you normally can also retrieve a WaitHandle from an IAsyncResult object instead of creating an AutoResetEvent manually, but this is not possible on WP7.

Categories: C#, REST, Windows Phone 7

Using SFont sprite fonts in XNA

I am currently busy porting a SDL based Perl game to C#, XNA and Windows Phone 7. During the development I was confronted with the problem that I had to convert a SFont sprite font to something that XNA can handle.

The XNA content processor by default transforms a windows font file to sprite font with the aid of an xml file that describes the export settings. The problem was that I didn’t have the font file. I only had a texture with the letters. Luckily I found out that there was also another way in XNA.  If each character is completely surrounded with magenta then XNA can also use a texture. The SFont font format on the other hand requires only that the pixels of the top row are magenta for separating the different characters. So I couldn’t do a straight import of the SFont format.

Being a geek I decided to write a small command line application to transfer the SFont fonts; instead of doing the transformation by hand in Photoshop.

After this we only need to specify the font texture as “Sprite Font Texture” and set the first character to  “!”.

Next we can load the sprite font the usual way:

protected override void LoadContent() 
{
	// ..
	spriteFont = Content.Load<SpriteFont>(“fontName”);
	// ..
}

And draw text with it using:

protected override void Draw(GameTime gameTime)
{
	// ..
	spriteBatch.DrawString(spriteFont, "your message", new Vector2D(x, y), Color.White);
	// ..
}

For people interested: my command line tool be downloaded at:
http://rapidshare.com/files/401795596/SFontToXnaFontConverter.rar.html

You can use it by running:
SFontToXnaFontConverter.exe [inputfile] [outputfile]

More information about SFont can be found at:
http://www.nostatic.org/sfont/

Categories: C#, Windows Phone 7, XNA