×
Namespaces

Variants
Actions

Getting started with Buddy services: Create your own location based social app

From Nokia Developer Wiki
Jump to: navigation, search

This article explains how to use the buddy service platform using the example of a location based social app

Needs-update.pngThis article needs to be updated: If you found this article useful, please fix the problems below then delete the {{ArticleNeedsUpdate}} template from the article to remove this warning.

Reasons: hamishwillee (talk) (11 Nov 2013)
The Buddy API changed completely since this article was written and the online documentation does not seem to be up to date. The article needs to be updated to reflect the current API. Ideally the ArticleMetadata "dependencies" information should list the version of the API for which it is accurate. Note also that the Nokia Premium Developer Program has been replaced by Nokia Developer Offers, and the information about free service calls is no longer true.

Note.pngNote: This article was a winner in the Windows Phone 8 Wiki Competition 2012Q4.

SignpostIcon HereMaps 99.png
WP Metro Icon UI.png
WP Metro Icon Web.png
SignpostIcon XAML 40.png
WP Metro Icon WP8.png
Article Metadata
Code ExampleTested withCompatibility
Platform(s): Windows Phone 8
Windows Phone 8
Platform Security
Capabilities: LOCATION, MAP
Article
Keywords: buddy, social, gps
Created: MaMi (09 Dec 2012)
Last edited: RAVI (09 Feb 2014)

Contents

Introduction

Buddy is a service that offers developers a wide range of "standard" web services, allowing you to focus on developing your app and not caring about all the web services management part.

Nokia introduced its Premium Developer Program and one of the benefits of this program is to give you 500000 extra service calls per month on Buddy.com. Meaning that each month you can consume as much as 1 000 000 API calls for free.

This article will help you to understand what is Buddy.com and how it can be used by creating a location based social application. The examples cover how to:

  • Create a Buddy account
  • Create a Buddy application
  • Create a Windows Phone 8 application solution
  • Create a user with Buddy's services
  • Retrieve this user
  • Allow the user to check-in
  • Display the check-ins history
  • Allow the user to search friends
  • Send friend requests
  • List and accept friend requests
  • See friends and their position


Note that the final app should not be considered as a code or design reference as lot of tasks were done in a way to keep it very simple. A non-exhaustive list of possible improvements was added after each tasks for your convenience.

Create your Buddy account

First thing first, you'll need to create an account on buddy.com

If you are a member of the Nokia Premium Developer Program

Go to this page and click the link "Already a member? Click here for your benefits"

Buddy getting started 0.JPG

You will reach a page listing all your tokens, just click on the Request Link and it will redirect you to buddy.com where you can create your account.

If you are not a member of Nokia Premium Developer Program

Simply go to this page fill the 3 mandatory fields and you are done.

Create your first app services

Once you've signed up you'll reach your Buddy Developer Dashboard. Now you will have to create your first app, fill the Name field in the Creating a new app section and Voilà!

Buddy getting started 1.jpg

Your new app will appear in the applications list, now click the key icon to retrieve your app service ids, you'll need them to call services from your application

Buddy getting started 2.jpg

Buddy getting started 3.jpg

Create your Windows Phone app

Let's create a new Windows Phone app in Visual studio with the default template, it will be named MySocialApp

Buddy getting started 4.JPG

Select Windows Phone 8.0 as target version (note that buddy service are probably working with 7.1 apps but you'll need Windows Phone 8 API for the application). Once the app is created, add a reference to buddy API by using NuGet, to do so right click on your project in the solution explorer and select "Manage NuGet Packages..."

Buddy getting started 5.jpg

  1. Click on the Online Item on the left,
  2. Type buddy in the search field,
  3. Click install on the BuddyPlatformSdk


Buddy getting started 6.JPG

You'll now be able to call Buddy's services from your application. In order to manage the service integration, add a first class to the project named ServiceManager.cs, it will contain our ids and a BuddyClient required to perform basic service calls and a AuthenticatedUser for user related ones

    internal static class ServiceManager
{
public const string BUDDY_APP_NAME = "<PUT YOUR APP NAME HERE FROM THE BUDDY DASHBOARD>";
public const string BUDDY_APP_KEY = "<PUT YOUR APP PASSWORD HERE FROM THE BUDDY DASHBOARD>";
 
private static BuddyClient m_client;
public static BuddyClient Client
{
get
{
if(m_client == null)
m_client = new BuddyClient(BUDDY_APP_NAME,BUDDY_APP_KEY);
return m_client;
}
}
 
//Buddy Authenticated user
public static AuthenticatedUser User;
 
}



Possible improvements

  • Use a secured storage for your service identifiers
  • ...

Authenticate user

Add a first page to the project in order for the user to authenticate himself, right click on your project, select Add => New item Windows Phone Portrait Page, name it LoginPage.xaml

Put 2 fields and 2 buttons to let the user register or sign into the application

        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<StackPanel>
<TextBlock Text="Login" Margin="12,0"/>
<TextBox x:Name="LoginBox"/>
<TextBlock Text="Password" Margin="12,0"/>
<PasswordBox x:Name="PasswordBox"/>
<Button Content="Sign in" Click="LoginButton_Click" />
<Button Content="Register" Click="RegisterButton_Click" />
</StackPanel>
</Grid>

Let's manage the code behind, on button click call create profile service from Buddy or the recover one

        private void RegisterButton_Click(object sender, RoutedEventArgs e)
{
ServiceManager.Client.CreateUserAsync(HandleUser, LoginBox.Text, PasswordBox.Password);
}
 
private void LoginButton_Click(object sender, RoutedEventArgs e)
{
ServiceManager.Client.LoginAsync(HandleUser, LoginBox.Text, PasswordBox.Password);
}
 
private void HandleUser(AuthenticatedUser p_user, BuddyCallbackParams p_params)
{
//check if everything went fine
if (p_params.Exception != null || p_user == null)
{
//Display the buddy error if something went bad
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
MessageBox.Show("Something went wrong " + ((BuddyServiceException)p_params.Exception).Error);
});
}
else
{
//Store the user
ServiceManager.User = p_user;
Debug.WriteLine("Success we got our user");
}
}

Finally ensure that the app navigate on this page first, to do so open the properties folder in the solution explorer and double click on the WMAppManifest.xml

Here on the Application UI tab, replace the Navigation Page: with LoginPage.xaml

Buddy getting started 7.JPG


Possible improvements

  • Create a dedicated page for both register and login
  • Check that fields are properly filled
  • Use a viewmodel
  • Store required variables in order to keep the user logged
  • Handle all possible service errors
  • Add a loading bar
  • ...


Let's try this thing

Buddy getting started 8.png

If you fill the fields and click the button you should see a message in your console stating "Success we got our user", but if you click again on the button then an error will appear.

Let's see what buddy documentation is saying regarding errors returned for this service

Buddy getting started 9.JPG

I guess that's the problem!

Tip.pngTip: Always refer to buddy documentation. It is well written and largely complete.

One last thing, once the user succeeded to register or login, we will navigate to the mainpage of the application, like this

                //Store the user
ServiceManager.User = p_user;
Debug.WriteLine("Success we got our user");
 
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
NavigationService.Navigate(new Uri("/MainPage.xaml",UriKind.Relative));
});

Check in

The next step will be to allow user to check in, meaning send his location to the server with a comment to name his location. To do so will start by modifying the MainPage.xaml and include a Pivot in it with a first PivotItem containing a textbox for the place name and a button

    <phone:Pivot Title="MySocialApp">
<phone:PivotItem Header="Check in">
<StackPanel>
<TextBlock Text="Place name:" Margin="12,0"/>
<TextBox x:Name="CheckInNameBox"/>
<Button Content="Checkin" Click="Checkin_Click"/>
</StackPanel>
</phone:PivotItem>
</phone:Pivot>

It should look like that

Buddy getting started 11.png

Let's have a look at the checkin service provided by buddy As expected it requires a Latitude and Longitude as parameters, to get those value we will request the user location using the new GeoLocation API for WP8 (more about this here)

First thing to do is to allow location usage in your app by adding the proper capability in the WMAppManifest

Go to the capabilities tab and check ID_CAP_LOCATION

Buddy getting started 10.JPG

Now back to the code, request user position asynchronously and then send the check-in to the server

private async void Checkin_Click(object sender, RoutedEventArgs e)
{
string l_name = CheckInNameBox.Text;
Geocoordinate l_coordinate = await GetSinglePositionAsync();
ServiceManager.User.CheckInAsync(HandleCheckin, l_coordinate.Latitude, l_coordinate.Longitude, l_name);
}
 
public async Task<Windows.Devices.Geolocation.Geocoordinate> GetSinglePositionAsync()
{
Windows.Devices.Geolocation.Geolocator geolocator = new Windows.Devices.Geolocation.Geolocator();
Windows.Devices.Geolocation.Geoposition geoposition = await geolocator.GetGeopositionAsync();
return geoposition.Coordinate;
}
 
private void HandleCheckin(Boolean p_result, BuddyCallbackParams p_params)
{
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
if (p_result && p_params.Exception == null)
{
MessageBox.Show("Success");
//we clear the box content
CheckInNameBox.Text = "";
}
else
{
MessageBox.Show("An error occured "+(p_params.Exception as BuddyServiceException).Error);
}
});
}

That was easy wasn't it?


Possible improvements

  • Use the application bar instead of a button
  • Ensure that the location was properly retrieved
  • Check that TextBox content is not empty
  • Create a viewmodel
  • Add a loading bar
  • Handle all possible service errors
  • ...

Retrieve and display user history

Add a new PivotItem in the main page and put a list and a button into it.

You will need to design the list item template in order to directly handle the CheckInLocation object received from service.

<phone:PivotItem Header="History">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Button Content="GetData" Click="GetCheckins_Click"/>
<ListBox Grid.Row="1" x:Name="CheckHistoryListBox" Margin="24,0">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding PlaceName}" FontWeight="Bold"/>
<TextBlock Text="{Binding CheckInDate}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</phone:PivotItem>

Let's retrieve the history using UserAccount Location GetHistory service.

#region Checkin history
 
private void GetCheckins_Click(object sender, RoutedEventArgs e)
{
ServiceManager.User.GetCheckInsAsync(HandleCheckins);
}
 
private void HandleCheckins(List<CheckInLocation> arg1, BuddyCallbackParams arg2)
{
//Assign check list to our listbox
CheckHistoryListBox.ItemsSource = arg1;
}
 
#endregion

You should now see appear all your check-ins in the list after pressing the Refresh data button

Buddy getting started 12.png


Possible improvements

  • Use the ApplicationBar instead of button
  • Autoload data when navigating on the page or pivot item
  • Create a viewmodel
  • Add a loading bar
  • Allow user to see the checkins on a map
  • Handle all possible service errors
  • ...

Add friends

Now let's make this app social, start with the possibility to search for a friend

Add a new PivotItem with a search box and a ListBox for search results

         <phone:PivotItem Header="Search friends">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel>
<TextBlock Text="Friend name:" Margin="12,0"/>
<TextBox x:Name="FriendNameBox"/>
<Button Content="Search" Click="SearchFriend_Click"/>
</StackPanel>
<ListBox Grid.Row="1" x:Name="FriendSearchResultListBox" Margin="12,0" >
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding UserName}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</phone:PivotItem>

Now proceed the search in the code behind using the UserAccount Profile GetFromUserName service

#region Search friends
List<DataContract_PublicUserProfile> m_searchResultList;
 
private void SearchFriend_Click(object sender, RoutedEventArgs e)
{
ServiceManager.Client.Service.UserAccount_Profile_GetFromUserNameCompleted += Service_UserAccount_Profile_GetFromUserNameCompleted;
ServiceManager.Client.Service.UserAccount_Profile_GetFromUserNameAsync(ServiceManager.BUDDY_APP_NAME, ServiceManager.BUDDY_APP_KEY, ServiceManager.User.Token, FriendNameBox.Text);
}
 
void Service_UserAccount_Profile_GetFromUserNameCompleted(object sender, UserAccount_Profile_GetFromUserNameCompletedEventArgs e)
{
ServiceManager.Client.Service.UserAccount_Profile_GetFromUserNameCompleted -= Service_UserAccount_Profile_GetFromUserNameCompleted;
 
m_searchResultList = e.Result.ToList<DataContract_PublicUserProfile>();
FriendSearchResultListBox.ItemsSource = m_searchResultList;
}
 
#endregion

You should now be able to search for a registered user by entering his name.

Buddy getting started 13.png


Possible improvements

  • Use the ApplicationBar instead of button
  • Create a viewmodel
  • Add a loading bar
  • Handle all possible service errors
  • ...


Now that you can retrieve user let's find a way to send them a friend request.

Start by adding a selection changed event handler to the friends' list

                <ListBox Grid.Row="1" x:Name="FriendSearchResultListBox" Margin="12,0" SelectionChanged="FriendSearchResultListBox_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding UserName}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

When user will tap one item in the list, call the dedicated service to Add a friend request , note that this service require a proper User object so you will first have to retrieve it using Find user from ID service

        private void FriendSearchResultListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
 
if (((ListBox)sender).SelectedIndex >= 0)
{
//retrieve target user id
int l_userId = int.Parse(m_searchResultList[((ListBox)sender).SelectedIndex].UserID);
 
//retrieve target user
ServiceManager.User.FindUserAsync((l_searchedUser,args) =>
{
//Once retrieve ensure it is not null, then send the request
if (l_searchedUser != null)
ServiceManager.User.Friends.Requests.AddAsync(HandleFriendRequestCreation, l_searchedUser);
else
{
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
MessageBox.Show("An error occured");
});
}
 
},l_userId);
}
 
//don't forget to reset list index
((ListBox)sender).SelectedIndex = -1;
 
}
 
private void HandleFriendRequestCreation(Boolean p_result, BuddyCallbackParams p_params)
{
if (!p_result)
{
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
MessageBox.Show("An error occured");
});
}
else
{
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
MessageBox.Show("Request sent");
});
}
}

Finally add another PivotItem to list the user's friend requests

        <phone:PivotItem Header="Friend requests">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Button Content="GetData" Click="GetRequests_Click"/>
<ListBox Grid.Row="1" x:Name="FriendRequestListBox" Margin="12,0">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Name}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</phone:PivotItem>

And retrieve the data using FriendRequest Get

#region Friend s Requests
 
List<User> m_requestList;
private void GetRequests_Click(object sender, RoutedEventArgs e)
{
ServiceManager.User.Friends.Requests.GetAllAsync(HandleFriendRequestList);
}
 
private void HandleFriendRequestList(List<User> p_requests, BuddyCallbackParams p_params)
{
if (p_requests == null || p_params.Exception != null)
{
//Display the buddy error if something went bad
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
MessageBox.Show("Something went wrong " + ((BuddyServiceException)p_params.Exception).Error);
});
}
else
{
 
//Store the result in a local list
m_requestList = p_requests;
FriendRequestListBox.ItemsSource = m_requestList;
}
 
}
#endregion
Buddy getting started 14.png

Once again modify the list to handle item selection

 <ListBox Grid.Row="1" x:Name="FriendRequestListBox" Margin="12,0" SelectionChanged="FriendRequestListBox_SelectionChanged">

In the code ask the user if he want to accept or deny the selected request and we will proceed accordingly using the FriendRequest Deny service or the FriendRequest Accept one

        private void FriendRequestListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
 
if (((ListBox)sender).SelectedIndex >= 0)
{
User l_selectedRequestUser = m_requestList[((ListBox)sender).SelectedIndex];
//Ask the user what he want to do with selected request
if (MessageBox.Show("Accept or Deny the request from " + l_selectedRequestUser.Name, "", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
{
//If user accept request
ServiceManager.User.Friends.Requests.AcceptAsync((response, s2) =>
{
//Check the response
Deployment.Current.Dispatcher.BeginInvoke(delegate()
{
if (s2.Exception != null)
MessageBox.Show("Accept Friend Request Error: " + s2.Exception.Message);
else
{
MessageBox.Show("Accept Friend Request Success!");
 
//clear the list to avoid issue, ugly way to handle this
FriendRequestListBox.ItemsSource = new List<User>();
}
});
}, l_selectedRequestUser);
}
else
{
//If user deny request
ServiceManager.User.Friends.Requests.DenyAsync((response, s2) =>
{
//Check the response
Deployment.Current.Dispatcher.BeginInvoke(delegate()
{
if (s2.Exception != null)
MessageBox.Show("Deny Friend Request Error: " + s2.Exception.Message);
else
{
MessageBox.Show("Deny Friend Request Success!");
 
//clear the list to avoid issue, ugly way to handle this
FriendRequestListBox.ItemsSource = new List<User>();
}
});
}, l_selectedRequestUser);
}
}
 
 
//don't forget to reset list index
((ListBox)sender).SelectedIndex = -1;
}


Possible improvements

  • Display a custom message box with accept / deny buttons
  • Handle all possible service errors
  • Add a loading bar
  • Add a view model
  • Remove only the selected item from list instead of clearing it
  • Autoload data when navigating on the page or pivot item
  • ...

See friends location

One last thing to do is to list the friends, that will be pretty similar to getting the friends requests, so just add another PivotItem

    <phone:PivotItem Header="Friends">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Button Content="GetData" Click="GetFriends_Click"/>
<ListBox Grid.Row="1" x:Name="FriendsListBox" Margin="12,0" SelectionChanged="FriendsListBox_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Name}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</phone:PivotItem>

And handle the code behind to retrieve user friends' list using Friends GetList

        List<User> m_friendsList;
private void GetFriends_Click(object sender, RoutedEventArgs e)
{
ServiceManager.User.Friends.GetAllAsync(HandleFriendList);
}
 
private void HandleFriendList(List<User> p_friends, BuddyCallbackParams p_params)
{
if (p_friends == null || p_params.Exception != null)
{
//Display the buddy error if something went bad
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
MessageBox.Show("Something went wrong " + ((BuddyServiceException)p_params.Exception).Error);
});
}
else
{
//Store the result in a local list
m_friendsList = p_friends;
FriendsListBox.ItemsSource = m_friendsList;
}
 
}
Buddy getting started 15.png

Now add the possibility to see the last position of a friend on a map, to do so create a new page named MapPage.xaml.

This page will contain a Windows Phone 8 map control and should look like this

<phone:PhoneApplicationPage 
xmlns:Controls="clr-namespace:Microsoft.Phone.Maps.Controls;assembly=Microsoft.Phone.Maps"
x:Class="MySocialApp.MapPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
mc:Ignorable="d"
shell:SystemTray.IsVisible="True">
 
<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock x:Name="NameTextBlock" Margin="24,0" FontSize="48"/>
<Controls:Map Grid.Row="1" x:Name="FriendMap" ZoomLevel="16"/>
</Grid>
 
</phone:PhoneApplicationPage>

Don't forget to check the ID_CAP_MAP in your WMAppManifest.xml if you want to be able to use it.

Create a DataTemplate to design the way the friend will be displayed on map.

   <phone:PhoneApplicationPage.Resources>
<DataTemplate x:Name="PinTemplate">
<StackPanel>
<Grid Background="Black">
<TextBlock Text="{Binding}" Foreground="White" Margin="6"/>
</Grid>
<Path Data="M 0,0 L 0,0 0,14 14,0" Fill="Black" UseLayoutRounding="False" />
</StackPanel>
</DataTemplate>
</phone:PhoneApplicationPage.Resources>

Retrieve the friend data from the navigation context by overriding the onNavigatedTo() method, and create a new MapOverlay which will represent our friend using the previously defined template

        protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (NavigationContext.QueryString.ContainsKey("lat") && NavigationContext.QueryString.ContainsKey("lon") && NavigationContext.QueryString.ContainsKey("name"))
{
double l_lat = double.Parse(NavigationContext.QueryString["lat"], CultureInfo.CurrentCulture);
double l_lon = double.Parse(NavigationContext.QueryString["lon"], CultureInfo.CurrentCulture);
string l_name = NavigationContext.QueryString["name"];
GeoCoordinate l_friendCoordinate = new GeoCoordinate(l_lat, l_lon);
FriendMap.Center = l_friendCoordinate;
MapLayer l_layer = new MapLayer();
l_layer.Add(new MapOverlay() { Content = l_name, GeoCoordinate = l_friendCoordinate, ContentTemplate = PinTemplate, PositionOrigin = new Point(0, 1) });
FriendMap.Layers.Add(l_layer);
 
NameTextBlock.Text = l_name;
}
base.OnNavigatedTo(e);
}

Finally add the navigation with proper parameters in the MainPage, when a list item is selected on the friend list

   private void FriendsListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (((ListBox)sender).SelectedIndex >= 0)
{
User l_friend = m_friendsList[((ListBox)sender).SelectedIndex];
NavigationService.Navigate(new Uri("/MapPage.xaml?lat=" + l_friend.Latitude+"&lon="+l_friend.Longitude+"&name="+l_friend.Name, UriKind.Relative));
}
((ListBox)sender).SelectedIndex = -1;
}

You should now be able to see the map with the friend on it and it should look like this

Buddy getting started 16.png


Possible improvements

  • Check that friends location is not null or 0
  • Handle all possible service errors
  • Autoload data when navigating on the page or pivot item
  • Add a loading bar
  • Add a view model
  • ...

Buddy services pro/con

Pro

  • Easy to use
  • Perfectly integrated with Windows phone
  • Good documentation
  • Lot of Windows phone examples
  • Notification management
  • Pretty flexible thanks to metadata
  • 500 000 free Api calls each month

Con

  • But you'll need to pay if you want more or the service will stop to work
  • Need to rely on a third party for your services
  • Some services does not seem to work (e.g. Delete friend will delete all user friends)
  • No forums to exchange
  • Hard to impossible to get answer to your questions
This page was last modified on 9 February 2014, at 09:31.
295 page views in the last 30 days.
×