How to create an Extended Splashscreen for Universal Apps

Recently, I started to create a real world app to demonstrate the usage of my WordPressUniversal library. While I was working on it, I also decided to extend the Splahscreen which is mandatory for universal apps.There are several reasons to extend the splash screen, the most obvious is to hide initial data loading.

The only sample I found had a separate solution for the Windows and the Windows Phone application, and I decided to put them together to use the advantages of the Shared project that comes with every universal app.

The first step is to add your Splashscreen images to both projects. To do so, open their Package.appxmanifest files and go to the ‘Visual Assets’ tab. Add your images:

Screenshot (371)

Now add a UserControl to your shared project and rename the control type to “Grid” in the XAML file. After that, let us design the UI that is shown to the user when he starts our app:

<Grid.RowDefinitions>
    <RowDefinition/>
    <RowDefinition Height="180"/>
</Grid.RowDefinitions>

<!--Windows needs a Canvas-->
<Canvas x:Name="Win_Splash_Img" 
        Grid.Row="0" 
        Grid.RowSpan="2" 
        Visibility="Collapsed">
    <Image x:Name="extendedSplashImage_Win" 
           Source="Assets/SplashScreen.png"/>
</Canvas>

<!--Windows Phone needs a Viewbox-->
<Viewbox 
    x:Name="WP_Splash_Img"
    Grid.Row="0" Grid.RowSpan="2" 
    Visibility="Collapsed">
    <Image x:Name="extendedSplashImage_WP" 
           Source="Assets/SplashWindowsPhone.png"/>
</Viewbox>

<!--this StackPanel holds our ProgressRing that is telling the user we are doing some work-->
<StackPanel 
    Grid.Row="1" 
    HorizontalAlignment="Center">
    <ProgressRing x:Name="progressRing" 
                  IsActive="True" Margin="0,0,0,12" 
                  Foreground="White" 
                  Background="Black">            
    </ProgressRing>
    <TextBlock x:Name="progressText" 
               Style="{StaticResource TitleTextBlockStyle}" 
               TextAlignment="Center" 
               HorizontalAlignment="Center">
 </TextBlock>
</StackPanel>

This XAML code is the base for our extended Splashscreen. It defines a row height of 180 to place the StackPanel that holds the ProgressRing at the bottom of our control. The main difference here is that Windows Apps use a Canvas while Windows Phone uses Viewbox to hold our Splashscreen Image. We need to set the Visibility on both to collapsed as our code decides which one will be displayed on Launch.

In our code page, we have a bit more work to do. Let’s go through it step by step:

Make sure you have added the following Namespaces:

using Windows.ApplicationModel.Activation;
using Windows.UI.Core;
using ExtendedSplash.Common;

Note: if you do not have a Common folder in your Shared Project, you can add it manually and copy the classes from the demo project attached to this project. Don’t forget to change the Namespaces of the classes to your project name after you added them.

The next step is to declare some objects that we need for the extended Splashscreen:

internal Rect splashImageRect; 
internal bool dismissed = false; 
internal Frame rootFrame;
private SplashScreen splash;

The Rect is used to place the Splashscreen Image in it and will be sized by our code which we will add later. The dismissed bool is used to determine when the system Splashscreen gets dismissed. The rootFrame is used for the navigation to our first application page, while the splash is used to read the needed values for placing our image into the Rect.

After we have declared those objects, we need to overload the main class of our control:

public ExtendedSplash(SplashScreen splashcreen, bool loadstate)

The splashcreen tells us the coordinates and the height of the splash image. You can use the loadstate bool to determine data that needs to be restored by the SuspensionManager, if needed.

As users are snapping our apps or rotating the device, we need to handle this. To do so, we need to add the following line to our constructor:

Window.Current.SizeChanged += new WindowSizeChangedEventHandler(ExtendedSplash_OnResize);

Add this code to handle the resizing:

if (splash != null)
{
    splashImageRect = splash.ImageLocation;
    PositionImage();
}

If the user causes the WindowSizeChanged event to fire, the splash will be loaded again and submits new coordinates to our splash object. To properly handle the positioning, we are using the PositionImage() method:

        void PositionImage()
        {
#if WINDOWS_PHONE_APP
            extendedSplashImage_WP.SetValue(Viewbox.HeightProperty, splashImageRect.Height);
            extendedSplashImage_WP.SetValue(Viewbox.WidthProperty, splashImageRect.Width);
#else
            extendedSplashImage_Win.SetValue(Canvas.LeftProperty, splashImageRect.X);
            extendedSplashImage_Win.SetValue(Canvas.TopProperty, splashImageRect.Y);
            extendedSplashImage_Win.Height = splashImageRect.Height;
            extendedSplashImage_Win.Width = splashImageRect.Width;
#endif
        }

As you can see, we use the preprocessor directive WINDOWS_PHONE_APP to declare the height and width of the Viewbox. If it is not running on Windows Phone, we are setting the canvas coordinates and size via this method. This is not the only point where we need this method, as you will see later in this post.

Let’s go back to our constructor and add this line to load the system’s Splashscreen values into our object:

splash = splashcreen;

Now that we have these values, we are finally able to receive the coordinates and declare which Splashscreen will be used:

            if (splash != null)
            {
                //handle the dismissing of the system's splash 
                splash.Dismissed += new TypedEventHandler<SplashScreen, Object>(DismissedEventHandler);

                //get the system's splashscreen values
                splashImageRect = splash.ImageLocation;

                //decide which control is used to display the splashscreen image and size the progressRing
#if WINDOWS_PHONE_APP
                Win_Splash_Img.Visibility = Visibility.Collapsed;
                WP_Splash_Img.Visibility = Visibility.Visible;
                progressRing.Height = 50;
                progressRing.Width = 50;

#else
                Win_Splash_Img.Visibility = Visibility.Visible;
                WP_Splash_Img.Visibility = Visibility.Collapsed;
                progressRing.Height = 70;
                progressRing.Width = 70;
#endif
                //position and size the image properly
                PositionImage();

            }

 

Let me explain what I have done here. First we need to check if our splash object has a value. Then, we need to handle the Dismissing of the system’s Splashscreen with this TypedEventHandler:

private void DismissedEventHandler(SplashScreen sender, object args)
{
    dismissed = true;
}

After that, I am declaring when to show Windows Phone’s Viewbox and Windows’ Canvas as well as setting the size of the ProgressRing. The last step is to position and size the image again with our PositionImage() method. This will cause the app to switch to our extended Splashscreen.

Now we have to declare a new Frame instance and begin to load our data:

// this frame acts as navigation context
rootFrame = new Frame();
//start loading your data:
LoadData();

For this demo, I used a delay to keep the ProgressRing spinning:

async void LoadData()
{
    progressText.Text = "sleeping, please wait until I wake up...";
    //using a delay to keep the progress ring spinning for this demo
    await Task.Delay(TimeSpan.FromSeconds(5));
    //Navigate to the first application page after all work is done
    rootFrame.Navigate(typeof(MainPage));
    Window.Current.Content = rootFrame;
}

That’s all of the code we need inside our ExtendSplash control. If you now build the project, it will compile, but nothing will happen. other than going directly to the MainPage.

We need to add some additional code to our App.xaml.cs in the OnLaunched event:

//only show the splash if the app wasn't running before
if (e.PreviousExecutionState != ApplicationExecutionState.Running)
{
    //check the loadstate if necessary
    bool loadState = (e.PreviousExecutionState == ApplicationExecutionState.Terminated);
    //create a new instance of our ExtendedSplash
    ExtendedSplash extendedSplash = new ExtendedSplash(e.SplashScreen, loadState);
    //declare our extendedSplash as root content
    rootFrame.Content = extendedSplash;
}

If you hit the debug button, you should have similar results to these:

Screenshot (374)

Screenshot (375)

For your convenience, I created a small demo project. Download it here.

As always, I hope this blog post is helpful for some of you. If you have questions or feedback, feel free to leave a comment below.

WordPressUniversal – a PCL library for WordPress based C# mobile apps

WP_CSharp_Lib

As I have already developed a news reader app for my blog, I got asked quite a few times if I want to share my code to help others creating their apps. As I need to redesign my blog reader to match the latest OS features of Windows and Windows Phone, I decided to create my WordPressUniversal library.

Automattic, the company behind WordPress, integrated a powerful JSON API into their JetPack plugin. My library is based on this API. Please make sure the JSON API is active on the blog you are developing your app for.

The library currently provides the following features:

  • getting a list posts or pages
  • getting a list of all categories
  • getting a list of comments for the site and single posts
  • supports Windows Phone 8 & 8.1 Silverlight, Windows Phone 8.1 RT, Windows 8, Xamarin.iOS and Xamarin.Android

The library deserializes all data into C# objects you can immediately work with.

It is still a work in progress, but as it provides already a bunch of options to get you started, I am making this public already.

I am constantly working on the library, so be sure to follow the project along.

Note: JetPack’s JSON API does not support guest commenting at the moment. I already reached out to Automattic to (hopefully) find a solution for this. If you cannot wait, Disqus has a portable solution for Windows Phone apps.

Please make sure to see the documentation on my GitHub page.

If you have any questions, idea, wishes for me, just post a comment here or ping on Twitter.

Happy coding everyone!

Book review: iOS Development with Xamarin Cookbook (Dimitris Tavlikos)

I love to learn and expand my knowledge. Because of this, I was absolutely happy when I was asked for a book review about Dimitris’ iOS book.

The book is a huge collection of iOS recipes using Xamarin. The first three chapters are going deeply into the UI of an iOS application, looking on a lot (almost all) possible aspects of UI elements. What I like very much is that the author shows the code, usually with a step by step guide, and after that delivers a detailed explanation why something works in the way it does.

The next two chapters are all about creating and displaying data, files and sqlite, providing the same experience as the first chapters.

The sixth chapter is all about consuming services, such as web services, REST services or even WCF services (I wasn’t even aware of this being possible). Very good starting point for so many app ideas.

So far, the book shows already a lot of what we can do with Xamarin. But modern apps often contain media content: videos, photos, capturing media – this is what chapter 7 is all about.

Like all modern Smartphone operating systems, iOS provides some methods to let our apps interact with the OS. The 8th chapter is all about those interactions, like contacts, mail and more and has the matching real world scenarios.

The most usable apps use a device’s sensors, touch and gestures. Of course, with Apple being the leader in this space for a long time (we just need to be fair in this point), iOS has a lot of APIs for these. Chapter nine has some good recipes to help us with improving our app’s UX.

If your app needs location services and maps, chapter 10 is your friend. It shows you how to interact with Apple’s map services, add annotations and a lot more.

Users love when apps have some nice animations when something changes in an app. iOS provides a lot of options, and chapter 11 explains a lot about animations and drawing methods.

One of the most important parts when developing an app is lifecycle handling. As with any other OS, also iOS has its specific methods to handle the lifecycle. Background operations are part of this handling. In chapter 12, Dimitri tells us a lot about handling the states of an app as well as background operations.

Chapter 13 consists of tips and recipes for localization of an iOS app.

One of the most important steps when creating an iOS app is deploying the app. Apps should of course be tested on real devices, and this what chapter 14 is about – but not only. Also the required steps to prepare and app for submission as well as the submission to the store are explained.

The final chapter contains some additional recipes that can make your app more valuable like content sharing or text-to-speech.

Conclusion

I only began with Xamarin.iOS a few month ago. This book provides a great insight into development for iOS using the Xamarin IDE. As I said already, I like the approach of showing code first and then explaining what it does exactly and provide additional info if suitable. This book is absolutely worth every single cent if you want to start with iOS and Xamarin.

If you’re interested in the book, you’re just a click away: http://bit.ly/1tnxmGX

Note: This post was completely written on my phone. If you find typos, you can keep them ;-).

Book review: Learning Windows Azure Mobile Services for Windows 8 and Windows Phone 8 (Geoff Webber-Cross)

During the last months, I used the few times of my spare time when I wasn’t in the mood for programming to read Geoff’s latest book for diving deeper into Azure Mobile Services. Geoff is well known in the community for his Azure experience, and I absolutely recommend to follow him! I am really glad he asked me to review his book and need to apologize that it took so long to get this review up.

The book itself is very well structured with a true working XAML based game that utilizes both Windows 8 and Windows Phone 8 and connects them to one single Mobile Service.

Even if you are completely new to Azure, you will quickly get things done as the whole book is full of step-by-step instructions. Let’s have a quick look on what you will learn while reading this book:

  1. Prepare your Azure account and set up your first Mobile Service
  2. Bring your Mobile Service to life and connect Visual Studio
  3. Securing user’s data
  4. Create your own API endpoints
  5. use Git via the console for remote development
  6. manage Push Notifications for both Windows and Windows Phone apps
  7. use the advantages of the Notification hub
  8. Best practices for app development – some very useful general guilty tips!

I already use a Mobile Service with my Windows Phone App TweeCoMinder. I have already started a Windows 8 version of that app, which basically only needs to be connected to my existing Azure Mobile Service to finish it.

Screenshot (359)

While reading Geoff’s book, I learned how I effectively can achieve this and also improve my code for handling the push notifications on both systems. The book is an absolutely worthy investment if you look into Azure and Mobile Services and has a lot of sample code that can be reused in your own application.

As this is my first book review ever, feel free to leave your feedback in the comments.

You can buy the book right here.

Happy coding, everyone!

Save and load multiple selected items with Telerik’s RadListPicker on Windows Phone 8 & 8.1

wp_ss_20140706_0005

While I am continuing to add new features to my current main project UniShare, I am facing also problems that I never had before in my other apps.

One of those problems is to save and load multiple selected items on Telerik’s RadListPicker control. While the control itself is pretty easy to use, there is no documentation and also no blog posts on how to save and load those selected items.

If you are using Windows Phone Toolkit’s ListPicker, you should be fine by following this post I found during research for a solution. If you are using Telerik’s control like I am, this post is for you.

The main problem we have is that the SelectedItems property cannot be set directly. It has only a get accessor, which results in an error from Visual Studio if you try to set it. Luckily, there is still a way to set the saved  SelectedItems.

You need two things before we can go on: of course Telerik’s Windows Phone UI controls, and JSON.net, which we are using to serialize and deserialize our SelectedItems.

We are going to start with adding a ListPicker to our page:

            <telerikInput:RadListPicker 
                x:Name="TestPicker" Header="select items" 
                OkButtonIconUri="/Assets/PickerOK.png" 
                CancelButtonIconUri="/Assets/PickerCancel.png" 
                SelectionMode="Multiple" 
                SelectionChanged="TestPicker_SelectionChanged">
                <telerikInput:RadListPicker.PopupItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding name}" Margin="16 0 0 0" TextWrapping="Wrap"></TextBlock>
                    </DataTemplate>
                </telerikInput:RadListPicker.PopupItemTemplate>
                <telerikInput:RadListPicker.PopupHeaderTemplate>
                    <DataTemplate>
                        <TextBlock Text="choose item:" Margin="16 0 0 0" TextWrapping="Wrap" Style="{StaticResource PhoneTextTitle2Style}"></TextBlock>
                    </DataTemplate>
                </telerikInput:RadListPicker.PopupHeaderTemplate>
            </telerikInput:RadListPicker>

Pretty easy to use, right? Until now, our RadListPicker does nothing except being there. We need to hook up some code to it.

First we declare a data class for our RadListPicker ItemsSource:

        public class PickerItems
        {
            public string name { get; set; }
        }

After that, we need to get some items into our ListPicker. For this demo I am using static items, but this works also with dynamic ones:

public MainPage()
        {
            InitializeComponent();

            pickerSource = new List<PickerItems>();
            pickerSource.Add(new PickerItems() { name = "item 1" });
            pickerSource.Add(new PickerItems() { name = "item 2" });
            pickerSource.Add(new PickerItems() { name = "item 3" });
            pickerSource.Add(new PickerItems() { name = "item 4" });
            pickerSource.Add(new PickerItems() { name = "item 5" });

            TestPicker.ItemsSource = pickerSource;
            //registering the SummaryForSelectedItemsDelegate event
            TestPicker.SummaryForSelectedItemsDelegate += TestPicker_SummaryForSelectedItemsDelegate;
        }

“pickerSource” is just a List<PickerItems> that is defined globally for the page. Noticed the registration of the SummaryForSelectedItemsDelegate object? Awesome, because we are continuing with exactly that:

        //getting the string that is displayed when our ListPicker is not expanded
        private object TestPicker_SummaryForSelectedItemsDelegate(System.Collections.IList list)
        {
            string summary = string.Empty;

            for (int i = 0; i < list.Count; i++)
            {
                //getting the last item
                bool isLast = i == list.Count - 1;
                //generating the string
                PickerItems groupItem = (PickerItems)list[i];
                summary = String.Concat(summary, groupItem.name);
                summary += isLast ? string.Empty : ", ";
            }

            if (summary == string.Empty)
            {
                summary = "none";
            }

            return summary;
        }

This object is used to get the text that is displayed in the RadListPicker while it is not expanded.

Of course we need to handle the changed selection, that’s why we hook into our TestPicker’s SelectionChanged event:

        private void TestPicker_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {

            //saving the selected items
            if (TestPicker.SelectedItems.Count == 0)
            {
                //WP8.1
                //App.SettingsStore.selectedItemsString = string.Empty;

                //WP8
                App.selectedItemsString = string.Empty;
            }
            else
            {
                //WP8.1
                //App.SettingsStore.selectedItemsString = JsonConvert.SerializeObject(TestPicker.SelectedItems);

                //WP8
                App.selectedItemsString = JsonConvert.SerializeObject(TestPicker.SelectedItems);
            }

            //WP8
            if (IsolatedStorageSettings.ApplicationSettings.Contains("selectedItemsString"))
            {
                IsolatedStorageSettings.ApplicationSettings.Remove("selectedItemsString");
            }
            IsolatedStorageSettings.ApplicationSettings.Add("selectedItemsString", App.selectedItemsString);
        }

If we do not have selected items, we are going to save an empty string. Otherwise, we just serialize the selected items (which are an IList<PickerItems>) and save this code to our IsolatedStorage (on WP8) or ApplicationDataContainer (on WP8.1). This way, we can save the selected items without any trouble.

Until now, we only saved our items. Of course we want our app to select those saved items if our users return to this point in our app. The solution to this is a mix of JSON deserialization and LINQ. Add this code to your OnNavigatedTo event:

        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            //WP8.1
            //if (App.SettingsStore.selectedItemsString != string.Empty)
            //WP8
            if (App.selectedItemsString != string.Empty)
            {
                try
                {
                    //WP8.1
                    //var selectedItems = JsonConvert.DeserializeObject<List<PickerItems>>(App.SettingsStore.selectedItemsString);
                    //WP8
                    var selectedItems = JsonConvert.DeserializeObject<List<PickerItems>>(App.selectedItemsString);

                    foreach (var item in selectedItems)
                    {
                        //using LINQ to get the matching item from pickerSource
                        var selectedItem = pickerSource.Where(x => x.name == item.name).Single<PickerItems>();
                        //getting the index
                        int index = pickerSource.IndexOf(selectedItem);
                        //setting the item as selected
                        TestPicker.SelectedItems.Add(pickerSource[index]);
                    }
                }
                catch { }
            }

        }

Let me explain what I have done in there. First, I checked if there are selected items by checking if the saved string is empty. If not, I am deserializing the saved JSON string into a List<PickerItems>.

In the next step, we are iterating with a foreach loop over this List<PickerItems>. We are looking for each item that is in this list, and if it exists, we pick up this item from our pickerSource. This item has its own index position within the pickerSource List<PickerItems>. We assign this position as a an integer value to a local object in the foreach loop.

The most important point is the last step: adding the item to the SelectedItems IList<PickerItems>. After adding all items, our SummaryForSelectedItemsDelegate automatically reflects those changes. Bonus: this way, also the order of the selected items is still the same as at the time the user selected those items (which can be a case).

wp_ss_20140706_0004

If you do not want this, you should sort the SelectedItems before saving them. I wrapped the code in a try catch blog to avoid serialization exceptions for this demo project, you should handle/avoid them of course in a real world app.

Once one figured these steps out, pretty easy to solve. And finally, it is also documented by a blog post. As always, I hope this is helpful for some of you.

For your convenience, you can RadListPickerMultiSelect.

Until the next post, happy coding!

Using BugSense to track errors and events in a Windows Phone app

BugSenseWhy BugSense?

Errors/exceptions are annoying and helpful at the same time. They can annoy you while creating your app. At the same time, they help you to improve the quality of your app (most of the time, that is). They annoy your users, if they lead to crash your app. At the same time, they are a good chance to get in contact with your users – for example you could catch unhandled exceptions and ask the user to send it over to you.

But what if your users choose to ignore the error? How should you improve your app’s quality? What if the only thing you get are bad reviews? Pretty hard task, especially if you have a completely new app. I had that situation over and over again – and of course, I was annoyed of that fact.

So I researched the internet for solutions. Google Analytics is one service that works and is mostly used in enterprise apps. I use it in the app I am developing for my 9to5 job on Windows Phone and Android, but I only am able to use it on Windows Phone due to a third party library. If the developer chooses to not continue his efforts, at one point it will stop working or at least needs manual maintenance from my part  (looking at you, TweetSharp).

BugSense was the second alternative I had a look on. They are  a big player in the mobile monitoring market, and have a very good basic model, that fits perfectly for the average developer (500 errors per month, 350000 data points per month for free) to get started, and their first pricing stage if you have more apps comes close to what indie developers like I am need to maintain more than one app.

On top, there is often the possibility to gain promo codes that unlock some of the functionalities for free for a limited time (like DVLUP promo codes etc.).

I can only recommend to give it at least a try. On major point on the plus side was the fact that BugSense also has a Windows Phone app that helps you to keep up to date with the errors and insights while you are on the go.

Setting up an app is also pretty easy, be it tracking errors or tracking events. Let’s have a look at the code.

Error handling

The first thing you’ll need to to install is the BugSense SDK either via Nuget (‘BugSense.WP8′ for WP 8.0 / 8.1 Silverlight, ‘BugSense.WP81′ for WP 8.1 Runtime) or you can download the package manually here and import the dll for SL projects.

Next step is to authorize your app in your app’s constructor:

public App()
{
    //connect your app to the BugSense API’s
    BugSenseHandler.Instance.InitAndStartSession(new ExceptionManager(Current), RootFrame, "");
}

For WINPRT projects, you’ll leave the Rootframe parameter out.

The official documentation says you don’t need the UnhandledException handler any longer and can remove it. In a real Windows Phone app, this could lead to crashes from exceptions by the BugSense handler that are not caught without any error logging – thanks to Sara Silva for pointing me to that (follow her!). I’ll leave it up to you if you leave it there to handle those errors or if you are fine with your app being crashing in this case.

I am also telling you what I did: I left the UnhandledException handler in there because my users are already used to another thing I used before: Telerik’s RadDiagnostics, which enables users to send those error messages via mail. I left it there for two reasons:

  • to keep the interaction with my user that I already had when an error showed up
  • to prevent my app from crashing – no matter if the error comes from BugSense or my code

For error logging, there is only one point left to do. After my experience, error logging only works after registering a new instance of the BugSense handler (I am doing this in my first page’s Loaded event):

BugSenseHandler.Instance.RegisterAsyncHandlerContext();

That’s all, now all your errors are collected into your BugSense account.

Event tracking

If you want to track events in your app, BugSense is helpful on that task, too. The easiest way to achieve is this one:

await BugSenseHandler.Instance.LogEventAsync(“");

Conclusion

With BugSense you don’t need a complex setup to collect errors and track events remotely from your users devices. Pricing is moderate, and you even have a mobile app that allows you to keep track of errors when your are not on your dev machine. BugSense has a lot more options, for getting started, I hope this post is helpful for some of you.

Until the next post, happy coding!

How to load a list of a user’s twitter friends/followers in your Windows Phone app

TwitterFriendsList_WP_Blog During the last days, I was adding a new function to UniShare that suggests users the Twitter handles while typing in some text. The base of this new function is a list of the user’s twitter friends. In this post, I am going to show you how to generate this list and save it for further use. First thing I need to talk about: you can only load a maximum of 3000 friends at once due to the rate limit on Twitter’s part. At the end of the post, I’ll give you also an idea how to continue this after the first 3000 users were loaded. For the most scenarios, 3000 should be enough to cover the major part of your users. To be able to load all friends we first create a Task that fetches 200 entries of our user’s friends list. To be able to perform paging through all entries, Twitter uses so called cursors, which are 64-bit signed integers (long). You can read more about that here on Twitter’s API documentation. Let’s have a look on this Task:

        private async Task<string> TwitterFriendsListString(long twitterCursor)
        {
            ShowProgressIndicator("generating mention suggestion base...");

            //needed for generating the Signature
            string twitterRequestUrl = "https://api.twitter.com/1.1/friends/list.json";

            //used for sending the request to the API
            //for usage of the url parameters, go to https://dev.twitter.com/docs/api/1.1/get/friends/list
            string twitterUrl = string.Format("https://api.twitter.com/1.1/friends/list.json?cursor={0}&screen_name={1}&count=200&skip_status=true&include_user_entities=false", twitterCursor, App.SettingsStore.twitterName);

            string timeStamp = GetTimeStamp();
            string nonce = GetNonce();

            string response = string.Empty;

            //we need to include all url parameters in the signature
            //IMPORTANT: Twitter's API demands them to be sorted alphabetically, otherwise the Signature will not be accepted
            string sigBaseStringParams = "count=200";
            sigBaseStringParams += "&" + "cursor=" + twitterCursor;
            sigBaseStringParams += "&" + "include_user_entities=false";
            igBaseStringParams += "&" + "oauth_consumer_key=" + twitterConsumerKey;
            sigBaseStringParams += "&" + "oauth_nonce=" + nonce;
            sigBaseStringParams += "&" + "oauth_signature_method=HMAC-SHA1";
            sigBaseStringParams += "&" + "oauth_timestamp=" + timeStamp;
            sigBaseStringParams += "&" + "oauth_token=" + App.SettingsStore.twitteroAuthToken;
            sigBaseStringParams += "&" + "oauth_version=1.0";
            sigBaseStringParams += "&" + "screen_name=" + App.SettingsStore.twitterName;
            sigBaseStringParams += "&" + "skip_status=true";
            string sigBaseString = "GET&";
            sigBaseString += Uri.EscapeDataString(twitterRequestUrl) + "&" + Uri.EscapeDataString(sigBaseStringParams);

            string signature = GetSignature(sigBaseString, twitterConsumerSecret, App.SettingsStore.twitteroAuthTokenSecret);

            string authorizationHeaderParams =
                "oauth_consumer_key=\"" + twitterConsumerKey +
                "\", oauth_nonce=\"" + nonce +
                "\", oauth_signature=\"" + Uri.EscapeDataString(signature) +
                "\", oauth_signature_method=\"HMAC-SHA1\", oauth_timestamp=\"" + timeStamp +
                "\", oauth_token=\"" + Uri.EscapeDataString(App.SettingsStore.twitteroAuthToken) +
                "\", oauth_version=\"1.0\"";

            HttpClient httpClient = new HttpClient();

            httpClient.DefaultRequestHeaders.Authorization = new HttpCredentialsHeaderValue("OAuth", authorizationHeaderParams);
            var httpResponseMessage = await httpClient.GetAsync(new Uri(twitterUrl));

            response = await httpResponseMessage.Content.ReadAsStringAsync();

            return response;
        }

As you can see, we need to create our signature based on the url parameters we are requesting. Twitter demands them to be sorted alphabetically. If you would not sort them this way, the Signature is wrong and your request gets denied by Twitter. We are overloading this Task with the above mentioned cursor to get the next page of our user’s friends list. If you need the GetNonce() and GetSignature() methods, take a look at this post, I am using them for all requests to Twitter. Now that we have this Task ready to make our requests, lets load the complete list. First, declare these objects in your page/model:

        public List<TwitterMentionSuggestionBase> twitterMentionSuggestionsList;
        public long nextfriendlistCursor = -1;
        public string friendsResponseString = string.Empty;
        public string friendsJsonFileName = "twitterFriends.json";

Then we need to create a loop to go through all pages Twitter allows us until we are reaching the rate limit of 15 requests per 15 minutes. I using a do while loop, as this is the most convenient way for this request:

            //to avoid double entries, make sure the list is we are using is empty
            if (twitterMentionSuggestionsList.Count != 0)
            {
                twitterMentionSuggestionsList.Clear();
            }
            //starting the do while loop
            do
            {
                //fetching the Json response
                //to get the first page of the list from Twitter, the cursor needs to be -1
                friendsResponseString = await TwitterFriendsListString(nextfriendlistCursor);

                //using Json.net to deserialize the string
                var friendslist = JsonConvert.DeserializeObject<TwitterFriendsClass.TwitterFriends>(friendsResponseString);
                //setting the cursor for the next request
                nextfriendlistCursor = friendslist.next_cursor;

                //adding 200 users to our list
                foreach (var user in friendslist.users)
                {
                    //using the screen name ToLower() to make the further usage easier
                    TwitterMentionSuggestionsList.Add(new TwitterMentionSuggestionBase() { name = "@" + user.screen_name.ToLower() });
                }

                //once the last page is reached, the cursor will be 0
                if (nextfriendlistCursor == 0)
                {
                    //break will continue the code after the do while loop
                    break;
                }
            }
            //the while condition needs to return true if you would set up a Boolean for it!
            while (nextfriendlistCursor != 0);

As long as the cursor is not 0, the loop will load the json string with 200 entries. The class you’ll need for deserializing can be easily generated. Just set a breakpoint after the call of our Task, copy the whole response string and go to http://json2csharp.com to get your class. The TwitterMentionSuggestionBase class only contains a string property for the name and can be extended for you needs:

    public class TwitterMentionSuggestionBase
    {
        public string name { get; set; }
    }

Of course we need to save the list for further use. The code I use is pretty much the same you’ll find when you search for “saving json string to file” with your favorite search engine and works with Windows Phone 8 and 8.1:

            //saving the file to Isolated Storage
            var JsonListOfFriends = JsonConvert.SerializeObject(twitterMentionSuggestionsList);
            try
            {
                //getting the localFolder our app has access to
                StorageFolder localFolder = ApplicationData.Current.LocalFolder;
                //create/overwrite a file
                StorageFile friendsJsonFile = await localFolder.CreateFileAsync(friendsJsonFileName, CreationCollisionOption.ReplaceExisting);
                //write the json string to the file
                using (IRandomAccessStream writeFileStream = await FriendsJsonFile.OpenAsync(FileAccessMode.ReadWrite))
                {
                    using (DataWriter streamWriter = new DataWriter(writeFileStream))
                    {
                        streamWriter.WriteString(JsonListOfFriends);
                        await streamWriter.StoreAsync();
                    }
                }
            }
            catch
            {

            }

This way, we can easily generate a friends list for our users, based on their Twitter friends. Some points that might be helpful:

  • users with more than 3000 friends will receive an error after reaching this point on our task. Catch this error, but continue to save the already loaded list. Save the latest cursor for the next page and prompt the user to continue loading after 15 minutes to continue loading.
  • if you want to have a list with more details about a user’s friends, extend the TwitterMentionSuggestionBase class with the matching properties.
  • this code can also be used to determine the followers of a user, you just need to change the url parameters as well as the signature parameters according to the matching Twitter endpoint

As always, I hope this is helpful for some of you. Until the next post, happy coding!

How to connect your Windows Phone 8 & 8.1 app to Yammer

In my recent project UniShare I also added Yammer, because some of users asked for it and we use it also at Telefónica.

This post is all about how to connect you Yammer. First, we need to prepare our app. Five steps are needed for preparation.

First, we need an uri scheme to launch our app. To add an uri scheme, right click on the WMAppManifest.xml and click on ‘Open With…’ and select ‘XML (Text) Editor with Encoding’. After the ‘Tokens’ section, add your custom uri scheme within the ‘Extensions’ tag, for example:

      <Protocol Name="yourapp-yammercallback" NavUriFragment="encodedLaunchUri=%s" TaskID="_default" />

Next step is to add a proper UriMapper:

public class UriMapper : UriMapperBase
{
    public override Uri MapUri(Uri uri)
    {
        if (uri.ToString().Contains("yourapp-yammercallback"))
        {
            string decodedUri = HttpUtility.UrlDecode(uri.ToString());

            int redirectUriIndex = decodedUri.IndexOf("yourapp-yammercallback");
            string redirectParams = new Uri(decodedUri.Substring(redirectUriIndex)).Query;
            // Map the OAuth response to the app page
            return new Uri("/MainPage.xaml" + redirectParams, UriKind.Relative);
        }

        else return uri;
    }
}

If you want to learn more about uri schemes, you can read my blog post here.

The third step is to generate your app on Yammer to get your Tokens. Open https://www.yammer.com/client_applications, click on ‘Register New App’ and fill in the form:

Screenshot (354)

After clicking on continue, click on ‘Basic Info’ and add your uri scheme in the field ‘Redirect Uri’ and click on ‘Save’.

Screenshot (356)

The fourth step starts with downloading the Yammer oAuth SDK for Windows Phone from Github. Open the solution and built all projects. After that, you can close the solution. Go back into your project, and right click on ‘References’, followed by ‘Add Reference’. Browse to the folder ‘\WPYammer-oauth-sdk-demo-master\windows-phone-oauth-sdk-demo-master\Yammer.OAuthSDK\Bin\Release’ and add the file with the name ‘Yammer.OAuthSDK.dll’.

The last step is to add your keys and the redirect uri in your app’s resource dictionary:

<model:OAuthClientInfo xmlns:model="clr-namespace:Yammer.OAuthSDK.Model;assembly=Yammer.OAuthSDK" x:Key="MyOAuthClientInfo"
    ClientId="your client id" 
    ClientSecret="your client secret" 
    RedirectUri="yourapp-yammercallback" />

Now that our app is prepared, we can finally launch the oAuth process. First, we need to read our values from our app’s resource dictionary. Add this to the constructor to do so:

YammerClientId = App.MyOAuthClientInfo.ClientId;
YammerClientSecret = App.MyOAuthClientInfo.ClientSecret;
YammerCallbackUri = App.MyOAuthClientInfo.RedirectUri;

To kick the user out to the oAuth process, which happens in the phone’s browser, just add these two lines to your starting event (for example a button click event).

OAuthUtils.LaunchSignIn(YammerClientId, YammerCallbackUri);
App.Current.Terminate();

You might notice the app gets terminated. We have to do this because only this way, the uri scheme we added earlier can do its work. If the app is not terminated, the values cannot be passed into our app. Technically, it would also be possible to use the WebAuthenticationBroker on 8.1 for this. Sadly, the Yammer authorization pages do not work well with the WAB. The best way to use it with this library, is to kick the user to the browser.

Once we are receiving the values of the authentication, we can continue the authentication process to get the final access token. Add this code to your OnNavigatedTo event:

ShowProgressIndicator("connecting to Yammer...");

if (NavigationContext.QueryString.ContainsKey(Constants.OAuthParameters.Code) && NavigationContext.QueryString.ContainsKey(Constants.OAuthParameters.State) && e.NavigationMode != NavigationMode.Back)
{
    OAuthUtils.HandleApprove(
        YammerClientId,
        YammerClientSecret,
        NavigationContext.QueryString[Constants.OAuthParameters.Code],
        NavigationContext.QueryString[Constants.OAuthParameters.State],
        onSuccess: () =>
        {
            GetYammerCurrentUserData();
        }, onCSRF: () =>
        {
            MessageBox.Show("Please contact us via the 'help & support' page.", "Invalid redirect", MessageBoxButton.OK);
        }, onErrorResponse: errorResponse =>
        {
            Dispatcher.BeginInvoke(() => MessageBox.Show(errorResponse.OAuthError.ToString(), "Invalid operation", MessageBoxButton.OK));
            HideProgressIndicator();
        }, onException: ex =>
        {
            Dispatcher.BeginInvoke(() => MessageBox.Show(ex.ToString(), "Unexpected error", MessageBoxButton.OK));
            HideProgressIndicator();
        }
    );
}
// "Deny"
else if (NavigationContext.QueryString.ContainsKey(Constants.OAuthParameters.Error) && e.NavigationMode != NavigationMode.Back)
{
    string error, errorDescription;
    error = NavigationContext.QueryString[Constants.OAuthParameters.Error];
    NavigationContext.QueryString.TryGetValue(Constants.OAuthParameters.ErrorDescription, out errorDescription);

    string msg = string.Format("error: {0}\nerror_description:{1}", error, errorDescription);
    MessageBox.Show(msg, "Error", MessageBoxButton.OK);

    if (NavigationContext.QueryString != null)
    {
        string[] NavigationKeys = NavigationContext.QueryString.Keys.ToArray();
        ClearNavigationContext(NavigationKeys);
    }

    OAuthUtils.DeleteStoredToken();

}

With this, you are handling all errors and events properly. If the call ends successfully, we are finally able to get our user’s data:

public void GetYammerCurrentUserData()
{
    ShowProgressIndicator("connecting to Yammer...");

    var baseUrl = new Uri("https://www.yammer.com/api/v1/users/current.json", UriKind.Absolute);

    OAuthUtils.GetJsonFromApi(baseUrl,
        onSuccess: response =>
        {
            //do something with the result (json string)

            HideProgressIndicator();

        }, onErrorResponse: errorResponse =>
        {
            Dispatcher.BeginInvoke(() =>
            {
                MessageBox.Show(errorResponse.OAuthError.ToString(), "Invalid operation", MessageBoxButton.OK);
                HideProgressIndicator();

            });
        }, onException: ex =>
        {
            Dispatcher.BeginInvoke(() =>
            {
                MessageBox.Show(ex.ToString(), "Unexpected error", MessageBoxButton.OK);
                HideProgressIndicator();

            });
        }
    );
}

As you can see above, the result is a json string that contains the current user’s data. You can either create a class/model to deserialize the values or use anonymous deserialization methods.

One important point: you cannot publish your app outside your home network until it got approved as a global app by Yammer. I am waiting for nearly two weeks now for UniShare to get approved and hope it will become available for all soon.

As always, I hope this post is helpful for some of you.

Happy coding!

How to use the WebAuthenticationBroker in a Windows Phone 8.1 Silverlight app

oAuthDance

I already wrote how to use the WebAuthenticationBroker (WAB) in a Windows Phone Runtime app. With the need for me to switch back to Silverlight for UniShare, I needed to perform some rewriting of the WAB code.

The WAB needs some other code to work properly in a Silverlight project, and this post will got through all steps that are needed for this. I will reference to the above blog post where the methods itself are the same. I am just highlighting the changes that are needed in an 8.1 Silverlight project.

Preparing our App

First, we need to set up the proper continuation event in App.xaml.cs. We are doing this by adding this line of code in the App class:

public WebAuthenticationBrokerContinuationEventArgs WABContinuationArgs { get; set; }

This event is used when we are coming back to our app after the WAB logged the user in. The next step we need to do, is to tell our app that we have performed an authentication, and pass the values back to our main code. Unlike in the Runtime project, we are using the Application_ContractActivated event for this:

        private void Application_ContractActivated(object sender, Windows.ApplicationModel.Activation.IActivatedEventArgs e)
        {
            var _WABContinuationArgs = e as WebAuthenticationBrokerContinuationEventArgs;
            if (_WABContinuationArgs != null)
            {
                this.WABContinuationArgs = _WABContinuationArgs;
            }
        }

If you are upgrading from a WP8 project, you might have to add this event manually. Our app is now prepared to get results from the WAB.

Preparing oAuth

I am going to show you the oAuth process of Twitter to demonstrate the usage of the WAB. First, we need again the GetNonce(), GetTimeStamp () and GetSignature(string sigBaseString, string consumerSecretKey, stringoAuthTokenSecret=null) methods from my former blog post.

Performing the oAuth process

In the oAuth authentication flow, we need to obtain a so called Request Token, which allows our app to communicate with the API (in this case Twitter’s API).

Add the following code to your “connect to Twitter”- Button event:

                        string oAuth_Token = await GetTwitterRequestTokenAsync(TwitterCallBackUri, TwitterConsumerKey);
                        string TwitterUrl = "https://api.twitter.com/oauth/authorize?oauth_token=" + oAuth_Token;

                        WebAuthenticationBroker.AuthenticateAndContinue(new Uri(TwitterUrl), new Uri(TwitterCallBackUri));

Like in a Runtime app, we are getting the request token first (code is also in my former blog post), once we obtained the request token, we are able to get the oAuth token that enables us to get the final user access tokens.

Once the user has authenticated our app, we’ll receive the above mentioned oAuth tokens. To use them, add the following code to your OnNavigatedTo event:

                var appObject = Application.Current as App;

                if (appObject.WABContinuationArgs != null)
                {
                    WebAuthenticationResult result = appObject.WABContinuationArgs.WebAuthenticationResult;

                    if (result.ResponseStatus == WebAuthenticationStatus.Success)
                    {
                        await GetTwitterUserNameAsync(result.ResponseData.ToString());
                    }
                    else if (result.ResponseStatus == WebAuthenticationStatus.ErrorHttp)
                    {
                        MessageBox.Show(string.Format("There was an error connecting to Twitter: \n {0}", result.ResponseErrorDetail.ToString()), "Sorry", MessageBoxButton.OK);

                    }
                    else
                    {
                        MessageBox.Show(string.Format("Error returned: \n{0}", result.ResponseStatus.ToString()), "Sorry", MessageBoxButton.OK);
                        HideProgressIndicator();
                    }
                }

The WebAuthenticationResult now holds all values that we need to perform the final actions. To complete the oAuth process on Twitter, you can use the GetTwitterUserNameAsync(string webAuthResultResponseData) method from my former blog post. If you are not using other methods to control the result of the WAB, don’t forget to set appObject.WABContinuationArgs to null after you finished obtaining all tokens and data from Twitter (or other services).

As you can see, there are some structural differences in using the WAB when creating a Silverlight app, but we are also able to use a lot of code from my Runtime project. I hope this post is helpful for some of you to get the oAuth dance going.

In my next post, I will show you how to authenticate your app with Yammer (Microsoft’s enterprise social network).

Until then, happy coding!

How to send a mail from your Windows Phone 8.1 app

The old way

Sometimes, we need to pass some values to a newly generated E-Mail. In Windows Phone, we always had the EmailComposeTask for that:

EmailComposeTask mailTask = new EmailComposeTask();
mailTask .To = "mail@domain.com";
mailTask .Subject = "this is the Subject";
mailTask.Body = "this is the Body";

mailTask.Show();

This way was pretty straight forward. It will work in a Windows Phone 8.1 Silverlight app, but not in a WINPRT app.

The new way

I looked around and found the EmailManager class, which is also pretty easy to use. Let’s go through the code. First, we need to declare the EmailRecipient(s):

EmailRecipient sendTo = new EmailRecipient()
{
    Address = "mail@domain.com"
};

After that, we are now able to set up our EmailMessage, which works in a similar way like the old EmailComposeTask:

EmailMessage mail = new EmailMessage();
mail.Subject = "this is the Subject";
mail.Body = "this is the Body";

After setting up the Subject and the Body, we need to add our recipients to the EMailMessage. This is the only way to add “To”, “Bcc” and “CC” objects to our EMailMessage:

mail.To.Add(sendTo);
//mail.Bcc.Add(sendTo);
//mail.CC.Add(sendTo);

Last but not least, we are calling the  ShowComposeNewEmailAsync() method of the EmailManager class, which will open the Share contract with mail only:

await EmailManager.ShowComposeNewEmailAsync(mail);

 

wp_ss_20140424_0002

Here is once again the complete code for you to copy:

//predefine Recipient
EmailRecipient sendTo = new EmailRecipient()
{
    Address = "mail@domain.com"
};

//generate mail object
EmailMessage mail = new EmailMessage();
mail.Subject = "this is the Subject";
mail.Body = "this is the Body";

//add recipients to the mail object
mail.To.Add(sendTo);
//mail.Bcc.Add(sendTo);
//mail.CC.Add(sendTo);

//open the share contract with Mail only:
await EmailManager.ShowComposeNewEmailAsync(mail);

The new way works for both Windows Phone 8.1 Runtime and Silverlight apps.

The dirty way:

I found also another way that works with an Uri including the values as parameters launched by LaunchUriAsync() that gets recognized by the OS:

var mail = new Uri("mailto:?to=tickets@msiccdev.uservoice.com&subject=this is the Subject&body=this is the Body");
await Launcher.LaunchUriAsync(mail);

The parameters get automatically parsed by the Mail app.

I’ll leave it up to you which way you are using.

As always, I hope this is helpful for some of you.

Happy coding!