https://github.com/tiknil/objective-c-style-guide
Tiknil's style guide & coding conventions for Objective-C projects
https://github.com/tiknil/objective-c-style-guide
Last synced: 3 months ago
JSON representation
Tiknil's style guide & coding conventions for Objective-C projects
- Host: GitHub
- URL: https://github.com/tiknil/objective-c-style-guide
- Owner: tiknil
- License: mit
- Created: 2015-11-07T14:42:47.000Z (over 10 years ago)
- Default Branch: master
- Last Pushed: 2015-11-25T08:19:50.000Z (over 10 years ago)
- Last Synced: 2025-01-16T07:54:28.163Z (over 1 year ago)
- Homepage: http://www.tiknil.com
- Size: 16.6 KB
- Stars: 1
- Watchers: 5
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# objective-c-style-guide #
:exclamation: DRAFT :exclamation:
Guida di riferimento per i progetti Objective-C in Tiknil.
Non vuole essere l'ennesima riproposizione dello stile di stesura dei progetti in questo linguaggio, ma uno strumento utile per il team e i suoi collaboratori.
Sentitevi liberi di dissentire da quanto abbiamo deciso di tenere come stile guida! :wink:
### TL;DR ###
Troppo lunga da leggere? E' solo l'ennesima guida di stile di Obj-C?
Ok, passiamo al dunque, nerd: usa i tool che ti elenchiamo per cominciare a 'subire' un po' di codice di qualità:
1) [XCode snippets](https://github.com/tiknil/xcode-snippets) - dovresti leggere perché usarli, almeno
2) Installa `BBUncrustifyPlugin` tramite [Alcatraz](http://alcatraz.io/) e usa il file `uncrustify.cfg` che trovi nel presente repo. Tranquilli, è tutto ben descritto in [Tools](#tools).
### References ###
Di seguito le linee guida che abbiamo consultato e a cui facciamo riferimento per la stesura di questo documento:
* [Apple coding guidelines](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CodingGuidelines/CodingGuidelines.html)
* [Ray Wenderlich Obj-C style guide](https://github.com/raywenderlich/objective-c-style-guide)
* [NY Times Obj-C style guide](https://github.com/NYTimes/objective-c-style-guide)
* [GitHub Obj-C style guide](https://github.com/github/objective-c-style-guide)
* [Google Obj-C style guide](https://google.github.io/styleguide/objcguide.xml)
### Concetti di base ###
Perché abbiamo preso certe scelte e non altre? Ecco i concetti che guidano alcune scelte esposte in questa guida (in ordine non per forza di priorità):
* [Bellezza](https://it.wikipedia.org/wiki/Bellezza) e stile uniforme, anche nel codice
* Comprensibilità del codice da chiunque
* Velocità di scrittura del codice
* Produzione della documentazione in Italiano
* Somiglianze con altri linguaggi che utilizziamo per i progetti
* Abitudini nostre (in via di miglioramento)
### Sommario ###
1. [Lingua](#lingua)
2. [Organizzazione implementazione delle classi](#organizzazione-implementazione-delle-classi)
3. [Commenti](#commenti)
4. [Naming](#naming)
* [Dichiarazione dei metodi](#dichiarazione-dei-metodi)
* [Variabili](variabili)
* [Attributi delle `@property`](#attributi-delle-property)
* [Underscores](#underscores)
* [Categories](#categories)
5. [Literals](#literals)
[Tools](#tools)
### Lingua ###
Usare la lingua **Inglese** per il **codice**, quella **Italiana** per i **commenti** e la **documentazione** del codice (ove non espressamente richiesta la lingua inglese)
:+1: `UIColor *myColor = [UIColor whiteColor];`
:-1: `UIColor *mioColore = [UIColor whiteColor];`
### Organizzazione implementazione delle classi ###
Raccomandato l'uso dei ```#pragma mark```per raggruppare i metodi in gruppi funzionali e legati all'implementazione dei protocolli/delegati seguendo la struttura seguente (da [RW Obj-C style guide](https://github.com/raywenderlich/objective-c-style-guide)):
```
#pragma mark - Class methods
+ (instancetype) shared;
#pragma mark - Lifecycle
- (instancetype)init {}
- (void)dealloc {}
- (void)viewDidLoad {}
- (void)viewWillAppear:(BOOL)animated {}
- (void)didReceiveMemoryWarning {}
#pragma mark - Custom Accessors
- (void)setCustomProperty:(id)value {}
- (id)customProperty {}
#pragma mark - IBActions
- (IBAction)submitData:(id)sender {}
#pragma mark - Public
- (void)publicMethod {}
#pragma mark - Private
- (void)privateMethod {}
#pragma mark - Protocol conformance
#pragma mark - UITextFieldDelegate
#pragma mark - UITableViewDataSource
#pragma mark - UITableViewDelegate
#pragma mark - NSCopying
- (id)copyWithZone:(NSZone *)zone {}
#pragma mark - NSObject
- (NSString *)description {}
```
Per semplificare l'utilizzo dell'organizzazione del codice come descritto consigliamo di utilizzare lo *snippet* di XCode apposito come descritto nel repo [Xcode-snippets](https://github.com/tiknil/xcode-snippets): basta digitare ```def``` quando si sta per stendere l'implementazione di una nuova classe.

### Commenti ###
Per scrivere codice di qualità i commenti sono fondamentali: essi rientrano nei [requisiti non funzionali o di qualità (ISO IEC 9126)](https://it.wikipedia.org/wiki/ISO/IEC_9126) di tutti i progetti sofware all'interno della voce "Manutenibilità".
* I commenti, quando necessari, devono spiegare perché una particolare parte di codice fa qualcosa. Ogni commento che è utilizzato dev'essere sempre aggiornato o eliminato.
* Preferire codice auto-esplicativo (dando nomi significativi alle variabili e ai metodi, vedi [Naming](#naming), se possibile, rispetto ai commenti. Nel dubbio, metterli entrambi.
Come commentare? Ecco un ottimo (e breve) articolo su NSHipster relativo alla documentazione Obj-C [Documentation](http://nshipster.com/documentation/)
```
/**
Questo è un commento
*/
```
e
```
/**
Questo è il commento alla dichiarazione di questo metodo che ha come parametro paramValue e che ritorna come risultato resultValue
@param paramValue il parametro passato a questo metodo
@result resultValue il risultato che viene ritornato x o y in base al parametro
*/
```
Non sei sicuro di riuscire a ricordarti sempre come scrivere i commenti? Fatti aiutare dagli [snippets `com`...](https://github.com/tiknil/xcode-snippets)!
### Naming ###
Fare riferimento alle [linee guida Apple](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CodingGuidelines/Articles/NamingBasics.html#//apple_ref/doc/uid/20001281-BBCHBFAH) riprese anche da [RW](https://github.com/raywenderlich/objective-c-style-guide/blob/master/README.md#naming) per cui:
I nomi dei metodi e delle variabili devono essere descrittivi, va bene anche se sono lunghi
:+1: `UIButton *settingsButton;`
:-1: `UIButton *setBut;`
Le costanti devono essere *camel-case* con tutte le parole con la prima lettera maiuscola e devono iniziare con il nome della classe a cui fanno riferimento (se lo fanno).
:+1: `static NSTimeInterval const RWTTutorialViewControllerNavigationFadeAnimationDuration = 0.3;`
:-1: `static NSTimeInterval const fadetime = 1.7;`
I campi (`@property`) delle classi devono essere *camel-case* con la prima lettera minuscola. Preferire l'auto-sintesi dei campi piuttosto che scrivere manualmente i `@synthesize` a meno che ci sia una buona ragione.
:+1: `@property (strong, nonatomic) NSString *descriptiveVariableName;`
:-1: `id varnm;`
#### Dichiarazione dei metodi ####
I nomi dei metodi devono essere descrittivi, come già detto nel paragrafo precedente. I parametri formali del metodo devono essere separati da uno spazio (come da stile Apple). Aggiungere sempre un nome per il parametro e descrivere a cosa serve quel parametro.
Non usare le parole 'and' e 'with' o similari, come descritto in questi esempi:
:+1:
```
- (void) setExampleText:(NSString *)text image:(UIImage *)image;
- (void) sendAction:(SEL)aSelector to:(id)anObject forAllCells:(BOOL)flag;
- (id) viewWithTag:(NSInteger)tag;
- (instancetype) initWithWidth:(CGFloat)width height:(CGFloat)height;
```
:-1:
```
- (void) setT:(NSString *)text i:(UIImage *)image;
- (void) sendAction:(SEL)aSelector :(id)anObject :(BOOL)flag;
- (id) taggedView:(NSInteger)tag;
- (instancetype) initWithWidth:(CGFloat)width andHeight:(CGFloat)height;
- (instancetype) initWith:(int)width and:(int)height; // Never do this.
```
#### Variabili ####
Le variabili devono essere il più descrittive possibile. L'uso di variabili con una sola lettera è ammesso solo per i cicli `for`.
Dove si mette l'asterisco per le variabili che puntano ad un oggetto?
:+1: `NSString *text`
:-1: `NSString* text` or `NSString * text` (tranne che per le costanti)
Si preferisce l'uso delle `@property` private piuttosto che d'istanza. Per `@property` private si intende quelle con definizione nel file `.m` in una categoria detta **anonima** (indicata dal fatto che è descritta con `()`):
```
interface RWTDetailViewController ()
@property (strong, nonatomic) GADBannerView *googleAdView;
@property (strong, nonatomic) ADBannerView *iAdView;
@property (strong, nonatomic) UIWebView *adXWebView;
@end
```
Si preferisce usare le `@property` private piuttosto che i campi d'istanza. Questo vale anche per i campi `IBOutlet` generati (o predisposti) da drag&drop a partire da Interface Builder: di default vanno messi come `@property` privata nel file `.m`; qualora sia necessario averli pubblici, allora verranno spostati nel `.h`.
:+1:
```
@interface RWTTutorial : NSObject
@property (strong, nonatomic) NSString *tutorialName;
@end
```
:-1:
```
@interface RWTTutorial : NSObject {
NSString *tutorialName;
}
```
Come descritto in [Underscores](#underscores) si preferisce non accedere direttamente alle `@property` se non nei metodi di 'Lifecicle' dell'oggetto (`init`, `dealloc`, etc) e nei 'custom accessors'.
#### Attributi delle `@property` ####
Gli attributi delle property devono essere scritti perché servono ed aiutano chi legge il codice a comprenderlo meglio. L'ordine degli attributi deve essere: storage > atomicity così da essere coerente con il codice generato da Interface Builder quando si trascinano i collegamenti agli elementi UI.
:+1:
```
@property (weak, nonatomic) IBOutlet UIView *containerView;
@property (strong, nonatomic) NSString *tutorialName;
```
:-1:
```
@property (nonatomic, weak) IBOutlet UIView *containerView;
@property (nonatomic) NSString *tutorialName;
```
Preferire **`strong`** a **`retain`** (che sono la stessa cosa: [SO answer](http://stackoverflow.com/questions/8927727/objective-c-arc-strong-vs-retain-and-weak-vs-assign) - [Apple Doc](https://developer.apple.com/library/mac/releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html)) per migliore formattazione del codice
Usare sempre **`weak`** per gli oggetti `IBOutlet`. Ti chiedi perché? Fattelo spiegare da [NSHipster](http://nshipster.com/ibaction-iboutlet-iboutletcollection/) e dalla [Resource Programming Guide section on Nib Files di Apple](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/LoadingResources/CocoaNibs/CocoaNibs.html).
La [RW Obj-C style guide](https://github.com/raywenderlich/objective-c-style-guide/blob/master/README.md#error-handling) suggerisce di utilizzare **`copy`** piuttosto di **`strong`** per avere la certezza che la `@property` non venga mutata una volta assegnata. Chiaramente dipende dal contesto, quindi valutate di conseguenza
#### Underscores ####
Quando si usano i campi (`@property`) d'istanza essi devono essere sempre richiamati usando `self.`. Questo rende più evidente in maniera visiva l'utilizzo dei campi d'istanza.
Fa eccezione l'utilizzo dei campi con *underscore* (`_variableName`) nei metodi `init` o nei metodi getter/setter che ne richiedano l'utilizzo per il corretto funzionamento.
Le variabili locali **non devono contenere underscore**.
#### Categories ####
Le categories devono avere nomi che ne definiscano la funzionalità. Attenzione a non creare categories che fanno uso di altre categories (il debug potrebbe diventare arduo).
:+1: `@interface NSString (StringEncodingDetection)`
:-1: `@interface NSString (Utilities)`
_I metodi delle category devono avere sempre il prefisso seguito da underscore._ Questo limita la possibilità di creare eventuali duplicati di metodi esistenti tra le varie librerie.
`- (NSStringEncoding) sed_detectStringEncoding:(NSString*)string;`
Se hai necessità di esporre dei metodi privati per delle sottoclassi o per fare test crea una categories chiamata `Class+Private`
### Literals ###
Preferire sempre l'uso dei literals piuttosto delle descrizioni estese per gli oggetti del framework, in particolare `NSString`, `NSDictionary`, `NSArray` e `NSNumber`:
:+1:
```
NSArray *names = @[@"Brian", @"Matt", @"Chris", @"Alex", @"Steve", @"Paul"];
NSDictionary *productManagers = @{@"iPhone": @"Kate", @"iPad": @"Kamal", @"Mobile Web": @"Bill"};
NSNumber *shouldUseLiterals = @YES;
NSNumber *buildingStreetNumber = @10018;
```
:-1:
```
NSArray *names = [NSArray arrayWithObjects:@"Brian", @"Matt", @"Chris", @"Alex", @"Steve", @"Paul", nil];
NSDictionary *productManagers = [NSDictionary dictionaryWithObjectsAndKeys: @"Kate", @"iPhone", @"Kamal", @"iPad", @"Bill", @"Mobile Web", nil];
NSNumber *shouldUseLiterals = [NSNumber numberWithBool:YES];
NSNumber *buildingStreetNumber = [NSNumber numberWithInteger:10018];
```
### Tools ###
Per noi è importante trovare i tool che ci permettano di mantenere certe scelte in modo costante e coerente di progetto in progetto. Partecipando ad un interessante *talk* di Anastasia Kazakova (@anastasiak2512) alla #Pragma conf 2015 a Firenze abbiamo visto che IDE come AppCode integrano strumenti per la formattazione del codice in modo avanzato ma tramite alcuni plugin e risorse è possibile avere queste funzionalità anche su XCode.
Quello che abbiamo trovato più completo e facile da capire è [Uncrustify](http://uncrustify.sourceforge.net/) che in XCode è facilmente intergrabile tramite il plugin [BBUncrustifyPlugin](https://github.com/benoitsan/BBUncrustifyPlugin-Xcode), installabile anch'esso tramite [Alcatraz](http://alcatraz.io/).
Una volta installato basta andare in `Edit > Format Code > BBUncrustifyPlugin preferences`, scegliere come formatter `Uncrustify` e alla voce `Clang style` scegliere `Custom Style (File)` (se lo desiderate, altrimenti scegliete il formattatore che più vi [aggrada](https://www.youtube.com/watch?v=b3mGYIgR5_c)).
Alla voce `Configuration File` dunque scegliere `Create Configuration File` e il vostro editor di testo preferito (sarà indubbiamente [Sublime Text](http://www.sublimetext.com/).
Per utilizzare lo stile delineato in questa guida basta prendere il file `uncrustify.cfg` e copiarlo in una qualsiasi cartella padre della cartella del progetto di XCode che avete aperto. Il consiglio è di avere il file `uncrustify.cfg` nella cartella root dei vostri progetti iOS/OSX.
Se volete fare le cose per bene, fate così:
1) Fate un fork di questo repository e scaricatelo in locale nella cartella `$OBJ_C_STYLE_GUIDE_REPO`
2) Quindi create un link simbolico al file `uncrustify.cfg` nella cartella root dei vostri progetti iOS/OSX
```
ln -s $OBJ_C_STYLE_GUIDE_REPO/uncrustify.cfg $IOS_OSX_PROJECTS_ROOT/uncrustify.cfg
```
Per formattare un file o le righe selezionate in XCode tramite Uncrustify basterà quindi selezionare `Edit > Format Code > ` e scegliere `Format Selected Files`, `Format Active File` o `Format Selected Lines`.
Puoi impostare gli shortcut da tastiera semplicemente nell'app `Preferences` di sistema: 