×
Namespaces

Variants
Actions
Revision as of 08:03, 8 November 2013 by hamishwillee (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Integrar o Facebook numa aplicação Windows Phone

From Nokia Developer Wiki
Jump to: navigation, search

Este artigo explica como integrar o Facebook numa aplicação Windows Phone.

WP Metro Icon Web.png
SignpostIcon XAML 40.png
WP Metro Icon WP8.png
SignpostIcon WP7 70px.png
Article Metadata

Exemplo de código
Testado com
Compatibilidade
Artigo
Tradução:
Por saramgsilva
Última alteração feita por hamishwillee em 08 Nov 2013

Contents

Introdução

Facebook é neste momento a rede social mais popular no mundo. Poderá obter benefícios da integração do Facebook na sua aplicação, por exemplo, ganhar mais utilizadores, publicar coisas em nome da sua aplicação, etc Este artigo irá mostrar-lhe como integrar facilmente o Facebook na sua aplicação do Windows Phone 8.

Criar aplicação Facebook

Primeiro que tudo, é necessário criar uma aplicação Facebook no site do Facebook.O "link" de referência é https://developers.facebook.com/apps.

Clique no botão "Create New App"

FacebookCreateNewApp.jpg

Introduza o Nome da aplicação e o "namespace" (opcional)

FacebookCreateNewApp2.jpg

Anote o "App ID" e o "App Secret" que será preciso no desenvolvimento da aplicação Windows Phone.

FacebookCreateNewApp3.jpg

Configure o Projeto

Prepare as páginas

Coloque os botões Connect/Disconnect assim como Post Message on Wall na MainPage.

Para conetar a aplicação ao Facebook, é preciso precionar o botão "Connect", a aplicação irá navegar para a próxima página "ConnectPage"

MainPage.xaml

XAML1.jpg

A página ConnectPage é apenas uma página em XAML com um "WebBrowser"

ConnectPage.xaml

XAML2.jpg

<phone:WebBrowser x:Name="mWebBrowser"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Height="696"
Width="480"
IsScriptEnabled="True"
Navigated="WebBrowser_Navigated"/>

Adicionar bibliotecas

É preciso adicional 4 pequenos ficheiros que encontram abaixo. Para o primeiro, FacebookClient.cs, é preciso adicionar o App ID e o App Secret às variáveis appId e clientSecret.

// FacebookUtils/FacebookClient.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.IO.IsolatedStorage;
 
namespace FacebookUtils
{
public class FacebookClient
{
private static FacebookClient instance;
private string accessToken;
 
private static readonly IsolatedStorageSettings appSettings = IsolatedStorageSettings.ApplicationSettings;
 
private String appId = "xxx";
private String clientSecret = "xxx";
private String scope = "publish_stream";
 
public FacebookClient()
{
try
{
accessToken = (string)appSettings["accessToken"];
}
catch (KeyNotFoundException e)
{
accessToken = "";
}
}
 
public static FacebookClient Instance
{
get
{
if (instance == null)
instance = new FacebookClient();
return instance;
}
set
{
instance = value;
}
}
 
public string AccessToken
{
get
{
return accessToken;
}
set
{
accessToken = value;
if (accessToken.Equals(""))
appSettings.Remove("accessToken");
else
appSettings.Add("accessToken", accessToken);
}
}
 
public virtual String GetLoginUrl()
{
return "https://m.facebook.com/dialog/oauth?client_id=" + appId + "&redirect_uri=https://www.facebook.com/connect/login_success.html&scope=" + scope + "&display=touch";
}
 
public virtual String GetAccessTokenRequestUrl(string code)
{
return "https://graph.facebook.com/oauth/access_token?client_id=" + appId + "&redirect_uri=https://www.facebook.com/connect/login_success.html&client_secret=" + clientSecret + "&code=" + code;
}
 
public virtual String GetAccessTokenExchangeUrl(string accessToken)
{
return "https://graph.facebook.com/oauth/access_token?client_id=" + appId + "&client_secret=" + clientSecret + "&grant_type=fb_exchange_token&fb_exchange_token=" + accessToken;
}
 
public void PostMessageOnWall(string message, UploadStringCompletedEventHandler handler)
{
WebClient client = new WebClient();
client.UploadStringCompleted += handler;
client.UploadStringAsync(new Uri("https://graph.facebook.com/me/feed"), "POST", "message=" + HttpUtility.UrlEncode(message) + "&access_token=" + FacebookClient.Instance.AccessToken);
}
 
public void ExchangeAccessToken(UploadStringCompletedEventHandler handler)
{
WebClient client = new WebClient();
client.UploadStringCompleted += handler;
client.UploadStringAsync(new Uri(GetAccessTokenExchangeUrl(FacebookClient.Instance.AccessToken)), "POST", "");
}
 
}
}
// FacebookUtils/ResponseData.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace FacebookUtils
{
public class ResponseData
{
public string id { get; set; }
public ErrorData error { get; set; }
}
 
public class ErrorData
{
public int code { get; set; }
public int error_subcode { get; set; }
}
}
// Tools/UriToolKits.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Text.RegularExpressions;
 
namespace Tools
{
public static class UriToolKits
{
private static readonly Regex QueryStringRegex = new Regex(@"[\?&](?<name>[^&=]+)=(?<value>[^&=]+)");
 
public static IEnumerable<KeyValuePair<string, string>> ParseQueryString(this string uri)
{
if (uri == null)
throw new ArgumentException("uri");
 
var matches = QueryStringRegex.Matches(uri);
for (var i = 0; i < matches.Count; i++)
{
var match = matches[i];
yield return new KeyValuePair<string, string>(match.Groups["name"].Value, match.Groups["value"].Value);
}
}
}
}
// Tools/KeyValuePairUtils.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace Tools
{
public static class KeyValuePairUtils
{
public static TValue GetValue<TKey, TValue>(this IEnumerable<KeyValuePair<TKey, TValue>> pairs, TKey key)
{
foreach (KeyValuePair<TKey, TValue> pair in pairs)
{
if (key.Equals(pair.Key))
return pair.Value;
}
 
throw new Exception("the value is not found in the dictionary");
}
}
}

Lidando com a janela de login do Facebook

Wp ss 20121213 0002.jpg

Uma vez que o botão Connect é pressionado, a aplicação irá navegar para a ConnectPage.Uma vez que a página é inicializada, é preciso atribuir o "source" ao "WebBrowser" usando o url preparado pelo FacebookClient. Por favor note, que é necessário limpar "cookies" antes de atribuir o "source" para limpar registos efetuados anteriormente.

public ConnectPage()
{
InitializeComponent();
 
// Clear Cookie to remove current logged in user data
mWebBrowser.ClearCookiesAsync();
 
// Go to Login url
mWebBrowser.Source = new Uri(FacebookClient.Instance.GetLoginUrl());
}

Agora o que é preciso é verificar o url atual do "WebBrowser" usando o evento "Navigated". Se o processo de "logging" foi realizado com sucesso o url final será "http://www.facebook.com/connect/login_success.html" ou "https://www.facebook.com/connect/login_success.html". Uma vez obtido este resultado, é necessário extrair o parâmetro "code" através de "query string" para assim procedermos ao próximo passo.

private void WebBrowser_Navigated(object sender, NavigationEventArgs e)
{
String uri = e.Uri.ToString();
 
if (uri.StartsWith("https://www.facebook.com/connect/login_success.html") || uri.StartsWith("http://www.facebook.com/connect/login_success.html"))
{
// Remove junk text added by facebook from url
if (uri.EndsWith("#_=_"))
uri = uri.Substring(0, uri.Length - 4);
 
String queryString = e.Uri.Query.ToString();
 
// Acquire the code from Query String
IEnumerable<KeyValuePair<string, string>> pairs = UriToolKits.ParseQueryString(queryString);
string code = KeyValuePairUtils.GetValue(pairs, "code");
 
// Get access_token from code using Asynchronous HTTP Request
WebClient client = new WebClient();
client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(AccessTokenDownloadCompleted);
client.DownloadStringAsync(new Uri(FacebookClient.Instance.GetAccessTokenRequestUrl(code)));
}
}

O parâmetro "code" é necessário para as trocas do token de acesso que é o parâmetro real que é preciso quando se pretende usar a conta do Facebook via Facebook App. Para trocar o código para o token de acesso, é necessário fazer um "POST request" ao servidor usando o "WebClient" como é mostrado de seguida- Uma vez que os dados estão disponíveis, extrai-se o parâmetro "access_token" e guarda-se o valor, regressando novamente à MainPage.

void AccessTokenDownloadCompleted(object sender, DownloadStringCompletedEventArgs e)
{
string data = e.Result;
data = "?" + data;
 
// Acquire access_token and expires timestamp
IEnumerable<KeyValuePair<string, string>> pairs = UriToolKits.ParseQueryString(data);
string accessToken = KeyValuePairUtils.GetValue(pairs, "access_token");
string expires = KeyValuePairUtils.GetValue(pairs, "expires");
 
// Save access_token
FacebookClient.Instance.AccessToken = accessToken;
 
// Back to MainPage
var rootFrame = Application.Current.RootVisual as PhoneApplicationFrame;
if (rootFrame != null)
rootFrame.GoBack();
}

Escrever no Wall

Na realidade o access_token é a chave para conetar ao Facebook. Uma vez obtido isto, é possível fazer qualquer coisa com a API. Por agora, apenas irei mostrar como escrever uma mensagem no "wall". Para o fazer simplesmente chamo o métodol FacebookClient.Instance.PostMessageOnWall

FacebookClient.Instance.PostMessageOnWall(TextToPost, new UploadStringCompletedEventHandler(PostMessageOnWallCompleted));

PostMessageOnWall é um pedido assincrono,e é preciso lidar com o resultado depois de tudo. De notar que o "access_token" tem uma data limite. Caso expira, é preciso trocar por um novo "access_token" antes de fazer algo.

void PostMessageOnWallCompleted(object sender, UploadStringCompletedEventArgs e)
{
if (e.Cancelled)
return;
if (e.Error != null)
{
MessageBox.Show("Error Occurred: " + e.Error.Message);
return;
}
 
System.Diagnostics.Debug.WriteLine(e.Result);
 
string result = e.Result;
byte[] data = Encoding.UTF8.GetBytes(result);
MemoryStream memStream = new MemoryStream(data);
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(ResponseData));
ResponseData responseData = (ResponseData)serializer.ReadObject(memStream);
 
if (responseData.id != null && !responseData.id.Equals(""))
{
// Success
MessageBox.Show("Message Posted!");
}
else if (responseData.error != null && responseData.error.code == 190)
{
if (responseData.error.error_subcode == 463)
{
// Access Token Expired, need to get new token
FacebookClient.Instance.ExchangeAccessToken(new UploadStringCompletedEventHandler(ExchangeAccessTokenCompleted));
}
else
{
// Another Error with Access Token, need to clear the Access Token
FacebookClient.Instance.AccessToken = "";
SetLoggedInState(false);
}
}
else
{
// Error
}
}
 
void ExchangeAccessTokenCompleted(object sender, UploadStringCompletedEventArgs e)
{
// Acquire access_token and expires timestamp
IEnumerable<KeyValuePair<string, string>> pairs = UriToolKits.ParseQueryString(e.Result);
string accessToken = KeyValuePairUtils.GetValue(pairs, "access_token");
 
if (accessToken != null && !accessToken.Equals(""))
{
MessageBox.Show("Access Token Exchange Failed");
return;
}
 
// Save access_token
FacebookClient.Instance.AccessToken = accessToken;
FacebookClient.Instance.PostMessageOnWall(TextToPost, new UploadStringCompletedEventHandler(PostMessageOnWallCompleted));
}
Wp ss 20121213 0008.jpg

E é isto que iremos obter no "Wall" do Facebook!

PostedToWall.jpg

Parabéns. A sua aplicação está conectada ao Facebook! Para ter mais funcionalidade poderá modificar o FacebookClient.cs. Para obter mais informações sobre a API consulte https://developers.facebook.com/docs/reference/api/

Código Fonte

O código fonte para o exemplo pode ser obtido em File:FacebookConnect.zip

This page was last modified on 8 November 2013, at 08:03.
185 page views in the last 30 days.
×