Mianem dynamic framework określna jest biblioteka, która zostanie podlinkowana do programu już w trakcie jego działania, zamiast standardowo w trakcie kompilacji. Apple wprowadziło takie rozwiązanie, aby zredukować czas uruchamiania aplikacji oraz zmniejszyć wykorzystanie zasobów urządzenia. Pierwszymi z brzegu przykładami takich bibliotek będą UIKit oraz Foundation, z których z całą pewnością zdarzyło Wam już skorzystać 😎. Od iOS w wersji 8 Apple pozwoliło na implementację zewnętrznych bibliotek dynamicznych.

Dynamiczne biblioteki zostaną załadowane da pamięci urządzenia dopiero w chwili, w której będą faktycznie potrzebne. Biblioteki statyczne są natomiast ładowane są do pamięci urządzenia w chwili startu aplikacji, co oczywiście negatywnie wpływa na czas jej uruchomienia. Redukcja wykorzystania zasobów urządzenia – określana jako „Reduce memory footprint” – oznacza zmiejszenie rozmiarów pliku samej aplikacji, jak również ograniczenie jej wpływu na pamięć urządzenia. Dynamic frameworks mogą również (tak samo jak biblioteki statyczne) przechowywać foldery z assetami, takim jak choćby pliki .nib lub zdjęcia.

Tak wygląda dodawanie biblioteki statycznej do pliku wykonywalnego aplikacji:

Źródło

 

Biblioteka statyczna zostaje bezpośrednio wbudowana. Biblioteka dynamiczna dodawana jest natomiast w sposób przedstawiony na poniższej ilustracji:

 

Źródło

 

W przypadku dynamic framework kod biblioteki ładowany jest do pamięci urządzenia dopiero w chwili, gdy po raz pierwszy chcemy z niej skorzystać. Plik wykonywalny aplikacji nie będzie nim obciążony. Może się oczywiście zdarzyć tak, że będziemy chcieli skorzystać z danej biblioteki już na starcie aplikacji i tym sam zostanie ona załadowana do pamięci już na samym początku. Nie zmienia to jednak faktu, że sam plik wykonywalny nie będzie zawierał w sobie kopii danej biblioteki.

Każdy plik wykonywalny zawiera listę bibliotek, z których dana aplikacja będzie korzystała. Biblioteki te dzielą się na wymagane oraz opcjonalne. Za ładowanie odpowiednich frameworków odpowiada z kolei inna biblioteka o nazwie dynamic loader – w skrócie dyld. To tyle teorii. Za chwilę zbudujemy wspólnie prostą aplikację, w której sprawdzimy jak to sprawdza się w praktyce 🙃.

 

Dyanimic frameworks w praktyce

 

Stwórzcie nowy projekt w Xcode. Nazwę możecie wybrać dowolną, ale proponuję DynamicFrameworksDemo. Jako język możecie wybrać Swift, a dla reszty ustawień możecie zostawić domyślną wartość:

 

 

Po uruchomieniu projektu w oknie nawigatora wybierzcie DynamicFrameworksDemo, następnie Bulid Phases i rozwińcie zakładkę Link Binary With Libraries. Za pomocą przycisku „+” dodajcie dwie zależności – AVFoundation.framework oraz CoreBluetooth.framework. Zmieniając wartość w kolumnie „Status” ustawcie bibliotekę CoreBluetooth jako opcjonalną:

 

 

Zbudujcie projekt na emulatorze za pomocą skrótu Cmd + B, ale jeszcze nie uruchamiajcie go na emulatorze. Po zakończeniu builda (nie powinno być żadnych błędów) w nawigatorze rozwińcie folder Products, a następnie kliknijcie prawym przyciskiem na pliku DynamicFrameworksDemo.app i wybierzcie „Show in finder”:

 

 

Ukaże Wam się folder, w którym przechowywany jest plik .ipa aplikacji. Kliknijcie na nim prawy przyciskiem i wybierzcie „Show Package Contents”. Zostanie Wam zaprezentowany folder zwierający wszystkie pliki wymagane do uruchomienia aplikacji:

 

 

Skorzystamy teraz z narzędzia o nazwie otool, które pozwala na sprawdzenie jakie biblioteki zostały podlinkowane do aplikacji. Otwórzcie okno terminala i wpiszcie poniższe polecenie, ale nie wciskajcie jeszcze enter:

 

Dodajcie spację i przeciągnijcie do okna terminala plik wykonywalny aplikacji (ten o nazwie DynamicFrameworksDemo). Okno terminala powinno wyglądać mniej więcej tak:

 

Naciśnijcie teraz enter i Waszym oczom powinien ukazać się widok podobny do poniższego:

 

 

Dzięki narzędziu otool uruchomionemu z flagą -L możemy podejrzeć listę dynamicznych bibliotek, które zostały dołączone do naszej aplikacji. Oprócz bibliotek, które dodaliśmy ręcznie na liście pojawiły się frameworki, które wykorzystywane są w każdej aplikacji iOS – Foundation oraz UIKit.

Tak wygląda ścieżka, w której przechowywane są dynamic frameworks:

Musicie jednak pamiętać o tym, że powyższa ścieżka wskazuję lokalizację na urządzeniu, na którym aplikacja została uruchomiona. W tym przypadku będzie to wirtualna lokalizacja na emulatorze. O ile to właśnie na nim testujecie aplikację 🤓.

Jeszcze raz skorzystamy z narzędzia otool, ale tym razem zmienimy flagę na małe „l”. Pozwoli nam to na wyświetlenie poszczególnych instrukcji load, odpowiedzialnych za ładowanie bibliotek do pamięci urządzenia. Otwórzcie ponownie okno terminala i naciśnijcie strzałkę „do góry” na klawiaturze, aby przywołać ostatnio wykonaną instrukcje. Teraz wystarczy, że zamienicie flagę z wielkiego ‚L’ na małe ‚l’:

 

Naciśnijcie enter, a w terminalu powinien pojawić się widok podobny do poniższego (wersja skrócona):

 

Korzystając teraz ze skrótu Cmd + F wyszukajcie wzmianki o CoreBluetooth oraz AVFoundation:

 

Porównajcie sobie wartość pola cmd. Dla AVFoundation wartość ta będzie równa LC_LOAD_DYLIB. CoreBluetooth zostało natomiast oznaczone LC_LOAD_WEAK_DYLIB. Jak się pewnie domyślacie drugi przypadek oznacza, że dana biblioteka traktowana jest jako opcjonalna.

Kiedy oznaczanie biblioteki jako opcjonalnej może okazać się przydatne? Załóżmy mocno abstrakcyjną sytuację, w której piszemy aplikację przeznaczoną do współpracy z urządzeniami Bluetooth. Najniższa wspierana przez naszą aplikację wersja iOS to 10.0. Współpraca z biblioteką CoreBluetooth nie będzie więc problemem. Na pewnym etapie zdecydujemy jednak, że fajnie będzie dodać do naszej apki elementy bardzo popularnej ostatnio rozszerzonej rzeczywistości. Biblioteka ARKit wymaga jednak iOS’a przynajmniej w wersji 11. W takiej sytuacji CoreBluetooth dodamy jako framework wymagany, natomiast ARKit jako framework opcjonalny.

I to właściwie wszystko. Możecie spokojnie wyrzucić z dysku aplikację, na której pracowaliśmy, bo raczej nie będzie Wam już do niczego potrzebna 😅.

 

Słowo na drogę

 

Dynamics frameworks leżą u podstaw działania wszystkich aplikacji napisanych z myślą o iOS. Warto posiadać choćby podstawową wiedzę na temat ich działania. Na początku może wydawać się to mało intuicyjne, ale jak sami mogliście się przekonać, rozłożenie każdej z operacji na mniejsze fragmenty pozwala poukładać to sobie jakoś w głowie 🤯. Do następnego 🧐.

 

 

Comments

    1. Artykuł ciekawy. Ale generalnie przypadek ten odnosi się do znacznej ilości bibliotek dynamicznych. Warto jednak faktycznie zwrócić na niego uwagę 😉

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *