Bring It preview

Just a quick little preview of my package tracking app. Added a little fun gimmick where you can see where the last transport event took place using Bing maps. Still some styling left to do and get it all prettified, but it’s starting to come together.

http://player.vimeo.com/video/16043460

Bring It Preview from Frode Hus on Vimeo.

Advertisements

Using reactive extensions with WebRequest

I’ve recently started looking at the Rx library from Microsoft labs and it’s very interesting stuff, even though I have to admit I have a hard time wrapping my head around it. But it starts to sink in, bit by bit 🙂


When working with Windows Phone 7 development and my SharePoint library for WP7, I do a lot of asynchronous calls to web services. This code can often get a bit messy with all the callback methods so I tried to refactor it using reactive extensions and I am pretty pleased with the result:) I’m no expert on the field so I won’t guarantee that this is the best way to do it, but it works.

Here’s a sample of how to do a call to the Lists.asmx web service in SharePoint:
string Envelope = @"<?xml version=""1.0"" encoding=""utf-8""?>
                                    <soap:Envelope xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"">
                                        <soap:Body>
                                            <GetList xmlns=""http://schemas.microsoft.com/sharepoint/soap/"">
                                                <listName>{0}</listName>
                                            </GetList>
                                        </soap:Body>
                                    </soap:Envelope>";

        public void GetList(string server, string name, Action<XDocument> handler)
        {
            HttpWebRequest req = WebRequest.Create(string.Format("{0}/_vti_bin/lists.asmx", server)) as HttpWebRequest;
            req.Headers["SOAPAction"] = "http://schemas.microsoft.com/sharepoint/soap/GetList";
            req.ContentType = "text/xml; charset=utf-8";
            req.Method = "POST";
            var listRequest = (from request in Observable.FromAsyncPattern<Stream>(req.BeginGetRequestStream, req.EndGetRequestStream)().Do(stream =>
            {
                UTF8Encoding encoding = new UTF8Encoding();
                string e = string.Format(Envelope, name);
                byte[] bytes = encoding.GetBytes(e);
                stream.Write(bytes, 0, bytes.Length);
                stream.Close();
            })
                     from response in Observable.FromAsyncPattern<WebResponse>(req.BeginGetResponse, req.EndGetResponse)()
                     select HandleResponse(response)).Subscribe(handler);
        }
        private void DoStuff(XDocument xml)
        {
                //parse the xml result here
        }
        private XDocument HandleResponse(WebResponse response)
        {
            HttpWebResponse res = response as HttpWebResponse;
            if (res != null && res.StatusCode == HttpStatusCode.OK)
            {
                XDocument doc = XDocument.Load(response.GetResponseStream());
                return doc;
            }
            return null;
        }

Then of course we call the method:

GetList("http://spserver.com", "Pages", DoStuff);

In Windows Phone 7 we could add .ObserveOnDispatcher() before our .Subscribe() in the LINQ query so that the current Dispatcher is used when notifying observers.

We could also generalize the method so that it returns a IObservable<T> instead which we can subscribe to.

SharePhone continues on

Just wanted to inform that I’ll be adding Forms Based Authentication as well as Basic Authentication modes as options in SharePhone so that the library can be used for those that has these kinds of authentication methods configured for their SharePoint sites.

The Empire strikes back

I shamelessly stole a tweet for the title of this entry (hope you don’t mind, chetansharma) as I found it very fitting for what transpired today in New York at the Windows Phone 7 keynote.

First off, I’ll get my pet peeves off my chest regarding Windows Phone 7:

  • No cut and paste (slated for early 2011, so at least it’s coming – yes Microsoft, we do use this functionality still)
        • No multitasking
        • Certain functionality missing from the API which I won’t get into here

Now, I do understand that certain things had to be cut for the first release in order to provide a good and stable experience and so I hope that the rest will come in (near) future updates. The approach to do quality over quantity is a good one if this new platform is to stick, we don’t need for WP7 to fail right out of the gate.

So, all that settled, let’s get to the real news: WP7 has launched and the devices has done their stroll down the catwalk! I find myself in a pickle; I don’t know which device I want as they all seem so tastySmile

I do hope that WP7 marks Microsoft’s comeback into the smartphone marked and not a complete failure like, for example, Gartner predicts. Microsoft has done a solid piece of work; they started completely fresh (pretty gutsy and costly) and even came up with their own interface or as the keynote promoted: A different kind of phone. I won’t get into all the features as plenty of articles out there do indepth reviews of them shortly, I assume, but the idea of aggregating information from different sources and placing the data at your fingertips via the tiles is an interesting approach and I think it will work delightfully.

The Metro design is a matter of taste, I’m a big fan of graphically esthetic interfaces and I love the transition effects they do. I know some think they’ve overdone it and some even say its just stupid and a poor attempt at doing something to win over the masses. I’ll just say that my personal opinion is that I love my phone to be all pretty and fancy and leave it at that.

Also, Microsoft finally did what they should have done way earlier: Set some hardware requirements for their OS to ensure smooth running and good user experience across vendors. That’s one of the main advantages a certain fruit has had as they had firm control over the hardware their OS would run on.

I have one little nuisance nagging me and that’s the availability of certain services in my country. As far as I know, there will be no Xbox Live, no Zune and no Marketplace in Norway the day the devices are out in stores. I’m rather tired of fun functionality being available only in the US such as movie rentals etc but that’s an annoying licensing matter.

But, WP7 delivers what I’ve been waiting for: A development platform where I can use Silverlight and XNA and most importantly, Visual Studio. It’s easy for beginners to get into and for more advanced developers to have fun with. That’s where the nameless fruit fails horribly. I just hope that it will get firm footing in the marked and developing WP7 applications won’t become something rare and for especially interested.

And that’s my little comment on today’s keynote.
Wonderfully and delightfully yours.

Bring It

So, I decided to do a Windows Phone 7 application as a trial run and get the feel of it all instead of just small tests and demos.

It’s called Bring It, named after Bring which is a transportation service here in Norway and the application lets you track your packages, display a barcode for easy pickup at the post office, etc. I originally intended to add this to the Marketplace when it opened up, but I see that Posten has already developed and published their own application for free on the iPhone AppStore and Android Market so I figure they’ll do the same for Windows Phone 7 at one point.

Anyway, with that in mind I figured I’d post this app up for anyone who wants to use it as a sample and perhaps finish it (styling needs work for example).

I’ve added support for themes and globalization (even though the messages that come from the tracking service is in norwegian, so really only the headers and such are globalized), pivot control, it uses a MVVM pattern (still a bit new on that arena, so it might not be a perfect implementation – anyone with tips, please shareSmile ). Oh and it all works by pulling XML down from a public service provided by Posten.

It’s not entirely complete, missing a few features (such as deleting packages and such), but it works. As you can see from the screenshots, I used it to track my new Xbox 360 shipment Winking smile

Here are some mandatory screenshots:

image  imageimage

The fun bit is the ease of which WP7 application development is done. This app (granted, it’s simple, but still) only took a couple of hours to do.
I’d love to add push notification for tracking changes etc, maybe later.

Source:

Download

WP7 and IsolatedStorage

If you want to store data on your device, you’ll need IsolatedStorage. This is a sandbox storage for each application which means no application can read data belonging to another.
Also, you can’t browse the filesystem on your device – you only get access to your own application’s file.
Thus: Isolated storage.

There are various ways of going about using it (I believe someone is even making a local database based on IsolatedStorage).
The two basic ways are storing your data in the applications setting store or in a custom file.

Application settings

IsolatedStorage provides a way to store objects using IsolatedStorageSettings.ApplicationSettings, this is the easiest way of storing simple data. You just add your data to the settings store like so:
IsolatedStorageSettings.ApplicationSettings.Add(“myProperty”, value);
IsolatedStorageSettings.ApplicationSettings.Save();

The value object is then serialized down to disk automatically when calling Save() and can be read back thusly:
List<string> mydata = (List<string>)IsolatedStorageSettings.ApplicationSettings[“myProperty”];

Using files

This is basic IO really. You open up a stream and write to it.

using(IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication()){
   using(IsolatedStorageFileStream fs = storage.CreateFile(“myfile.wp”)){
       using(StreamWriter writer = new StreamWriter(fs)){
          XmlSerializer serializer = new XmlSerializer(typeof(List<string>));
          serializer.Serialize(writer, myStringList);
       }
    }
}

This example merely serializes a list of strings to xml located in IsolatedStorage.
Reading a file back is the almost the same basic code.

using(IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication()){
   using(IsolatedStorageFileStream fs = storage.OpenFile(“myfile.wp”, FileMode.Open)){
      XDocument doc = XDocument.Load(fs);
      XmlSerializer serializer = new XmlSerializer(typeof(List<string>));
      List<string> myData = (List<string>)serializer.Deserialize(doc.CreateReader());
   }
}

I like dealing with objects so I usually use serialization or Xml. That way, I can work with the objects themselves and bind them to various controls either by binding the objects themselves or using LINQ To Xml. Using text files with various formatting usually leads to a lot of overhead to do simple updates to the data.

Hopefully this helps out some of the new people that are flooding to the WP7 platform 🙂

WP7 Capabilities

I’ve seen some posts around on the interwebs regarding problems with networking code in XNA apps for WP7 and one of the reasons for this might be missing capability definition in WMAppManifest.xml.

When you create a new Silverlight for Windows Phone 7  or Windows Phone Game project, these capabilities are set up for you (as long as you’re using the latest SDK refresh, at least).
Otherwise you’ll need to add a <Capabilities/> section in WMAppManifest.xml. This section defines what your application is capable of – so if you haven’t specified ID_CAP_NETWORKING, your application won’t be allowed to connect to the network.

The default capabilities are:

  • ID_CAP_NETWORKING
  • ID_CAP_LOCATION
  • ID_CAP_SENSORS
  • ID_CAP_MICROPHONE
  • ID_CAP_MEDIALIB
  • ID_CAP_GAMERSERVICES
  • ID_CAP_PHONEDIALER
  • ID_CAP_PUSH_NOTIFICATION
  • ID_CAP_WEBBROWSERCOMPONENT

A sample of this might look like so:

<Capabilities>
    <Capability Name=”ID_CAP_NETWORKING”/>
</Capabilities>