Saltar para o conteúdo
megapromotingVamos falar

Especialização · Aplicações móveis

Aplicações para telemóvel, construídas de forma a que a lógica possa ser verificada sem telemóvel.

Construímos aplicações nativas iOS em Swift, com sensores e HealthKit, e aplicações com um único código para iOS, Android e web quando o projeto não requer sensores. O núcleo da lógica é testado separadamente do ecrã.

Já construídoSunt trei implementări proprii, nu una. Un depozit cu cinci ținte de aplicație (patru iOS și una macOS) definite în `project.yml`, ale cărui teste de logică le-am rulat azi: 160 din 160 trec. O a doua aplicație iOS, în alt proiect, cu 40 de fișiere Swift și HealthKit. Și o a treia direcție, cu un singur cod pentru iOS, Android și web, a cărei variantă web răspunde astăzi. Rezerva care schimbă răspunsul la întrebarea pe care o pune orice cumpărător înainte de toate: niciuna dintre aplicațiile noastre nu este publicată în App Store sau Google Play. Motivul e unul singur și are nume — `DEVELOPMENT_TEAM` este gol în configurația de proiect, adică lipsește identificatorul de echipă din Apple Developer Program. Mașina are o identitate de semnare validă, suficientă pentru instalare pe dispozitiv propriu, insuficientă pentru distribuție în magazin. E o problemă de cont, nu de cod, dar rămâne o problemă și o scriem aici, nu la subsol.

Uma aplicação móvel tem duas partes que avariam de forma diferente. A parte que lê sensores e calcula algo — um ângulo, uma pontuação, um estado — e a parte que desenha ecrãs. Mantemo-las separadas, e não por motivos estéticos: no nosso repositório principal de iOS, os ficheiros do núcleo não importam a interface, pelo que podem ser compilados diretamente com `swiftc` no Mac e executados como um programa normal, sem simulador e sem telemóvel. A suite tem 160 verificações agrupadas em 16 etapas; executámo-la hoje e passa na totalidade. Esse é o motivo pelo qual podemos dizer o que um algoritmo faz exatamente, em vez de dizer que “funciona bem”.

Em iOS trabalhamos em Swift 6, com objetivo mínimo de iOS 17. O mesmo repositório define cinco aplicações como alvos separados: quatro para iPhone e uma para macOS, e a de macOS reutiliza quinze ficheiros do núcleo da de iOS, sem cópia. Os sensores são lidos na origem: a interface da Apple para os sensores nos auscultadores expõe a orientação da cabeça, e a aplicação compara o ângulo atual com uma posição que o utilizador calibra no início da sessão. Os limiares não são “ajustes internos”: abaixo de 7° está direito, entre 7° e 13° está em desvio, acima de 13° mantido durante três segundos dispara o alerta, e o alisamento usa uma média exponencial com o coeficiente 0,15. Os quatro valores estão em quatro linhas consecutivas de código e podem ser mostrados.

Quando o projeto não precisa de sensores, não recomendamos nativo. A terceira direção no portefólio é um único código que se compila para iPhone, Android e browser — React Native com Expo — e a versão web está publicada e responde hoje. A diferença prática para o cliente: um questionário, uma calculadora ou um painel de controlo não justificam duas equipas e dois repositórios; uma aplicação que escuta um sensor a vinte amostras por segundo, sim.

O que ainda não podemos. Nenhuma aplicação nossa está na App Store ou no Google Play. Não porque não compile — compila, instala-se no simulador e passa nos testes — mas porque na configuração do projeto o identificador de equipa Apple está vazio, ou seja, não existe uma inscrição no Apple Developer Program associada a estas builds. No Mac existe uma identidade de assinatura válida, de tipo desenvolvimento, que chega para instalação no próprio dispositivo e não chega para a loja. Para um projeto de cliente, a conta de desenvolvedor é aberta em nome da empresa cliente e fica a ser dela — essa é a conversa que deve ser feita no início, não no fim.

Qué incluye

El trabajo, por componentes

Lemos o sensor na origem, não através de uma biblioteca intermédia

Em iOS usamos diretamente as interfaces da Apple: `CMHeadphoneMotionManager` para a orientação da cabeça nos auscultadores, com delegado para ligação e desligação, e verificação explícita do estado de autorização antes de iniciar o fluxo. Se o sensor não estiver disponível, o estado passa para `waiting`, não para erro silencioso.

O núcleo da lógica não sabe que existe um ecrã

Os ficheiros de análise, calibração, histórico e políticas são Swift simples. Compilam-se com `swiftc` juntamente com o ficheiro de testes e executam-se como binário de linha de comandos. O resultado de hoje: 160 verificações, 16 etapas de 10, todas passadas. Um teste que corre em dois segundos no Mac corre a cada alteração; um que pede simulador, não.

A interface é construída sobre o núcleo, em iOS e em macOS ao mesmo tempo

SwiftUI para ambos. O alvo de macOS no mesmo repositório inclui quinze ficheiros do núcleo de iOS como fontes partilhadas, não como ficheiros copiados, portanto uma correção no algoritmo chega simultaneamente às duas aplicações.

Um único código para iOS, Android e web, quando essa é a escolha correta

Expo sobre React Native, com `react-native-web` para a versão de browser, tipos de letra carregados do pacote e ícones de aplicação separados para Android, incluindo a variante monocromática exigida pelo sistema. A mesma aplicação corre no telemóvel e na página, a partir de um único repositório.

Dados de saúde: uma política declarada para cada tipo de dado

Não “lemos o HealthKit”, mas sim uma tabela no código: onze tipos de dados (ângulos posturais, movimento bruto dos auscultadores, pulsação e variabilidade, sono, marcha, exposição áudio, sessões guiadas e outros) e cinco regimes possíveis (apenas local, leitura do HealthKit, gravação de treino, gravação de sessão de relaxamento, gravação de percurso). Cada tipo recebe explicitamente um dos regimes. A segunda aplicação iOS do portefólio, de um projeto privado, usa a mesma abordagem em 40 ficheiros Swift.

Os ficheiros de privacidade exigidos pela Apple, presentes desde o início

Quatro alvos têm `PrivacyInfo.xcprivacy` incluído como recurso de build, não adicionado à pressa após a primeira rejeição. As descrições de utilização para movimento, câmara, microfone, HealthKit e notificações estão escritas em romeno, na configuração do projeto, não geradas automaticamente.

O que sai do telefone: no caso da aplicação iOS de referência, nada

A pesquisa por `URLSession` nas fontes do alvo iOS devolve zero resultados. O histórico é gravado no dispositivo, através de `FileManager` e `UserDefaults`, com opção de apagar o ficheiro. O único código de rede no repositório está numa função da aplicação de macOS, num ficheiro separado. Quando uma aplicação não precisa de servidor, não lhe pomos um.

O percurso inicial, testado como estado, não como ecrã

O onboarding tem 24 passos com identificadores únicos e ordenados, e alguns passos pedem uma confirmação explícita (limites do sensor, funcionamento em primeiro plano, privacidade, preparação) sem a qual o botão de continuar permanece bloqueado. O estado é codificado e retomado. Dez dos 160 testes verificam exatamente isso.

Assinatura e distribuição, ditas desde o início

Verificamos que conta de developer existe, em que empresa, quem a administra e o que falta para que o build possa ser assinado para a loja. É uma lista curta e aborrecida, mas é a diferença entre uma aplicação que funciona no nosso telefone e uma que chega aos utilizadores.

Qué aspecto tiene

El recorrido, paso a paso.

01

Decidimos nativo ou código comum, com base nos sensores

A questão não é de gosto, mas de hardware: a aplicação precisa de movimento, saúde, Bluetooth, câmara em tempo real, plano de fundo? Se sim, nativo. Se se trata de formulários, cálculos, listas e um painel de controlo, um único código para iOS, Android e web faz a mesma tarefa com metade da manutenção. Entregamos a decisão por escrito, com a razão.

02

Construímos o núcleo antes dos ecrãs e cobrimo-lo com testes que correm sem telefone

O algoritmo, os limiares, os estados e a persistência. Os testes compilam-se diretamente no Mac e correm em poucos segundos. Entregamos a suíte e o respetivo resultado, não uma promessa de qualidade.

03

Colocamos a interface sobre o núcleo e corremos no simulador e no dispositivo

SwiftUI em iOS e macOS, ou React Native quando escolhemos o código comum. Verificamos o percurso inicial, as permissões e o comportamento quando o sensor falta ou se desliga a meio da sessão — o caso que muitas vezes falha na prática.

04

Preparamos a distribuição, com a conta do cliente

Identificador de pacote, versão, ícones, ficheiro de confidencialidade, descrições de permissões, identificador de equipa do Apple Developer Program. É aqui que ficam bloqueados os projetos que não trataram da conta no início — incluindo os nossos, o que é exatamente o motivo pelo qual colocamos este passo por escrito.

Ce vede utilizatorulAplicațiaRețea și securitateGăzduire și dateFIECARE STRAT, ALES ȘI EXPLICAT
Patru straturi, de jos în sus: senzorii platformei (mișcare din căști, HealthKit, notificări); nucleul de logică în Swift simplu, care nu importă interfața și de aceea poate fi rulat pe Mac fără telefon; interfața SwiftUI, aceeași pentru iPhone și macOS; și stratul de distribuție — fișier de confidențialitate, permisiuni declarate, semnare. Ultimul strat e singurul pe care nu l-am parcurs până la capăt, și de aceea e desenat deschis.

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.

Onde ficam os dados quando a aplicação não tem servidor
No dispositivo. O histórico postural é serializado num ficheiro próprio através de `FileManager`, e as preferências em `UserDefaults`, com chaves prefixadas por aplicação. Existe um comando para apagar o ficheiro de histórico. Nada é enviado para um servidor pelo simples motivo de a aplicação não conter código de rede.
Os dados de saúde só são lidos com consentimento, e apenas os declarados
O HealthKit exige o consentimento do utilizador ao nível do tipo de dado, e a aplicação declara na configuração por que motivo os pede. A política no código separa explicitamente o que é lido do que é escrito de volta em Saúde. Não é feito diagnóstico e nada nos é transmitido.
O que a Apple exige que declare, independentemente do que faça com os dados
O ficheiro de confidencialidade da aplicação e as descrições de utilização para cada permissão (movimento, câmara, microfone, saúde, notificações). São condição de aceitação na loja, não opção, e são escritos na língua que o utilizador fala.
Quanto tempo se guarda
O tempo que o utilizador decidir, quando os dados ficam no telefone: a desinstalação da aplicação leva-os consigo, e a eliminação dentro da aplicação é uma operação explícita. Quando um projeto tem servidor, a retenção é escrita no contrato antes da primeira linha de código, porque determina o que se pode e o que não se pode construir.
A conta de developer e as chaves de assinatura
Continuam a ser do cliente, na empresa do cliente. Nós trabalhamos com acesso delegado. O motivo é prático, não de princípio: uma aplicação publicada na conta do fornecedor torna-se impossível de transferir no dia em que o fornecedor muda.

Un caso

Uma aplicação de iPhone que mede uma única coisa, e mede-a de forma verificável

A situação

Um projeto próprio, não de um cliente: um cronómetro de concentração que observa o quanto a cabeça se inclinou em relação a uma posição calibrada pelo utilizador no início da sessão. Precisávamos de um caso em que as afirmações sobre o algoritmo pudessem ser mostradas, não descritas.

Qué construimos

Separei o núcleo da interface e escrevi os limiares no código, não na documentação: abaixo de 7° está direito, entre 7° e 13° é deslizamento, acima de 13° mantido durante três segundos dispara o alerta háptico, com suavização exponencial no coeficiente 0,15. Os dados vêm da interface Apple para os sensores nos auscultadores, com tratamento explícito da desconexão. O onboarding tem 24 passos, dos quais quatro pedem a confirmação dos limites antes de deixar o utilizador avançar. Construí a partir do mesmo núcleo também uma variante de macOS.

Qué salió

A suite de lógica compila com `swiftc` e corre no Mac em alguns segundos: 160 verificações em 16 etapas, todas aprovadas na última execução. A aplicação instala-se e arranca no simulador. Qualquer afirmação do parágrafo acima pode ser verificada abrindo quatro linhas de código.

Qué no dice el caso

Não está na App Store. A configuração do projeto tem o identificador de equipa Apple vazio, portanto o build não pode ser assinado para distribuição — uma falta de inscrição no programa Apple, não uma falta de funcionalidade. E há ainda outro limite, do produto e não do código: mede a inclinação da cabeça, não a saúde da coluna, e funciona com os auscultadores que expõem sensores de movimento através da interface Apple.

Perguntas

Lo que nos pregunta la gente antes de llamar

Têm uma aplicação publicada na App Store, para eu a poder ver?

Não. Nenhuma das nossas aplicações está na App Store ou no Google Play, e é correto perguntar isso primeiro. O que podemos mostrar: cinco destinos de aplicação definidos no mesmo projeto, dos quais quatro para iPhone e um para macOS, que compilam e se instalam no simulador, mais a suite de lógica de 160 verificações, executada a pedido à sua frente. O bloqueio na publicação é `DEVELOPMENT_TEAM` vazio na configuração do projeto, ou seja, a ausência de um identificador de equipa do Apple Developer Program. No Mac existe uma identidade de assinatura válida, do tipo desenvolvimento — chega para instalação em dispositivo próprio, não para a loja.

Então, como sei que vocês conseguem levar uma aplicação até à loja?

De nada, se pedir uma prova de publicação — não a temos e não a inventamos. O que pode verificar é o resto da cadeia: código que compila, testes que passam, ficheiros de confidencialidade presentes, permissões declaradas, ícones e versões configurados. O passo que falta é uma inscrição paga num programa Apple, feita na empresa que detém a aplicação. Num projeto de cliente, essa conta é do cliente e é aberta no início, exatamente para que não seja ela o passo que surpreende alguém no fim.

Nativo ou uma única aplicação para iOS e Android?

Depende dos sensores. Se a aplicação lê movimento, saúde, Bluetooth ou câmara em tempo real, nativo — essas interfaces são da plataforma e qualquer camada intermédia acrescenta latência e novas formas de falhar. Se a aplicação é, essencialmente, formulários, cálculos e ecrãs de resultado, um único código cobre iOS, Android e browser a partir de um repositório. Temos ambas as variantes no portefólio e escolhemo-las com argumento escrito, não por defeito.

Também fazem aplicações para Android?

Através de código comum, sim: o mesmo projeto Expo gera build para Android, com o ícone adaptativo e a variante monocromática exigida pelo sistema já configurados. Android nativo, em Kotlin, não temos no portefólio — se um projeto o exigir, dizemo-lo antes, não depois da assinatura.

Como verificam que a lógica está correta se não têm o meu telefone?

Pelo facto de o núcleo não depender do ecrã. Os ficheiros de análise compilam-se separadamente, com o compilador Swift, e correm como programa no Mac. A suíte atual tem 160 verificações em 16 etapas e executa-se em poucos segundos. O que não pode ser verificado assim — como se sente uma vibração, como fica um ecrã num telemóvel específico, como se comportam os auscultadores quando saem de uma orelha — testa-se no dispositivo, e diz-se o que é o quê.

A aplicação pode ler os meus dados da Saúde?

Só se os aprovar, tipo por tipo, no ecrã da Apple, e apenas os declarados. No código, a política é explícita para cada tipo de dado: alguns ficam apenas no telefone, outros são lidos do HealthKit, outros podem ser escritos de volta como treino ou como sessão de relaxamento. Não se faz diagnóstico, e os dados não chegam até nós.

O que acontece aos dados se a aplicação não tiver servidor?

Ficam no telefone. Na aplicação iOS de referência no nosso portefólio não existe qualquer chamada de rede — a pesquisa por `URLSession` nas fontes desse alvo devolve zero resultados. O histórico é gravado num ficheiro local e pode ser apagado na aplicação. Quando um projeto precisa de servidor, nós construímo-lo, mas não o colocamos por reflexo.

Podemos assumir uma aplicação existente, feita por outra pessoa?

Começa com uma verificação de compatibilidade, não com uma proposta: que versão de plataforma visa, que dependências tem e quais delas ainda são mantidas, se o build se reproduz numa máquina limpa, quem detém a conta de programador e as chaves. Há projetos em que a resposta honesta é que reescrever o núcleo custa menos do que mantê-lo.

Também fazem aplicações de desktop?

No macOS, sim, e a partir do mesmo núcleo: no nosso repositório principal, o alvo de macOS reutiliza quinze ficheiros de lógica da aplicação de iPhone, como fontes partilhadas. Windows não está no portefólio.

Em que se baseiam as afirmações acima (11 fontes)
  1. Varianta web a aplicației cu cod comun răspunde azihttps://longevita-alpha.vercel.app/ · 2026-09-06

10 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