Marco de redes sociales en Xamarin. iOSSocial Framework in Xamarin.iOS

El marco de redes sociales proporciona una API unificada para interactuar con redes sociales, como Twitter y Facebook, así como SinaWeibo para los usuarios de China.The Social Framework provides a unified API for interacting with social networks including Twitter and Facebook, as well as SinaWeibo for users in China.

El uso del marco de redes sociales permite a las aplicaciones interactuar con redes sociales desde una sola API sin tener que administrar la autenticación.Using the Social Framework allows applications to interact with social networks from a single API without having to manage authentication. Incluye un controlador de vista proporcionado por el sistema para la creación de publicaciones, así como una abstracción que permite el consumo de la API de cada red social a través de HTTP.It includes a system provided view controller for composing posts as well as an abstraction that allows consuming each social network’s API over HTTP.

Conexión a TwitterConnecting to Twitter

Configuración de la cuenta de TwitterTwitter Account Settings

Para conectarse a Twitter mediante el marco de redes sociales, es necesario configurar una cuenta en la configuración del dispositivo, tal como se muestra a continuación:To connect to Twitter using the Social Framework, an account needs to be configured in the device settings as shown below:

Una vez que se ha escrito y comprobado una cuenta con Twitter, cualquier aplicación en el dispositivo que use las clases de marco de redes sociales para acceder a Twitter usará esta cuenta.Once an account has been entered and verified with Twitter, any application on the device that uses the Social Framework classes to access Twitter will use this account.

Envío de tweetsSending Tweets

El marco de redes sociales incluye un controlador denominado SLComposeViewController que presenta una vista proporcionada por el sistema para editar y enviar un tweet.The Social Framework includes a controller called SLComposeViewController that presents a system provided view for editing and sending a tweet. En la captura de pantalla siguiente se muestra un ejemplo de esta vista:The following screenshot shows an example of this view:

Para usar un SLComposeViewController con Twitter, se debe crear una instancia del controlador llamando al método FromService con SLServiceType.Twitter como se muestra a continuación:To use an SLComposeViewController with Twitter, an instance of the controller must be created by calling the FromService method with SLServiceType.Twitter as shown below:

var slComposer = SLComposeViewController.FromService (SLServiceType.Twitter);

Una vez devuelta la instancia de SLComposeViewController, se puede usar para presentar una interfaz de usuario para publicar en Twitter.After the SLComposeViewController instance is returned, it can be used to present a UI to post to Twitter. Sin embargo, lo primero que hay que hacer es comprobar la disponibilidad de la red social, en este caso Twitter, llamando a IsAvailable:However, the first thing to do is to check the availability of the social network, Twitter in this case, by calling IsAvailable:

if (SLComposeViewController.IsAvailable (SLServiceKind.Twitter)) {
  ...
}

SLComposeViewController nunca envía un tweet directamente sin la interacción del usuario.SLComposeViewController never sends a tweet directly without user interaction. Sin embargo, se puede inicializar con los métodos siguientes:However, it can be initialized with the following methods:

  • SetInitialText: agrega el texto inicial que se va a mostrar en el tweet.SetInitialText – Adds the initial text to show in the tweet.
  • AddUrl: agrega una dirección URL al tweet.AddUrl – Adds a Url to the tweet.
  • AddImage: agrega una imagen al tweet.AddImage – Adds an image to the tweet.

Una vez inicializado, al llamar a PresentVIewController se muestra la vista creada por el SLComposeViewController.Once initialized, calling PresentVIewController displays the view created by the SLComposeViewController. El usuario puede editar y enviar el tweet opcionalmente, o cancelar su envío.The user can then optionally edit and send the tweet, or cancel sending it. En cualquier caso, el controlador debe descartarse en el CompletionHandler, donde también se puede comprobar el resultado para ver si se ha enviado o cancelado el tweet, como se muestra a continuación:In either case, the controller should be dismissed in the CompletionHandler, where the result can also be checked to see if the tweet was sent or cancelled, as shown below:

slComposer.CompletionHandler += (result) => {
  InvokeOnMainThread (() => {
    DismissViewController (true, null);
    resultsTextView.Text = result.ToString ();
  });
};

Ejemplo de TweetTweet Example

En el código siguiente se muestra el uso de la SLComposeViewController para presentar una vista usada para enviar un Tweet:The following code demonstrates using the SLComposeViewController to present a view used to send a 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 TwitterCalling Twitter API

El marco de redes sociales también incluye compatibilidad para hacer solicitudes HTTP a redes sociales.The Social Framework also includes support for making HTTP requests to social networks. Encapsula la solicitud en una clase SLRequest que se usa para dirigirse a la API de la red social concreta.It encapsulates the request in an SLRequest class that is used to target the particular social network’s API.

Por ejemplo, el código siguiente realiza una solicitud a Twitter para obtener la escala de tiempo pública (expandiendo en el código indicado anteriormente):For example, the following code makes a request to Twitter to get the public timeline (by expanding on the code given above):

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 en detalle.Let's look at this code in detail. En primer lugar, obtiene acceso al almacén de cuentas y obtiene el tipo de una cuenta de Twitter:First, it gains access to the Account Store and gets the type of a Twitter account:

var accountStore = new ACAccountStore ();
var accountType = accountStore.FindAccountType (ACAccountType.Twitter);

Después, pregunta al usuario si la aplicación puede tener acceso a su cuenta de Twitter y, si se concede el acceso, la cuenta se carga en la memoria y la interfaz de usuario se actualiza:Next, it asks the user if your app can have access to their Twitter account and, if access is granted, the account is loaded into memory and the UI updated:

// 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 la escala de tiempo (al pulsar un botón en la interfaz de usuario), la aplicación crea primero una solicitud para acceder a los datos desde Twitter:When the user requests the timeline data (by tapping a button in the UI), the app first forms a request to access the data from 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);

En este ejemplo se limitan los resultados devueltos a las últimas diez entradas mediante la inclusión de ?count=10 en la dirección URL.This example is limiting the returned results to the last ten entries by including ?count=10 in the 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:Finally, it attaches the request to the Twitter account (that was loaded above) and performs the call to Twitter to fetch the data:

// 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 se muestra en la salida del ejemplo siguiente):If the data was successfully loaded, the raw JSON data will be displayed (as in the example output below):

En una aplicación real, los resultados de JSON se pueden analizar como normal y los resultados se presentan al usuario.In a real app, the JSON results could then be parsed as normal and the results presented to the user. Vea Introducción a los servicios web para obtener información sobre cómo analizar JSON.See Introduction Web Services for information on how to parse JSON.

Conexión a FacebookConnecting to Facebook

Configuración de la cuenta de FacebookFacebook Account Settings

La conexión a Facebook con el marco de redes sociales es casi idéntica al proceso usado para Twitter mostrado anteriormente.Connecting to Facebook with the Social Framework is nearly identical to the process used for Twitter shown above. Una cuenta de usuario de Facebook debe estar configurada en la configuración del dispositivo, tal como se muestra a continuación:A Facebook user account must be configured in the device settings as shown below:

Una vez configurada, cualquier aplicación en el dispositivo que use el marco de redes sociales usará esta cuenta para conectarse a Facebook.Once configured, any application on the device that uses the Social Framework will use this account to connect to Facebook.

Publicar en FacebookPosting to Facebook

Como el marco de redes sociales es una API unificada diseñada para tener acceso a varias redes sociales, el código sigue siendo casi idéntico, independientemente de la red social utilizada.As the Social Framework is a unified API designed to access multiple social networks, the code remains nearly identical regardless of the social network being used.

Por ejemplo, el SLComposeViewController se puede utilizar exactamente como en el ejemplo de Twitter mostrado anteriormente, lo único que cambia a la configuración y las opciones específicas de Facebook.For example, the SLComposeViewController can be used exactly as in the Twitter example shown earlier, the only different is switching to the Facebook-specific settings and options. Por ejemplo:For example:

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 es prácticamente idéntica al ejemplo de Twitter, que muestra Facebook como título en este caso:When used with Facebook, the SLComposeViewController displays a view that looks nearly identical to the Twitter example, showing Facebook as the title in this case:

Llamada a Graph API de FacebookCalling Facebook Graph API

Al igual que en el ejemplo de Twitter, el objeto de SLRequest de la plataforma social se puede usar con la API Graph de Facebook.Similar to the Twitter example, the Social Framework’s SLRequest object can be used with Facebook’s graph API. Por ejemplo, el código siguiente devuelve información de la API Graph sobre la cuenta de Xamarin (mediante la expansión del código anterior):For example, the following code returns information from the graph API about the Xamarin account (by expanding on the code given above):

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 de obtener un identificador específico para desarrolladores o aplicaciones (que puede generar en el portal para desarrolladores de Facebook), que debe establecerse como una opción al realizar la solicitud:The only real difference between this code and the Twitter version presented above, is Facebook's requirement to get a Developer/App specific ID (which you can generate from Facebook's Developer Portal) which must be set as an option when making the request:

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á ningún dato.Failure to set this option (or using an invalid key) will result in either an error or no data being returned.

ResumenSummary

En este artículo se ha mostrado cómo usar el marco de redes sociales para interactuar con Twitter y Facebook.This article showed how to use the Social Framework to interact with Twitter and Facebook. Se mostró dónde configurar cuentas para cada red social en la configuración del dispositivo.It showed where to configure accounts for each social network in the device settings. También se describe cómo usar el SLComposeViewController para presentar una vista unificada para la publicación en redes sociales.It also discussed how to use the SLComposeViewController to present a unified view for posting to social networks. Además, examinó la clase SLRequest que se usa para llamar a la API de cada red social.Additionally, it examined the SLRequest class that is used to call each social network’s API.