Friday, May 18, 2012

LocationServices for Windows Phone: Bing Translation made simple

Hello again. To be honest, a translation API is not in any way a location-aware API (unless you can send in coordinates and get the target language), but it is a tremendously useful API none the less and a lot of solutions could benefit from having one.

For that reason I’ve implemented Bing Translation in the LocationServices for Windows Phone framework.

Usage is exactly like the rest of the framework: you specify a criteria (in this case a Translation criteria) and then you fire that at the service and out you get an observable Translation (or a collection of that, depending on how you use it).

translation

In the screenshot above I’ve sent the Swedish words “badplatser”, “lekpark”, “samhälle”, “polis” & “källkod” for translation to it’s English equivalent.

The implementation is created in such a way that you can add several words (or phrases for that matter) to the criteria and it will only fire one shot at the service, instead of one per word/phrase.

Enough talk, let’s code.

References

These are the bare minimum references needed.

  • RestSharp
    • local build of RestSharp 103.1 with a tiny change. Located in the lib folder.
  • Reactive Extensions
    • NuGet: Rx_Experimental-Xaml
  • LocationServices for WIndows Phone
    • Usoniandream.WindowsPhone.LocationServices
    • Usoniandream.WindowsPhone.LocationServices.Bing

ViewModel code

in short: an ObservableCollection for the result, a ServiceLayer and a method that wires the translation.

    public class MainViewModel : ViewModelBase
    {
        private ObservableCollection<Usoniandream.WindowsPhone.LocationServices.Models.Bing.Translation> translations;
        public ObservableCollection<Usoniandream.WindowsPhone.LocationServices.Models.Bing.Translation> Translations
        {
            get
            {
                if (translations == null)
                    translations = new ObservableCollection<Usoniandream.WindowsPhone.LocationServices.Models.Bing.Translation>();
                return translations;
            }
            set
            {
                translations = value;
            }
        }

        public Usoniandream.WindowsPhone.LocationServices.Service.Bing.Reactive.ServiceLayer serviceLayer { get; set; }

        public MainViewModel()
        {
            serviceLayer = new Usoniandream.WindowsPhone.LocationServices.Service.Bing.Reactive.ServiceLayer();
        }

        public void WireBingTranslation()
        {
            IsDataLoading = true;
            Usoniandream.WindowsPhone.LocationServices.SearchCriterias.Bing.Translation criteria = new Usoniandream.WindowsPhone.LocationServices.SearchCriterias.Bing.Translation("sv", "en", "en-US", "badplatser", "lekpark", "samhälle", "polis", "källkod");
            var rxbing = serviceLayer.Translate(criteria)
                .ObserveOnDispatcher()
                .Finally(() =>
                {
                    IsDataLoading = false;
                })
                .Subscribe(
                // result
                    x =>
                    {
                        Translations.Add(x);
                    },
                // exception
                    ex =>
                    {
                        MessageBox.Show(ex.Message);
                    });
        }
        public bool IsDataLoading { get; set; }
    }

XAML code

I’ve left out everything from the view except this tiny ListBox implementation ‘cause it really is the only interesting part.

            <ListBox ItemsSource="{Binding Translations}">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <StackPanel>
                            <TextBlock Margin="12,0" Text="{Binding From}" Style="{StaticResource PhoneTextNormalStyle}" />
                            <TextBlock Margin="12,0" Text="translates to" Style="{StaticResource PhoneTextSubtleStyle}" />
                            <TextBlock Margin="12,0,12,24" Text="{Binding To}" Style="{StaticResource PhoneTextNormalStyle}" />
                        </StackPanel>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>

And, as shown above, that gives us:

translation

Wrapping up

That sample code is available here for download, just remember that you need a Bing AppID of your own and set that in the App.xaml. If you don't already have an AppID, you can sign up and get it at http://www.bing.com/developers/appids.aspx.

Now, for anyone using the other parts of the framework you also have the option of sending any model that implements ILocation in the criteria instead of strings. Doing so will translate the Content property of that object. In a future version you’ll get the sent in object back translated, but for now you’ll just have to do with the content as a Translation.

The framework libraries, source code and sample app are all on GitHub: http://peterdrougge.github.com/Usoniandream.WIndowsPhone.LocationServices/

No comments: