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:

Twitter Account Settings

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:

This screenshot shows an example of the SLComposeViewController

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):

An example of the raw JSON data display

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:

Facebook Account Settings

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:

The SLComposeViewController display

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.