酢ろぐ!

カレーが嫌いなスマートフォンアプリプログラマのブログ。

Facebookへ投稿をしよう!〜Facebook C# SDKの導入と認証〜

Windows Phone Advent Calendar "ひとり" 2011」と「Windows Phone Advent Calendar」第8日目です。

少しSilverlight for Windows Phone ToolkitのTipsから離れて、これから数日間Windows Phoneでソーシャルネットサービス方面の機能を強化する方法をご紹介していきたいと思います。

改めて語る必要はないと思いますが、Windows Phoneは、ソーシャルネットワーキングサービス(以後、SNS)方面を強化したOSになっています。しかしながら複数のサービスにシンプルに対応するために、各サービス単位でみるとサポートされていない機能があります。
Windows Phone OS 7.1で採用されている機能は、ShareLinkTask APIとShareStatusTask APIを使ったステータスの共通とウェブサイトへのリンクの共通に留まっています。

これから数日間、SNSの代表格でもあるTwitterとFacebookの機能にアクセスしやすくするライブラリの導入と認証についてご紹介させて頂きます。

今回はFacebookにアクセスしやすくするライブラリの導入と認証についてご紹介させて頂きます。

Facebookのアプリケーション登録

FacebookのAPIを使用するには、まずFacebook側でアプリケーションの登録が必要です。Facebookの開発者サイトのURLは以下の通りです。

https://developers.facebook.com/apps

Facebook の開発者サイトを開くと、下図のようなダイアログが表示されます。「許可する」をクリックしてください。

右上に表示されている「新しいアプリケーションを作成」をクリックします。

新しいアプリケーションの登録ダイアログが表示されるので、App Display Nameの欄に使用したいアプリケーションの名前を登録してください。利用規約を読んだうえで、I agree to the Facebook Platform Policiesにチェックをつけて「続行」をクリックします。
ここではch3cooh_testというアプリ名を付けたこととします。


次に基本設定画面が表示されるので、App IDとApp Secretのキーを控えておいてください。FacebookのAPIを使用する際に、このアプリケーションキーとシークレットキーの二つが必要となります。

次にアプリケーションとFacebookの連携を行うために、左側に表示されているメニューから詳細設定を選択します。

Facebook APIを使用するにはアプリケーションキーとシークレットキーの他に、アクセストークンというものが必要になります。ユーザーからアプリケーションからFacebookへのアクセスが許可されるとアクセストークンが発行されるのですが、これを受け取るためにApp Typeの設定を「Navite/Desktop」に変更します。

他の項目も下図を参照して頂いて、必要に応じて変更しておいてください。

以上でFacebookへのアプリケーション登録準備は完了です。

Facebook C# SDKの導入

Facebook C# SDKは、Facebookとクライアント間でのOAuth認証やウォールへのステータスやリンクの投稿、友達リストの取得など様々な機能を簡単に扱えるようにしたSDKです。

ここでは別段取り上げませんが、ASP.NET MVCやデスクトップでのWPFなどでも同じ使い勝手で利用できるそうです。

http://facebooksdk.codeplex.com/

右にダウンロードページへのリンクがありますので、ダウンロードしておきます。執筆時点の最新ビルドのv5.3.2での使用方法についてご説明させて頂きます。

ビルド済みのアセンブリファイルがZIPファイルで提供されているので、任意のフォルダに解凍しておきましょう。解凍するとWindows Phone向けのビルドが「sl3-wp」フォルダには以下の3ファイルが格納されています。

  • Facebook.dll
  • Facebook.pdb
  • Facebook.xml

このファイルを自分のプロジェクトのフォルダに追加しておきます。

これらのファイルを自分のプロジェクトに移動し、参照の追加をおこなってください。

Facebookの認証

実際にウォールへの投稿などのFacebookのAPIを利用する前段階として、今作っているサンプルアプリケーションから、Facebookへアクセスしても良いのかをユーザーに許可してもらう必要があります。

何はともあれ許可する前に、ユーザーにFacebookにログインしてもらう必要があります。Facebook C# SDKの場合、ウェブブラウザ上でログインしますので、画面(MainPage.xaml)にはWebBrowserコントロールを用意しています。

最終的にアクセストークンを含んだURLへ遷移するのですが、その遷移にはJavaScriptを使用しているようです。WebBrowserコントロールのIsScriptEnabledプロパティを有効にしておくのを忘れないでください。

XAML

Facebookのログインに必要なのはウェブブラウザだけですので、Navigatedイベントハンドラの定義と、IsScriptEnabledプロパティをTrueに設定します。

  <phone:WebBrowser Name="webBrowser" Navigated="webBrowser_Navigated" Grid.ColumnSpan="2" IsScriptEnabled="True" />

取得したアクセストークンやログインしたユーザー名を表示させるTextBlockも用意しています。後程使用します。

<phone:PhoneApplicationPage 
    x:Class="FacebookTest.MainPage"
    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"
    mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="696"
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}"
    SupportedOrientations="Portrait" Orientation="Portrait"
    shell:SystemTray.IsVisible="True">

    <Grid x:Name="LayoutRoot" Background="Transparent">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition/>
        </Grid.RowDefinitions>

        <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
            <TextBlock x:Name="ApplicationTitle" Text="SOFTBUILD" Style="{StaticResource PhoneTextNormalStyle}"/>
            <TextBlock x:Name="PageTitle" Text="FacebookTest" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
        </StackPanel>

        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
        	<Grid.ColumnDefinitions>
        		<ColumnDefinition Width="0.329*"/>
        		<ColumnDefinition Width="0.671*"/>
        	</Grid.ColumnDefinitions>
        	<Grid.RowDefinitions>
        		<RowDefinition Height="0.8*"/>
        		<RowDefinition Height="0.1*"/>
        		<RowDefinition Height="0.1*"/>
        	</Grid.RowDefinitions>
            <phone:WebBrowser Name="webBrowser" Navigated="webBrowser_Navigated" Grid.ColumnSpan="2" IsScriptEnabled="True" />
            <TextBlock Grid.Row="1" TextWrapping="Wrap" Text="AccessToken" d:LayoutOverrides="Width" VerticalAlignment="Center" Margin="12,0,0,0"/>
            <TextBlock Grid.Row="2" TextWrapping="Wrap" Text="Name" VerticalAlignment="Center" Margin="12,0,0,0"/>
            <TextBlock x:Name="textAccessToken" HorizontalAlignment="Left" Grid.Row="1" TextWrapping="Wrap" VerticalAlignment="Center" Margin="8,0,0,0" Grid.Column="1"/>
            <TextBlock x:Name="textName" HorizontalAlignment="Left" Grid.Row="2" TextWrapping="Wrap" VerticalAlignment="Center" Margin="8,0,0,0" Grid.Column="1"/>
        </Grid>
    </Grid>

    <phone:PhoneApplicationPage.ApplicationBar>
        <shell:ApplicationBar IsVisible="True" IsMenuEnabled="True">
            <shell:ApplicationBarIconButton IconUri="/icons/appbar.share.rest.png" Text="Update Statues"/>
            <shell:ApplicationBarIconButton IconUri="/icons/appbar.upload.rest.png" Text="Upload"/> 
        </shell:ApplicationBar>
    </phone:PhoneApplicationPage.ApplicationBar>

</phone:PhoneApplicationPage>

以上で、XAML側の定義は完了です。

C#

引き続き、プログラム側の紹介をしていきます。画面遷移時に呼ばれるOnNavigatedToメソッドにて、Facebook C# SDKの認証用のFacebookOAuthClientクラスのインスタンスの生成と、WebBrowserコントロールに渡すログイン用のURLを作成します。

下記のコード内にstring型のApplicationIDとApplicationSecretを用意していますので、Facebookのアプリケーション登録にて取得したApp IDとApp Secretのキーをそれぞれ貼り付けてください。

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Windows.Navigation;
using Facebook;
using Microsoft.Phone.Controls;

namespace FacebookTest {
    public partial class MainPage : PhoneApplicationPage {
        public MainPage() {
            InitializeComponent();
        }

        // アプリケーション キー
        private readonly string ApplicationID = "取得したアプリキー";
        private readonly string ApplicationSecret = "取得したシークレットキー";
        // アクセストークンを保持する
        string accessToken = "";

        protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e) {
            var oauthClient = new FacebookOAuthClient { AppId = ApplicationID };
            var prams = new Dictionary<string, object>();
            prams["response_type"] = "code";
            prams["scope"] = "user_about_me,user_photos,offline_access";

            // 認証用のページURLを取得
            var url = oauthClient.GetLoginUrl(prams);

            // 認証ページへ遷移
            webBrowser.Navigate(url);
        }

正しいキーを設定した上で実行すると下図の通りログイン画面が表示されます。

通常時にFacebookにアクセスする時のメールアドレスとパスワードを入力して、ログインボタンをクリックします。

ユーザーのログインが完了後、このアプリケーションからFacebookへアクセスしてもよいか?の画面に切り替わります。アクセスの許可をクリックすると、セキュリティコード付きのURLの画面へ遷移します。

FacebookOAuthResult.TryParseメソッドにe.Uriを渡して、現在WebBrowserコントロールで表示されているページのURLにOAuthのレスポンスコードを含んでいるか確認を行います。FacebookOAuthResult.ExchangeCodeForAccessTokenAsyncメソッドのパラメータにレスポンスコードを指定して、アクセストークンの取得を要求します。

        private void webBrowser_Navigated(object sender, NavigationEventArgs e) {
            Debug.WriteLine("webBrowser_Navigated: {0}", e.Uri);

            FacebookOAuthResult oauthResult;
            if (!FacebookOAuthResult.TryParse(e.Uri, out oauthResult) || !oauthResult.IsSuccess) {
                return;
            }

            var oauthClient = new FacebookOAuthClient { AppId = ApplicationID };
            oauthClient.AppSecret = ApplicationSecret;
            var code = oauthResult.Code;

            // アクセストークンを取得する
            oauthClient.ExchangeCodeForAccessTokenCompleted += oauthClient_ExchangeCodeForAccessTokenCompleted;
            oauthClient.ExchangeCodeForAccessTokenAsync(code);
        }

アクセストークンの取得処理が、非同期にて実行されます。サーバーから返ってきたデータをe.GetResultDataメソッドで取得して、IDictionaryにキャストします。

"access_token"のキーでアクセストークンが取得できるので、下記コードではそのままアクセストークンを表示させるようにしています。

        void oauthClient_ExchangeCodeForAccessTokenCompleted(object sender, FacebookApiEventArgs e) {
            var result = e.GetResultData() as IDictionary<string, object>;
            if (result == null) return;

            accessToken = (string)result["access_token"];

            Dispatcher.BeginInvoke(() => {
                textAccessToken.Text = accessToken;
            });
        }
    }
}

次回は、このアクセストークンを使用して基本データの取得とウォールへのステータスの投稿についてご紹介させて頂きます。