Social Framework in Xamarin.iOS
Social Framework offre un'API unificata per interagire con i social network, tra cui Twitter e Facebook, nonché SinaWeibo per gli utenti in Cina.
L'uso di Social Framework consente alle applicazioni di interagire con i social network da una singola API senza dover gestire l'autenticazione. Include un controller di visualizzazione fornito dal sistema per la composizione di post e un'astrazione che consente di utilizzare l'API di ogni social network tramite HTTP.
Connessione su Twitter
Account Twitter Impostazioni
Per connettersi a Twitter tramite Social Framework, è necessario configurare un account nelle impostazioni del dispositivo, come illustrato di seguito:
Dopo che un account è stato immesso e verificato con Twitter, qualsiasi applicazione nel dispositivo che usa le classi social framework per accedere a Twitter userà questo account.
Invio di tweet
Social Framework include un controller denominato SLComposeViewController
che presenta una visualizzazione fornita dal sistema per la modifica e l'invio di un tweet. Lo screenshot seguente mostra un esempio di questa visualizzazione:
Per usare un con SLComposeViewController
Twitter, è necessario creare un'istanza del controller chiamando il FromService
metodo con SLServiceType.Twitter
come illustrato di seguito:
var slComposer = SLComposeViewController.FromService (SLServiceType.Twitter);
Dopo aver restituito l'istanza SLComposeViewController
, può essere usata per presentare un'interfaccia utente da pubblicare su Twitter. Tuttavia, la prima cosa da fare è controllare la disponibilità del social network, Twitter in questo caso, chiamando IsAvailable
:
if (SLComposeViewController.IsAvailable (SLServiceKind.Twitter)) {
...
}
SLComposeViewController
non invia mai un tweet direttamente senza interazione dell'utente. Tuttavia, può essere inizializzato con i metodi seguenti:
SetInitialText
: aggiunge il testo iniziale da visualizzare nel tweet.AddUrl
: aggiunge un URL al tweet.AddImage
: aggiunge un'immagine al tweet.
Dopo l'inizializzazione, la chiamata PresentVIewController
visualizza la vista creata dall'oggetto SLComposeViewController
. L'utente può quindi eventualmente modificare e inviare il tweet oppure annullarlo. In entrambi i casi, il controller deve essere ignorato in CompletionHandler
, dove il risultato può anche essere controllato per verificare se il tweet è stato inviato o annullato, come illustrato di seguito:
slComposer.CompletionHandler += (result) => {
InvokeOnMainThread (() => {
DismissViewController (true, null);
resultsTextView.Text = result.ToString ();
});
};
Esempio di tweet
Il codice seguente illustra l'uso di SLComposeViewController
per presentare una visualizzazione usata per inviare 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
}
}
Chiamata dell'API Twitter
Social Framework include anche il supporto per l'esecuzione di richieste HTTP ai social network. Incapsula la richiesta in una SLRequest
classe usata per specificare come destinazione l'API del social network.
Ad esempio, il codice seguente invia una richiesta a Twitter per ottenere la sequenza temporale pubblica (espandendo il codice indicato in precedenza):
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
Esaminiamo questo codice in dettaglio. In primo luogo, ottiene l'accesso all'Account Store e ottiene il tipo di un account Twitter:
var accountStore = new ACAccountStore ();
var accountType = accountStore.FindAccountType (ACAccountType.Twitter);
Chiede quindi all'utente se l'app può accedere al proprio account Twitter e, se viene concesso l'accesso, l'account viene caricato in memoria e l'interfaccia utente aggiornata:
// 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;
});
}
});
Quando l'utente richiede i dati della sequenza temporale (toccando un pulsante nell'interfaccia utente), l'app crea prima una richiesta di accesso ai dati da 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);
Questo esempio limita i risultati restituiti alle ultime dieci voci includendo ?count=10
nell'URL. Infine, allega la richiesta all'account Twitter (caricato in precedenza) ed esegue la chiamata a Twitter per recuperare i dati:
// 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);
});
}
});
Se i dati sono stati caricati correttamente, i dati JSON non elaborati verranno visualizzati (come nell'output di esempio seguente):
In un'app reale, i risultati JSON possono quindi essere analizzati come normali e i risultati presentati all'utente. Per informazioni su come analizzare JSON, vedere Introduction Web Services (Introduzione ai servizi Web).
Connessione su Facebook
Account Facebook Impostazioni
Connessione a Facebook con il Social Framework è quasi identico al processo usato per Twitter illustrato in precedenza. Un account utente di Facebook deve essere configurato nelle impostazioni del dispositivo, come illustrato di seguito:
Una volta configurata, qualsiasi applicazione nel dispositivo che usa Social Framework userà questo account per connettersi a Facebook.
Post su Facebook
Poiché Social Framework è un'API unificata progettata per accedere a più social network, il codice rimane quasi identico indipendentemente dal social network in uso.
Ad esempio, SLComposeViewController
può essere usato esattamente come nell'esempio di Twitter illustrato in precedenza, l'unico diverso è passare alle impostazioni e alle opzioni specifiche di Facebook. Ad esempio:
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
}
}
Se usato con Facebook, SLComposeViewController
visualizza una visualizzazione quasi identica all'esempio di Twitter, che mostra Facebook come titolo in questo caso:
Chiamata all'API Graph di Facebook
Analogamente all'esempio di Twitter, l'oggetto di SLRequest
Social Framework può essere usato con l'API graph di Facebook. Ad esempio, il codice seguente restituisce informazioni dall'API graph sull'account Xamarin (espandendo il codice indicato in precedenza):
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
L'unica differenza reale tra questo codice e la versione di Twitter presentata in precedenza è il requisito di Facebook di ottenere un ID specifico per sviluppatore/app (che è possibile generare dal portale per sviluppatori di Facebook) che deve essere impostato come opzione quando si effettua la richiesta:
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) => {
...
});
Se non si imposta questa opzione (o si usa una chiave non valida), si verifica un errore o non viene restituito alcun dato.
Riepilogo
Questo articolo ha illustrato come usare il Social Framework per interagire con Twitter e Facebook. Ha mostrato dove configurare gli account per ogni social network nelle impostazioni del dispositivo. Ha inoltre illustrato come utilizzare per SLComposeViewController
presentare una visione unificata per la pubblicazione sui social network. Inoltre, ha esaminato la classe usata per chiamare l'API SLRequest
di ogni social network.