Przejdź do treści
megapromotingPorozmawiajmy

Ekspertyza · Aplikacje mobilne

Aplikacje na telefon, zbudowane tak, aby logikę dało się zweryfikować bez telefonu.

Budujemy natywne aplikacje iOS w Swift, z czujnikami i HealthKit, oraz aplikacje z jednym kodem dla iOS, Android i webu, gdy projekt nie wymaga czujników. Rdzeń logiki testuje się oddzielnie od ekranu.

Już zbudowaneSą trzy własne implementacje, nie jedna. Repozytorium z pięcioma celami aplikacji (cztery iOS i jedno macOS) zdefiniowanymi w `project.yml`, którego testy logiki uruchomiliśmy dziś: 160 z 160 przechodzi. Druga aplikacja iOS, w innym projekcie, z 40 plikami Swift i HealthKit. I trzeci kierunek, z jednym kodem dla iOS, Androida i webu, którego wersja web odpowiada dziś. Zastrzeżenie, które zmienia odpowiedź na pytanie, jakie zadaje każda kupująca osoba przede wszystkim: żadna z naszych aplikacji nie jest opublikowana w App Store ani Google Play. Powód jest jeden i ma nazwę — `DEVELOPMENT_TEAM` jest puste w konfiguracji projektu, czyli brakuje identyfikatora zespołu z Apple Developer Program. Maszyna ma ważną tożsamość podpisu, wystarczającą do instalacji na własnym urządzeniu, niewystarczającą do dystrybucji w sklepie. To problem konta, nie kodu, ale nadal jest to problem i zapisujemy go tutaj, a nie w przypisie.

Aplikacja mobilna ma dwie części, które psują się inaczej. Część, która odczytuje czujniki i coś oblicza — kąt, wynik, stan — oraz część, która rysuje ekrany. Trzymamy je osobno i nie z powodów estetycznych: w naszym głównym repozytorium iOS pliki rdzenia nie importują interfejsu, więc można je skompilować bezpośrednio przez `swiftc` na Macu i uruchomić jak zwykły program, bez symulatora i bez telefonu. Zestaw ma 160 weryfikacji pogrupowanych w 16 etapów; uruchomiliśmy go dziś i przechodzi w całości. To dlatego możemy powiedzieć dokładnie, co robi algorytm, zamiast mówić, że „działa dobrze”.

Na iOS pracujemy w Swift 6, z minimalnym celem iOS 17. To samo repozytorium definiuje pięć aplikacji jako osobne targety: cztery dla iPhone'a i jedną dla macOS, a wersja macOS ponownie wykorzystuje piętnaście plików z rdzenia iOS, bez kopiowania. Czujniki odczytujemy u źródła: interfejs Apple dla czujników w słuchawkach udostępnia orientację głowy, a aplikacja porównuje bieżący kąt z pozycją, którą użytkownik kalibruje na początku sesji. Progi nie są „wewnętrznymi ustawieniami”: poniżej 7° jest prosto, między 7° a 13° jest pochylenie, powyżej 13° utrzymane przez trzy sekundy wywołuje alert, a wygładzanie używa średniej wykładniczej ze współczynnikiem 0,15. Wszystkie cztery wartości znajdują się w czterech kolejnych liniach kodu i można je pokazać.

Gdy projekt nie potrzebuje czujników, nie zalecamy natywnie. Trzeci kierunek w portfolio to jeden kod, który kompiluje się dla iPhone'a, Androida i przeglądarki — React Native z Expo — a wersja web jest opublikowana i odpowiada dziś. Praktyczna różnica dla klienta: kwestionariusz, kalkulator albo pulpit nawigacyjny nie uzasadniają dwóch zespołów i dwóch repozytoriów; aplikacja, która nasłuchuje czujnika dwadzieścia razy na sekundę, tak.

Czego jeszcze nie możemy. Żadna z naszych aplikacji nie jest w App Store ani Google Play. Nie dlatego, że się nie kompilują — kompilują się, instalują na symulatorze i przechodzą testy — lecz dlatego, że w konfiguracji projektu identyfikator zespołu Apple jest pusty, czyli nie ma powiązanej z tymi buildami rejestracji w Apple Developer Program. Na Macu istnieje prawidłowa tożsamość podpisywania, typu deweloperskiego, która wystarcza do instalacji na własnym urządzeniu i nie wystarcza do sklepu. Dla projektu klienta konto deweloperskie zakłada się na firmę klienta i pozostaje jego — to rozmowa, którą trzeba przeprowadzić na początku, nie na końcu.

Co obejmuje

Praca, komponent po komponencie

Odczytujemy czujnik u źródła, nie przez pośrednią bibliotekę

Na iOS używamy bezpośrednio interfejsów Apple: `CMHeadphoneMotionManager` do orientacji głowy ze słuchawek, z delegatem dla podłączenia i odłączenia oraz z wyraźnym sprawdzeniem stanu autoryzacji przed uruchomieniem strumienia. Jeśli czujnik nie jest dostępny, stan przechodzi w `waiting`, a nie w cichy błąd.

Rdzeń logiki nie wie, że istnieje ekran

Pliki analizy, kalibracji, historii i polityk to zwykły Swift. Kompilują się przez `swiftc` razem z plikiem testów i uruchamiają jako binarka wiersza poleceń. Dzisiejszy wynik: 160 weryfikacji, 16 etapów po 10, wszystkie zaliczone. Test, który uruchamia się w dwie sekundy na Macu, uruchamia się przy każdej zmianie; taki, który wymaga symulatora, nie.

Interfejs jest budowany ponad rdzeniem, jednocześnie na iOS i na macOS

SwiftUI dla obu. Cel macOS z tego samego repozytorium zawiera piętnaście plików z rdzenia iOS jako współdzielone źródła, a nie jako skopiowane pliki, więc poprawka w algorytmie trafia jednocześnie do obu aplikacji.

Jeden kod dla iOS, Androida i web, gdy to jest właściwy wybór

Expo nad React Native, z `react-native-web` dla wersji przeglądarkowej, czcionkami ładowanymi z pakietu i osobnymi ikonami aplikacji dla Androida, w tym wersją monochromatyczną wymaganą przez system. Ta sama aplikacja działa na telefonie i na stronie, z jednego repozytorium.

Dane zdrowotne: zadeklarowana polityka dla każdego typu danych

Nie „czytamy HealthKit”, tylko tabelę w kodzie: jedenaście typów danych (kąty posturalne, surowy ruch z słuchawek, puls i zmienność, sen, chodzenie, ekspozycja audio, sesje prowadzone i inne) oraz pięć możliwych reżimów (tylko lokalnie, odczyt z HealthKit, zapis treningu, zapis sesji relaksacyjnej, zapis trasy). Każdy typ dostaje jawnie jeden z reżimów. Druga aplikacja iOS z portfolio, z prywatnego projektu, używa tego samego podejścia w 40 plikach Swift.

Pliki prywatności wymagane przez Apple, obecne od początku

Cztery cele mają `PrivacyInfo.xcprivacy` dołączony jako zasób builda, a nie dodany w pośpiechu po pierwszym odrzuceniu. Opisy użycia dla ruchu, kamery, mikrofonu, HealthKit i powiadomień są napisane po rumuńsku, w konfiguracji projektu, a nie generowane automatycznie.

Co wychodzi z telefonu: w przypadku referencyjnej aplikacji iOS, nic

Wyszukiwanie `URLSession` w źródłach celu iOS zwraca zero wyników. Historia jest zapisywana na urządzeniu, przez `FileManager` i `UserDefaults`, z opcją usunięcia pliku. Jedyny kod sieciowy w repozytorium jest w funkcji aplikacji macOS, w osobnym pliku. Gdy aplikacja nie potrzebuje serwera, nie dodajemy jej serwera.

Ścieżka startowa, testowana jako stan, nie jako ekran

Onboarding ma 24 kroki z unikalnymi i uporządkowanymi identyfikatorami, a niektóre kroki wymagają wyraźnego potwierdzenia (ograniczenia sensora, działanie na pierwszym planie, prywatność, przygotowanie), bez którego przycisk kontynuacji pozostaje zablokowany. Stan jest kodowany i przywracany. Dziesięć z 160 testów sprawdza dokładnie to.

Podpisywanie i dystrybucja, powiedziane na początku

Sprawdzamy, jakie konto deweloperskie istnieje, na jaką firmę, kto nim zarządza i czego brakuje, aby build mógł zostać podpisany do sklepu. To krótka i nudna lista, ale to różnica między aplikacją, która działa na naszym telefonie, a taką, która trafia do użytkowników.

Jak to wygląda

Trasa, krok po kroku.

01

Decydujemy natywnie albo wspólnym kodem, na podstawie sensorów

Pytanie nie jest kwestią gustu, tylko sprzętu: czy aplikacja potrzebuje ruchu, zdrowia, Bluetooth, kamery w czasie rzeczywistym, tła? Jeśli tak, natywnie. Jeśli chodzi o formularze, obliczenia, listy i pulpit, jeden kod dla iOS, Androida i webu robi to samo przy połowie utrzymania. Dostarczamy decyzję na piśmie, z uzasadnieniem.

02

Budujemy rdzeń przed ekranami i pokrywamy go testami, które działają bez telefonu

Algorytm, progi, stany i trwałość. Testy kompilują się bezpośrednio na Macu i uruchamiają w kilka sekund. Dostarczamy zestaw i jego wynik, a nie obietnicę jakości.

03

Nakładamy interfejs na rdzeń i uruchamiamy na symulatorze oraz na urządzeniu

SwiftUI na iOS i macOS, albo React Native, gdy wybraliśmy wspólny kod. Sprawdzamy ścieżkę startową, uprawnienia i zachowanie, gdy sensor znika lub rozłącza się w środku sesji — przypadek, który często psuje się w praktyce.

04

Przygotowujemy dystrybucję, z kontem klienta

Identyfikator pakietu, wersja, ikony, plik prywatności, opisy uprawnień, identyfikator zespołu z Apple Developer Program. Tutaj blokują się projekty, które nie omówiły konta na początku — także nasze, co jest dokładnie powodem, dla którego zapisujemy ten krok na papierze.

Ce vede utilizatorulAplikacjaSieć i bezpieczeństwoHosting i daneKAŻDA WARSTWA, WYBRANA I WYJAŚNIONA
Cztery warstwy, od dołu do góry: czujniki platformy (ruch ze słuchawek, HealthKit, powiadomienia); rdzeń logiki w zwykłym Swift, który nie importuje interfejsu i dlatego można go uruchomić na Macu bez telefonu; interfejs SwiftUI, ten sam dla iPhone'a i macOS; i warstwa dystrybucji — plik prywatności, zadeklarowane uprawnienia, podpisywanie. Ostatnia warstwa to jedyna, której nie przeszliśmy do końca, i dlatego jest narysowana linią przerywaną.

Dane

Czego dotykamy, gdzie to leży i jak długo zostaje

Pytania, które zadaje każdy, kto ma inspektora ochrony danych — postawione tutaj, zanim on je zada.

Gdzie są dane, gdy aplikacja nie ma serwera
Na urządzeniu. Historia postawy jest serializowana do własnego pliku przez `FileManager`, a preferencje w `UserDefaults`, z kluczami z prefiksem aplikacji. Istnieje polecenie usunięcia pliku historii. Nic nie trafia na serwer z prostego powodu: aplikacja nie zawiera kodu sieciowego.
Dane zdrowotne są odczytywane tylko za zgodą, i tylko te zadeklarowane
HealthKit wymaga zgody użytkowniczki lub użytkownika na poziomie typu danych, a aplikacja deklaruje w konfiguracji, do czego ich potrzebuje. Polityka w kodzie wyraźnie rozdziela to, co jest odczytywane, od tego, co jest zapisywane z powrotem do Zdrowia. Nie stawia się diagnozy i nic nie jest przekazywane do nas.
Co Apple wymaga zadeklarować, niezależnie od tego, co robisz z danymi
Plik poufności aplikacji i opisy użycia dla każdego uprawnienia (ruch, kamera, mikrofon, zdrowie, powiadomienia). Są warunkiem akceptacji w sklepie, nie opcją, i są zapisywane w języku, którym posługuje się użytkowniczka lub użytkownik.
Jak długo są przechowywane
Tak długo, jak decyduje użytkowniczka lub użytkownik, gdy dane są przechowywane na telefonie: odinstalowanie aplikacji zabiera je ze sobą, a usunięcie z aplikacji jest operacją jawna. Gdy projekt ma jednak serwer, retencja jest zapisywana w umowie przed pierwszą linią kodu, ponieważ określa, co można, a czego nie można zbudować.
Konto deweloperskie i klucze podpisywania
Pozostają po stronie klienta, na firmę klienta. Pracujemy z dostępem delegowanym. Powód jest praktyczny, nie zasadniczy: aplikacja opublikowana na koncie dostawczyni lub dostawcy staje się niemożliwa do przeniesienia w dniu, w którym dostawczyni lub dostawca się zmienia.

Przykład

Aplikacja na iPhone'a, która mierzy jedną rzecz, i mierzy ją weryfikowalnie

Sytuacja

Własny projekt, nie klienta: stoper koncentracji, który obserwuje, o ile głowa odchyliła się od pozycji skalibrowanej przez użytkowniczkę lub użytkownika na początku sesji. Potrzebowaliśmy przypadku, w którym twierdzenia o algorytmie można pokazać, a nie opisać.

Co zbudowaliśmy

Oddzieliłem rdzeń od interfejsu i zapisałem progi w kodzie, nie w dokumentacji: poniżej 7° prosto, między 7° a 13° odchylenie, powyżej 13° utrzymane przez trzy sekundy uruchamia alert haptyczny, z wygładzaniem wykładniczym przy współczynniku 0,15. Dane pochodzą z interfejsu Apple dla czujników w słuchawkach, z wyraźną obsługą rozłączenia. Onboarding ma 24 kroki, z czego cztery wymagają potwierdzenia limitów, zanim użytkowniczka lub użytkownik przejdzie dalej. Z tego samego rdzenia zbudowano też wariant dla macOS.

Co z tego wyszło

Pakiet logiki kompiluje się z `swiftc` i działa na Macu w kilka sekund: 160 weryfikacji w 16 etapach, wszystkie zaliczone przy ostatnim uruchomieniu. Aplikacja instaluje się i uruchamia na symulatorze. Każde twierdzenie z powyższego akapitu można zweryfikować, otwierając cztery linie kodu.

Czego nie mówi ten przypadek

Nie jest w App Store. Konfiguracja projektu ma pusty identyfikator zespołu Apple, więc build nie może być podpisany do dystrybucji — brak zapisania do programu Apple, nie brak funkcjonalności. I jeszcze jedno ograniczenie, produktu, nie kodu: mierzy odchylenie głowy, nie zdrowie kręgosłupa, i działa ze słuchawkami, które udostępniają czujniki ruchu przez interfejs Apple.

Pytania

O co pytają ludzie, zanim zadzwonią

Czy macie opublikowaną aplikację w App Store, żebym mogła lub mógł ją zobaczyć?

Nie. Żadna z naszych aplikacji nie jest w App Store ani Google Play, i słusznie pytasz o to na początku. Co możemy pokazać: pięć celów aplikacji zdefiniowanych w tym samym projekcie, z czego cztery dla iPhone'a i jeden dla macOS, które kompilują się i instalują na symulatorze, plus pakiet logiki 160 weryfikacji, uruchamiany na żądanie na twoich oczach. Blokadą publikacji jest puste `DEVELOPMENT_TEAM` w konfiguracji projektu, czyli brak identyfikatora z Apple Developer Program. Na Macu istnieje poprawna tożsamość podpisywania, typu deweloperskiego — wystarcza do instalacji na własnym urządzeniu, nie do sklepu.

Skąd więc mam wiedzieć, że potraficie doprowadzić aplikację do sklepu?

Z niczego, jeśli prosisz o dowód publikacji — nie mamy go i nie wymyślamy go. To, co możesz zweryfikować, to reszta łańcucha: kod, który się kompiluje, testy, które przechodzą, obecne pliki poufności, zadeklarowane uprawnienia, skonfigurowane ikony i wersje. Brakuje kroku: płatnego zapisania do programu Apple, dokonanego na firmę, która posiada aplikację. W projekcie klienta to konto należy do klienta i jest otwierane na początku, dokładnie po to, żeby to nie ono było krokiem, który zaskoczy kogoś na końcu.

Natywna czy jedna aplikacja na iOS i Android?

To zależy od czujników. Jeśli aplikacja odczytuje ruch, zdrowie, Bluetooth albo kamerę w czasie rzeczywistym, to natywnie — te interfejsy należą do platformy i każda warstwa pośrednia dodaje opóźnienie oraz nowe sposoby awarii. Jeśli aplikacja to w zasadzie formularze, obliczenia i ekrany wyników, jeden kod obejmuje iOS, Android oraz przeglądarkę z jednego repozytorium. Mamy obie wersje w portfolio i wybieramy je z pisemnym uzasadnieniem, nie domyślnie.

Tworzycie też aplikacje na Androida?

Przez wspólny kod, tak: ten sam projekt Expo generuje build dla Androida, z ikoną adaptacyjną i monochromatyczną wersją wymaganą przez system, już skonfigurowanymi. Natywnego Androida, w Kotlinie, nie mamy w portfolio — jeśli projekt tego wymaga, mówimy to przed podpisaniem, nie po.

Jak sprawdzacie, że logika jest poprawna, jeśli nie macie mojego telefonu?

Przez to, że rdzeń nie zależy od ekranu. Pliki analizy kompilują się osobno, kompilatorem Swift, i uruchamiają się jako program na Macu. Obecny zestaw ma 160 sprawdzeń w 16 etapach i wykonuje się w kilka sekund. To, czego nie da się tak sprawdzić — jak czuje się wibracja, jak wygląda ekran na konkretnym telefonie, jak zachowują się słuchawki, gdy wypadają z jednego ucha — testuje się na urządzeniu i mówi się, co jest czym.

Czy aplikacja może czytać moje dane z Zdrowia?

Tylko jeśli wyrazisz zgodę, typ po typie, na ekranie Apple, i tylko te zadeklarowane. W kodzie polityka jest jawna dla każdego rodzaju danych: niektóre zostają tylko na telefonie, inne są odczytywane z HealthKit, inne można zapisać z powrotem jako trening albo sesję relaksacyjną. Nie stawia się diagnozy, a dane nie trafiają do nas.

Co dzieje się z danymi, jeśli aplikacja nie ma serwera?

Zostają na telefonie. W referencyjnej aplikacji iOS z naszego portfolio nie ma żadnego wywołania sieciowego — wyszukiwanie `URLSession` w źródłach tego targetu zwraca zero wyników. Historia jest zapisywana w pliku lokalnym i można ją usunąć z aplikacji. Gdy projekt potrzebuje serwera, budujemy go, ale nie dodajemy go odruchowo.

Czy możemy przejąć istniejącą aplikację, zrobioną przez kogoś innego?

Zaczyna się od sprawdzenia zgodności, nie od oferty: jaką wersję platformy targetuje, jakie ma zależności i które z nich są jeszcze utrzymywane, czy build odtwarza się na czystej maszynie, kto posiada konto deweloperskie i klucze. Są projekty, w których uczciwa odpowiedź brzmi, że przepisanie rdzenia kosztuje mniej niż jego utrzymanie.

Tworzycie też aplikacje desktopowe?

Na macOS, tak, i z tego samego rdzenia: w naszym głównym repozytorium target macOS ponownie wykorzystuje piętnaście plików logiki z aplikacji na iPhone’a jako współdzielone źródła. Windows nie jest w portfolio.

Na czym opierają się powyższe stwierdzenia (11 źródeł)
  1. Wariant webowy aplikacji ze wspólnym kodem odpowiada dziśhttps://longevita-alpha.vercel.app/ · 2026-09-06

10 z nich to kod i pliki z naszych repozytoriów. Nie publikujemy ich nazw ani numerów linii: razem, na jednej stronie, opisałoby to zbyt dokładnie, jak zbudowane są systemy, które nie należą tylko do nas. Przechodzimy je razem z Tobą, w repozytorium, na życzenie — weryfikacja pozostaje możliwa, tylko odbywa się w rozmowie.

Co chcesz, żeby działało lepiej?

Opowiedz nam o swoim procesie. Wspólnie ustalimy, co warto zbudować, co da się połączyć i jak sprawdzimy wynik.

Porozmawiajmy