пятница, 29 октября 2010 г.

wFace – windows phone 7 facebook integration part 1

Published: 31 Aug 2010
By: Manfred Pohler

This article shows how to use the Facebook graph_API (http://developers.facebook.com/docs/API) in a windows phone 7 (wp7) Silverlight application. All used tools are free software - for downloads take a look at the links at the end of this document.

Contents [hide]
  • 2 Facebook integration - a closer look
  • 3 Create the wp7 application in Visual Studio 2010 (Express)
  • 4 Authentication - a deeper look
  • 5 Our start page
  • 6 The Login Page
  • 7 Resources
  • The wFace – windows phone 7 facebook integration Series

    This article series shows how to use the Facebook graph_API (http://developers.facebook.com/docs/API) in a windows phone 7 (wp7) Silverlight application. All used tools are free software - for downloads take a look at the links at the end of this document.

  • Part1
  • Part2
  • The Idea behind

    This article shows how to use the Facebook graph_API (http://developers.facebook.com/docs/API) in a windows phone 7 (wp7) Silverlight application. All used tools are free software - for downloads take a look at the links at the end of this document.

    We made a .NET iPhone application using MonoTouch. The thing is a Rock Paper Scissors game (RPS).

    A well known game I would say. The special thing about our implementation is a tight Facebook integration.We hold a game server to store high-scores and allow internet playing. Instead of handling user management ourselves we use Facebook to do this.

    Further we post results (new rank reached, game won / lost) on the user's Facebook wall.

    Since the code is .NET it looks as if a port from iPhone to wp7 is an easy task. But there are some problems and differences between the two platforms. A part of the problems may disappear after wp7 (beta at the moment) reaches RTM.

    The sample - and what’s missing

    This sample consists of two parts. In part one I'll cover authentication. Part2 will be about data retrieval posting data to Facebook.

    Missing things:

    • UIX. I'll use simple stiles to focus on content. The nature of Silverlight projects allows you to make the things looking cool without the need to "recode" anything.
    • Excessive Error handling. In a real world application there would be "error pages" which provide meaningful user information. In this project we just show the plain error messages.

    Prerequisites

    To build / run the project you'll need:

    • The Windows phone developer tools (free)http://developer.windowsphone.com/
    • A Facebook account
    • A Facebook application. You can create an application here: http://www.facebook.com/developers/ . I'll explain later how to setup an application.
    • Some experiences with Silverlight and .NET development. I'll only focus wp7 specific Silverlight topics. There are tons of good Silverlight articles on the web to get the basics.

    The “project”

    Our project will have 2 screens, one "Main Screen" and a "Login Screen". In wp7 such screens are (there are other options to) "Pages".

    Facebook integration - a closer look

    The Facebook application

    A Facebook application is a piece of information which interacts with the user. There are different types of application but they share some common information.

    First of all (and primarily important for us) imagine a Facebook application as a kind of contract between you (the developer) and the user (Facebook account owner). You identify yourself via properties of the application and further (via code) you ask for permissions.

    In our case we want to several things:

    • We want to get some information from the users profile
    • We want to post in the name of the user

    Authentication

    The steps (from the user's perspective) look like this.

    • Our application sends the users to the Facebook login page. Assume the users enters valid credentials there.
    • The user is redirected to the "application permissions" page http://developers.facebook.com/docs/authentication/
    • The user is redirected to a special page. At this point we get some kind of credentials for further use. This is a "token" which we further use to make calls to the Facebook API.

    Creating your Facebook application

    To create your first Facebook application login with your Facebook account and visit http://www.facebook.com/developers/ - this is an application and you see a dialog as explained in paragraph 2 above.

    Figure 1: Developer Application Permissions

    Developer Application     Permissions

    After you allow the application access to your Facebook account you'll be redirected to the developers home page. Near the top (right side in main content) is a button "+Set up new application". Click this to create a new application.

    Figure 2: Create application part 1

    Create application part 1

    Enter a unique Name and click "Create Application". An error may occur - ignore it (if it is not "Name not allowed") and follow the next steps.

    Go back to http://www.facebook.com/developers/ and notice that below the "+Set up new application" button is a list of your applications. Click on your newly created application and make a note of the two fields "Application ID" and "Application Secret". You need these two values later in your wp7 application.

    Figure 3: Application Settings

    Application Settings

    IMPORTANT: those two values are confidential! Do not post them like I do here. I'll use this application for the article and delete it later. So again: please do never publish these values!

    NOTE

    Do not change the application settings (unless you know how the things work) - the default is perfect to use it in this sample.

    Create the wp7 application in Visual Studio 2010 (Express)

    Create a new project

    Don't worry - later I'll explain in more details what's going on behind the scenes. But at the moment just follow this guide. Select "File/New Project" from the menu to get the following dialog:

    Figure 4: New Project Dialog

    New Project Dialog

    In this case we use a simple "Windows Phone Application". Select a directory and give the thing a meaningful name. In the next step you should see a XAML file and a preview of your application.

    Authentication - a deeper look

    How it works

    Facebook uses OAuth 2.0 -the details are described here http://developers.facebook.com/docs/authentication/.

    Normally we would use "Desktop authentication" http://developers.facebook.com/docs/authentication/desktop but due to a bug in the wp7 beta bits we have to take a different approach.

    In simple words the things work like this: we provide the user a webpage (the page comes from Facebook) and there he enters his credentials. We'll never get access to the credential values. Further we pass our "Application ID" (see above) to this page and last not least we inform the page about the access we need.

    The user enters his credential and Facebook redirects him to a page where the user must allow our application to access the properties / operations. There are a lot of possible values for allowance. You can find them on this page: http://developers.facebook.com/docs/authentication/permissions.

    You may notice a "publish_stream" value which is important for us to post on the users wall. And we (just to show "extended profile permissions") will also ask for "home_town".

    After this we will get an "access_token" which has to be passed to every API call we make.

    Our “desktop application” login page

    From what we have learned on the desktop authentication page we need the following URL to provide the user with the appropriate login page:

    The base URL including our "Application ID"

    https://graph.facebook.com/oauth/authorize?client_id=10181612...

    next the "special redirect url"

    &redirect_uri=http://www.facebook.com/connect/login_success.html

    followed by the application type (determines how login works)

    &type=user_agent

    further the layout of the page (touch or wap) is OK for devices

    &display=touch

    and finally the privileges we need

    &scope=publish_stream,user_hometownFacebook

    The last step

    After everything was ok we will be redirected to success page and retrieve the access token http://www.facebook.com/connect/login_success.html#access_token=...&expires_in=... This kind of information (parameter) passing is known as "fragment".

    Bug in wp7 beta

    Unfortunately there is a bug in the wp7 beta which suppresses this value. Here are the details:

    http://social.msdn.microsoft.com/Forums/en- US/windowsphone7series/thread/b13d9acc-ddfa-4235-8de8-3ebb440b7fa2

    So we have to take a different approach. This is a bit more complicated - but in general it is the same approach. We need to use the "Web application authentication" as described here: http://developers.facebook.com/docs/authentication/

    It is almost the same as the "desktop authentication" except of 3 differences.

    • We do not set the type to "user_agent". No problem at all - we just don't pass the type parameter
    • We have to pass our "application secret". This is the real problem - normally we would never give a user access to this value. With web application it doesn't matter - the value never leaves our web server. But for client applications we have to "ship" this value inside our application.
    • We have to make an extra call to get the "access token". We will do this in a very simple manner - no problem at all

    Anyhow - this is a workaround so I hope with the wp7 RTM we'll no longer have a need for this.I also use the "special desktop authentication return URL" - it works also in our case.I'll include the "bug free" code in this sample - so if the bug is gone you'll already have to uncomment it.

    Our start page

    Silverlight differences to other platforms

    Wp7 Silverlight is some kind of Silverlight 3.0 with extra controls and some (a lot?) missing features compared to the "full version".

    We have special support for the application lifetime (state storage, extra events), access to hardware features (GPS, accelerator, Phone, ...) and the control set is different.

    Important for our case - we have a "PhoneApplicationPage" and a navigation framework.

    Both things are already included in the template - so we just have to use them. The most basic controls (Grid, Button, Text..., StackPanel, Image, ...) do also exist; so we don't take too much care about it and simply start coding our project.

    The navigation framework

    This framework provides us with the ability to navigate through our pages. The typical behavior is to open a page via a control (Button, List element ...) and leave it with the "Back Button" - a piece of hardware which every windows phone 7 device provides.

    Screen orientation

    In general there are three possible orientations (unfortunately "reverse portrait" which exists on the iPhone is missing) - portrait, landscape left and landscape right.

    In our sample we'll only use landscape but the idea behind supporting different orientations is either a "fluid layout" or some "rearrange code".

    Basic layout

    "Metro Style applications" should have a common look and feel. On part of it is the information provided on top of a page. It consists of an application title and a page title. Both elements do already exist in the template so (if you want) simply change these values.

    Notice there is a grid "LayoutRoot" which holds a StackPanel (the titles) and a second grid "ContentGrid" where we'll place our content.

    Time to code

    You can simply copy and paste the following XAML to your application. BUT - notice that you'll not have the used event handlers in your code behind (this results in XAML errors). Either ignore them (we'll add the handlers soon) or got into XAML - delete the name of the handler, type a blank and intellisense will ask you to create a handler for you.

    01.<Grid x:Name="ContentGrid" Grid.Row="1">
    02.    <Grid.RowDefinitions>
    03.        <RowDefinition Height="Auto"/>
    04.        <RowDefinition Height="*"/>
    05.        <RowDefinition Height="Auto"/>
    06.    </Grid.RowDefinitions>
    07.    <Grid x:Name="fbUserGrid" Grid.Row="0">
    08.        <Grid.ColumnDefinitions>
    09.            <ColumnDefinition Width="105"/>
    10.            <ColumnDefinition Width="*"/>
    11.        </Grid.ColumnDefinitions>
    12.        <Grid.RowDefinitions>
    13.            <RowDefinition Height="Auto"/>
    14.            <RowDefinition Height="60"/>
    15.            <RowDefinition Height="Auto"/>
    16.            <RowDefinition Height="Auto"/>
    17.        </Grid.RowDefinitions>
    18.        <TextBlock Text="User Data" Grid.ColumnSpan="2" TextAlignment="Center"/>
    19.        <Image Source="{Binding Path=PictureLink}" Grid.Row="1"  Stretch="None" VerticalAlignment="Center" />
    20.        <TextBlock Text="{Binding Path=Name}" Grid.Row="1" Grid.Column="1" VerticalAlignment="Center"/>
    21.        <TextBlock Text="Gender" Grid.Row="2"/>
    22.        <TextBlock Text="{Binding Path=Gender}" Grid.Row="2" Grid.Column="1"/>
    23.        <TextBlock Text="Hometown" Grid.Row="3"/>
    24.        <TextBlock Text="{Binding Path=HomeTown.Name}" Grid.Row="3" Grid.Column="1"/>
    25.    </Grid>
    26.    <StackPanel Grid.Row="2">
    27.        <Button x:Name="btnLogin" Click="btnLogin_Click" Content="Login to facebook" />
    28.        <Button x:Name="btnGetUserData" Click="btnGetUserData_Click" Content="Load User Data" IsEnabled="False" />
    29.        <Button x:Name="btnPostToWall" Click="btnPostToWall_Click" Content="Post to wall" IsEnabled="False" />
    30.        <Button x:Name="btnShowFriends" Click="btnShowFriends_Click" Content="Show Friends" IsEnabled="False" />
    31.        <TextBlock x:Name="txtStatus" Text="Login to enable facebook funtions" Style="{StaticResource PhoneTextNormalStyle}" />
    32.        <TextBlock Height="80" TextWrapping="Wrap" x:Name="txtError" Text="OK" Style="{StaticResource PhoneTextAccentStyle}" />
    33.    </StackPanel>
    34.</Grid>

    Figure 5: Layout provided by this xaml

    Layout provided by this xaml

    The buttons "Load User Data", "Post to wall" and "Show friends" will be handled in part 2 of this article series. Here we'll focus on Login.

    Navigate to the top of your XAML (place the cursor there) and via "Properties / Events" add a page loaded event handler.

    So after all we have layout the loaded event handler and our button handlers. This is the code:

    01.private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e) {
    02.}
    03.private void btnLogin_Click(object sender, RoutedEventArgs e) {
    04.}
    05.private void btnGetUserData_Click(object sender, RoutedEventArgs e) {
    06.}
    07.private void btnPostToWall_Click(object sender, RoutedEventArgs e) {
    08.}
    09.private void btnShowFriends_Click(object sender, RoutedEventArgs e) {
    10.}

    Our approach is to load the "Login page" which shall (after a successful login) provide us with the "access_token" we need for further calls to the Facebook API.

    Understanding navigation

    Although you can provide your own navigation framework we'll use the built in one. This works by removing the current page and loading the page we are navigating to.

    Or in other words - every page is created from scratch when we navigate to it. This is also true for the calling page. So navigating to PGLogin.xaml and coming back to the main page after login means:

    • MasterPage is destroyed
    • PGLogin is created (loaded event)
    • PGLogin is destroyed
    • MasterPage is created (loaded event)

    The problem now - how to pass parameters to / from PGLogin. The navigation framework works pretty much like HTML navigation, so we can pass "Query strings" and retrieve them in a special event: OnNavigatedTo

    Controls are not loaded in OnNavigatedTo

    Be aware that controls are not fully loaded in this handler. So for an example a "webBrowser.Navigate" will fail with an exception "must be fully loaded before you navigate..."

    In our case we'll take a different approach - we'll keep the shared information (access_token) in a global static variable. The best place for this is App.xaml.cs (the code behind App.xaml).

    Select App.xaml in the Solution Explorer, right click it an choose View Code (F7). Add the following code;

    1.#region AccessToken
    2.private static string m_strAccessToken;
    3.public static string AccessToken {
    4.    get { return m_strAccessToken; }
    5.    set { m_strAccessToken = value; }
    6.}
    7.#endregion

    Save and close the file.

    Next let us navigate to our Login page - I assume you named it (like shown above) PGLogin.xaml.In MainPage.xaml.cs change the login button handler to:

    1.private void btnLogin_Click(object sender, RoutedEventArgs e) {
    2.    NavigationService.Navigate(new Uri("/PGLogin.xaml", UriKind.Relative));
    3.}

    What are we doing here? We use the Navigation service and tell it to navigate to our login page. We don't care about coming back - you remember - this is done via the "Back Button" on our windows phone 7 device.

    Before we first run the application we will simulate a login. This has two reasons - first it is time to see something going on - second this will show how we can intercept the "Back Button navigation".The reason for doing this could (for an example) be a data entry form where we detect changed data, and ask if the user wants to save the changed data before he leaves the page.

    Open PGLogin.xaml - place the cursor on top of the xaml and via "Properties / Events" add a handler for the BackKeyPressEvent. Add the following code to the handler.

    1.private void PhoneApplicationPage_BackKeyPress(object sender, System.ComponentModel.CancelEventArgs e) {
    2.    App.AccessToken = "TOKEN_SET";
    3.}

    The only thing left is some kind of "Logged in signal" on our main page.Did you notice the text (second line from the bottom) on our Main page? "Login to enable..."

    So let's enable the buttons. Change the page loaded event handler to:

    1.private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e) {
    2.    bool bWeAreLoggedIn = !string.IsNullOrEmpty(App.AccessToken);
    3.    btnLogin.IsEnabled=!bWeAreLoggedIn; //reverse logic
    4.    btnGetUserData.IsEnabled = bWeAreLoggedIn;
    5.    btnPostToWall.IsEnabled = bWeAreLoggedIn;
    6.    btnShowFriends.IsEnabled = bWeAreLoggedIn;
    7.    txtStatus.Text=bWeAreLoggedIn ? "Use the above buttons to access facebook" : "Login to enable facebook funtions";
    8.}

    Run your application and check if the things work like expected. They should, if you didn't make a copy and paste error.

    The Login Page

    The best things come in threes

    As on the main page we'll add 2 informational controls on the bottom of the page. And as real content we need a WebBrowser Control. Replace you PGLogin Content grid with the following markup:

    01.<Grid x:Name="ContentGrid" Grid.Row="1">
    02.    <Grid.RowDefinitions>
    03.        <RowDefinition Height="*"/>
    04.        <RowDefinition Height="Auto"/>
    05.    </Grid.RowDefinitions>
    06.    <phone:WebBrowser x:Name="wbLogin" IsScriptEnabled="True" />
    07.    <StackPanel Grid.Row="1" >
    08.        <TextBlock x:Name="txtStatus" Text="Loading login page" Style="{StaticResource PhoneTextNormalStyle}" />
    09.        <TextBlock Height="80" TextWrapping="Wrap" x:Name="txtError" Text="OK" Style="{StaticResource PhoneTextAccentStyle}" />
    10.    </StackPanel>
    11.</Grid>
    Remove the BackKeyPress handler from PGLogin.xaml

    This is important else it would override our access_token.

    Notice that I set IsScriptEnabled to true on the WebBrowser control. The Facebook pages use a lot of scripts and by default scripting is disabled. So in order to have functional pages we need to enable it.

    URLs URIs and more

    The whole Facebook API access is done via "web links". Silverlight wants to have URIs instead of URLs (strings). And we'll need a lot of them. So I decided to create a helper class which provides those URIs.Since we'll need other helper classes for part 2 of this article series I first add a folder to the solution, so the things are better organized. Right click you project in Solution Explorer and add a folder call "HelperClasses".

    Next right click this folder, choose "Add / Class" and add FBUris to the project. The project should now look like this:

    Figure 6: Project tree

    Project tree

    Our FBUris class will provide us with well formatted URIs. I decided to make the class static.

    01.public static class FBUris {
    02.    #region AppID
    03.    private static string m_strAppID = "101816123213455";
    04.    #endregion
    05.    #region AppSecret - only needed because of the fragment bug
    06.    private static string m_strAppSecret = "a96c7b28c49664b12a5fe8a1555388b3";
    07.    #endregion
    08.    //the correct url - but not working due to the WebBrowser fragment bug
    09.    //private static string m_strLoginURL = "https://graph.facebook.com/oauth/authorize?client_id={0}
    10. 
    11.&redirect_uri=http://www.facebook.com/connect/login_success.html&type=user_agent&display=touch&scope=publish_stream,user_hometown";
    12.    private static string m_strLoginURL = "https://graph.facebook.com/oauth/authorize?client_id={0}
    13. 
    14.&redirect_uri=http://www.facebook.com/connect/login_success.html&display=touch&scope=publish_stream,user_hometown";
    15.    private static string m_strGetAccessTokenURL = "https://graph.facebook.com/oauth/access_token?client_id={0}
    16. 
    17.&redirect_uri=http://www.facebook.com/connect/login_success.html&client_secret={1}&code={2}";
    18.    public static Uri GetLoginUri() {
    19.        return (new Uri(string.Format(m_strLoginURL, m_strAppID), UriKind.Absolute));
    20.    }
    21.    public static Uri GetTokenLoadUri(string strCode) {
    22.        return (new Uri(string.Format(m_strGetAccessTokenURL, m_strAppID, m_strAppSecret, strCode), UriKind.Absolute));
    23.    }
    24.}
    Please ensure that you use your own application Id and application secret

    The used values are no longer valid - I deleted the application.

    Don't take too much care about the TokenLoadUri and GetAccessTokenURL - I told you above, that we need a third step to retrieve the access_token since we have to use "web authenticate". I'll explain this later when it takes place in our code. Notice also that I provided the "not bugged" URL as comment.

    The rest is pretty simple - the changing parts of our URLs are marked as "string format placeholders" {x} so that we can pass these values as parameters.

    Now that we have got our "navigation addresses" (URIs) easily use them in our code. The first thing we want to do is to load the Facebook login page into our WebBrowser control. A good place to do this is the PageLoaded event handler. Add a Loaded event handler to PGLogin and change it to:

    1.private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e) {
    2.    wbLogin.Navigate(FBUris.GetLoginUri());
    3.}

    When you run the application our login page should look like this:

    Figure 7: Empty login form

    Empty login form

    After entering your credentials, click login and you'll be redirected to the "application permissions" page:

    Figure 8: Application asking for permissions

    Application asking for     permissions

    Scroll down (drag content) and you'll find the "allow / Don't allow" buttons. Don't press a button now - just close your application.

    You see, it was pretty easy to get this going - now comes the (a bit) harder part. In a "bug free" situation the things are easier - but we have to do a bit more.

    Reading the Facebook documentation (in this case for Web-Login) we learn that

    If the user authorizes your application, we redirect the user back to the redirect URI you specified with a verification string in the argument code, which can be exchanged for an oauth access token.Exchange it for an access token by fetching https://graph.facebook.com/oauth/access_token.Pass the exact same redirect_uri as in the previous step:…

    So (for a web application) this means to place the "redirect URL" to a page at your site where you check and use the parameter sent to the page. But we have no web server - we have a windows phone browser control.

    No problem at all - remember we set a (stolen from desktop authentication) special URL. All we have to check is when the user (the browser via redirections) reaches this page. Then we should find the "code" in the URL of that page. Our "special page" was http://www.facebook.com/connect/login_success.html and it should have a "code" parameter set. So the final URL would look something like: http://www.facebook.com/connect/login_success.html?code=...

    Fortunately there is an event when the WebBrowser control loaded a page. Goto XAML of PGLogin, locate the WebBrowser Control and inside the tag type LoadCompleted= - which brings up intellisense and allows you to add an event handler. The LoadCompleted event fires when the WebBrowser finished loading a page.

    This event handler has a parameter of the type "System.Windows.Navigation.NavigationEventArgs". This class has a property called Uri - which represents the address (and parameters) of the page the browser loaded.

    Bug free version

    Here we would get http://www.facebook.com/connect/login_success.html#access_token=...

    We could simply use the "Fragment" property of the Uri to check for the presences of such an address.

    If it is there we parse the fragment - and get our access_token - done.

    To get the "bugged" version going we simply check if we reach an address that starts with the expected value and behind this the "code" can be found. So the handler should look like this:

    1.private void wbLogin_LoadCompleted(object sender, System.Windows.Navigation.NavigationEventArgs e) {
    2.    string strLoweredAddress = e.Uri.OriginalString.ToLower();
    3.    if(strLoweredAddress.StartsWith("http://www.facebook.com/connect/login_success.html?code=")) {
    4.        txtStatus.Text = "We got the code";
    5.        txtError.Text = e.Uri.OriginalString.Substring(56);
    6.        return;
    7.    }
    8.}

    For the first step we just display a message that we got the code - and in the last line (blue one) of our form we display the code itself. There is no need to lower the URL - but I prefer this. Maybe Facebook decides to forward to the same URL with different casing...

    Web authentication get’s a code and has to change this to an access token

    As I told above there is an extra step to obtain an access_token needed with workaround. This is how it works.

    The code is no help at all for us. For web applications to retrieve the (needed) access_token it requires an extra step which must provide the applications secret and the (just received) code.

    In the class FBUris we already have a method which builds this request for us. The URL looks like this:

    First again a URL where we pass our application ID

    https://graph.facebook.com/oauth/access_token?client_id={0}

    then we must provide the exactly same URL as in the call before as redirect

    &redirect_uri=http://www.facebook.com/connect/login_success.html

    further we must provide our application secret

    &client_secret={1}

    the last parameter is the code we got from the previous call

    &code={2}

    Again we change our LoadCompleted handler now to:

    1.private void wbLogin_LoadCompleted(object sender, System.Windows.Navigation.NavigationEventArgs e) {
    2.    string strLoweredAddress = e.Uri.OriginalString.ToLower();
    3.    if(strLoweredAddress.StartsWith("http://www.facebook.com/connect/login_success.html?code=")) {
    4.        txtStatus.Text = "Trying to retrieve access token";
    5.        wbLogin.Navigate(FBUris.GetTokenLoadUri(e.Uri.OriginalString.Substring(56)));
    6.        return;
    7.    }
    8.}

    This means we load a different page and this will also redirect to http://.../connect/login_success.htm

    Instead of sending the access_token as a parameter this value is passed as content of the page. So we could also use a web request to do this. But since the browser is already there we'll use this guy to do the job.

    So again we check for this page - but this time without the parameter ?code=…

    When we find it we access the page content and parse it for the access_token. The content of the page looks something like <HTML><BODY><PRE>access_token=….</PRE></BODY…

    01.private void wbLogin_LoadCompleted(object sender, System.Windows.Navigation.NavigationEventArgs e) {
    02.    string strLoweredAddress = e.Uri.OriginalString.ToLower();
    03.    if(strLoweredAddress.StartsWith("http://www.facebook.com/connect/login_success.html?code=")) {
    04.        txtStatus.Text = "Trying to retrieve access token";
    05.        wbLogin.Navigate(FBUris.GetTokenLoadUri(e.Uri.OriginalString.Substring(56)));
    06.        return;
    07.    }
    08.    string strTest = wbLogin.SaveToString();
    09.    if(strTest.Contains("access_token")) {
    10.        int nPos = strTest.IndexOf("access_token");
    11.        string strPart = strTest.Substring(nPos + 13);
    12.        nPos = strPart.IndexOf("</PRE>");
    13.        strPart = strPart.Substring(0, nPos);
    14.        App.AccessToken = strPart;
    15.        //automaticall leave the page after login success
    16.        //NavigationService.GoBack();
    17.        txtStatus.Text = "Authenticated - use back to see results";
    18.        txtError.Text = "OK";
    19.        return;
    20.    }
    21.}

    The final code has a commented option. In fact it could be a good idea to just bring the user away from this page to where he came from (NavigationServices.GoBack()). So PGLogin would act like a login dialog which closes when the login is done.

    Let's make a change in the MainPage Loaded event handler. It will display the access_token instead of "OK".

    01.private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e) {
    02.    bool bWeAreLoggedIn = !string.IsNullOrEmpty(App.AccessToken);
    03.    btnLogin.IsEnabled = !bWeAreLoggedIn;   //reverse logic
    04.    btnGetUserData.IsEnabled = bWeAreLoggedIn;
    05.    btnPostToWall.IsEnabled = bWeAreLoggedIn;
    06.    btnShowFriends.IsEnabled = bWeAreLoggedIn;
    07.    txtStatus.Text = bWeAreLoggedIn ? "Use the above buttons to access facebook" : "Login to enable facebook funtions";
    08.    txtError.Text = bWeAreLoggedIn ? App.AccessToken : "OK";
    09.}

    This ends part one of the article series. In part two we will retrieve and send data using the Facebook API.

    Resources

    Комментариев нет:

    Linux.org.ru News

    Вебпланета - все новости

    CNews - Издание о высоких технологиях