La programmazione e l’opensource

Ultimamente mi sono ritrovato a lavorare a vari progetti iOS sviluppati da terzi e di cui non detenevo i diritti del codice sorgente, cioè la maggior parte del lavoro era stato fatto da altri.

La cosa che mi è saltata subito all’occhio è stato il numero elevato di codice opensource utilizzato, potrei ipotizzare il 90% del codice totale.

Ad una prima analisi viene da esclamare “bello! ci sono già un sacco di cose pronte!” ma in realtà questa situazione mi mette a disagio. Stiamo programmando un software o stiamo assemblando i pezzetti fatti da altri cercando di farli coesistere?

Sono pienamente convinto che ci sia una grande differenza tra programmare e utilizzare codice opensource in modo massiccio e l’avvento di soluzioni come CocoaPods e affini forse sta incentivando questa mania.
Sono a favore dell’opensource e sono a favore dell’utilizzo del codice open nei progetti ma con parsimonia.

Nei miei progetti, quelli che creo per i miei clienti, il codice è al 90% mio e solo un 10% è codice opensource.

Qual’è il motivo? Semplice, si tratta di avere il massimo controllo del progetto. Ovviamente c’è del lavoro in più da fare ma questo mi permette di poter operare all’interno del codice del mio software in ogni maniera.

Ci sono alcuni punti durante la vita di un progetto che vanno presi in considerazione:

  1. Bugs. I software contengono sempre dei bugs e se il codice non è nostro, una volta scovato, è un problema risolverlo. Se utilizziamo codice opensource la procedura di fix è decisamente più lunga e talvolta controproducente.
  2. Aggiornamenti. Apple ci sta abituando a lavorare con un linguaggio di programmazione in continua evoluzione: Swift. Cosa accade quando toglierà il supporto a Swift 3 e dovremo passare a Swift 4? Se utilizziamo codice di qualcun altro è possibile che saremo costretti ad attendere. Ma il nostro cliente,  il nostro business e peggio ancora, il business del nostro cliente avrà tutto questo tempo?
  3. Manutenzione. Se il codice open che abbiamo utilizzato smette di essere mantenuto cosa accade? Passiamo ad altro!, potremmo dire, ma questo comporta del lavoro in più, chi lo paga? Altri potrebbero dire “ci facciamo nostro il codice e continuiamo a mantenerlo”, ma mantenere codice non nostro significa doverlo analizzare in profondità per conoscere ogni riga. Chi lo paga questo tempo?

Solo questi 3 punti mi bastano per capire che utilizzare codice opensource in modo massiccio all’interno dei progetti per i miei clienti non è una scelta saggia, né per me né per i clienti stessi che si aspettano alta professionalità e si affidano a questa per portare avanti il proprio business.

Altra nota negativa è che in questo modo stiamo crescendo programmatori con l’idea che la realizzazione di un software sia l’assemblaggio di pezzi di codice altrui.
A mio avviso è un grande danno, perché il mondo della programmazione, quello reale, quello dove si sta ore su ore davanti al codice per creare un software, è molto differente rispetto allo studiarsi le API di un framework su cui baseremo un software non sapendo minimamente cosa quel codice farà.

Mi ripeto, non sono contro l’opensource né contro l’utilizzo di quest’ultimo all’interno dei progetti. Va usato con parsimonia.

Buona programmazione!

Swift 3 e la Configurazione Remota

Oggi parleremo di Configurazione Remota o anche Remote Configuration, ma cosa è?

Prendiamo come esempio l’applicazione Costituzione Italiana. Questo genere di progetto ha al suo interno alcune tecnologie basilari come Google Analytics, Arena Daemon e altri servizi esterni.
Cosa accade se ad un certo punto volessi disattivarne uno? Esatto, dovrei fare una nuova build e inviarla ad Apple.

Se volessi fare dei test A/B sarebbe un vero dramma.

La soluzione è avere una configurazione remota. L’app quindi prima di avviare i servizi controlla un file di configurazione remoto ed applica i comportamenti indicati.

Sul mio server ho inserito un piccolo file JSON:

{
	"enableGoogleAds": true,
	"enableGoogleAnalytics": true
}

L’app quindi si comporterà in base a questi due valori.

A questo punto non ci rimane che scrivere il codice Swift e per l’occasione ne approfitteremo per iniziare a scrivere qualcosa nella sua ultima versione, la 3.

Creiamo quindi una classe chiamata RemoteConfiguration.
Dovrà utilizzare il pattern Singleton così da avere una singola istanza per tutta la vita della nostra app.

class RemoteConfiguration {
	static let sharedInstance = RemoteConfiguration()
}

Aggiungiamo poi una proprietà chiamata baseURL:URL che andremo a configurare in un secondo momento. Poi ci serve un metodo che ci permette di recuperare il file. Questo è il momento giusto per utilizzare una callback, quindi creiamo un metodo chiamato configuration e come argomento deve accettare una closure di questo tipo: (dictionary:[String:AnyObject]))->().

class RemoteConfiguration {
	static let sharedInstance = RemoteConfiguration()
	var baseURL:URL?

	func configuration(handler:@escaping (_ dictionary:[String:AnyObject]?)->()) {

	}
}

La logica che ho pensato è questa: Se i dati non sono mai stati scaricati vado a recuperarli dall’URL indicato,  se invece li ho già scaricati non farò alcuna chiamata al server ed utilizzerò i dati in memoria.
Per farlo serve una proprietà privata configurationDictionary in cui salveremo i dati.

class RemoteConfiguration {
	static let sharedInstance = RemoteConfiguration()
	var baseURL:URL?

	private var configurationDictionary:[String:AnyObject]?

	func configuration(handler:@escaping (_ dictionary:[String:AnyObject]?)->()) {

	}
}

Adesso andiamo a creare la magia.
Per convenienza ho scritto una piccola classe chiamata Request che si occupa di scaricare i dati dalla rete in modo asyncrono, la troverete nel file Playground.

Request ritorna un oggetto Data che andremo a convertire in un dizionario usando la classe JSONSerialization e il metodo jsonObject.
Questo metodo solleva un’eccezione ma in questo momento non ci interessa controllare l’eventuale errore e quindi  possiamo utilizzare try? in modo da avere un oggetto Optional. In alternativa avremmo dovuto utilizzare un blocco do {} catch {}.

class RemoteConfiguration {
	static let sharedInstance = RemoteConfiguration()
	var baseURL:URL?
	
	private var configurationDictionary:[String:AnyObject]?
	
	func configuration(handler:@escaping (_ dictionary:[String:AnyObject]?)->())
	{
		guard let baseURL = baseURL else { assertionFailure("URL cannot be nil"); return }
		
		if let configuration = configurationDictionary
		{
			handler(configuration)
		}
		else
		{
			Request.url(url: baseURL, completion: {
				data, error in
				
				if let data = data, error == nil
				{
					if let json = try? JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String:AnyObject]
					{
						handler(json)
						return
					}
				}
				
				handler(nil)
				
			})
		}
	}
}

È arrivato il momento di provare il nostro codice, configuriamo RemoteConfiguration e richiediamo i dati:

let rc = RemoteConfiguration.sharedInstance
rc.baseURL = URL(string: "http://localhost/pills/p-01/remote-config.json")
rc.configuration { configuration in
	if let configuration = configuration
	{
		debugPrint(configuration)
	}
}

Se tutto è andato bene dovremmo vedere nel debugger la stampa del dizionario:

["enableGoogleAds": 1, "enableGoogleAnalytics": 1]

Questa classe è un ottimo punto di partenza nella nostra implementazione di una configurazione remota. Personalmente la trovo davvero molto utile per fare test A/B e per attivare o disattivare funzionalità o servizi senza dover ricompilare tutto.

Ovviamente è un punto di partenza, ci sono molte ottimizzazioni da poter fare e funzionalità da implementare. Potrebbero essere argomento nei prossimi articoli.

Potete scaricare il file Playground da GitHub.

Happy coding!

Quanto costa e come realizzare un’applicazione per iOS o per Android

Ho deciso di riprendere l’argomento che avevo già trattato in passato perché nel frattempo sono cambiate molte cose e quindi è necessario aggiornarsi.

Il mercato delle applicazioni per SmartPhone (iPhone, iPad, Android in generale) si è espanso e nel frattempo sono nati nuovi tipi di dispositivi come i Tablet, gli SmartWatch e le SmartTV.
Ad aggiungersi sono nate anche nuove tecnologie di sviluppo che ci permettono di abbassare drasticamente i costi.

Fino a 5-6 anni fa mettere un’app in uno Store, sia App Store che Google Play, ci dava la certezza di avere dei buoni download ed una buona visibilità, la concorrenza non era così spietata e quindi potevamo pensare ad avventurarci in questo mondo a fronte di un costo abbastanza elevato ma comunque con dei ritorni quasi certi.

Oggi le cose si sono invertite. Sviluppare un’app non è più così costoso o almeno ci sono metodi che permettono di far risparmiare molto ma è altrettanto molto difficile avere dei buoni dati di download e quindi dei buoni profitti.

È necessario quindi affrontare il progetto in modo più intelligente e più orientato al marketing.

Come realizzare un’app?

Qui entra in gioco la prima parte, come poter sviluppare un’applicazione affinché funzioni realmente, sia apprezzata dal pubblico e permetta di avere quei profitti tanto desiderati.
Intanto alla base deve esserci un buon piano marketing che dia la giusta visibilità al progetto.

Dopo di che è necessario affidarsi ad un Team di sviluppo adeguato, che sappia analizzare correttamente l’app e il progetto da realizzare e sappia prendere le giuste decisioni. Queste infatti si rifletteranno sia in modo imminente durante la vendita dell’app sia in seguito durante la sua manutenzione nel tempo.

Ci sono fondamentalmente due metodi per fare un’applicazione:

Realizzarla in modo Nativo

  • Significato
    • Sviluppare l’applicazione utilizzando sia il linguaggio di programmazione che l’SDK della casa costruttrice del dispositivo. Per iOS significa sviluppare con i linguaggi Objective-C o Swift utilizzando direttamente l’SDK di Apple. Per Android invece significa sviluppare con il linguaggio Java utilizzando l’SDK di Google.
  • Pro
    • Le applicazioni realizzate in questo modo sfruttano al 100% l’hardware di ogni device, senza alcun limite. Significa poter realizzare praticamente ogni cosa (con i limiti del caso), accedere ad ogni risorsa e avere a disposizione tutta la potenza dei device.
  • Contro
    • Ogni versione dell’app, iOS e Android, devono essere sviluppate indipendentemente ed è necessario avere degli sviluppatori o un Team competente per le due risorse, i costi quindi sono più alti.

Realizzarla in modo Ibrido

  • Significato
    • Sviluppare l’applicazione utilizzando un linguaggio ibrido come il linguaggio di programmazione Web (HTML, CSS, Javascript). Questo viene interpretato da un browser che simulerà il comportamento di un’applicazione nativa.
  • Pro
    • Le applicazioni realizzate in questo modo hanno il privilegio di poter essere sviluppate usando un codice unico che poi sarà compilato per ogni device. I costi vengono ridotti dal fatto di poter realizzare un’unica applicazione che poi girerà su ogni dispositivo.
  • Contro
    • Proprio per la sua caratteristica di simulazione questo genere di applicazione è più limitato e quindi ha un accesso alle risorse e alle prestazioni limitato.

Il Team di sviluppo al quale vi rivolgerete dovrà scegliere quale metodo utilizzare in base al tipo di applicazione.
Personalmente preferisco lavorare in modo Nativo per poter sfruttare a pieno ogni device e poter realizzare un’app davvero innovativa ed unica. Ma queste decisioni comunque sono da prendere in base al progetto, al budget e a molti altri aspetti.

Quanto costa realizzare un’app?

Come abbiamo visto prima il costo cambia in base al metodo di sviluppo.
Ma ci sono anche altri aspetti da valutare. Intanto partiamo con il dire che tutto dipende dal tempo che servirà per realizzarla.
Di base, più complessa è l’app e più tempo servirà, quindi il costo sarà maggiore.

I punti da analizzare sono:

  • Funzionalità di network (i dati saranno presi dal web? dobbiamo gestire utenze (login/registrazione)?
  • Interfaccia grafica: Realizzazione grafica
  • Interfaccia grafica: Realizzazione esperienza utente (animazioni, funzionalità grafiche particolari, schermate per la manipolazione dei dati, ecc.)

Questi tre punti sono quelli che inizialmente possono influire sui costi.
Implementare funzionalità di rete complesse come la registrazione utente necessitano di tempo (tempo di analisi, di sviluppo e di testing).
Anche creare interfacce grafiche complesse aumentano il tempo di sviluppo, invece utilizzare la UI di sistema è più economico; non in tutti casi è la scelta migliore.

Un altro fattore da valutare è il Team di sviluppo. Più esperienza c’è e meno tempo utilizzeranno per realizzare il prodotto e quindi sarà possibile sia risparmiare che investire il tempo per creare un prodotto migliore.

È vero, non sempre è così, anzi molti grandi aziende che si occupano di sviluppo applicazioni hanno costi davvero alti. Ma vale la pena farsi fare un’analisi e un preventivo.

E quindi quanto costa? Impossibile dirlo senza sapere cosa c’è da realizzare ma posso sbilanciarmi dicendo che per un piccolo progetto è necessario almeno un mese intero di lavoro, per una singola versione Nativa (iOS o Android) o per le due versioni in modo Ibrido.

Ovviamente lo sviluppo di un software è molto più complesso di quello che ho descritto qui sopra, ma volevo darvi un’idea delle cose che dovete prendere in considerazione nel momento in cui volete sviluppare un’app per la vostra azienda o un’app per un vostro progetto.

Se avete necessità di fare un preventivo potete scrivermi.

Icon Recolor – App per ricolorare le icone su macOS

icon

IconRecolor è un’applicazione per macOS che fa una cosa: Ricolora le icone PNG in un click.

Il suo funzionamento è semplicissimo, basta fare drag & drop dei file da ricolorare, scegliere il colore e salvare le nuove icone.

Ho realizzato quest’app pensando a tutti gli sviluppatori e i grafici che hanno bisogno di modificare velocemente le icone durante lo sviluppo.
Quante volte accade che le specifiche vengono cambiate al volo, o c’è bisogno di fare un test veloce sull’abbinamento dei colori? IconRecolor permette di colorare le icone in modo davvero veloce e semplice diminuendo drasticamente i tempi di lavoro.

Potete scaricare la versione 1.0 direttamente Mac App Store.