Techniczne aspekty budowy aplikacji startupu Vector24, czyli ta sama historia w oczach project managera

Autorzy: Rafał Linowiecki

10.05.2017

Z Androida na PC

Klient przyjechał do nas z olbrzymim plakatem, zawierającym pełne flow aplikacji w oparciu o makiety. Oczywiście, były one przeznaczone na wersję mobilną – dokładnie na system Windows Phone. Gdy usiedliśmy do rozmów o projekcie, klient bardzo szybko zdał sobie sprawę, że rynek, dla którego głównie kierowana była aplikacja (rynek poligraficzny) bardzo często korzysta z tradycyjnych PC-tów, w związku z tym dobrze byłoby przygotować wersję aplikacji na tzw. Desktopy. Ponieważ mieliśmy do czynienia ze startupem, w pierwszej iteracji miała pójść wersja MVP (Minimum Variable Product), która zgodnie z założeniem powinna być wersją działającą, stabilną i zawierającą najważniejsze funkcjonalności co pozwoli przekonać potencjalnych inwestorów jak i przyszłych użytkowników do zainwestowania w ten pomysł.


CODE SHARING

Ponieważ nasza firma specjalizuje się w technologii Xamarin z użyciem frameworka MVVM Cross, mając perspektywę tworzenia projektu zarówno na systemy desktop oraz mobile, podjęliśmy decyzję, że wersję desktop zaimplementujemy w oparciu o technologię WPF (Windows Presentation Foundation), a część logiczną, tzw. ‘core’, wydzielimy do części wspólnej. To oznacza, że piszemy jeden kod, który możemy wykorzystać zarówno na systemach mobilnych (Android, IOS, WindowsPhone) jak również na aplikacjach desktopowych.


SYNCHRONIZACJA DANYCH

Kolejnym wyzwaniem okazał się sposób synchronizacji danych w całej aplikacji – urządzenia miały mieć możliwość synchronizacji z każdego miejsca na świecie, a dodatkowo wszystkie operacje wykonywane przez innych użytkowników z tej samej firmy miały być dostępne w ‘real time’ dla każdego. Wykorzystaliśmy do tego celu rozwiązanie cloudowe (tzw. chmurę), gdzie umieściliśmy zaimplementowane wcześniej API (Application Programming Interface), które odpowiedzialne jest za całą logikę systemu wraz z połączeniem do bazy danych oraz innych serwisów i providerów zintegrowanych w aplikacji.


Z powodu wielkości aplikacji i stopnia skomplikowania procesów w niej zachodzących postawiliśmy na sprawdzone rozwiązania – API stworzone przy użyciu technologii ASP.NET WebAPI, z którą mamy ogromne doświadczenie, oraz relacyjną bazę danych opartą na MS SQL. W całym rozwiązaniu brakowało tylko jednego, bardzo istotnego komponentu – wywołań asynchronicznych ze strony serwera dla dedykowanej grupy użytkowników, które miałyby informować ich o zmianie danych podczas wykonywanych operacji przez innych. Tutaj z pomocą przyszedł nam znany i sprawdzony SignalR, który pozwolił nam aktualizować dane użytkowników w oparciu o dane pobrane z serwera tylko w sytuacjach, kiedy faktycznie było to konieczne. Atutem tego rozwiązania była biblioteka kliencka dla SignalR, która również została wykorzystana dla wszystkich platform – cała implementacja znalazła się w Corze, dzięki czemu po stronie platformowej musieliśmy obsłużyć tylko odpowiednie zdarzenia i odpowiednio zareagować na widoku.

ZEWNĘTRZNE SERWISY

Oprócz standardowych rozwiązań technicznych aplikacja musiała korzystać również z zewnętrznych serwisów, które umożliwiały kupowanie subskrypcji produktu, wysyłania smsów oraz maili wraz z odpowiednim rejestrowaniem wszystkich operacji dla danego konta. Dla subskrypcji produktu postawiliśmy na system Recurly, który w prosty i przejrzysty sposób pozwala na zarządzanie własnym kontem dla użytkowników z poziomu aplikacji desktopowej. To rozwiązanie było podyktowane również modelem biznesowym, na którym opiera się aplikacja – klienci płacą za kolejnych użytkowników w firmie i/lub za każdy wysłany sms. Ponieważ wiedzieliśmy, jaka będzie przyszła skala projektu, postanowiliśmy przenieść obsługę sms oraz email do sprawdzonych serwisów – dla pierwszego wybraliśmy Twilio, który w pełni odpowiadał naszym oczekiwaniom. Możemy tworzyć subkonta dla każdego nowego klienta, co istotnie wpływa na kontrolę wydatków przy wysyłaniu dużej ilości sms. Do wysyłania masowej ilości wiadomości elektronicznych (e-mail) wykorzystaliśmy sprawdzony już wcześniej system SendGrid, który dodatkowo został skonfigurowany aby korzystać z domen klienta – oznacza to tyle, że przychodzące wiadomości email mają przekierowanie na domenę klienta co dodatkowo wpływa pozytywnie na aspekt postrzegania technicznej strony całego projektu.

Oczywiście - korzystając z rozwiązań chmurowych trzeba liczyć się z przyszłym obciążeniem serwera, ilością generowanych zapytań przez klientów, zależnościami do bazy danych a także kosztami utrzymania tej infrastruktury. Problem polegał na tym, że chcąc mieć zawsze aktualne dane dla każdego użytkownika aplikacji, liczba zapytań do serwera wzrastała w wykładniczym tempie – musieliśmy coś z tym zrobić. W tym celu konieczna okazała się modyfikacja części architektury odpowiadającej za pobieranie danych z API, aby zredukować ilość wysłanych zapytań do minimum otrzymując jednocześnie pełne dane konieczne do synchronizacji. Takie rozwiązanie pozwoliło zmniejszyć liczbę ruchu na serwerze ponad 10-krotnie!

Istotnym problemem przy aplikacjach opartych o chmurę jest… połączenie z internetem. Również w tym przypadku wystąpiły problemy ze stabilnością sieci oraz częstym przerywaniem sygnału. Chcąc dostarczyć użytkownikowi aplikację, która będzie potrafiła radzić sobie z tego typu przeszkodami musieliśmy zaimplementować klika mechanizmów działających w tle, które na bieżąco analizują sytuację stabilności połączenia z serwerem i w przypadku problemów automatycznie próbują nawiązać połączenie oraz zsynchronizować dane bez konieczności ingerencji użytkownika. Dodatkowym wyzwaniem była obsługa stanu uśpienia i zawieszenia aplikacji lub urządzenia oraz ponownego przywrócenia wraz z najświeższymi danymi – tutaj z pomocą również przyszła obsługa odpowiednich zdarzeń systemowych i ponownie praca „backgroundowych” mechanizmów pozwalających na przyjemne korzystanie z aplikacji

Z MVP do 1.0

Największym jednak wyzwaniem w całej aplikacji była budowa wersji MVP, która… przeistoczyła się w trakcie developmentu w pełną wersję 1.0 – zabrakło tutaj jasno określonych granic funkcjonalności i zmiany koncepcji w trakcie implementacji przyczyniły się do tego, że pierwszy scope zakończył się nie małą pokazową aplikacją, lecz pełnym systemem, który ma już swoje wdrożenia u klientów naszego klienta