Saltar para o conteúdo
megapromotingVamos falar

Especialização · Aplicações desktop

Aplicações que se instalam no computador. No macOS, construímos duas; para Windows e Linux, esta página é uma oferta, não um histórico.

Construímos aplicações nativas para macOS, com o núcleo da lógica separado do ecrã, para que a mesma lógica também funcione no telemóvel. Para Windows e Linux/Ubuntu ainda não temos nada entregue e escrevemos isso como tal, com as condições em que aceitaríamos o trabalho. A primeira pergunta continua a ser se você realmente precisa de uma aplicação instalada.

Oferta, com condiçõesRegula e mecanică și o aplic mecanic. Pe macOS avem două implementări proprii, construite și rulabile: o aplicație de bară de meniu cu 25 de fișiere Swift, care refolosește 15 fișiere din nucleul unui proiect de iPhone, și o a doua aplicație, mai simplă, care e un înveliș WebKit peste o aplicație web. Ambele au binar compilat pe această mașină. Dar serviciul, așa cum e numit, acoperă trei familii de sisteme, iar pentru două dintre ele — Windows și Linux/Ubuntu — am căutat serios și am găsit zero: niciun proiect .NET sau Qt propriu, niciun `tauri.conf.json`, niciun Electron scris de noi, niciun `.desktop`, niciun ambalaj deb, rpm sau AppImage. În plus, niciuna dintre cele două aplicații de macOS nu a fost vreodată împachetată într-un instalator distribuibil. Cu doar una din trei platforme acoperită și zero distribuții, pagina se scrie ca ofertă cu condiții. Când vom livra prima aplicație de Windows sau de Linux, se schimbă valoarea, nu textul.

A primeira pergunta que lhe fazemos não é para que sistema, mas se precisa mesmo de uma aplicação instalada. Vale a pena instalá-la quando precisa de algo que o navegador não lhe dá: acesso direto a sensores ou periféricos, presença permanente na barra do sistema, trabalho sem internet, acesso aos ficheiros no disco sem que a pessoa os carregue de cada vez, ou execução em segundo plano quando a janela é fechada. Se nada disto for necessário, um site que se abre a partir de uma ligação é mais barato de construir, de atualizar e de manter — e dizemo-lo, mesmo que o trabalho fique mais pequeno.

No macOS, temos duas aplicações construídas. A primeira é uma aplicação de barra de menu: 25 ficheiros Swift próprios, mais 15 ficheiros de núcleo retirados diretamente do projeto de iPhone do mesmo produto — os mesmos ficheiros, não uma cópia. Constrói-se com um script que chama diretamente o compilador Swift, alvo `arm64-apple-macosx14`, ligando onze frameworks de sistema, entre os quais SwiftUI, AppKit, CoreMotion, Vision e UserNotifications. O binário resultante tem 6.516.128 bytes. A segunda é muito mais simples e é honesto dizer quanto: três ficheiros Swift, uma camada WebKit por cima de uma aplicação web, com sandbox e runtime endurecido ativados, compilado universalmente para processadores Intel e Apple. São duas coisas diferentes e chamamo-las de forma diferente.

O que não temos, dito claramente. Windows: zero. Procurámos projetos .NET, WPF, WinForms, WinUI, ficheiros `.xaml`, `.appxmanifest`, `.msi`, `.wxs` — tudo o que encontrámos no disco pertence a uma biblioteca C de terceiros, vendorizada noutro projeto, que não escrevemos nós. Linux desktop: zero — nenhum ficheiro `.desktop`, nenhum pacote deb ou AppImage construído aqui. Electron ou Tauri escritos por nós: zero. E, igualmente importante: nenhuma das duas aplicações de macOS foi alguma vez empacotada num instalador. Existem como pacotes `.app` construídos localmente, assinados ad-hoc, sem identificador de equipa.

O que, ainda assim, transfere a experiência até agora, e é a parte que importa para um projeto novo: a disciplina de manter o núcleo da lógica separado da interface. No projeto de macOS, os ficheiros de cálculo e de políticas não importam a interface, por isso compilam e correm no Mac como programa normal, sem simulador; a sua suíte de lógica corre em poucos segundos. A mesma separação faz com que a portabilidade para outro sistema seja um problema de camada, não de reescrita. É nisso que nos baseamos quando dizemos que poderíamos fazer Windows ou Linux — não numa experiência que não temos.

Qué incluye

El trabajo, por componentes

Antes de mais, decidimos se lhe é necessária uma aplicação instalada

Cinco critérios, verificados um a um: acesso a sensores ou periféricos, presença na barra do sistema, trabalho sem internet, acesso direto aos ficheiros no disco, execução em segundo plano com a janela fechada. Se nenhum se aplicar, a recomendação é uma aplicação web, e o motivo é prático: uma aplicação instalada tem de ser assinada, distribuída e atualizada em cada computador, e cada um dos três passos custa continuamente, não apenas uma vez.

O núcleo escreve-se uma vez e não sabe em que é executado

Na nossa aplicação de macOS, o alvo desktop lista 15 ficheiros do núcleo do projeto de iPhone como fontes próprias — cálculo, calibração, histórico, políticas de notificação e de dados de saúde. Não estão copiados, são os mesmos ficheiros. Consequência: uma correção de algoritmo faz-se num só lugar e aparece em ambos. Segunda consequência, mais importante para si: o núcleo pode ser testado sem iniciar a aplicação.

A camada da plataforma mantém-se fina, e dizemos-lhe quão fina

A aplicação de barra de menu usa `MenuBarExtra` sobre um delegado de aplicação AppKit — código nativo, mas pouco, porque o resto é o núcleo comum. A nossa outra aplicação de macOS está no extremo oposto: três ficheiros, um `WKWebView` empacotado para SwiftUI, ou seja, uma janela sobre uma aplicação web. Ambas são aplicações legítimas de macOS, mas significam coisas diferentes em esforço, em velocidade e em acesso ao sistema. Qual das duas lhe é necessária decide-se no início, não se descobre na entrega.

Construímos com um script, não com um clique num botão

A aplicação de barra de menu é construída a partir de um script com menos de cem linhas que chama diretamente o compilador Swift, com o target e a lista de frameworks escritos explicitamente, depois coloca o pacote `.app` e assina-o. Uma build que cabe num script corre da mesma forma noutra máquina e pode ser colocada numa linha automática; uma build que existe apenas na interface de um programa de desenvolvimento não pode.

Sandbox e runtime reforçado, quando a aplicação sai para a rede

A segunda aplicação de macOS arranca com o sandbox ativado e com uma única permissão de rede, a de cliente — não servidor, não acesso aos ficheiros do utilizador, não câmara, não microfone. O runtime reforçado é ativado a partir da configuração do projeto. As permissões são declaradas desde o início, como uma lista curta que se pode ler, não são adicionadas ao longo do processo quando algo não funciona.

A assinatura é um problema de conta, não de código, e colocamo-la na mesa no início

As nossas aplicações de macOS são assinadas ad-hoc: a verificação passa localmente, mas não existe identificador de equipa, e na configuração do projeto o campo da equipa de desenvolvimento está vazio. Para distribuição fora da loja, um pacote de macOS precisa de assinatura com um certificado de programador identificável e da passagem pela notarização da Apple, caso contrário o sistema operativo de quem o recebe bloqueia-o. É um problema de conta e de processo, não de funcionalidade — mas é um problema real e não o escondemos na última reunião.

Windows e Linux: o que pedimos antes de aceitar

Uma verificação de compatibilidade paga como primeira etapa, que termina com um esqueleto que arranca no seu computador, não com um documento. Nela decidem-se três coisas: que ambiente de execução usamos e porquê, quem detém o certificado de assinatura e a conta de distribuição, e como é que uma atualização chega aos computadores das pessoas. Se uma dessas três não tiver resposta, o trabalho não começa. Não assumimos uma plataforma que não entregámos fingindo que é uma formalidade.

Linux server não é Linux desktop, e não confundimos os dois

Os nossos sistemas correm dia após dia em Linux: unidades de sistema com reinício em caso de falha, servidor web na frente, registos e a sua rotação. Isto é experiência real com Linux, mas é experiência de server. Uma aplicação com janelas para Ubuntu é outra disciplina — empacotamento, integração com o ambiente gráfico, distribuição por repositório ou por ficheiro auto-contido — e aí não temos nada entregue. Essa diferença um engenheiro vê em três segundos; é melhor dizê-la nós antes.

O que não fazemos

Não prometemos um instalador que nunca produzimos sem dizer que é a primeira vez. Não escolhemos um ambiente de execução apenas porque está na moda, sem verificar primeiro o que a aplicação exige do sistema. E não assumimos uma aplicação desktop existente antes de a podermos construir de raiz, na nossa máquina, a partir das fontes recebidas — se a build não se reproduz, qualquer estimativa depois disso é um palpite.

Qué aspecto tiene

El recorrido, paso a paso.

01

Decidimos instalado ou web, por cinco critérios

Sensores e periféricos, barra de sistema, trabalho sem internet, acesso a ficheiros, execução em segundo plano. Entregamos a decisão por escrito, com o motivo, mesmo quando o motivo é “não precisa de aplicação instalada”. Esta etapa é curta e pode parar aqui sem perda.

02

Construímos o núcleo e testamo-lo sem plataforma

A lógica, os estados, a persistência, as políticas — escritos para que a interface não importe e possam ser compilados e executados como programa de linha de comando. Entregamos a suíte de testes e o comando com que você a executa. Se mais tarde surgir uma segunda plataforma, aqui vê-se se o trabalho foi feito corretamente desde o início.

03

Colocamos o invólucro da plataforma

Em macOS: janelas ou barra de menu, notificações, permissões, o pacote `.app`, o script de construção. Em Windows ou Linux: após a verificação de compatibilidade da primeira etapa, com o ambiente de execução escolhido aí. No final da etapa a aplicação arranca na sua máquina, não na nossa.

04

Assinatura, distribuição, atualização

A etapa que a maioria dos projetos descobre tarde e nós colocamos por último de forma explícita, para que seja vista: certificado, conta, notarização onde a plataforma o exigir, canal de atualização. Aqui está também o nosso bloqueio atual no macOS — as aplicações estão assinadas ad-hoc, sem identificador de equipa. Num teu projeto, a conta é tua e o bloqueio desaparece.

DocumenteConversațiiSurseSintezăAcțiuneEchipăContexteazăSurse autorizate. Acțiuni revizuite.
Un nucleu în centru — calcul, calibrare, istoric, politici — care nu importă nicio interfață și de aceea se testează singur. În jur, patru învelișuri de platformă: iPhone și macOS, legate și construite, desenate plin; Windows și Linux desktop, desenate deschis, pentru că nu există. Al cincilea nod, distribuția, e legat de macOS printr-o linie întreruptă: pachetul se construiește și se semnează ad-hoc, dar nu trece de notarizare, deci nu ajunge pe alt calculator. Desenul spune ce e făcut și ce nu, în aceeași imagine.

Os dados

Qué tocamos, dónde están y cuánto se quedan

Las preguntas que hace cualquiera que tenga un delegado de protección de datos — hechas aquí antes de que las haga él.

Uma aplicação instalada vê mais do que uma do browser
Esta é a razão por que a queres e, ao mesmo tempo, o seu risco: tem acesso ao disco, ao sistema de ficheiros do utilizador e, se lhe forem dados permissões, a periféricos. Por isso as permissões são declaradas explicitamente e mantidas no mínimo. A nossa aplicação com sandbox tem exatamente uma permissão, a de cliente de rede.
Onde ficam os dados quando a aplicação não tem servidor
No computador da pessoa. Na aplicação da barra de menu, o histórico é escrito num ficheiro próprio, e as preferências na loja de definições do sistema, com chaves prefixadas pela aplicação. Nada é enviado para um servidor por uma razão simples: não existe código de rede na aplicação. Quando existe, é escrita na página de permissões quem recebe o quê.
O que não recolhemos por defeito
Nenhuma telemetria, nenhum identificador de dispositivo, nenhum relatório de utilização, se não forem pedidos explicitamente e declarados na interface. Uma aplicação desktop é um lugar onde a telemetria passa despercebida; por isso, se for colocada, é colocada visivelmente, com botão de desligar, e é escrito que campos saem.
As atualizações são uma decisão, não um detalhe técnico
Hoje não temos construído um canal de atualização automática. Num projeto novo, essa é uma das primeiras três decisões, juntamente com a assinatura e a distribuição: atualiza-se manualmente, pela loja da plataforma, ou por um canal próprio? Cada variante tem outro custo permanente e outra superfície de segurança, e escolhe-se antes da primeira linha de código, não depois.
O que fica connosco
As fontes, enquanto trabalhamos; após a entrega, o que foi acordado no contrato. Os certificados de assinatura ficam, idealmente, na tua conta de organização — se ficarem na nossa, ficas ligado a nós para cada atualização, e isso tem de ser uma escolha consciente, não uma consequência.

Un caso

Uma aplicação de macOS extraída do núcleo de uma aplicação de iPhone, sem segunda implementação

A situação

Tínhamos um produto próprio para iPhone, que mede a inclinação da cabeça em relação a uma posição calibrada no início da sessão. As mesmas regras — calibração, limiares, histórico, políticas de notificação — faziam sentido também no Mac, onde a pessoa está de qualquer forma em frente ao ecrã. A pergunta real não era se era possível, mas quanto da lógica devia ser reescrito.

Qué construimos

Zero, porque o núcleo tinha sido escrito desde o início sem saber do ecrã. O alvo de macOS lista 15 ficheiros do projeto de iPhone como fontes próprias, aos quais se juntam 25 ficheiros Swift específicos do desktop: a janela, o menu na barra de sistema através de um delegado AppKit, as notificações, o serviço de ambiente. A construção não passa pela interface Xcode: um script chama diretamente o compilador Swift com o alvo `arm64-apple-macosx14` e liga explicitamente onze frameworks de sistema, depois coloca o pacote `.app` e assina-o, e no fim verifica a assinatura.

Qué salió

Um binário de 6.516.128 de octetos para processadores Apple, que arranca e fica na barra de menu, construído a partir de um único comando. A mesma correção de algoritmo chega ao telefone e ao Mac, porque é o mesmo ficheiro, não uma cópia sincronizada manualmente.

Qué no dice el caso

A aplicação não é distribuída e não pode ser, hoje, nesta forma: a assinatura é ad-hoc, sem identificador de equipa, e o campo da equipa de desenvolvimento está vazio na configuração do projeto. Noutro computador seria bloqueada pelo sistema. É um problema de conta e de notarização, não de funcionalidade — mas continua a ser um problema não resolvido e nós escrevemo-lo assim, não como detalhe.

Perguntas

Lo que nos pregunta la gente antes de llamar

Porque é que está escrito «oferta» nesta página, se dizem que têm duas aplicações de Mac?

Porque o serviço se chama «aplicações desktop» e abrange três famílias de sistemas, e nós temos entregue numa delas. A regra que aplicamos a nós próprios exige no mínimo duas implementações próprias, demonstráveis em código, para cada afirmação do tipo «fizemos». No macOS, temos. No Windows e no Linux, temos zero, e nenhuma das duas aplicações para Mac alguma vez foi empacotada num instalador distribuível. Uma página que dissesse outra coisa cairia à segunda pergunta de um engenheiro.

Vocês têm uma aplicação de Mac que eu possa descarregar agora?

Não. Ambas existem como pacotes `.app` construídos na nossa máquina: uma compilada para processadores Apple, a outra universal, para Intel e Apple. São assinadas ad hoc, o que significa que passam a verificação local, mas não têm identificador de equipa, por isso noutro computador o sistema bloquearia-as. O que podemos fazer diante de si é executá-las, abrir o código e o script de construção e correr a suíte de lógica.

Qual é a diferença, para vocês, entre as duas aplicações de Mac?

Uma é nativa, a outra é uma janela sobre a web, e a diferença é grande. A nativa tem 25 ficheiros Swift próprios mais 15 ficheiros de núcleo comuns com a versão de iPhone, fixa-se na barra de menu através de um delegado de aplicação AppKit e liga onze estruturas de sistema, entre as quais sensores de movimento, notificações e processamento de imagem. A segunda tem três ficheiros e apresenta uma aplicação web num `WKWebView`. A segunda faz-se rapidamente e é uma escolha correta quando a sua aplicação já é web e você quer apenas um ícone no Dock. Não é uma escolha correta quando você precisa de sistema.

Vocês fazem aplicações para Windows?

Não entregámos nenhuma e não afirmamos outra coisa. Procurámos nos nossos discos qualquer vestígio — projetos .NET, WPF, WinForms, WinUI, ficheiros de interface XAML, manifestos de aplicação, pacotes MSI ou WiX — e tudo o que aparece pertence a uma biblioteca C de terceiros que apenas usamos noutro projeto. Se você precisa de Windows, a primeira etapa é uma verificação de compatibilidade que termina com um esqueleto que arranca no seu computador, e só depois disso discutimos o resto.

E para Linux ou Ubuntu?

A mesma posição, com uma precisão que importa. Aplicação com janelas para Linux: zero entregues, nenhum pacote deb ou AppImage construído por nós. Servidores Linux: dia a dia — unidades de sistema, servidor web à frente, registos, reinício em caso de falha. São duas disciplinas diferentes e seria desonesto usar a primeira como prova da segunda.

Porque não Electron, se assim é mais simples?

Porque não entregámos nenhuma e não vamos afirmar que temos experiência onde não temos. Nos nossos discos existem duas aplicações Electron funcionais, mas são repositórios clonados de outros autores, com zero contributos nossos — verificámo-los no histórico de commits precisamente para não acabarem como «prova» nesta página. Num projeto real, a escolha entre um ambiente web empacotado e código nativo faz-se depois de se saber o que a aplicação exige do sistema, quanto pesa o pacote e quem paga a manutenção, não pela moda.

O que bloqueia, para vocês, a publicação de uma aplicação de Mac?

A conta, não o código. Na configuração do projeto, o campo da equipa de desenvolvimento está vazio, e a assinatura do pacote construído é ad hoc, sem identificador de equipa. Para distribuição fora da loja, o macOS exige um certificado de programador identificável e a passagem do pacote por notarização. Num projeto seu, o certificado e a conta são da sua organização, por isso esse bloqueio simplesmente não aparece — mas tem de ser previsto desde o início, com o seu custo e tempo.

Não é mais simples fazermos um site e acabarmos?

Muitas vezes sim, e nós dizemo-lo antes de você no-lo dizer. Um site não precisa de assinatura, de notarização, de instalador, de canal de atualização nem de uma versão para cada sistema operativo. A aplicação instalada ganha quando você precisa de sensores, de periféricos, de trabalho sem internet, de presença permanente na barra do sistema ou de acesso direto aos ficheiros da pessoa. Se nenhum destes estiver na lista, o dinheiro gasta-se melhor noutra parte.

Vocês podem assumir uma aplicação desktop que já temos?

Com uma condição verificada antes de qualquer estimativa: que possamos construí-la do zero, na nossa máquina, a partir dos fontes recebidos. Se o build não se reproduzir — faltam dependências, certificados, passos não escritos — então ninguém pode estimar honestamente nada, e o primeiro trabalho passa a ser a reprodução do build, não a funcionalidade nova. Dizemo-lo antes, para não se descobrir a meio.

Em que se baseiam as afirmações acima (14 fontes)

14 delas são código e ficheiros dos nossos repositórios. Não publicamos o nome nem a linha: juntos, numa única página, descreveriam com demasiada precisão como estão construídos sistemas que não são só nossos. Percorremo-los consigo, no repositório, a pedido — a verificação continua possível, só que se faz numa conversa.

O que gostaria que funcionasse melhor?

Conte-nos o seu processo. Em conjunto decidimos o que vale a pena construir, o que podemos ligar e como verificamos o resultado.

Vamos falar