Social Framework en Xamarin.iOS
The Social Framework proporciona una API unificada para interactuar con las redes sociales, como Twitter y Facebook, así como SinaWeibo para los usuarios de China.
El uso de Social Framework permite a las aplicaciones interactuar con redes sociales desde una sola API sin tener que administrar la autenticación. Incluye un controlador de vista proporcionado por el sistema para redactar publicaciones, así como una abstracción que permite consumir cada API de red social a través de HTTP.
Conexión a Twitter
Configuración de la cuenta de Twitter
Para conectarse a Twitter mediante Social Framework, es necesario configurar una cuenta en la configuración del dispositivo, como se muestra a continuación:
Una vez que se ha escrito y comprobado una cuenta con Twitter, cualquier aplicación del dispositivo que use las clases de Social Framework para acceder a Twitter usará esta cuenta.
Envío de tweets
Social Framework incluye un controlador llamado SLComposeViewController
que presenta una vista proporcionada por el sistema para editar y enviar un tweet. En la captura de pantalla siguiente se muestra un ejemplo de esta vista:
Para usar un SLComposeViewController
con Twitter, se debe crear una instancia del controlador llamando alFromService
método con SLServiceType.Twitter
como se muestra a continuación:
var slComposer = SLComposeViewController.FromService (SLServiceType.Twitter);
Una vez que se devuelve la instancia de SLComposeViewController
, se puede usar para presentar una interfaz de usuario para publicar en Twitter. Sin embargo, lo primero que debe hacer es comprobar la disponibilidad de la red social, Twitter en este caso, llamando a IsAvailable
:
if (SLComposeViewController.IsAvailable (SLServiceKind.Twitter)) {
...
}
SLComposeViewController
nunca envía un tweet directamente sin interacción del usuario. Sin embargo, se puede inicializar con los métodos siguientes:
SetInitialText
: Agrega el texto inicial que se va a mostrar en el tweet.AddUrl
: Agrega una dirección URL al tweet.AddImage
: Agrega una imagen al tweet.
Una vez inicializado, al llamar a PresentVIewController
se muestra la vista creada por el SLComposeViewController
. Después, el usuario puede editar y enviar el tweet o cancelar su envío. En cualquier caso, el controlador debe descartarse en el CompletionHandler
, donde también se puede comprobar el resultado para ver si el tweet se envió o canceló, como se muestra a continuación:
slComposer.CompletionHandler += (result) => {
InvokeOnMainThread (() => {
DismissViewController (true, null);
resultsTextView.Text = result.ToString ();
});
};
Ejemplo de tweet
En el código siguiente se muestra cómo usar el SLComposeViewController
para presentar una vista que se usa para enviar un tweet:
using System;
using Social;
using UIKit;
namespace SocialFrameworkDemo
{
public partial class ViewController : UIViewController
{
#region Private Variables
private SLComposeViewController _twitterComposer = SLComposeViewController.FromService (SLServiceType.Twitter);
#endregion
#region Computed Properties
public bool isTwitterAvailable {
get { return SLComposeViewController.IsAvailable (SLServiceKind.Twitter); }
}
public SLComposeViewController TwitterComposer {
get { return _twitterComposer; }
}
#endregion
#region Constructors
protected ViewController (IntPtr handle) : base (handle)
{
}
#endregion
#region Override Methods
public override void ViewWillAppear (bool animated)
{
base.ViewWillAppear (animated);
// Update UI based on state
SendTweet.Enabled = isTwitterAvailable;
}
#endregion
#region Actions
partial void SendTweet_TouchUpInside (UIButton sender)
{
// Set initial message
TwitterComposer.SetInitialText ("Hello Twitter!");
TwitterComposer.AddImage (UIImage.FromFile ("Icon.png"));
TwitterComposer.CompletionHandler += (result) => {
InvokeOnMainThread (() => {
DismissViewController (true, null);
Console.WriteLine ("Results: {0}", result);
});
};
// Display controller
PresentViewController (TwitterComposer, true, null);
}
#endregion
}
}
Llamada a la API de Twitter
Social Framework también incluye compatibilidad con la realización de solicitudes HTTP a redes sociales. Encapsula la solicitud en una SLRequest
clase que se usa para dirigirse a la API de la red social concreta.
Por ejemplo, el código siguiente realiza una solicitud a Twitter para obtener la escala de tiempo pública (expandiendo el código indicado anteriormente):
using Accounts;
...
#region Private Variables
private ACAccount _twitterAccount;
#endregion
#region Computed Properties
public ACAccount TwitterAccount {
get { return _twitterAccount; }
}
#endregion
#region Override Methods
public override void ViewWillAppear (bool animated)
{
base.ViewWillAppear (animated);
// Update UI based on state
SendTweet.Enabled = isTwitterAvailable;
RequestTwitterTimeline.Enabled = false;
// Initialize Twitter Account access
var accountStore = new ACAccountStore ();
var accountType = accountStore.FindAccountType (ACAccountType.Twitter);
// Request access to Twitter account
accountStore.RequestAccess (accountType, (granted, error) => {
// Allowed by user?
if (granted) {
// Get account
_twitterAccount = accountStore.Accounts [accountStore.Accounts.Length - 1];
InvokeOnMainThread (() => {
// Update UI
RequestTwitterTimeline.Enabled = true;
});
}
});
}
#endregion
#region Actions
partial void RequestTwitterTimeline_TouchUpInside (UIButton sender)
{
// Initialize request
var parameters = new NSDictionary ();
var url = new NSUrl("https://api.twitter.com/1.1/statuses/user_timeline.json?count=10");
var request = SLRequest.Create (SLServiceKind.Twitter, SLRequestMethod.Get, url, parameters);
// Request data
request.Account = TwitterAccount;
request.PerformRequest ((data, response, error) => {
// Was there an error?
if (error == null) {
// Was the request successful?
if (response.StatusCode == 200) {
// Yes, display it
InvokeOnMainThread (() => {
Results.Text = data.ToString ();
});
} else {
// No, display error
InvokeOnMainThread (() => {
Results.Text = string.Format ("Error: {0}", response.StatusCode);
});
}
} else {
// No, display error
InvokeOnMainThread (() => {
Results.Text = string.Format ("Error: {0}", error);
});
}
});
}
#endregion
Echemos un vistazo a este código con detalle. En primer lugar, obtiene acceso al Almacén de cuentas y obtiene el tipo de una cuenta de Twitter:
var accountStore = new ACAccountStore ();
var accountType = accountStore.FindAccountType (ACAccountType.Twitter);
A continuación, pregunta al usuario si la aplicación puede tener acceso a su cuenta de Twitter y, si se concede acceso, la cuenta se carga en la memoria y la interfaz de usuario se actualiza:
// Request access to Twitter account
accountStore.RequestAccess (accountType, (granted, error) => {
// Allowed by user?
if (granted) {
// Get account
_twitterAccount = accountStore.Accounts [accountStore.Accounts.Length - 1];
InvokeOnMainThread (() => {
// Update UI
RequestTwitterTimeline.Enabled = true;
});
}
});
Cuando el usuario solicita los datos de escala de tiempo (pulsando un botón en la interfaz de usuario), la aplicación forma primero una solicitud para acceder a los datos desde Twitter:
// Initialize request
var parameters = new NSDictionary ();
var url = new NSUrl("https://api.twitter.com/1.1/statuses/user_timeline.json?count=10");
var request = SLRequest.Create (SLServiceKind.Twitter, SLRequestMethod.Get, url, parameters);
Este ejemplo limita los resultados devueltos a las diez últimas entradas mediante la inclusión ?count=10
en la dirección URL. Por último, adjunta la solicitud a la cuenta de Twitter (que se cargó anteriormente) y realiza la llamada a Twitter para capturar los datos:
// Request data
request.Account = TwitterAccount;
request.PerformRequest ((data, response, error) => {
// Was there an error?
if (error == null) {
// Was the request successful?
if (response.StatusCode == 200) {
// Yes, display it
InvokeOnMainThread (() => {
Results.Text = data.ToString ();
});
} else {
// No, display error
InvokeOnMainThread (() => {
Results.Text = string.Format ("Error: {0}", response.StatusCode);
});
}
} else {
// No, display error
InvokeOnMainThread (() => {
Results.Text = string.Format ("Error: {0}", error);
});
}
});
Si los datos se cargaron correctamente, se mostrarán los datos JSON sin procesar (como en la salida de ejemplo siguiente):
En una aplicación real, los resultados JSON se podrían analizar como normales y los resultados presentados al usuario. Vea Introducción a los servicios web para obtener información sobre cómo analizar JSON.
Conexión a Facebook
Configuración de la cuenta de Facebook
La conexión a Facebook con social Framework es casi idéntica al proceso usado para Twitter mostrado anteriormente. Una cuenta de usuario de Facebook debe configurarse en la configuración del dispositivo, como se muestra a continuación:
Una vez configurada, cualquier aplicación del dispositivo que use Social Framework usará esta cuenta para conectarse a Facebook.
Publicar en Facebook
Como Social Framework es una API unificada diseñada para acceder a varias redes sociales, el código sigue siendo casi idéntico independientemente de la red social que se use.
Por ejemplo, el SLComposeViewController
se puede usar exactamente como en el ejemplo de Twitter mostrado anteriormente, la única diferencia es cambiar a la configuración y las opciones específicas de Facebook. Por ejemplo:
using System;
using Foundation;
using Social;
using UIKit;
namespace SocialFrameworkDemo
{
public partial class ViewController : UIViewController
{
#region Private Variables
private SLComposeViewController _facebookComposer = SLComposeViewController.FromService (SLServiceType.Facebook);
#endregion
#region Computed Properties
public bool isFacebookAvailable {
get { return SLComposeViewController.IsAvailable (SLServiceKind.Facebook); }
}
public SLComposeViewController FacebookComposer {
get { return _facebookComposer; }
}
#endregion
#region Constructors
protected ViewController (IntPtr handle) : base (handle)
{
}
#endregion
#region Override Methods
public override void ViewWillAppear (bool animated)
{
base.ViewWillAppear (animated);
// Update UI based on state
PostToFacebook.Enabled = isFacebookAvailable;
}
#endregion
#region Actions
partial void PostToFacebook_TouchUpInside (UIButton sender)
{
// Set initial message
FacebookComposer.SetInitialText ("Hello Facebook!");
FacebookComposer.AddImage (UIImage.FromFile ("Icon.png"));
FacebookComposer.CompletionHandler += (result) => {
InvokeOnMainThread (() => {
DismissViewController (true, null);
Console.WriteLine ("Results: {0}", result);
});
};
// Display controller
PresentViewController (FacebookComposer, true, null);
}
#endregion
}
}
Cuando se usa con Facebook, el SLComposeViewController
muestra una vista que parece casi idéntica al ejemplo de Twitter, que muestra Facebook como título en este caso:
Llamada a Facebook Graph API
De forma similar al ejemplo de Twitter, el objeto de SLRequest
Social Framework se puede usar con graph API de Facebook. Por ejemplo, el código siguiente devuelve información de graph API sobre la cuenta de Xamarin (expandiendo el código indicado anteriormente):
using Accounts;
...
#region Private Variables
private ACAccount _facebookAccount;
#endregion
#region Computed Properties
public ACAccount FacebookAccount {
get { return _facebookAccount; }
}
#endregion
#region Override Methods
public override void ViewWillAppear (bool animated)
{
base.ViewWillAppear (animated);
// Update UI based on state
PostToFacebook.Enabled = isFacebookAvailable;
RequestFacebookTimeline.Enabled = false;
// Initialize Facebook Account access
var accountStore = new ACAccountStore ();
var options = new AccountStoreOptions ();
var options.FacebookAppId = ""; // Enter your specific Facebook App ID here
accountType = accountStore.FindAccountType (ACAccountType.Facebook);
// Request access to Facebook account
accountStore.RequestAccess (accountType, options, (granted, error) => {
// Allowed by user?
if (granted) {
// Get account
_facebookAccount = accountStore.Accounts [accountStore.Accounts.Length - 1];
InvokeOnMainThread (() => {
// Update UI
RequestFacebookTimeline.Enabled = true;
});
}
});
}
#endregion
#region Actions
partial void RequestFacebookTimeline_TouchUpInside (UIButton sender)
{
// Initialize request
var parameters = new NSDictionary ();
var url = new NSUrl ("https://graph.facebook.com/283148898401104");
var request = SLRequest.Create (SLServiceKind.Facebook, SLRequestMethod.Get, url, parameters);
// Request data
request.Account = FacebookAccount;
request.PerformRequest ((data, response, error) => {
// Was there an error?
if (error == null) {
// Was the request successful?
if (response.StatusCode == 200) {
// Yes, display it
InvokeOnMainThread (() => {
Results.Text = data.ToString ();
});
} else {
// No, display error
InvokeOnMainThread (() => {
Results.Text = string.Format ("Error: {0}", response.StatusCode);
});
}
} else {
// No, display error
InvokeOnMainThread (() => {
Results.Text = string.Format ("Error: {0}", error);
});
}
});
}
#endregion
La única diferencia real entre este código y la versión de Twitter presentada anteriormente, es el requisito de Facebook para obtener un identificador específico de desarrollador o aplicación (que puede generar desde el Portal para desarrolladores de Facebook), que debe establecerse como una opción al realizar la solicitud:
var options = new AccountStoreOptions ();
var options.FacebookAppId = ""; // Enter your specific Facebook App ID here
...
// Request access to Facebook account
accountStore.RequestAccess (accountType, options, (granted, error) => {
...
});
Si no se establece esta opción (o se usa una clave no válida), se producirá un error o no se devolverán datos.
Resumen
En este artículo se muestra cómo usar social Framework para interactuar con Twitter y Facebook. Se mostró dónde configurar cuentas para cada red social en la configuración del dispositivo. También se explicó cómo usar el SLComposeViewController
para presentar una vista unificada para publicar en redes sociales. Además, examinó la clase SLRequest
que se usa para llamar a cada API de red social.