Windows Phone 8 in 10 zile 5
Azi o să introducem și Facebook în aplicația noastră, posibilitatea de a da share informațiilor din interiorul aplicației.
În primul rând intră pe: http://adriancoman.ro/facebook-login-c/ și urmărește pașii de acolo, mai puțin adăugarea butonului propriuzis în xaml. Acela îl vom face noi separat.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<Grid x:Name="LayoutRoot" Background="#c09a00"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28"> <Image Source="/Assets/SplashScreen.png" /> <Controls:ProfilePicture Width="100" Height="100" ProfileId="{Binding CurrentSession.FacebookId, ElementName=loginButton}" Name="profilePic" /> </StackPanel> <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> <StackPanel> <TextBlock Name="welcomeTxt" Text="Dă-ți login pe Facebook pt o experiență mai bună"/> <Controls:LoginButton Tap="logTap" SessionStateChanged="sesChange" Name="loginButton" HorizontalAlignment="Center" Margin="0,10,0,50" ApplicationId="233521076834347"/> <Button Content="Învață!" Tap="learnTap" /> <Button Content="Testează" Tap="newGameTap" /> </StackPanel> </Grid> </Grid> |
Vreau să am o imagine de profil pentru a înștiința utilizatorul când a dat login și un buton de login. Partea de cod nu este deosebit de grea. SDK-ul instalat de noi fiind de fapt cel care a făcut mare parte din logică.
Aplicația e în perfectă stare de funcționare acum, dar în momentul când dau login o să observați un mic lag până când îmi apare imaginea mea de profil. De fapt, nu este doar lag, chiar întreaga aplicație se blochează, ceea ce e VERY bad user experience. Pentru a combate acest lucru vom introduce un loading bar, sau mai exact un progress indicator foarte asemănător cu progress ring-ul din Windows 8 despre care am scris aici.
Codul pe care îl vom diseca imediat:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
public partial class MainPage : PhoneApplicationPage { public MainPage() { InitializeComponent(); Loaded += MaingPage_Loaded; BuildLocalizedApplicationBar(); } private void MaingPage_Loaded(object sender, RoutedEventArgs e) { SystemTray.ProgressIndicator = new ProgressIndicator(); } private static void SetProgressIndicator(bool isVisible) { try { SystemTray.ProgressIndicator.IsIndeterminate = isVisible; SystemTray.ProgressIndicator.IsVisible = isVisible; } catch (Exception ex) { } } private void logTap(object sender, System.Windows.Input.GestureEventArgs e) { SetProgressIndicator(true); SystemTray.ProgressIndicator.Text = "Așteaptă, ne logăm pe Facebook."; } private void learnTap(object sender, System.Windows.Input.GestureEventArgs e) { NavigationService.Navigate(new Uri("/Views/learn.xaml", UriKind.Relative)); } private void newGameTap(object sender, System.Windows.Input.GestureEventArgs e) { NavigationService.Navigate(new Uri("/Views/newGame.xaml", UriKind.Relative)); } private void BuildLocalizedApplicationBar() { ApplicationBar = new ApplicationBar(); ApplicationBarMenuItem appBarHowTo = new ApplicationBarMenuItem(AppResources.AppBarHowTo); ApplicationBar.MenuItems.Add(appBarHowTo); appBarHowTo.Click += appBarHowTo_Click; } private void appBarHowTo_Click(object sender, EventArgs e) { NavigationService.Navigate(new Uri("/Views/howTo.xaml", UriKind.Relative)); } private void sesChange(object sender, Facebook.Client.Controls.SessionStateChangedEventArgs e) { try { App.Token = this.loginButton.CurrentSession.AccessToken; SetProgressIndicator(false); } catch (Exception ex) { } } } |
Linia 3
Avem constructorul paginii principale, Loaded practică încarcă ProgressIndicator-ul și îl pregătește pentru când voi avea eu nevoie de el.
Linia 9 și 13
Acum încarc ProgressIndicator-ul și creez metoda SetProgressIndicator care va primi ca parametru bool-ul isVisible. By default acesta este false deci invizibil.
Linia 26
logTap este apelat în momentul în care am dat click pe butonul de Login. Îmi fac ProgressIndicatorul vizibil și acum o să îmi afișeze în partea de sus a ecranului bara de loading/progress împreună cu mesajul meu.
Linia 32-55
Navigarea pe care am făcut-o în ziua 2 și appar-ul construit în ziua 3. Nimic nou sub Soare.
Linia 57
Întru în App.xaml.cs și pe prima linie de cod o să scriu: public static string Token; sesChange o să se apeleze practic atunci când am terminat operațiunea de logare și practic o să salvez token-ul de acces pentru a îl folosi în alte pagini din interiorul aplicației mele.
Share the love
Ăsta e butonul care face share-ul posibil:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
private async void share(object sender, System.Windows.Input.GestureEventArgs e) { try { string s = (string)((TextBlock)sender).Text; var facebookClient = new Facebook.FacebookClient(App.Token); var postParams = new { name = "Știi sinonimul?", caption = "Care este sinonimul lui", description = sinonimTxt.Text, link = "http://bit.ly/1g798Lr", picture = "http://adriancoman.ro/wp-content/uploads/2014/03/sinonim300x.png" }; dynamic fbPostTaskResult = await facebookClient.PostTaskAsync("/me/feed", postParams); var result = (IDictionary<string, object="">)fbPostTaskResult; Dispatcher.BeginInvoke(() => { MessageBox.Show("Ți-ai întrebat prietenii! Să vedem", "Gata", MessageBoxButton.OK); }); } catch (Exception ex) { Dispatcher.BeginInvoke(() => { MessageBox.Show("Din cauza unei erori nu putem să dăm share, scuze :( ", "Eroare", MessageBoxButton.OK); }); } } |
Linia 6
După cum am zis, am nevoie de Token pentru că în el este specificat ceea ce am voie și ce nu am voie să fac prin aplicația mea. By default am acces la nume, imaginea de profil și pot să public pe wall-ul celor care dau accept.
Linia 8
Aici pregătesc mesajul care o să apară atunci când lumea o să dea share din interiorul aplicației. Sigur merge o variantă personalizată pentru fiecare view pe care-l am. Pentru newGame.xaml o să fie sub formă de întrebare și pentru learn.xaml o să postez un mesaj sub formă de informație cu scop educațional.
Link-ul din descriere duce spre pagina mea de download pentru că vreau ca prietenii care văr acest share să poată descărca aplicația. Am folosit un urlshortner (bitly) pentru că vreau să știu exact câte click-uri au generat mesajele postate și, din câte știu eu, aceasta este singura metodă.
În final mai am nevoie doar de o imagine care să reprezinte Logo-ul aplicației mele. Imagine pe care am hostat-o pe adriancoman.ro
Linia 18
Aici încerc deja să postez mesajul pe wall-ul utilizatorului, dacă inițial nu am cerut acordul pentru a publica informații, o să îi mai apară un mesaj care o să îl întrebe dacă e de acord sau nu să postez pe wall-ul lui.
Lina 21
Dacă am postat cu succes o să afișez un mesaj de informare utilizatorului. Desigur pot să nu mai informez deloc și să las așa fără. Depinde de voi.
Linia 26
Este foarte important să folosiți un try/catch aici. În principiu, singura eroare care o să apară este dată de apăsarea butonului de share fără ca utilizatorul să fie logat în aplicație. Sigur, există metode prin care să verific dacă utilizatorul a dat login și dacă nu a dat nici să nu îi afișez butonul, dar tot am avea nevoie de acest try/catch pentru alte probleme care pot apărea: îi mergea internetul când a dat login, dar între timp a rămas fără.
By: Adrian Coman