venerdì 23 marzo 2012

Come usare le SDK iOS 5.1 con XCode 4.2 e Snow Leopard

Evidentemente Apple preferisce che i suoi sviluppatori siano aggiornati con l’ultimo sistema operativo disponibile, infatti il nuovo XCode 4.3 è disponibile solo per la versione del sistema operativo Lion 10.7.x, e con esso la nuova versione 5.1 delle SDK di iOS

Per vari motivi uno sviluppatore potrebbe non essere interessato ad installare l’ultima versione del sistema operativo oppure questa è pianificata ma non nell’immediato.

Allo stesso tempo dovrebbe essere importante provare le proprie applicazioni con il simulatore del nuovo iPad oppure con dispositivi che hanno installato iOS 5.1 (in quest'ultimo caso sono obbligatorie le nuove SDK)

Ecoo la procedura per poter utilizzare le SDK 5.1 con XCode 4.2 e Snow Leopard.

Scaricare il dmg del nuovo XCode da questo link:
http://adcdownload.apple.com/Developer_Tools/xcode_4.3.1_for_lion/xcode_4.3.1_for_lion.dmg

Estrarre il dmg e cliccando con il tasto destro scegliere “Mostra contenuto pacchetto”

Una premessa sulle cartelle (e sottocartelle) che saranno coinvolte in questa procedura:
- come directory sorgente dei file nel dmg useremo: /Contents/Developer/
- il percorso di destinazione sarà invece all’interno dell’hard disk del computer e precisamente nella cartella di installazione di XCode che di default è /Developer/

Successivamente completare le seguenti 4 fasi:

1) Copiare l’intera cartella da Platfoms/iPhoneOS.platform/DeviceSupport/5.1(9B176)
(inoltre è consigliato creare un alias di questa cartella con il nome di Latest, sostituendo quello esistente, cosi XCode userà questa versione se configurato come Latest nelle proprietà di progetto)

2) Copiare l’intera cartella da Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk

3) Copiare l’intera cartella da Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.1.sdk

4) Copiare l’applicazione del nuovo simulatore da Platforms/iPhoneSimulator.platform/Developer/Applications/Simulatore iOS (eventualmente rinominare il precedente simulatore per mantenerne una copia)


Ora potete riaprire XCode e compilare con le nuove SDK e simulare i vostri progetti anche con iPad (retina)

giovedì 5 maggio 2011

Come fare se avete perso la Private Key del vostro Distribuition Certificate


Durante la creazione del certificato per poter pubblicare e testare le app sul vostro iphone / ipad viene fornita una chiave privata. La potete trovare nell'utility "Accesso Portachiavi" del vostro Mac.
E' possibile salvarla, basta selezionare il certificato, poi si seleziona la chiave privata corrispondente, click dx e poi "Esporta..". Sarà creato un file con estensione ".p12", salvatelo su un qualche supporto esterno.

Se perdete per caso(!!!) i dati sul vostro Mac, potete sempre scaricarvi di nuovo il certificato dal vostro account e recuperare la vostra chiave privata. Se invece non avete salvato la chiave, non vi rimane che ricreare un nuovo certificato.

La creazione di un nuovo certificato prevede l'eliminazione di quello precedente. Le app che sono già state pubblicate su AppStore con il vecchio certificato non subiranno conseguenze, mentre le app che devono essere ancora approvate probabilmente dovranno essere firmate con il nuovo certificato.

domenica 13 marzo 2011

DefferedLoadListBox

David Anson ha pubblicate le ultime versioni aggiornate del  LowProfileImageLoader e del controllo DeferredLoadListBox, scaricatele da qui .
Per una descrizione dei controlli date un'occhiata a questo post.
( Ringrazio David per aver linkato questo blog all'interno dell'articolo ! :) )

lunedì 21 febbraio 2011

Link diretto per aprire la pagina di un'Applicazione con Zune

Esiste un link che permette di aprire, direttamente dal browser, la pagina di un'applicazione sul MarketPlace tramite Zune, precisamente Microsoft fornisce il seguente link:

Link di esempio ad applicazione Coming Soon
zune://navigate/?appID=76583cd8-cf32-e011-854c-00237de2db9e

Link generico (sostutire con l'APPID desiderato)
zune://navigate/?appID=APPID

Purtroppo questo link sembra funzionare solo su Internet Explorer IE9, su altri browser compare il seguente errore:

Impossibile Aprire, l'elemento richiesto non è disponibile per la tua zona
Impossible to Open, Element Required Is Not Available in Your Region (in inglese)

Fortunatamente esiste un link per poter aprire la propria applicazione con zune anche da altri browser, testato su Firefox e Chrome:

Link di esempio ad applicazione Coming Soon
http://redirect.zune.net/External/LaunchZuneProtocol.aspx?pathuri=navigate?phoneAppID=76583cd8-cf32-e011-854c-00237de2db9e

Link generico (sostutire con l'APPID desiderato)
http://redirect.zune.net/External/LaunchZuneProtocol.aspx?pathuri=navigate?phoneAppID=APPID

In questo modo i link alle vostre applicazioni saranno correttamente utilizzabili.

lunedì 3 gennaio 2011

Preserve and Restore ListBox State for Windows Phone

Per salvare e recuperare lo stato selle pagine su phone 7 c'è un articolo interessante su msdn :

Nell'articolo mancano però i metodi per gestire il controllo ListBox, vi aggiungo qui sotto i metodi da aggiungere per poter agilmente salvare lo stato di questo controllo :


   1:  /// <summary>
   2:  /// Saves the scroll offset of a ListBox to the state dictionary.
   3:  /// </summary>
   4:  /// <param name="state">The calling page's state dictionary.</param>
   5:  /// <param name="scrollViewer">The ListBox to be preserved.</param>
   6:  public static void PreserveState(IDictionary<string, object> state, ListBox listbox)
   7:  {           
   8:              
   9:      ScrollViewer viewer = ((VisualTreeHelper.GetChild(listbox, 0) as FrameworkElement).FindName("ScrollViewer") as ScrollViewer);
  10:      if (viewer != null) {
  11:          state[listbox.Name + "_HorizontalOffset"] = viewer.HorizontalOffset;
  12:          state[listbox.Name + "_VerticalOffset"]   = viewer.VerticalOffset;
  13:      }
  14:   
  15:      state[listbox.Name + "_selectedIndex"] = listbox.SelectedIndex;
  16:  }
  17:   
  18:  public class datListBox {
  19:      public double offsetX=0;
  20:      public double offsetY=0;
  21:      public int selectedIndex=-1;
  22:  }
  23:   
  24:  /// <summary>
  25:  /// Retrieves the saved scroll offset from the state dictionary and creates a delegate to
  26:  /// restore the scroll position on the page's first render.
  27:  /// </summary>
  28:  /// <param name="state">The calling page's state dictionary</param>
  29:  /// <param name="scrollViewer">The ListBox to be restored</param>
  30:  public static datListBox RestoreState(IDictionary<string, object> state, ListBox listbox)
  31:  {
  32:      datListBox data = new datListBox();
  33:      data.offsetX = TryGetValue<double>(state, listbox.Name + "_HorizontalOffset", 0);
  34:      data.offsetY = TryGetValue<double>(state, listbox.Name + "_VerticalOffset", 0);
  35:      data.selectedIndex = TryGetValue<int>(state, listbox.Name + "_selectedIndex", -1);
  36:   
  37:      ScheduleOnNextRender(delegate { RestoreState(listbox,data); });
  38:      return data;
  39:  }
  40:   
  41:  private static void RestoreState(ListBox listbox,datListBox data)
  42:  {
  43:      if (listbox == null || data == null ) return;
  44:      ScrollViewer viewer = ((VisualTreeHelper.GetChild(listbox, 0) as FrameworkElement).FindName("ScrollViewer") as ScrollViewer);
  45:      if (viewer != null)
  46:      {
  47:          viewer.ScrollToHorizontalOffset(data.offsetX);
  48:          viewer.ScrollToVerticalOffset(data.offsetY);
  49:      }
  50:  }

Nel metodo RestoreState() potete aggiungere anche il ripristino dell'elemento selezionato se vi interessa (basta aggiungere : listbox.SelectedIndex = data.selectedIndex;)
Un'altra cosa, ho trovato un piccolo Bug nell'articolo MSDN sopra indicato, nel metodo PreserveState del controllo ScrollViewer viene salvato due volte il VerticalOffset :


   1:  public static void PreserveState(IDictionary<string, object> state, ScrollViewer scrollViewer)
   2:  {
   3:    state[scrollViewer.Name + "_HorizontalOffset"] = scrollViewer.VerticalOffset;
   4:    state[scrollViewer.Name + "_VerticalOffset"] = scrollViewer.VerticalOffset;
   5:  }

Modificatelo così :

   1:  public static void PreserveState(IDictionary<string, object> state, ScrollViewer scrollViewer)
   2:  {
   3:   state[scrollViewer.Name + "_HorizontalOffset"] = scrollViewer.HorizontalOffset;
   4:   state[scrollViewer.Name + "_VerticalOffset"] = scrollViewer.VerticalOffset;
   5:  }

mercoledì 22 dicembre 2010

Ottimizzare il controllo ListBox su phone 7

Se utilizzate il controllo ListBox per visualizzare e scorrere centinaia di item noterete una fluidità non meravigliosa, soprattutto se gli item contengono immagini. Ovviamente se la vostra listbox contiene poche decine di item potete tranquillamente utilizzarlo così com'è.
Leggendo il post Never do today what you can put off till tomorrow  di David Anson ho trovato alcune soluzioni interessanti, l'utilizzo di LowProfileImageLoader per il caricamento asincrono delle immagini e DeferredLoadListBox migliorare le prestazioni del listbox contol.
Per prima cosa se avete delle immagini che caricate dalla rete è necessario farle caricare non al trhead della UI, ma in modo asincrono, e potete utilizzare facilmente la classe LowProfileImageLoader. Questa classe ha migliorato di parecchio la fluidità delle mie listbox.. praticamente utilizza un worker thread per caricarsi le immagini.
Il controllo ListBox utilizzando al suo interno un VirtualizingStackPanel riesce a mantenere basso il consumo di memoria. Il  VirtualizingStackPanel riesce ad allocare solo i containers degli item visibili, riciclandoli quando si scorrono gli item. Quindi riesce a mantenere basso il numero di containers anche quando abbiamo un elevato numero di item. Purtroppo questo pesa a volte sul nostro UI thread, diminuendo la fluidità dello scrolling. Cosa succede se invece carico tutti i containers ? Basta sostituire il listbox con uno stackpanel, questo migliora la fluidità ma caricandovi tutti gli elementi vi richiede più memoria ed è più lento nella fase di caricamento iniziale.
In questo caso ci viene in aiuto la DeferredLoadListBox, praticamente fa in modo che il nostro listbox si comporti come uno stackpanel "evoluto", in pratica posticipa il caricamento degli item non visbili, in questo modo si migliora il tempo di caricamento iniziale ma il consumo della memoria, man mano che si scorrono gli elementi, aumenterà fino ad essere similare al consumo dello stackpanel. 


Possiamo dire quindi che la fluidità si paga in termini di memoria allocata, valutate a seconda delle vostre esigenze cosa vi conviene utilizzare.

giovedì 25 novembre 2010

Phone 7 : Interaction Guide & UI Design in pillole

Un elenco da stampare e appiccicare al muro se si ha intenzione di sviluppare per phone 7. 
Vi consiglio di leggere il documento integrale, di seguito un breve riassunto dei punti + importanti per lo sviluppatore:

Generici
  • Non usare Font con dimensione inferiore di 15pt, sarebbe faticosa la lettura.
  • Puoi usare un Font proprietario, e non solo quello usato di default cioè il Segoe WP.
  • Il touch target (ossia la zona sensibile al tocco..) deve essere almeno 34px x 34px oppure 9mm x 9mm, e deve distanziarsi da tocuh target adiacenti di 2mm x 8px. Se il touch target fa parte di un controllo molto usato, meglio aumentare le dimensioni.
  • Il touch element (ossia la zona grafica associata al touch target) può essere più piccolo del tocuh target ma non più del 60%.
  • Non usare transizioni personalizzate nel passare da landscape a portrait o viceversa.
  • Puoi personalizzare le Screen Transition, cioè l'effetto grafico durante il passaggio da una pagina ad un'altra.
  • Se la tua applicazione supporta il landscape view allora deve sopportare sia il right landscape che il left landscape.
  • La Application Bar supporta solo 4 ICONE e devono essere chiare e leggibili. Eventualmente possiamo aggiungere altri 5 item nel menù a tendina  chiamato Application bar menu.
  • Se si usa una pagina con il Page Title, allora è meglio che tutte le pagine ne siano provviste.
  • Le impostazioni della propria applicazione saranno da implementare all'interno di essa, quindi prevedere una pagina Settings. (Non prevedere eventuali conferme da parte dell'utente, le modifiche devono essere immediate). Non superare le due pagine per non avere impostazioni troppo complesse. La pagina si dovrà chiamare "settings" e come titolo "nome app".
  • Se si usano web-service verificare se il dispositivo non sia in modalità "airplane mode"

    Gesture
    • Touch & Hold (tenere premuto il dito sullo schermo): Per visualizzare un menù contestuale oppure per aprire una pagina di configurazione riferita all'item indicato.
    • Touch (toccare lo schermo e subito allontanare il dito): Quando il dito tocca il touch target siamo nella fase di touch indication, quando il dito non tocca + lo schermo siamo nella fase di tocuh execution.
    • Double Tap (doppio touch ravvicinato): In genere usato per lo zoom di un'area.
    • Pan (scorrere il dito sullo schermo mantenendo il contatto) : Usato per scorrere un controllo i spostare elementi.
    • Flick (scorrere velocemente e allontanare il dito, tipo sfogliare un libro velocemente): Usato per spostare elementi da una zona ad un'altra.
    • Pinch & Stratch (avvicinare o allontanare due dita a contatto con lo schermo): Usato per zoom in / zoom out continuo.

    Hardware button
    • Non è possibile interagire con il pulsante Search. E' possibile creare un button con la medesima icona e simulare una ricerca all'interno della nostra applicazione. (usando semmai la classe Search Task)
    • Il puslante Backbutton server per tornare alla pagine precedente o chiudere uno screen modale. Se siamo nella pagina principale e premiamo back, usciamo dall'applicazione.

    Controlli della GUI
    • I Button non devono contenere più di due parole. Quindi limitarsi con parole chiave chiare, tipicamente un verbo...
    • I pulsanti di conferma (tipo OK,YES) devono essere a sinistra, quelli di annullamento (tipo CANCEL, NO) a destra.
    • Se ho un controllo editabile multiline è lo sviluppatore che deve controllare che la linea attualmente editabile sia visibile e non coperta dalla tastiera a video.
    • Il Canvas è + performante del Grid ma non è adatto se vogliamo un layout ridimensionabile o che ruoti.
    • Il testo delle Checkbox sarebbe meglio non superasse le due linee.
    • Meglio non usare il terzo stato o stato indeterminato nelle Checkbox.
    • Usare gli Hyperlink solo per navigare tra le pagine, non per attivare azioni o interagire in altri modi con la GUI.
    • Non usare il MediaElement per effetti sonori, si usa solo per contenuti multimediali. Usare XNA SoundEffect per gli effetti.
    • La Background image del controllo Panorama Controdeve essere al massimo 1024x800 per avere prestazioni ottimali.
    • Un Panorama Control formato da 4 sezioni dovrebbe rispettare la proporzione 16:9
    • Il titolo del Panorama Contropuò ospitare anche loghi o immagini.
    • Una singola sezione del Panorama Control può ospitare un controllo con scrolling verticale, ma il controllo deve essere contenuto completamente all'interno della section. Non usare scrolling orizzontale nei controlli.
    • Il Pivot Control può essere usato efficacemente per visualizzare data sets o cmq tabelle contenenti molti dati.
    • Non innestare un Pivot Control dentro una'altro Pivot Control.
    • Non innestare un Pivot Control dentro un Panorama Control.
    • Tra le pagine di un controllo Pivot Control non vi devono essere grosse differenze di utilizzo e di layout di presentazione dei dati. (Devono essere pagine similari)
    • Usare gli Slider orizzontali piuttosto che gli slider verticali.