Vai al contenuto
megapromotingParliamone

Competenza · Applicazioni desktop

Applicazioni che si installano sul computer. Su macOS ne abbiamo costruite due; per Windows e Linux questa pagina è un’offerta, non una storia.

Costruiamo applicazioni native per macOS, con il nucleo della logica separato dallo schermo, così la stessa logica può funzionare anche sul telefono. Per Windows e Linux/Ubuntu non abbiamo ancora nulla consegnato e lo scriviamo come tale, con le condizioni in cui accetteremmo il lavoro. La prima domanda resta se ti serve davvero un'applicazione installata.

Offerta, con condizioniLa regola è meccanica e la applico meccanicamente. Su macOS abbiamo due implementazioni proprie, costruite ed eseguibili: un’applicazione da barra dei menu con 25 file Swift, che riutilizza 15 file dal nucleo di un progetto per iPhone, e una seconda applicazione, più semplice, che è un involucro WebKit sopra un’applicazione web. Entrambe hanno un binario compilato su questa macchina. Ma il servizio, così come è chiamato, copre tre famiglie di sistemi, e per due di esse — Windows e Linux/Ubuntu — abbiamo cercato seriamente e trovato zero: nessun progetto .NET o Qt proprio, nessun `tauri.conf.json`, nessun Electron scritto da noi, nessun `.desktop`, nessun pacchetto deb, rpm o AppImage. Inoltre, nessuna delle due applicazioni macOS è mai stata confezionata in un installer distribuibile. Con solo una su tre piattaforme coperta e zero distribuzioni, la pagina si scrive come offerta con condizioni. Quando consegneremo la prima applicazione per Windows o per Linux, cambia il valore, non il testo.

La prima domanda che Le facciamo non è per quale sistema, ma se Le serve davvero un’applicazione installata. Vale la pena installarla quando ha bisogno di qualcosa che il browser non le dà: accesso diretto ai sensori o alle periferiche, presenza permanente nella barra di sistema, funzionamento senza internet, accesso ai file sul disco senza che la persona li carichi ogni volta, oppure esecuzione in background quando la finestra è chiusa. Se nessuno di questi casi è richiesto, un sito che si apre da un link è più economico da costruire, aggiornare e mantenere — e glielo diciamo, anche se il lavoro risulta più piccolo.

Su macOS abbiamo due applicazioni costruite. La prima è un’applicazione per la barra dei menu: 25 file Swift proprietari, più 15 file di nucleo presi direttamente dal progetto iPhone dello stesso prodotto — gli stessi file, non una copia. Si costruisce con uno script che richiama direttamente il compilatore Swift, target `arm64-apple-macosx14`, collegando undici framework di sistema, tra cui SwiftUI, AppKit, CoreMotion, Vision e UserNotifications. Il binario risultante ha 6.516.128 byte. La seconda è molto più semplice ed è corretto dire quanto: tre file Swift, un involucro WebKit sopra un’applicazione web, con sandbox e runtime rafforzato attivati, compilato universalmente per processori Intel e Apple. Sono due cose diverse e le chiamiamo diversamente.

Ciò che non abbiamo, detto chiaramente. Windows: zero. Ho cercato progetti .NET, WPF, WinForms, WinUI, file `.xaml`, `.appxmanifest`, `.msi`, `.wxs` — tutto ciò che ho trovato sul disco appartiene a una libreria C di terze parti, vendorizzata in un altro progetto, che non abbiamo scritto noi. Linux desktop: zero — nessun file `.desktop`, nessun pacchetto deb o AppImage costruito qui. Electron o Tauri scritti da noi: zero. E, altrettanto importante: nessuna delle due applicazioni per macOS è mai stata impacchettata in un installer. Esistono come pacchetti `.app` costruiti localmente, firmati ad-hoc, senza identificatore di team.

Ciò che invece trasferisce l’esperienza finora acquisita, ed è la parte che conta per un nuovo progetto: la disciplina di tenere il nucleo logico separato dall’interfaccia. Nel progetto macOS, i file di calcolo e di policy non importano l’interfaccia, quindi si compilano ed eseguono su Mac come programma normale, senza simulatore; la loro suite logica gira in pochi secondi. La stessa separazione fa sì che il porting su un altro sistema sia un problema di involucro, non di riscrittura. Su questo ci basiamo quando diciamo che potremmo fare Windows o Linux — non su un’esperienza che non abbiamo.

Cosa comprende

Il lavoro, per componenti

Prima decidiamo se Le serve un’applicazione installata

Cinque criteri, verificati uno per uno: accesso a sensori o periferiche, presenza nella barra di sistema, funzionamento senza internet, accesso diretto ai file sul disco, esecuzione in background con la finestra chiusa. Se nessuno si applica, la raccomandazione è un’applicazione web, e il motivo è pratico: un’applicazione installata deve essere firmata, distribuita e aggiornata su ogni computer, e ciascuno di questi tre passaggi costa all’infinito, non una sola volta.

Il nucleo si scrive una volta e non sa su cosa gira

Nella nostra applicazione macOS, il target desktop elenca 15 file dal nucleo del progetto iPhone come sorgenti proprie — calcolo, calibrazione, storico, policy di notifiche e di dati sanitari. Non sono copiati, sono gli stessi file. Conseguenza: una correzione di algoritmo si fa in un solo posto e appare su entrambi. Seconda conseguenza, più importante per Lei: il nucleo si può testare senza avviare l’applicazione.

L’involucro di piattaforma resta sottile, e Le diciamo quanto è sottile

L’applicazione per la barra dei menu usa `MenuBarExtra` sopra un delegato applicativo AppKit — codice nativo, ma poco, perché il resto è il nucleo comune. La nostra altra applicazione per macOS è all’estremo opposto: tre file, un `WKWebView` impacchettato per SwiftUI, cioè una finestra sopra un’applicazione web. Entrambe sono applicazioni macOS legittime, ma significano cose diverse in termini di sforzo, velocità e accesso al sistema. Quale delle due Le serve si decide all’inizio, non si scopre alla consegna.

Costruiamo con uno script, non con la pressione di un pulsante

L’applicazione da barra dei menu si costruisce da uno script di meno di cento righe che richiama direttamente il compilatore Swift, con il target e l’elenco dei framework scritti esplicitamente, poi impacchetta il bundle `.app` e lo firma. Una build che sta in uno script gira allo stesso modo su un’altra macchina e può essere inserita in una linea automatica; una build che esiste solo nell’interfaccia di un programma di sviluppo non può.

Sandbox e runtime rafforzato, quando l’applicazione accede alla rete

La seconda applicazione macOS parte con sandbox attivato e con una sola autorizzazione di rete, quella di client — non server, nessun accesso ai file dell’utente, niente fotocamera, niente microfono. Il runtime rafforzato è attivato dalla configurazione del progetto. Le autorizzazioni si dichiarano dall’inizio, come lista breve e leggibile, non si aggiungono strada facendo quando qualcosa non funziona.

La firma è un problema di account, non di codice, e lo mettiamo sul tavolo dall’inizio

Le nostre applicazioni macOS sono firmate ad hoc: la verifica passa localmente, ma non esiste un identificatore di team, e nella configurazione del progetto il campo del team di sviluppo è vuoto. Per la distribuzione fuori dallo store, un pacchetto macOS ha bisogno della firma con un certificato di sviluppatore identificabile e del passaggio attraverso la notarizzazione Apple, altrimenti il sistema operativo di chi lo riceve lo blocca. È un problema di account e di processo, non di funzionalità — ma è un problema reale e non lo nascondiamo nell’ultima riunione.

Windows e Linux: cosa chiediamo prima di accettare

Una verifica di compatibilità a pagamento come prima fase, che si conclude con uno scheletro che parte sul tuo computer, non con un documento. In essa si decidono tre cose: quale ambiente di esecuzione usiamo e perché, chi detiene il certificato di firma e l’account di distribuzione, e come arriva un aggiornamento sui computer delle persone. Se uno dei tre non ha risposta, il lavoro non inizia. Non ci assumiamo una piattaforma che non abbiamo consegnato fingendo che sia una formalità.

Linux server non è Linux desktop, e non confondiamo le due cose

I nostri sistemi girano giorno dopo giorno su Linux: unità di sistema con riavvio in caso di errore, server web davanti, log e loro rotazione. Questa è esperienza reale con Linux, ma è esperienza da server. Un’applicazione con finestre per Ubuntu è un’altra disciplina — packaging, integrazione con l’ambiente grafico, distribuzione tramite repository o tramite file auto-contenuto — e lì non abbiamo nulla di consegnato. Questa differenza la vede un ingegnere in tre secondi; è meglio dirlo noi prima.

Cosa non facciamo

Non promettiamo un installer che non abbiamo mai prodotto senza dire che è la prima volta. Non scegliamo un ambiente di esecuzione solo perché è di moda, senza verificare prima cosa chiede l’applicazione al sistema. E non prendiamo in carico un’app desktop esistente prima di poterla costruire da zero, sulla nostra macchina, dai sorgenti ricevuti — se la build non si riproduce, ogni stima dopo è una supposizione.

Come si presenta

Il percorso, passo dopo passo.

01

Decidiamo installato o web, secondo cinque criteri

Sensori e periferiche, barra di sistema, lavoro senza internet, accesso ai file, esecuzione in background. Consegniamo la decisione scritta, con il motivo, anche quando il motivo è „non ti serve un’app installata”. Questa fase è breve e si può fermare qui senza perdita.

02

Costruiamo il nucleo e lo testiamo senza piattaforma

La logica, gli stati, la persistenza, le policy — scritte in modo che l’interfaccia non conti e che si possano compilare ed eseguire come programma da riga di comando. Consegniamo la suite di test e il comando con cui la esegui tu. Se in seguito compare una seconda piattaforma, qui si vede se il lavoro è stato fatto correttamente dall’inizio.

03

Mettiamo il rivestimento di piattaforma

Su macOS: finestre o barra dei menu, notifiche, permessi, il bundle `.app`, lo script di build. Su Windows o Linux: dopo la verifica di compatibilità della prima fase, con l’ambiente di esecuzione scelto lì. Alla fine della fase l’app si avvia sulla tua macchina, non sulla nostra.

04

Firma, distribuzione, aggiornamento

La fase che la maggior parte dei progetti scopre tardi e che noi mettiamo esplicitamente per ultima, così che sia visibile: certificato, account, notarizzazione dove la piattaforma la richiede, canale di aggiornamento. Qui c’è anche il nostro blocco attuale su macOS — le applicazioni sono firmate ad hoc, senza identificatore di team. In un tuo progetto, l’account è il tuo e il blocco scompare.

DocumenteConversazioniFontiSintesiAzioneTeamContestualizzaFonti autorizzate. Azioni revisionate.
Un nucleo al centro — calcolo, calibrazione, storico, politiche — che non importa nessuna interfaccia e per questo si testa da solo. Attorno, quattro involucri di piattaforma: iPhone e macOS, collegati e costruiti, disegnati pieni; Windows e Linux desktop, disegnati aperti, perché non esistono. Il quinto nodo, la distribuzione, è collegato a macOS con una linea tratteggiata: il pacchetto si costruisce e si firma ad-hoc, ma non supera la notarizzazione, quindi non arriva su un altro computer. Il disegno dice cosa è fatto e cosa no, nella stessa immagine.

I dati

Cosa tocchiamo, dove risiedono e quanto rimangono

Le domande che pone chiunque abbia un responsabile della protezione dei dati — poste qui prima che le ponga lui.

Un’app installata vede più di una dal browser
Questo è il motivo per cui la vuole e, allo stesso tempo, il suo rischio: ha accesso al disco, al file system dell’utente e, se le vengono concessi permessi, alle periferiche. Per questo i permessi si dichiarano esplicitamente e si tengono al minimo. La nostra applicazione con sandbox ha esattamente un permesso, quello di client di rete.
Dove stanno i dati quando l’app non ha server
Sul computer della persona. Nell’app della barra dei menu, la cronologia viene scritta in un file proprio, mentre le preferenze nella store di impostazioni del sistema, con chiavi prefissate per applicazione. Non parte nulla verso un server per un motivo semplice: nell’app non esiste codice di rete. Quando esiste, nella pagina dei permessi si scrive chi riceve cosa.
Cosa non raccogliamo per impostazione predefinita
Nessuna telemetria, nessun identificatore di dispositivo, nessun rapporto di utilizzo, se non sono richiesti esplicitamente e dichiarati nell’interfaccia. Un’app desktop è un luogo in cui la telemetria passa inosservata; per questo, se viene inserita, viene inserita in modo visibile, con un pulsante di disattivazione, e si scrive quali campi partono.
Gli aggiornamenti sono una decisione, non un dettaglio tecnico
Oggi non abbiamo costruito un canale di aggiornamento automatico. In un nuovo progetto questa è una delle prime tre decisioni, insieme alla firma e alla distribuzione: si aggiorna manualmente, tramite lo store della piattaforma, o tramite un canale proprio? Ogni variante ha un diverso costo permanente e un’altra superficie di sicurezza, e si sceglie prima della prima riga di codice, non dopo.
Cosa resta a noi
I sorgenti, finché lavoriamo; dopo la consegna, ciò che è stato concordato nel contratto. I certificati di firma restano, idealmente, sull’account della tua organizzazione — se restano sul nostro, sei legato a noi per ogni aggiornamento, e questo deve essere una scelta consapevole, non una conseguenza.

Un caso

Un’applicazione macOS estratta dal nucleo di un’applicazione iPhone, senza una seconda implementazione

La situazione

Avevamo un prodotto proprio per iPhone, che misura l’inclinazione della testa rispetto a una posizione calibrata all’inizio della sessione. Le stesse regole — calibrazione, soglie, cronologia, politiche di notifica — avevano senso anche su Mac, dove la persona sta comunque davanti allo schermo. La domanda reale non era se si potesse fare, ma quanta logica dovesse essere riscritta.

Cosa abbiamo costruito

Zero, perché il nucleo era stato scritto fin dall’inizio senza conoscere lo schermo. La target macOS elenca 15 file del progetto iPhone come sorgenti proprie, a cui si aggiungono 25 file Swift specifici del desktop: la finestra, il menu nella barra di sistema tramite un delegato AppKit, le notifiche, il servizio di ambiente. La costruzione non passa attraverso l’interfaccia Xcode: uno script chiama direttamente il compilatore Swift con il target `arm64-apple-macosx14` e collega esplicitamente undici framework di sistema, poi posiziona il pacchetto `.app` e lo firma, e alla fine verifica la firma.

Cosa è emerso

Un binario di 6.516.128 byte per processori Apple, che si avvia e resta nella barra dei menu, costruito da un solo comando. La stessa correzione dell’algoritmo arriva sul telefono e sul Mac, perché è lo stesso file, non una copia sincronizzata manualmente.

Cosa non dice il caso

L’app non è distribuita e non può esserlo, oggi, in questa forma: la firma è ad hoc, senza identificatore di team, e il campo del team di sviluppo è vuoto nella configurazione del progetto. Su un altro computer sarebbe bloccata dal sistema. È un problema di account e di notarizzazione, non di funzionalità — ma resta un problema irrisolto e lo scriviamo come tale, non come dettaglio.

Domande

Cosa ci chiedono le persone prima di chiamare

Perché su questa pagina c’è scritto «offerta», se dite di avere due applicazioni per Mac?

Perché il servizio si chiama “applicazioni desktop” e copre tre famiglie di sistemi, mentre noi ne abbiamo consegnata una su una sola. La regola che applichiamo a noi stessi richiede almeno due implementazioni proprie, mostrabili nel codice, per ogni affermazione del tipo “abbiamo fatto”. Su macOS le abbiamo. Su Windows e su Linux ne abbiamo zero, e nessuna delle due applicazioni Mac è mai stata impacchettata in un installer distribuibile. Una pagina che dicesse altro cadrebbe alla seconda domanda di un ingegnere.

Avete un’app per Mac che posso scaricare adesso?

No. Entrambe esistono come pacchetti `.app` costruiti sulla nostra macchina: una compilata per processori Apple, l’altra universale, per Intel e Apple. Sono firmate ad hoc, il che significa che superano la verifica locale ma non hanno un identificatore di team, quindi su un altro computer il sistema le bloccherebbe. Quello che possiamo fare davanti a lei è avviarle, aprire il codice e lo script di build e far girare la suite di logica.

Qual è la differenza, da voi, tra le due applicazioni per Mac?

Una è nativa, l’altra è una finestra sopra il web, e la differenza è grande. Quella nativa ha 25 file Swift propri più 15 file di nucleo comuni con la versione per iPhone, si aggancia alla barra dei menu tramite un delegato di applicazione AppKit e collega undici framework di sistema, tra cui sensori di movimento, notifiche ed elaborazione delle immagini. La seconda ha tre file e mostra un’app web in un `WKWebView`. La seconda si realizza rapidamente ed è una scelta corretta quando la vostra app è già web e volete solo un’icona nel Dock. Non è una scelta corretta quando avete bisogno del sistema.

Realizzate applicazioni per Windows?

Non ne abbiamo consegnata nessuna e non pretendiamo altro. Abbiamo cercato sui nostri dischi ogni traccia — progetti .NET, WPF, WinForms, WinUI, file di interfaccia XAML, manifesti di applicazione, pacchetti MSI o WiX — e tutto ciò che appare appartiene a una libreria C di terze parti che usiamo soltanto in un altro progetto. Se avete bisogno di Windows, la prima fase è una verifica di compatibilità che si conclude con uno scheletro che si avvia sul vostro computer, e solo dopo parliamo del resto.

E per Linux o Ubuntu?

La stessa posizione, con una precisazione che conta. Applicazione con finestre per Linux: zero consegnate, nessun pacchetto deb o AppImage costruito da noi. Server Linux: ogni giorno — unità di sistema, server web davanti, log, riavvio in caso di errore. Sono due discipline diverse e sarebbe disonesto usare la prima come prova della seconda.

Perché non Electron, se così è più semplice?

Perché non ne abbiamo consegnata nessuna e non diremo di avere esperienza dove non l’abbiamo. Sui nostri dischi esistono due applicazioni Electron funzionanti, ma sono repository clonati da altri autori, con zero contributi nostri — li abbiamo verificati nella cronologia dei commit proprio per non farli diventare „prova” su questa pagina. In un progetto reale, la scelta tra un ambiente web confezionato e codice nativo si fa dopo aver capito che cosa l’app richiede dal sistema, quanto pesa il pacchetto e chi paga la manutenzione, non per moda.

Che cosa blocca, da voi, la pubblicazione di un’applicazione Mac?

L’account, non il codice. Nella configurazione del progetto, il campo del team di sviluppo è vuoto, e la firma del pacchetto costruito è ad hoc, senza identificatore di team. Per la distribuzione al di fuori dell’App Store, macOS richiede un certificato di sviluppatore identificabile e il passaggio del pacchetto attraverso la notarizzazione. In un vostro progetto, il certificato e l’account appartengono alla vostra organizzazione, quindi questo blocco semplicemente non si presenta — ma va previsto dall’inizio, con il suo costo e il suo tempo.

Non è più semplice fare un sito e finire lì?

Molte volte sì, e ve lo diciamo noi prima che ce lo diciate voi. Un sito non ha bisogno di firma, di notarizzazione, di installatore, di canale di aggiornamento né di una versione per ogni sistema operativo. L’app installata vince quando avete bisogno di sensori, di periferiche, di lavoro senza internet, di presenza permanente nella barra di sistema o di accesso diretto ai file dell’utente. Se nessuno di questi elementi è in lista, i soldi si spendono meglio altrove.

Potete prendere in carico un’app desktop che abbiamo già?

Con una condizione verificata prima di ogni stima: che possiamo costruirla da zero, sulla nostra macchina, dai sorgenti ricevuti. Se il build non si riproduce — mancano dipendenze, certificati, passaggi non scritti — allora nessuno può stimare onestamente nulla, e il primo lavoro diventa la riproduzione del build, non la nuova funzionalità. Lo diciamo prima, così non si scopre a metà.

Su cosa si basano le affermazioni sopra (14 fonti)

14 di esse sono codice e file dei nostri repository. Non ne pubblichiamo il nome né la riga: insieme, in un'unica pagina, descriverebbero con troppa precisione come sono costruiti sistemi che non sono solo nostri. Le esaminiamo con te, nel repository, su richiesta — la verifica resta possibile, solo che avviene in una discussione.

Cosa vorresti che funzionasse meglio?

Raccontaci il tuo processo. Insieme stabiliamo cosa vale la pena costruire, cosa possiamo collegare e come verifichiamo il risultato.

Parliamone