IDE dedicate allo sviluppo PHP ne esistono tante, da quelle gratuite a quelle a pagamento. Per lungo tempo ho usato strumenti come Eclipse o Aptana, arrivando a servirmi di editor specializzati in HTML/Javascript e – addirittura – CSS. Da un anno a questa parte, tuttavia, credo di aver trovato definitivamento un ambiente completo che, almeno nel mio caso, risolve tutti i miei problemi: PhpStorm.
Articoli con Tag ‘Sviluppo’
PhpStorm 2.0
Very short trick: rendere invisibili i commenti HTML
Commentare codice HTML è una prassi durante le prime fasi di sviluppo Web. Tuttavia il codice commentato rimane visibile all’interno della pagina, anche se viene ignorato dal browser. Selezionando “Visualizza Sorgente” o “Visualizza Codice” dal nostro browser, saremo sempre in grado di vederlo.
Very short snippet: PHP, tagliare a parole, contando i caratteri
Come già visto in Very short snippet: PHP word cut è più gradevole spezzare un testo a “parole”, in quanto si evita di tagliare una parola. C’è comunque chi preferisce tagliare contando i caratteri, in quanto rende i “tagli” più omogenei e simili tra loro, nonostante il forte rischio di tagliare una parola, mozzandola di netto!
Come impostare XCode per usare l’iPhone al posto del simulatore
Objective-C: un’alternativa all’uso di CGRectMake
CGRectMake() è una funzione (in realtà è un inline #define) molto usata soprattutto quando si creano da codice oggetti grafici o di interfaccia utente. Il suo utilizzo è quindi spesso legato all’inizializzazione di componenti UIKit, ma anche a semplici UIView o UIImageView. CGRectMake() restituisce una struct (struttura di tipo) CGRect:
1 2 3 4 5 | struct CGRect { CGPoint origin; CGSize size; }; typedef struct CGRect CGRect; |
Che a sua volta è composta da due diverse struct CGPoint e CGSize:
1 2 3 4 5 6 7 8 9 10 11 12 13 | struct CGPoint { CGFloat x; CGFloat y; }; typedef struct CGPoint CGPoint; /* Sizes. */ struct CGSize { CGFloat width; CGFloat height; }; typedef struct CGSize CGSize; |
Che, a loro volta ancora, contengono tipi CGFloat, ovvero tipi float. Se andiamo ad analizzare il codice della CGRectMake() troviamo:
1 2 3 4 5 6 7 8 | CG_INLINE CGRect CGRectMake(CGFloat x, CGFloat y, CGFloat width, CGFloat height) { CGRect rect; rect.origin.x = x; rect.origin.y = y; rect.size.width = width; rect.size.height = height; return rect; } |
Ne deriva, quindi, che questa parte di codice:
1 2 3 4 | UIButton *gbutton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; gbutton.frame = CGRectMake (12,409,100,40); [gbutton setTitle:@"Press" forState:UIControlStateNormal]; [mainWindow addSubview:gbutton]; |
Potrebbe, a ragione, essere scritta anche come:
1 2 3 4 | UIButton *gbutton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; gbutton.frame = (CGRect) {12,409,100,40}; [gbutton setTitle:@"Press" forState:UIControlStateNormal]; [mainWindow addSubview:gbutton]; |
Giusto per velocizzare un po’ l’esecuzione del codice…
Xcode shortcut
Xcode è davvero un ottimo ambiente di sviluppo, curato e denso di dettagli che rendono la scrittura di codice efficiente e piacevole. Tra questi c’è sicuramente la comodità del completamento automatico durante la digitazione, soprattutto quando si scrivono applicazioni per Apple iPhone, dove i framework sono tanti e ricordarsi sintassi e nomenclatura è impresa da pochi.
iPhone SecondApp: indovina il numero – parte 2
Come anticipato in iPhone FirstApp: indovina il numero – parte 1 vediamo come realizzare un’applicazione per Apple iPhone senza usare Interface Builder! Anzi, elimineremo fisicamente i file di Interface Builder creati dal wizard di Xcode. Alla fine di questo post, quindi, avremo un’applicazione identica, in tutto e per tutto, a quella realizzata nella parte prima, con la differenza che realizzeremo tutti i nostri componenti visivi, compresa la Window principale, completamente da codice.
L’applicazione già fatta, se volete solo scaricarla, è disponibile sul mio Google Code repository:
Vorrei far notare da subito come lo ZIP di questo esempio pesi meno di quello della scorsa volta!
Creiamo il progetto
Iniziamo creando il nostro progetto SecondApp (per distinguerlo da FirstApp), anche se questa volta sceglieremo Window-based Application:

Adesso andiamo ad eliminare tutto ciò che riguarda Interface Builder. Eliminiamo il file MainWindow.xib, situato nella cartella Resources: eliminatelo anche dal file system, quindi selezionate Also Move to Trash. Selezionate, poi, il file SecondoApp-info.plist ed eliminate il riferimento alla MainWindow nella casella Main nib file base name:

A questo punto non abbiamo più nessuna Window, almeno tramite Interface Builder. Quindi apriamo il file main.m, situato in Other Sources, e modifichiamo la funzione main() in questo modo:
1 2 3 4 5 6 7 8 9 10 11 | int main(int argc, char *argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; // avendo eliminato il file .xib abbiamo perso il puntamento // all'app delegate, quindi lo passiamo a "mano" int retVal = UIApplicationMain(argc, argv, nil, @"SecondAppAppDelegate"); [pool release]; return retVal; } |
Apriamo quindi SecondAppAppDelegate.m e creiamo la Window principale via codice:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | - (void)applicationDidFinishLaunching:(UIApplication *)application { // ottiene le dimensioni delle schermo (320, 480) CGRect windowRect = [[UIScreen mainScreen] applicationFrame]; // creiamo una finestra - visto che abbiamo fatto bye bye a Interface Builder UIWindow *mainWindow = [[UIWindow alloc] initWithFrame:windowRect]; // impostiamo il background della Window a giallo, per differenziarlo // dalla precedente applicazione FirstApp [mainWindow setBackgroundColor:[UIColor yellowColor]]; [self setWindow:mainWindow]; [window makeKeyAndVisible]; [mainWindow release]; } |
Potete già provare l’applicazione; se appare una window gialla avete fatto tutto bene!
Nel file SecondAppAppDelegate.h possiamo eliminare IBOutlet, necessario solo se si usa Interface Builder. Inoltre aggiungiamo qui le nostre variabili globali che, nella scorsa volta, avevamo inserito nel Controller. Modifichiamo quindi il file SecondAppAppDelegate.h:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | #import <UIKit/UIKit.h> @interface SecondAppAppDelegate : NSObject <UIApplicationDelegate> { UIWindow *window; UITextField *numero; UIButton *bottone; int numeroACaso; } @property (nonatomic, retain) UIWindow *window; - (void)controllaNumero; @end |
Anche in questo caso abbiamo preparato la definizione del metodo controllaNumero, come la scorsa volta, ma abbiamo eliminato l’indicazione IBAction, in quanto non stiamo usando Interface Builder.
Costruiamo l’interfaccia da codice
E’ giunto il momento di creare tramite codice tutti i componenti della nostra interfaccia. Torniamo nel file SecondAppAppDelegate.m, posizioniamoci prima del [mainWindow release] ed inseriamo il seguente codice:
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 | // crea la barra del titolo UINavigationBar *myNavigationBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 44.0)]; myNavigationBar.barStyle = UIBarStyleDefault; UINavigationItem *navigationItem = [[UINavigationItem alloc] initWithTitle:@"Indovina un numero"]; [myNavigationBar pushNavigationItem:navigationItem animated:NO]; [window addSubview:myNavigationBar]; // crea la label UILabel *myLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 50, 300, 80)]; myLabel.backgroundColor = [UIColor clearColor]; myLabel.numberOfLines = 2; myLabel.text = @"iPhone ha pensato un numero da 1 a 10, prova ad indovinarlo?"; [window addSubview:myLabel]; // crea il text input numero = [[UITextField alloc] initWithFrame:CGRectMake(10, 120, 300, 30)]; numero.borderStyle = UITextBorderStyleRoundedRect; numero.textAlignment = UITextAlignmentCenter; numero.keyboardType = UIKeyboardTypeNumberPad; numero.placeholder = @"Inserisci il numero"; [window addSubview:numero]; // crea il bottone bottone = [UIButton buttonWithType:UIButtonTypeRoundedRect]; bottone.frame = CGRectMake(10, 180, 300, 30); [bottone setTitle:@"Premi qui" forState:UIControlStateNormal]; [bottone addTarget:self action:@selector(controllaNumero) forControlEvents:UIControlEventTouchUpInside]; [window addSubview:bottone]; [myLabel release]; [navigationItem release]; [myNavigationBar release]; |
Dato che l’applicationDidFinishLaunching corrisponde alla viewDidLoad della scorsa volta, subito dopo il [mainWindow release]; inseriamo:
1 | numeroACaso = 1 + arc4random() % 10; |
Ora non ci rimane che implementare il metodo controllaNumero, che sarà identico (a parte il prototipo) a quello usato la scorsa volta:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | - (void) controllaNumero { NSLog(@"Premuto bottone di controlla numero"); int numeroInserito = [numero.text integerValue]; NSString *message; NSLog(@"Il numero inserito è %d", numeroInserito ); if( numeroInserito <numeroACaso ) { message = @"Troppo basso..."; } else if (numeroInserito> numeroACaso ) { message = @"Troppo alto..."; } else if (numeroInserito == numeroACaso ) { message = @"Bravo hai indovinato"; numeroACaso = 1 + arc4random() % 10; NSLog(@"Numero pensato %d", numeroACaso); } UIAlertView *alertMessaggio = [[UIAlertView alloc] initWithTitle:@"Responso" message: message delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alertMessaggio show]; [alertMessaggio release]; numero.text = @""; } |
Abbiamo finito!
Conclusioni e considerazioni
Questo esempio non fa uso diretto di una UIView o di un UIViewController, proprio perchè volevo lasciarlo il più semplice e snello possibile e, anche, per dimostrare che non sono elementi sempre necessari. Tuttavia inserire gli oggetti direttamente nella window può avere un qualche senso in questo esempio ed in altri sporadici contesti. L’uso delle UIView e dei UIViewController portano comunque benefici in tantissimi altri casi, ein alcuni sono praticamente indispensabili; come avremo modo di vedere in futuro.
iPhone: tutti i font di sistema
L’Apple iPhone mette a disposizione un numero limitato di Font agli sviluppatori. La lista dei font disponibili è facilmente ottenibile da codice, come vedremo. Se volete usare un vostro font, ad esempio includendolo nelle risorse, la cosa è un pochino più articolata e conivolge anche la questione delle licenze (diritti) sui font “embeddati”… ne riparleremo in seguito. Tornando invece ai font ufficiali presenti nell’Apple iPhone questi sono (cliccate sull’immagine per ingrandire):
L’SDK di Apple iPhone permette di accedere a degli speciali font di sistema. Questi sono identificati da particolari costanti e sono:
1 2 3 | UIFont *myBoldFont = [UIFont boldSystemFontOfSize:12.0]; UIFont *mySystemFont = [UIFont SystemFontOfSize:12.0]; UIFont *myItalicFont = [UIFont italicSystemFontOfSize:12.0]; |
Se volete invece ottenere un puntatore ad uno odei font mostrati nell’immagine di sopra basta usare:
1 | UIFont *myCustomFont = [UIFont fontWithName:@"Helvetica-Bold" size:22.0]; |
Come avrete notato la gestione del font è particolare; oltre alla famiglia (Helvetica, Courier, etc…) bisogna specificare il tipo (bold, italic, etc…). In pratica, quindi, un font deve essere fornito di queste caratteristiche. L’Helvetica, ad esempio, è presente con:
1 2 3 4 | Helvetica Helvetica-Bold Helvetica-Oblique Helvetica-BoldOblique |
Se volete visualizzare direttamente i vostri font sull’iPhone, ecco qualche linea di codice utile:
1 2 3 4 5 6 7 8 9 10 11 12 | NSArray *listOfFonts = [[NSArray alloc] initWithArray:[UIFont familyNames]]; NSArray *subFontTypes; for (int i=0; i<[listOfFonts count]; i++) { NSLog(@"Font Family: %@", [listOfFonts objectAtIndex:i]); subFontTypes = [[NSArray alloc] initWithArray:[UIFont fontNamesForFamilyName:[listOfFonts objectAtIndex:i]]]; for (int j=0; j<[subFontTypes count]; j++) { NSLog(@"+----->Type: %@", [subFontTypes objectAtIndex:j]); } [subFontTypes release]; } [listOfFonts release]; |
Con le SDK 2.2.1, sul mio simulatore, ho ottenuto:
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 70 71 72 73 | Font Family: Courier +----->Type: Courier +----->Type: Courier-BoldOblique +----->Type: Courier-Oblique +----->Type: Courier-Bold Font Family: AppleGothic +----->Type: AppleGothic Font Family: Arial +----->Type: ArialMT +----->Type: Arial-BoldMT +----->Type: Arial-BoldItalicMT +----->Type: Arial-ItalicMT Font Family: STHeiti TC +----->Type: STHeitiTC-Light +----->Type: STHeitiTC-Medium Font Family: Hiragino Kaku Gothic ProN +----->Type: HiraKakuProN-W6 +----->Type: HiraKakuProN-W3 Font Family: Courier New +----->Type: CourierNewPS-BoldMT +----->Type: CourierNewPS-ItalicMT +----->Type: CourierNewPS-BoldItalicMT +----->Type: CourierNewPSMT Font Family: Zapfino +----->Type: Zapfino Font Family: Arial Unicode MS +----->Type: ArialUnicodeMS Font Family: STHeiti SC +----->Type: STHeitiSC-Medium +----->Type: STHeitiSC-Light Font Family: American Typewriter +----->Type: AmericanTypewriter +----->Type: AmericanTypewriter-Bold Font Family: Helvetica +----->Type: Helvetica-Oblique +----->Type: Helvetica-BoldOblique +----->Type: Helvetica +----->Type: Helvetica-Bold Font Family: Marker Felt +----->Type: MarkerFelt-Thin Font Family: Helvetica Neue +----->Type: HelveticaNeue +----->Type: HelveticaNeue-Bold Font Family: DB LCD Temp +----->Type: DBLCDTempBlack Font Family: Verdana +----->Type: Verdana-Bold +----->Type: Verdana-BoldItalic +----->Type: Verdana +----->Type: Verdana-Italic Font Family: Times New Roman +----->Type: TimesNewRomanPSMT +----->Type: TimesNewRomanPS-BoldMT +----->Type: TimesNewRomanPS-BoldItalicMT +----->Type: TimesNewRomanPS-ItalicMT Font Family: Georgia +----->Type: Georgia-Bold +----->Type: Georgia +----->Type: Georgia-BoldItalic +----->Type: Georgia-Italic Font Family: STHeiti J +----->Type: STHeitiJ-Medium +----->Type: STHeitiJ-Light Font Family: Arial Rounded MT Bold +----->Type: ArialRoundedMTBold Font Family: Trebuchet MS +----->Type: TrebuchetMS-Italic +----->Type: TrebuchetMS +----->Type: Trebuchet-BoldItalic +----->Type: TrebuchetMS-Bold Font Family: STHeiti K +----->Type: STHeitiK-Medium +----->Type: STHeitiK-Light |
iPhone FirstApp: indovina il numero – parte 1
Il primo sorgente che mi è passato tra le mani era scritto in Basic e consisteva in poche righe di codice, per me illuminanti. Era un semplice giochino che generava un numero casuale da 1 a 10 e, tramite l’input da tastiera, verificava che il numero inserito era maggione, minore o uguale al numero casuale. Nonostante la sua rozza semplicità rimane, per me, uno dei migliori esempi – semplici, divertenti e pratici – per spiegare a chi non sa nulla di programmazione cosa s’intenda effettivamente per “programma per computer”. Così ho pensato di riproporlo per Apple iPhone, magari aiuterà qualcuno…
Actionscript trace, Objective-C NSLog()
Riprendendo il post Da Actionscript ad Objective-C (dove si mettevano a confronto il codice e la sintassi Actionscript e Objective-C), in Actionscript abbiamo la comodissima funzione trace(), usata per il debug delle applicazioni. Questa funzione emette un output sulla console dell’ambiente di sviluppo Adobe Flash. Viene utilizzata principalmente nelle fasi di sviluppo e testing di “filmato”/applicativo. In XCode/Objective-C abbiamo: NSLog(). La sintassi di questa funzione è molto simile alla trace() di Actionscript:
1 | NSLog( @"Sono una linea di debug" ); |
In Actionscript avremmo:
1 | trace( "Sono una linea di debug" ); |
A parte l’uso della chiocciola (@), come potete vedere, sono identiche. Le differenze (e similitudini) iniziano quando si vogliano visualizzare valori di variabili; ad esempio in Actionscript potremmo avere:
1 2 3 | trace( "Coordinata x:" + x + " coordinata y:" + y ); // oppure trace( "Coordinate: ", x, y ); |
In Objective-C abbiamo:
1 | NSLog( @"Coordinata x:%i coordinata y:%i", x, y ); |
Nota:
NSLog()in realtà richiama la più generica funzioneNSLogv()che opera sull’Apple System Log. Le funzioni sono di fatto identica, cambiano solo i parametri in ingresso.
Gli sviluppatori C troveranno molto familiare la formattazione delle stringhe, come accade per printf() o sprintf(). Per dettagli si veda String Format Specifiers.








Ultimi Commenti
Giovambattista Fazioli: @vik: la validazione è sempre una questione complessa da gestire, in quanto bisogna...
vik: Users custom fields sembra interessante, andrebbe aggiunta la possibilità di validare il campo in base a...
kOoLiNuS: @Giovambattista Fazioli: ti ringrazio! più che volentieri!
Giovambattista Fazioli: @kOoLiNuS: Tranquillo, ti posso anticipare che probabilmente WPX cleanfix sarà gratuito, e...
kOoLiNuS: @kOoLiNuS: mancava un
e un