[iOs] Aggiornamento ad xCode 5: novità e how-to ai problemi post-upgrade

xCode 5Dopo gli upgrade di xCode, si hanno gli ormai inevitabili problemi di compatibilità o di change configuration di progetti scritti con una versione precedente. Sono passato al nuovo xCode 5 da quando è stato rilasciato per gli sviluppatori iOs, imbattendomi in alcune problematiche, e ho pensato di scrivere una sorta di “how-to” per la loro risoluzione, riportandolo in fondo a questo articolo.

Novità di xCode 5. Vediamo prima quali sono le novità introdotte in xCode 5:

  • Configurazione automatica: i progetti vengono automaticamente configurati per supportare i servizi Apple come iCloud, Passbook Game Center. Inserendo il proprio Apple ID, è possibile gestire anche il proprio team, i certificati e gli entitlements, il tutto direttamente da IDE (cosa che prima si effettuava connettendosi al Provisioning Portal). In base ai servizi richiesti, xCode importa anche i framework necessari e crea gli appropriati provisioning profiles, “firmando” l’app ogni volta che viene “buildata”.
  • Test Navigator: il test-driven development diventa più semplice, utilizzando il nuovo Test Navigator, editor in cui creare, modificare e lanciare gli unit tests. Si possono lanciare singoli test o gruppi di test, grazie ad Assistant Editor.
  • Bots per il Continuous Integration: xCode si integra (integrerà) con l’OS X Server del Sistema Operativo OS X Mavericks, permettendo la creazione di “bots” che “buildano” continuamente l’app ed eseguono i test e lo static analyzer per scovare potenziali bug. I bots possono essere lanciati su qualsiasi Mac presente in rete, monitorando l’integration work su macchina locale.
  • Auto Layout: l’auto-layouting permette di “aggiustare” automaticamente la dimensione delle view grafiche, il loro orientamento e la localizzazione (internazionalizzazione), direttamente da Interface Builder. Introdotti a tale scopo il free-form canvas e i constraints (in realtà già presenti nelle versioni precedenti di xCode).
  • Asset Management: grazie agli Asset Catalogs (salvati su file compressi con estensione .xcassets) si possono gestire le immagini inserite nelle app. Le diverse versioni della stessa immagine (per le differenti risoluzioni dei device) vengono collezionate tutte in un singolo file. L’Asset Catalog sceglie quale immagine renderizzare in base al device su cui si testa e permette anche di scalarla dinamicamente.
  • Debug deeper analysis: con il nuovo strumento di debug è possibile misurare anche il consumo dei dati, la memoria CPU occupata, l’energia in uso, e altri valori prestazionali (deeper analysis), allertando lo sviluppatore in caso di overhead.
  • Visual Debugger: il debugger utilizzato è l’LLDB engine (nelle precedenti versioni c’era anche GDB, adesso completamente rimosso). Resa più leggibile e chiara la visualizzazione dei messaggi di debug ed inseriti “data tips” più esplicativi. Finalmente, si può “ispezionare” con un singolo click la variabile/oggetto e stampare le sue proprietà direttamente sulla debug console.
  • Source Control: migliorato il sistema di versioning che visualizza anche i branch attivi di progetto e permette agevolmente di switchare, creare e mergiare i branch stessi. E’ possibile gestire in un singolo punto tutte le repository (Accounts preferences) e l’OS X Server su OS X Mavericks permette (permetterà) di “hostare” anche repository GIT per il team di sviluppo.

 

Problemi post-upgrade ad xCode 5. Riporto di seguito le anomalie riscontrate (e corrette) dopo l’aggiornamento ad xCode 5, su progetti scritti su versioni precedenti.

Nota. Questo articolo sarà costantemente aggiornato, man mano che mi si presenteranno anomalie su “vecchi” progetti nel nuovo ambiente di xCode 5.

  • Impossibile debuggare, visualizzazione del messaggio “Attaching appname” con schermata nera sul vostro Simulatore iOs. Se non riuscite più a debuggare le vostre app, vi viene mostrato continuamente il messaggio “Attaching <appname>” e lo screen del Simulatore vi rimane nero, senza dar minimo segno di visualizzazione della vostra app, nelle precedenti versioni di xCode bastava switchare dal debugger LLDB a GDB (Scheda Product>>Edit Scheme). Adesso, avendo eliminato il debugger GDB, tale procedura non funziona più e vi conviene seguire il seguente “how-to”: http://stackoverflow.com/questions/15174282/why-does-the-lldb-debugger-constantly-fail-to-attach. Occorre cioè assicurarsi che sul vostro file di hosts (presente al patch /private/etc/hosts del vostro Mac) si faccia lookup” di localhost su 127.0.0.1. Nel mio file di hosts, invece, vi erano mappati altri valori (colpa di Adobe Professional!).

(continua…)

 

[GIT] Il versionamento distribuito con GIT ed un efficiente modello di branching

Vi scrivo oggi di un interessante modello di versionamento che si basa sul famosissimo GIT, repo usata ai primordi per la distribuzione del kernel Linux e negli ultimi tempi come maturo e completo sistema di versioning distribuito. GIT ha attirato gran parte degli sviluppatori di vari linguaggi, tanto da diventare più utilizzato di SVN.

Per la configurazione di GIT e alcune nozioni di base, vi rimando all’ottimo articolo “CVS, SVN e GIT!“.
Per approfondire, il miglior riferimento è il freebook online: http://git-scm.com/book
Carina è anche la semplice guida “git – the simple guide
Personalmente uso il servizio online di GITHUB per versionare i miei progetti. Anche se mi sto trovando molto bene con Assembla, invece, per versionare piccoli progetti su repo SVN. Ho utilizzato Mercurial, ma ho avuto non pochi problemi di compatibilità/bug con vari plugin HG. Se volete versionare su una repo GIT, vi consiglio di installare i client SmartGIT, SourceTree o Tortoise (su Mac, ma alcuni anche per Windows). Su XCode in Mac, il plugin di GIT è già configurato e potete sceglierlo come versionatore del vostro progetto.
Ora, qual è il punto di forza di GIT? Sicuramente la decentralizzazione del codice sorgente. Nell’articolo che vi linko, si enumerano i punti a favore di GIT rispetto a sistemi centralizzati di controllo versione come SubversionWhy you should switch from SubVersione to GIT
In sintesi, come già detto, GIT ha il vantaggio di essere una repo distribuita. Invece di lanciare il comando “svn checkout (url)“, che preleva l’ultima versione della repository di progetto, su GIT si lancia il comando “git clone (url)”  che copia-clona l’intera history di progetto. Ciò significa che il clone non intacca il progetto originale presente sulla repo e uno sviluppatore può autonomamente lavorare su una sua copia, in modalità offline.
Con questo nuovo paradigma è possibile committare in una repository locale anche in assenza di connessione alla rete, cosa che invece non era possibile con SVN, visto che il committ viene fatto interamente sulla repo remota.
Altro vantaggio implicito di questo modello è che il workflow non ha un “single point of failure“. In GIT ciascun membro può pushare su qualsiasi altro server se quello centrale viene corrotto, così che altri membri possono accedere in SSH e ripristinare la working copy in pochi minuti.
Grazie al meccanismo di pull e push, la sincronizzazione tra le repo GIT di ciascun membro è alquanto efficiente. Il meccanismo distribuito permette di creare tante repo private (locali) e sincronizzarle con quelle pubbliche. Un integration manager può pullare tutte le copie pubbliche su un unico “gold repository”, dove ci sarà la versione stabile da deployare in produzione.

 

Una feature ben fatta di GIT è quella che permette il merging tra i branch. Ogni membro del team può creare la propria “feature” su un branch separato e committare/pullare il tutto sul branch condiviso (modello che approfondiremo in seguito).
Quando viene creato un branch in GIT, si può facilmente switchare a quello nuovo per iniziare a svilupparci sopra. I branch si possono riaprire per fixare bug, inserire nuovo codice e poi mergiare il tutto sulla “mainline work“. L’operazione di merge genera pochissimi conflitti sui file.
Esiste una vera e propria “area di sosta” dei file, detta staging area, che non è altro che una cache locale in cui si trovano le modifiche del codice prima del commit. Questa è molto utile per avere una peer-review del lavoro fatto. E’ possibile committare i singoli changeset in seguito. GIT mantiene traccia di “parti di file” (stage files) come delta delle modifiche apportate al codice, che si possono committare selettivamente (patch staging).
Queste modifiche, logicamente separate, possono essere committate separatamente per una facile review del progetto e tale feature è detta cherry-pickable.
Passiamo ora alla descrizione di un efficiente modello di branch di GIT, prendendo come riferimento l’articolo “A successful GIT branching model“.

 

In questo modello esiste una repo denominata “origin” che è quella centrale in cui tutti i membri del team pullano e pushano una versione stabile o condivisa delle modifiche.

 

 

Main branches. La repo centrale contiene due main branches che vivono per tutta la durata del progetto e che si chiamano “master” e “develop“.

 

Il branch origin/master conterrà il codice che verrà messo in produzione. Il branch origin/develop è quello dove vengono pushate tutte le modifiche di sviluppo di ciascun membro del team di sviluppo e che viene continuamente aggiornato fino a quando non si è prodotta una versione stabile da mettere in produzione. È anche detto “branch di integrazione” delle repo distribuite tra i vari sviluppatori.
Quando si reputa stabile, il codice su origin/develop viene mergiato su origin/master.
Supporting branches.
Oltre ai branch “principali”, esistono altre tipologie di branch di vita limitata (detti branch di supporto) che si classificano come segue:
  • Feature branches
  • Release branches
  • Hotfix branches

Feature branches. Si stacca (branch off) da develop e si mergia sempre in esso. Si può chiamare in qualsiasi modo tranne che master, develop, release-* o hotfix-*.
Si chiama anche “topic branches” e contiene gli sviluppi di una features o funzionalità logica del progetto.
Per creare un nuovo feature branch facendo il branch off da develop:
$ git checkout -b myfeature develop
Switched to a new branch "myfeature"
 Per mergiare la feature su develop quando è stata ultimata:
$ git checkout develop
#Switched to branch 'develop'
$ git merge --no-ff myfeature
#Updating ea1b82a..05e9557
#(Summary of changes)
$ git branch -d myfeature
#Deleted branch myfeature (was 05e9557).
$ git push origin develop
Il flag –no-ff (dove “ff” sta per “fast-forward”) evita di “confondere” il codice della features nella mainline di progetto. Molto utile nel caso si voglia ricostruire la storia dei commit.

 

Release branches. Il branch off qui avviene da develop e si può mergiare sia su master che su develop. La naming convention è release-*. Questo tipo di branch supporta la preparazione per un nuovo rilascio in produzione. Infatti, mette a disposizione un insieme di metatag utili per etichettare la build version, la data di rilascio, ecc.
Per creare un release branch da develop, supponendo di stare alla versione 1.1.5 in produzione e di voler passare alla 1.2:
$ git checkout -b release-1.2 develop
#Switched to a new branch "release-1.2"
$ ./bump-version.sh 1.2
#Files modified successfully, version bumped to 1.2.
$ git commit -a -m "Bumped version number to 1.2"
#[release-1.2 74d9424] Bumped version number to 1.2
#1 files changed, 1 insertions(+), 1 deletions(-)
 A questo punto, possiamo mergiare il release branch sul master:
$ git checkout master
#Switched to branch 'master'
$ git merge --no-ff release-1.2
#Merge made by recursive.
#(Summary of changes)
$ git tag -a 1.2
Per prendere le modifiche fatte nel release branch e portarle in develop:
$ git checkout develop
#Switched to branch 'develop'
$ git merge --no-ff release-1.2
#Merge made by recursive.
#(Summary of changes)
Infine, per rimuovere il release branch:
$ git branch -d release-1.2
#Deleted branch release-1.2 (was ff452fe).

 

Hotfix branches. Il branch off si fa da master e si mergia sia in master che in develop. Il naming convention è hotfix-*.
È come il release branch ma viene creato dopo che si ha uno stato indesiderato in produzione, come un bug critico da risolvere immediatamente. A tal scopo di fa un branch off dal corrispondente tag del master che marca la versione in produzione.

Supponendo di avere in produzione la versione 1.2 su cui è avvenuto un severe bug, un hotfix branch si crea così:

 

$ git checkout -b hotfix-1.2.1 master
#Switched to a new branch "hotfix-1.2.1"
$ ./bump-version.sh 1.2.1
#Files modified successfully, version bumped to 1.2.1.
$ git commit -a -m "Bumped version number to 1.2.1"
#[hotfix-1.2.1 41e61bb] Bumped version number to 1.2.1
#1 files changed, 1 insertions(+), 1 deletions(-)
 I commit delle modifiche per la correzione del bug si effettuano su tale hotfix:
$ git commit -m "Fixed severe production problem"
#[hotfix-1.2.1 abbe5d6] Fixed severe production problem
#5 files changed, 32 insertions(+), 17 deletions(-)
A fine correzione, il merge sul master si fa come un release branch:
$ git checkout master
#Switched to branch 'master'
$ git merge --no-ff hotfix-1.2.1
#Merge made by recursive.
#(Summary of changes)
$ git tag -a 1.2.1
E per allineare il develop con il bugfix:
$ git checkout develop
#Switched to branch 'develop'
$ git merge --no-ff hotfix-1.2.1
#Merge made by recursive.
#(Summary of changes)
Unica eccezione si ha quando la fix riguarda un release branch esistente. In tal caso, l’hotfix va mergiato su tale release, invece che su develop.
Per rimuovere l’ hotfix branch:
$ git branch -d hotfix-1.2.1
#Deleted branch hotfix-1.2.1 (was abbe5d6).

[BugTracker] Installazione di Mantis

In questo articolo, scrivo due righe sull’installazione di un software di bug tracker open-source: Mantis Bug Tracker (www.mantisbt.org). Poiché ho trovato la guida di installazione alquanto incompleta, vista poi la semplicità di setup e configurazione dello stesso, condivido qui la mia esperienza.

Ecco i singoli passi:

  • Download del pacchetto di Mantis dal sito ufficiale: http://www.mantisbt.org/download.php (io ho scaricato l’ultima versione che, ad oggi, è la 1.2.8);
  • Una volta scaricato il pacchetto, occorre scompattarlo e deployarlo nella directory del proprio web server (si richiede un server Apache con supporto a PhP – come segnalato nei requisiti minimi). Io ho usato EasyPhP 5.3, che trovate a questo link: www.easyphp.org; ma vi consiglio anche XAMPP (specie se usate ambiente Unix): www.apachefriends.org/it/xampp.html ;
  • Oltre al web server Apache, occorre mettere su un DBMS per poter permettere a Mantis di creare le tabelle di sistema. Il DBMS che richiede è MySQL (provato con la versione 5) oppure PostgreSQL (ancora sperimentale). Una volta installato il DBMS, basta appuntarsi le credenziali di un utente di root che ci serviranno per configurare Mantis;
  • Deployato il pacchetto scompattato di Mantis nel web server (nel mio caso, ho copiato il pacchetto mantis sotto la directory webapps), occorre installarlo. In primis, occorre rinominare il file config_inc.php.sample in config_inc.php e aprirlo per inserire le credenziali di accesso al database. Per esempio, ho creato un nuovo schema (mantis) in MySQL5, con un utente root (la cui password è root):

# — Database Configuration —
$g_hostname      = ‘localhost’;
$g_db_username   = ‘root’;
$g_db_password   = ‘root’;
$g_database_name = ‘mantis’;
$g_db_type       = ‘mysql’;

$g_default_language= ‘italian’; (questa riga l’ho messa io per settare la lingua di default)

NOTA. La creazione iniziale dello schema si può fare anche in automatico, con il passo che verrà descritto di seguito, ma ho preferito farla prima e mappare le credenziali di accesso nel file conf_inc.php, come suddetto.

  • A questo punto, siamo pronti per lanciare la procedura di installazione automatica, che permetterà a Mantis di creare tutte le tabelle di sistema nel nostro database: http://hostname:port/mantis/admin/install.php (sostituire, come è ovvio, hostname e port con il proprio hostname e la porta su cui espone il proprio web server; mantis è il context-root del pacchetto che ho precedentemente deployato sotto webapps);
  • Seguire la procedura guidata inserendo i campi richiesti (controllando la correttezza delle credenziali di accesso al database).

Se tutto è andato a buon fine, basta accedere alla pagina di login di Mantis (http://hostname:port/mantis/login_page.php) con l’account di amministrazione (di default è administrator, se non lo si modifica nella procedura guidata di installazione, con la password specificata oppure con la stessa del DBMS).

Ricordarsi, per motivi di sicurezza, di eliminare la cartella admin presente nella root di Mantis!

Creative Commons License
This work by Francesco Ficetola is licensed under a Creative Commons Attribution 4.0 International License.
Based on a work at www.francescoficetola.it.
Permissions beyond the scope of this license may be available at http://www.francescoficetola.it/2012/01/24/bugtracker-installazione-di-mantis/.

[Liferay5] Problema cancellazione utente/i da pannello di controllo

Mi è capitato un bug nella cancellazione degli utenti da pannello di controllo di Liferay. La versione incriminata è la 5.2.3. Il sistema ha creato in maniera errata alcuni account utente in fase di registrazione ed, evidentemente, alcune informazioni erano vitali per poter ricercare tali utenze da pannello di controllo, ed eseguire su di essi operazioni di modifica o cancellazione.

Probabilmente, il motivo di errata registrazione era dovuto ad una gestione non transazionale della creazione degli utenti in fase di autenticazione (è stata modificata la classe LoginUtil di Liferay, chiamando un WerbService per recuperare le informazioni di un utente registrato e memorizzando l’account sul db di Liferay, associandolo a gruppi e ruoli predefiniti).

Qualcosa in questi passi suddetti è andato storto, magari per un eccessivo carico di accessi al sistema. Fatto sta che alcuni account contenevano informazioni incomplete (utenze non associate a gruppi/ruoli, dettagli personali non aggiornati, … ) e non erano ricercabili dal quadro di controllo di Liferay e, dunque, nemmeno modificabili o cancellabili. Dopo averci sbattuto la testa e avendo provato diverse strade, la questione si è risolta con la soluzione che sto qui a dirvi, ossia con una cancellazione forzata con uno script SQL sulle tabelle di sistema di Liferay.

Da premettere che la cancellazione di questi account “corrotti” è stata necessaria per permettere a tali utenti di poter accedere al sistema con le proprie credenziali di posta. Liferay riconosce come già registrato al sistema un utente in base alla sua email (o screenName).

So che non è consigliabile mettere le mani sul db di Liferay, ma a mali estremi, estremi rimedi. Non potendo risolvere altrimenti (primo tentativo fatto con una portlet che richiamava le API di Liferay per la cancellazione di un utente – UserLocalServiceUtil.deleteUser(long idUser) – che ha funzionato solo per alcuni utenti), è stato indispensabile ed inevitabile cancellare con una query secca gli account corrotti.

Vi allego la procedura SQL creata (utilizzata su MySQL), che si può adattare anche ad altri DBMS. La soluzione è stata trovata nel forum di Liferay, di cui allego il link in fondo a questo articolo, ma modificando lo script SQL facendo delle cancellazioni puntuali sugli account corrotti e non sui record “orfani” che non trovano un riferimento (idUser) nella tabella User_. Usando, infatti, questa ultima soluzione (segnalata appunto nel post anzidetto), venivano cancellate una serie di informazioni vitali per il corretto funzionamento del sistema.

Ecco come si è proceduto per la cancellazione degli account utente “corrotti” dallo schema di Liferay, con una transazione SQL,:

  1. creazione di una tabella di appoggio (l’abbiamo chiamata USERS_TO_DELETE) in cui abbiamo elencato gli ID degli account da cancellare. Questi ID non sono altro che quelli che si recuperano dalla tabella User_ (colonna userID);
  2. creazione dello procedura SQL che elimina prima tutti record corrispondenti agli ID enumerati al punto 1 dalla tabella User_ e, successivamente, tutti i riferimenti agli stessi nelle altre tabelle di sistema di Liferay;
  3. Nello script SQL è stato mappato staticamente l’id di sistema del model “com.liferay.portal.model.User” (ID=10039 preso dalla tabella ClassName_);
  4. A questo punto, basta lanciare la procedura, a server spento!
  5. Dopo aver riavviato il server di Liferay, basta lanciare da pannello di amministrazione la funzionalità di svuotamento della cache del database (Quadro di controllo >> Gestione del server >> Svuota la cache del database).

Seguendo i precedenti passi, gli account che vogliamo eliminare, con tutte le informazioni correlate, vengono cancellati (in modo definitivo) dal sistema. Importante è l’operazione di svuotamento della cache del database, poiché mi è capitato di veder “magicamente” ricomparire un account cancellato!

Vi allego la procedura SQL e una serie di riferimenti usati per risolvere il problema.

Allegati

Procedura SQL Delete Users Liferay
Titolo: Procedura SQL Delete Users Liferay (0 click)
Etichetta:
Filename: procedure_delete_users_liferay.zip
Dimensione: 1 kB

Vi consiglio di leggere anche: