json

How to fetch articles from your uservoice knowledgebase into a Windows Phone app

As some of you might know, I recently switched to uservoice.com for feedback, support and also FAQ hosting (read more here). Of course I want to integrate all those features into my app(s) to make the user experience as native as possible.

First, you need to generate a new app in uservoice.com. Log into your account, click on ‘Admin Console’, ‘Settings’ and finally ‘Integrations’. Then add your API client, you will have something like this:

uservoice_api_client

Today, we are starting with getting our knowledge base articles into our app.

This is the easiest part besides assigning the support mail address to a button.

Here is how we are doing it:

First, we need to declare some constants:

//consumer key and secret are needed to authorize our requests (oAuth)
 //KB articles only need the ConsumerKey
 const string ConsumerKey = "<youKey>";
 const string ConsumerSecret = "<yourSecret>";
 //all KB articles:
 const string KnowledgebaseString = "http://<yoursubdomain>.uservoice.com/api/v1/articles.json?client={0}";
 //KB topic articles:
 //using sort=oldest ensures that you will get the right order of your articles
 const string KnowledgebaseTopicString = "http://<yousubdomain>.uservoice.com/api/v1/topics/{0}/articles.json?client={1}&sort=oldest";

static string articleJsonString;

As you can see, we have two options to fetch our knowledgebase articles – all articles (if you have only one app, you’re fine with that) or topic based.

To get the needed topic id, just open the topic in your browser. The topic id is part of the url:

uservoice_topic_id

For getting authorized to receive the JSON string of our knowledge base, we need to pass the consumer key as parameter “client” to the base url of our request. To get our list sorted, I am using the sort parameter as well.

To receive the JSON string, we are creating an async Task<string> that fetches our article. To make the result reloadable, add the IfModifiedSince Header (otherwise Windows Phone caches the result during the app’s current lifecycle).

//receiving the JSON string for our KB does not need any advanced requests: 
//a basic HttpClient handles everything for us, as we don't need any authentication here
public async Task<string> GetKBJsonString()
{
      string getKBJSonStringFromUserVoice = string.Empty;

     HttpClient getKBJsonClient = new HttpClient();
     getKBJsonClient.DefaultRequestHeaders.IfModifiedSince = DateTime.Now;

     getKBJSonStringFromUserVoice = await getKBJsonClient.GetStringAsync(new Uri(string.Format(KnowledgebaseTopicString, "47463", ConsumerKey), UriKind.RelativeOrAbsolute));

      return getKBJSonStringFromUserVoice;
 }

Of course we want to have a list shown to our users – to display our JSON string in a ListBox, we need to deserialize it. To be able to deserialize it, we need a data class. You can use json2sharp.com to generate the base class or use this one (download Link). It fits for both all articles or topic based articles.

First, create a ListBox with the corresponding DataTemplate (I am only using question and answer text for this demo).

            <ListBox x:Name="FAQListBox">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto"></RowDefinition>
                                <RowDefinition Height="Auto"></RowDefinition>
                            </Grid.RowDefinitions>
                            <TextBlock Grid.Row="0" x:Name="questionTB" Style="{StaticResource PhoneTextTitle2Style}" Text="{Binding question}" TextWrapping="Wrap"></TextBlock>
                            <TextBlock Grid.Row="1" x:Name="answerTB" Style="{StaticResource PhoneTextSubtleStyle}" Text="{Binding text}" TextWrapping="Wrap"></TextBlock>
                        </Grid>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>

I am using JSON.net for everything around JSON strings. Here is how to deserialize the JSON string and set the ItemsSource of our Listbox:

            articleJsonString = await GetKBJsonString();

            var articlesList = JsonConvert.DeserializeObject<KBArticleDataClass.KBArticleData>(articleJsonString);

            FAQListBox.ItemsSource = articlesList.articles;

You are now already able to run the project. Here is the result of my test app, displaying the FAQ of my NFC Toolkit app:

uservoice_listbox_testapp_screenshot

As you can see, it takes only about ten minutes to get the knowledge base into your app. Using a remote source has a lot of advantages, the most important one is you don’t need to update your app when you add new answered questions.

I am now starting to work on integrating the feedback forum. It requires an oAuth authentication, and will be a bit more complicated than this one. Of course I will share it with you all here on my blog – stay tuned.

Until then – happy coding!

Posted by msicc in Dev Stories, wpdev, 3 comments

Dev Story Series (Part 5 of many): Styling a WebView or WebBrowser element

This post is about styling our WebView or WebBrowser in our app. Until now, we only got the HTML string that we are displaying in our WebView or WebBrowser. It looks like this:

image.png

The content we receive from our WordPress post content includes already all kind of HTML tags like paragraphs, lists, links, images. That is the advantage for this solution: no parsing is needed, the string can be displayed as is. Both the WebView and the WebBrowser framework element (no, they are not controls) are able to read and render CSS code. And this is how we can match the whole element for our app.

HTML Pages can be styled by using a so called cascading style sheet (CSS), which is similar to XAML code. With a little bit of searching on the web you will be able to style “translate” your XAML properties into CSS.

Here is a sample CSS String:

<STYLE type="text/css">
body{background:#034786; width:450px; }
p{font-family:'Segoe UI';color: white;font-size:medium;}
h1{font-family:'Segoe UI';color: white;}
h2{font-family:'Segoe UI';color: white;}
h3{font-family:'Segoe UI';color: white;}
h4{font-family:'Segoe UI';color: white;}
pre{background-color: #C0C0C0; width:100%;}
blockquote{font-family:'Segoe UI';font-style:italic;}
a:link{font-family: 'Segoe UI';color: #C0C0C0; font-size: medium; text-decoration:underline}
li{font-family: 'Segoe UI';color: white;font-size: medium;list-style-type: square;}
img {text-align:center; width:100%: height:100%;}
</STYLE>";

Every CSS string has to be surrounded with “<STYLE type=”text/css”> </STYLE> “. Between those two Style tags, you can set different properties for each kind of HMTL tag:

  • body = the whole page is embedded in the body. this is where we set the background of our content as well as the width and the height
  • p = paragraphs. paragraphs can contain text as well as images or other multimedia content. Mainly used for text like in our blog post, we style how the user is able to read our blog post.
  • h1 – h4 = different kinds of headers. you can define four styles of headers
  • pre = is for lines of code
  • blockquote = if we quote people or other sites, we use quotes to clarify this aren’t our words. should be styled a bit differently than the rest of our blog (e.g. Italic)
  • a:link = how hyperlinks will be styled
  • li = this is how our list will be styled in this view
  • img = how we want to see our pictures in our post

Hint for using CSS in code behind:

If you just C&P the CSS string from above, it will result in some errors from Visual Studio. Visual Studio does not like the new lines in strings, so you have to add it as one line. Also is it not possible to use ‘”‘ within a string declaration. It has to be “escaped”, which we are doing with a simple before it: ‘”‘. I mentioned it because I learned it the very hard way by trying to solve it for 2 hours.

Only thing we now need to do is pass the CSS String together with our HTML string from our JSON to our WebView or WebBrowser element:

WebBrowser.NavigateToString(CSSString + ContentString);

After navigating to this both strings, our content is now displayed like native:

  styledNativeWebView

One last tip:

I recommend to set the Visibility of your WebBrowser or WebView to “Collapsed” until the whole rendering has done. Once the “navigation” has finished, set it via code to visible. This way the user does not recognize that we are rendering the post content for him. Just display a loading animation until that is done. Both elements have a “LoadCompleted” event. Once the rendering (= the navigation to our string) is done, the content of our blog post is shown as it would be natively in our app.

As always, I hope this is helpful for some of you and feel free to leave a comment below.

Posted by msicc in Dev Stories, win8dev, wpdev, 0 comments

Dev Story Series (Part 3 of many): Why I use a WebBrowser/WebView to display WordPress post content

When it comes to display the post content on a blog reader app, it starts to become a bit challenging. The post content is formatted to look great on your website. But when we pull our posts into an app, there is only the naked, HTML formatted string.

As developer, you have to think about several things now:

  • What part of the content do I want to be displayed?
  • How do I get the images there?
  • What if there is a video in the post?
  • Where do I put the Links in?
  • How can I handle enumerations?
  • and so on…

There is the HTMLAgilityPack out there, but I never got a satisfying result out of it. The next method would be to write a custom parser. This is what I have done before, in the old version of the app for my WordPress blog. It did work, but I had to invest a real big amount of time in it before I got a result that I was able to live with. I was also not too experienced with RegEx (and I am still not) that I could set up a perfect parser.

When I was creating the Windows 8 version of my app, I wanted to achieve a good reading experience. On the other side I  wanted the code to be as reliable as possible, because there are often changes on WordPress that can have impact on my app.

As I mentioned above, the post content is already formatted. It is formatted in HTML.  I decided to render the content string instead of parsing it.

It is pretty easy to do that. Just pass the content string to your desired details page, and use a WebBrowser on Windows Phone or a WebView on Windows 8. Without any parsing, just by “navigating” to the passed string, we will get a result like this:

image

So we have already a readable result, and if my app has only white background, I could leave it like it is and go on.  Without any additional line of code.

Using the WebBrowser/WebView brings also additional advantages:

  • Pinch-to-Zoom support
  • Orientation support
  • automatic image downloading without any additional control
  • WebView on Windows 8 embeds videos automatically

I don’t want to hide that there are a few points that we need to handle, which will be subject of additional posts:

  • styling of content to match our app colors
  • Navigation to links (including a solution for video links on Windows Phone)
  • Scroll direction in Windows 8 WebView

I know it might be not the best practice for displaying web content, but I am really satisfied what I achieved by using the WebBrowser and WebView element in my apps.

I hope the upcoming blog posts will be helpful for some of you to create also a good user experience by using these elements. Of course these posts will contain some code. Before starting the posts about it I just wanted to share why I used these elements.

 

Posted by msicc in Dev Stories, win8dev, wpdev, 0 comments

Dev Story Series (Part 2 of many): Getting recent posts from WordPress into your Windows Phone and Windows 8 app

Now that we have a full WordPress JSON class, we are able to download our recent posts from WordPress into our apps for Windows Phone and Windows 8. I am still not using MVVM to keep it simple (and because I have to dive into it more deeply).

The first thing we need to do is to download the JSON string for the recent posts. The Uri scheme is pretty simple: {yourblogadresshere}?json=get_recent_posts

I declared a public string in my MainPage for that, so it is very easy to use it in our app.

The second thing we are going to do is to download the JSON string into the app.

For Windows Phone I used a WebClient, as I want to keep it compatible with the Windows Phone 7 OS. I will update the App with an dedicated WP8 version later, for the moment it is working on both OS versions. Add this code to you Page_Loaded event:

                WebClient GetPostsClient = new WebClient();
                GetPostsClient.Headers[HttpRequestHeader.IfModifiedSince] = DateTime.Now.ToString();
                GetPostsClient.DownloadStringCompleted += new DownloadStringCompletedEventHandler(GetPostsClient_DownloadStringCompleted);
                GetPostsClient.DownloadStringAsync(new Uri(RecentPostJsonUri));

We will also have to add the Handler for GetPostsClient_DownloadStringCompleted:

 void GetPostsClient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            App.jsonString_result = e.Result;
        }

In Windows 8 there is no WebClient, so I used an HttpClient:

                        HttpClient getJsonStringClient = new HttpClient();
                        getJsonStringClient.DefaultRequestHeaders.IfModifiedSince = DateTime.UtcNow;
                        App.jsonString_result = await getJsonStringClient.GetStringAsync(RecentPostJsonUri);

Both the Windows Phone and the Windows 8 apps are downloading the string asynchronously, the UI is reliable all the time. You may have noticed the additional Header that I request. This way, we are able to integrate a refresh function into our app. If we leave this out, our app uses the cached string, and users will have to exit the app to refresh the list of our posts.

You will have to declare a public static string variable for the downloaded string in App.xaml.cs, that keeps the downloaded string accessible through the whole app.

Until now we have only downloaded our JSON String, which looks like this:

image

Side note: The WordPress JSON API has a dev mode. Just add “&dev=1” to your above created Uri, and you will be able to see the whole JSON string in a readable form in your browser.

Back to our topic. Off course this is not a good format for users. They want to see only the content, without all the formatting and structuring code around.

What we need to do, is to deserialize our JSON String. This is possible with Windows Phone and Windows 8 own API, but I highly recommend to use the JSON.net library. You can download and learn more about it here. To install the library, just go to Tools>Library Package Manager>Manage NuGet Packages for Solution, search for JSON.net, and install it.

After installing the package, we are able to use only one line of code to deserialize our JSON String to our data members:

var postList = JsonConvert.DeserializeObject<Posts>(App.jsonString_result);

Now we need the deserialized data to be displayed to the user. The desired control for Windows Phone is a ListBox, for Windows 8 you it is called  ListView. We need to create an ItemTemplate in XAML and bind the data we want to show to the user (Just change ListBox to ListView for Windows 8 in XAML):

<ListBox x:Name="PostListBox">
                <ListBox.ItemTemplate>
                    <DataTemplate>
				<StackPanel>
 				<Image x:Name="PostImage" 
				       Source="{Binding thumbnail}" />
                           	<TextBlock x:Name="TitleTextBlock" 
				           Text="{Binding title}" 
					   TextWrapping="Wrap" 
					   FontSize="20" />
                                <TextBlock x:Name="PublishedTextBlock" 
					   Text="{Binding date}" 
					   FontSize="12"/>
				</StackPanel>
                    </DataTemplate>
                </ListBox.ItemTemplate>
          </ListBox>

As you can see, we have set some Bindings in the code above. This Bindings rely on the DataContract Post, as every ListBox/ListView-Item represents one Post of our postList.

[DataContract]
public class Post
    {
        [DataMember]
        public int id { get; set; }
        [DataMember]
        public string type { get; set; }
        [DataMember]
        public string slug { get; set; }
        [DataMember]
        public string url { get; set; }
        [DataMember]
        public string status { get; set; }
        [DataMember]
        public string title { get; set; }
        [DataMember]
        public string title_plain { get; set; }
        [DataMember]
        public string content { get; set; }
        [DataMember]
        public string excerpt { get; set; }
        [DataMember]
        public string date { get; set; }
        [DataMember]
        public string modified { get; set; }
        [DataMember]
        public List<Category> categories { get; set; }
        [DataMember]
        public List<object> tags { get; set; }
        [DataMember]
        public Author author { get; set; }
        [DataMember]
        public List<comment> comments { get; set; }
        [DataMember]
        public List<Attachment> attachments { get; set; }
        [DataMember]
        public int comment_count { get; set; }
        [DataMember]
        public string comment_status { get; set; }
        [DataMember]
        public string thumbnail { get; set; }
    }

Choose the fields you want to display to create your own DataTemplate to show only the data you want. Last but not least we have to tell our app that the ItemSource of our ListBox is the deserialized list, which is also done easily:

PostListBox.ItemsSource = postList.posts;

If you now hit F5 on your keyboard, the app should be built and the device/emulator should show your recent posts in a list. You don’t need to add additional code to download the images, as the image source points already to an image and will be downloaded automatically.

Pro-Tip:

The thumbnails from the our DataContract Post are looking really ugly sometimes. To get a better looking result in your ListBox/ListView, I recommend to use the attached images. To do this, you will need the following code:

          foreach (var item in postList.posts)
            {
                var postImagefromAttachement = item.attachments.FirstOrDefault();
                if (postImagefromAttachement == null)
                {
                    item.thumbnail = placeholderImage; //add your own placeholderimage here
                }
                else
                {
                    item.thumbnail = postImagefromAttachement.images.medium.url;
                }

            }

This code checks your list of attachments in your post, takes the first image, and downloads a higher quality (medium/full).  I am using medium to get best results on quality and download speed.

I hope this is helpful for some of you to get forward for to create a WordPress blog app on Windows Phone and Windows 8.

Happy coding!

Posted by msicc in Dev Stories, win8dev, wpdev, 1 comment
Dev Story Series (Part 1 of many): Creating a data class for both Windows 8 and Windows Phone app

Dev Story Series (Part 1 of many): Creating a data class for both Windows 8 and Windows Phone app

As I promised earlier on my application for the Intel App Innovation Contest on codeproject.com, I will do a series of blog posts for my application MSicc´s Blog for Windows 8 and Windows Phone.

This is the first article in my new Dev Story Series, where I describe the development process of the app. I am starting with the very first steps that you have to do if you plan such an application. To make the application useful, we first have to decide how we want to get the data from our blog/website into our application.

One hint that will make some of you crying out loud: At the moment I am not using the MVVM pattern. I am aware of the fact that most devs for Silverlight/C# swear on it, but I still decided to go without it – as well on Windows Phone as on Windows 8. I will continue to learn it in one of my future project, but for the moment I just want to get things done – also if that means that I have to create some – well, let us call it “compromises”.

Which way to choose?

If you consider to create a “blog reader”, you have to think about how you want to get the data from your blog into your app. There are different ways:

  • via a RSS/Atom feed (that was in the old version of my Windows Phone app for msicc.net)
  • via XMLRPC (if your blog supports that)
  • via JSON

I decided to go with JSON for the new version. There were several reasons to do so:

  • there is an app err… an plugin for that on WordPress
  • JSON is fast
  • JSON is set to be the new standard for data consumption
  • With JSON.NET you can deserialize your data with only one line(!) of code

How do we get the data in our app?

Of course, we will download it. But if you only download your JSON data, the only thing you will get is a very weird looking string that looks like this:

json_string_unserialized

That´s pretty ugly, right? Of course we could work us through all arrays and objects there. That would take hours and hours until we would have covered all data we need for our apps. Luckily, there are two tools that make the whole thing a lot easier.

Two handy tools to make a dev´s life easier

The first tool I want to show you is “Beautify JSON”. It is a web based tool that makes strings like the one above readable for a human. Find it here.

Just paste the string of your JSON API in there, and you will get a readable version of your JSON string:

beautify_json

If you want to use only some of the data that your API provides, you can now easily search the string for the objects and arrays that you need.

If you quickly want to create a data class for all data that is provided, you can do this by using json2charp.  It provides a ready-to-use code that can easily be copied and pasted into your class file in Visual Studio:

json2charp

Now let´s have a look to the class itself:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;

namespace WordPressDataClass
{
 public class Posts
    {
        [DataMember]
        public string status { get; set; }
        [DataMember]
        public int count { get; set; }
        [DataMember]
        public int count_total { get; set; }
        [DataMember]
        public int pages { get; set; }
        [DataMember]
        public List<Post> posts { get; set; }
    }
}

As you can see, I created a DataContract and DataMember based class by using System.Runtime.Serialization. If you want to know more about DataContracts and DataMembers I recommend you to read MSDN: using Data Contracts.

I am not posting the whole class, only the key DataContract Posts, which will get us our List of posts. You can download the whole class at the end of the post. It will be very helpful if you want to create an app for your WordPress based blog.

I use the class in both my Windows 8 and my Windows Phone app without any differences. As you can see, If you are familiar with Windows Phone Development, there is only a small step to Windows 8 development.

I hope this article is helpful for some of you. In my next post I will show you how easily you can use the provided JSON Data in your app/s.

source code: JsonDataClass

Posted by msicc in Dev Stories, win8dev, Windows, Windows Phone, wpdev, 4 comments