[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…)

 

[iOs] Il Logging nelle nostre app con le Preprocessor Macros

Prima di un rilasciare una app iOS su Apple Store, è buona prassi fare un pò di pulizia dei log sparsi nel codice. Molti sviluppatori, infatti, sono restii all’utilizzo del debug e preferiscono utilizzare, man mano che sviluppano, la classe NSLog e farsi stampare gli output sulla console. Dunque, i nostri progetti rimangono pieni di NSLog che, tuttavia, è meglio non rilasciare sulle app in esercizio. Il motivo è dovuto al fatto che la scrittura dei log è onerosa e potrebbe ridurre le performance della nostra app. Inoltre, anche se la console del device è nascosta all’utente, potremmo dimenticare di loggare informazioni sensibili … e ciò è “no buono”.

Ho letto un pò di articoli a riguardo, tra cui i seguenti:

Ecco la procedura che ho seguito, utilizzando le Preprocessor Macros. L’idea è quella di inserire un flag (-DDEBUG) nella configurazione di DEBUG del nostro progetto e importare nelle nostre classi un log “custom” (DLog oppure ALog).

  • Per prima cosa, inserite un file Log.h nel vostro progetto con il seguente contenuto:
#ifdef DDEBUG

#   define DLog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);

#else

#   define DLog(...)

#endif

// ALog always displays output regardless of the DEBUG setting

#define ALog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
  •  Poi spostatevi nella configurazione del vostro progetto (click sulla root di progetto, selezionate Targets e poi spostatevi nella scheda Builds Settings). Qui, cercate la voce “Other C Flags” e inserite il flag -DDEBUG in corrispondenza della configurazione di DEBUG.

  • NOTA. Il punto precedente non è necessario se in Log.h si va a controllare il valore del flag nativo DEBUG (che è true se siamo in ambiente di debug, false quando si è in modalità Release/Ad Hoc), anzichè DDEBUG (che è una nostra variabile “custom”)
    #ifdef DEBUG
  • Importate l’interfaccia Log.h nel file di progetto <YourApp>_Prefix.pch, in modo da rendere visibile la macro in tutte le classi (senza importare esplicitamente la macro ogni volta). Nel mio caso, ecco il contenuto del .pch:
#import <Availability.h>
#import "Log.h"

#ifndef __IPHONE_5_0
#endif

#ifdef __OBJC__
	#import <UIKit/UIKit.h>
	#import <Foundation/Foundation.h>
#endif
  • Infine, potete utilizzare i log “custom” normalmente come fareste con NSLog, come segue:
 DLog(@"Logging %d con %@",1, @"DLog");
 ALog(@"Logging %d con %@",2, @"ALog");

Eccovi l’output di esempio delle precedenti righe di log:

2012-12-25 15:03:16.276 MyApp [4451:907] -[AppDelegate application:didFinishLaunchingWithOptions:] [Line 33] Logging 1 con DLog
2012-12-25 15:03:16.281 MyApp [4451:907] -[AppDelegate application:didFinishLaunchingWithOptions:] [Line 34] Logging 2 con ALog

DLog e ALog, per come sono stati configurati nel Log.h, stampano anche il nome della classe, il metodo e la riga di codice in cui si trovano. ALog stampa anche se non siamo in DEBUG (quindi, come NSLog, loggherebbe anche quando abbiamo rilasciato l’app su Apple Store o con una distribuzione “ad hoc”).

Quindi, lanciando la vostra app in DEBUG (sia sul Simulatore che sul device) vi troverete i log stampati sulla console. In Release (sia su App Store che su una distribuzione “ad hoc” dell’IPA) non verrà loggato nulla sul device dell’utente, se avete utilizzato DLog (e non ALog oppure NSLog).