Tworzenie i konfiguracja projektu (CD)
Atrybut | Typ | Opis |
---|---|---|
Excerpt | String | Opis danego zasobu (WordPressowa Zajawka) |
hasVisited | Bool | Czy użytkownik przeczytał/odsłuchał artykuł/podcast? |
id | UUID | Unikalny identyfikator zasobu |
name | String | Nazwa danego zasobu |
url | String | Adres URL danego zasobu |
Nie bez kozery atrybuty przedstawiłem w formie tabeli. Nie dość, że takie dane są sporo prostsze do przyswojenia przez człowieka w takiej formie, to jeszcze komputer również przechowuje je właśnie tak. Jak ktokolwiek miał do czynienia z relacyjnymi bazami danych (SQL), to wie, o co chodzi, a jeżeli nie, to zapraszam tutaj. Kiedyś o bazach zrobię osobny wpis, bo nawet jak nie jesteśmy programistami to bazy danych to super zabawa i warto się z nimi moim zdaniem zapoznać. Tymczasem jednak przejdźmy dalej, bo wciąż sporo pracy przed nami…
Tworzenie kontrolera danych
Gdy szablon naszej bazy jest już gotowy, możemy przejść do stworzenia czegoś, co ja nazwę sobie kontrolerem danych. Zadaniem tego prostego kawałka kodu będzie przygotowanie naszej biblioteki do używania. Przygotowanie, niezaładowanie. Bo co jeżeli nasza biblioteka miałaby na przykład 20 tysięcy podcastów? Wiem, Tyflopodcast tyle nie ma, ale może mieć, więc takie problemy należy przewidywać już na początku procesu pisania aplikacji, bo potem ich rozwiązanie może przyprawić nas o ból głowy.
Aby utworzyć nowy plik, należy wpierw przejść do nawigatora (wspominałem o nim krótko) przy pomocy skrótu Command + 1. Następnie z drzewka należy wybrać grupę o nazwie Tyflocentrum i w reszcie wcisnąć skrót CMD + N (New). Spowoduje to otwarcie okna tworzenia nowego pliku, które bardzo mocno przypomina to użyte przez nas wcześniej do stworzenia aplikacji. W siatce “Template chooser” wybieramy “Swift file” i klikamy “Next”. Jako nazwę wprowadzamy “DataController.swift” i klikamy “Save.
Edytor automatycznie otworzy nasz nowy plik, który wygląda tak.
//
// DataController.swift
// Tyflocentrum
//
// Created by Arkadiusz Świętnicki on 12/10/2022.
//
import Foundation
Jak widzimy, plik ten jak na razie nie zawiera w sobie wiele treści. Obecnie możemy wyróżnić w nim tylko dwa elementy.
- Linijki rozpoczynające się od dwóch znaków ukośnika (//). Taki zapis oznacza komentarz. Komentarz w programowaniu to nic innego jak znak dla komputera mówiący “Olej to, to cię nie dotyczy”.
- import Foundation: konstrukt
pozwala nam dodać do naszego programu jakąś funkcjonalność. Z polskiego na nasze gdy piszemy "import" to każemy komputerowi "zrekrutować" jakiś framework czyli jakąś funkcjonalność.
A propo konstruktu import to ustawiamy się w edytorze tuż przed linijką import Foundation
i robimy przed nią nową linię klawiszem Return. Następnie własnymi paluszkami wprowadzamy frazę import CoreData
. Jak chyba wcześniej wspominałem, „CoreData” jest frameworkiem służącym do wykonywania operacji na bazach danych.
Nie musimy importować bibliotek alfabetycznie, ale gwarantuję Wam, że przy bardziej skomplikowanych projektach taka praktyka może się nam bardzo przydać.
Idąc dalej, musimy utworzyć klasę. Klasa to nic innego jak swego rodzaju szablon, który opisuje jakiś mniej lub bardziej abstrakcyjny obiekt, na przykład Kotek, Auto czy… model danych. Na Wasze (i chyba moje też) nieszczęście akurat teraz mamy obiekt bardziej abstrakcyjny. No bo jak w świecie rzeczywistym możemy opisać kontroler danych? UFO na siedmiu nogach?
Na końcu naszego pliku dopisujemy sobie coś takiego.
class DataController: ObservableObject {
I znowu teoria (wiem, jak bardzo mnie kochacie). Ten króciutki fragment składa się aż z czterech możliwych do wyróżnienia części opisanych poniżej.
class
: kolejne już słowo kluczowe języka programowania Swift. Informuje ono komputer, że to, co następuje po nim, dotyczy klasy, a nie na przykład zmiennej, nazwy biblioteki czy komentarza.DataController
- To akurat nic innego jak moja własna nazwa dla klasy. Jest kilka sztywnych zasad nazywania klas, zmiennych i struktur, ale teraz nie o tym.
ObservableObject
: to jest już bardziej skomplikowana sprawa, albowiem jest to protokół, czyli kolejna bardzo ważna funkcja języka Swift. Protokoły to nic innego jak kontrakty czy umowy zawierane między nami — programistami- a językiem Swift. Taka umowa oznacza, że my, a właściwie nasza klasa musi spełnić pewne wymagania, w zamian za co Swift “gwarantuje nam” możliwość wykonania naszego kodu.
- (Lewy nawias klamrowy: mówi komputerowi, że rozpoczyna się nowy blok. Blok to nic innego jak związany ze sobą kontekstowo fragment kodu, w naszym przypadku klasa.
UWAGA!
Jeżeli w poprzedniej części, w paragrafie poświęconym konfiguracji środowiska XCode nie wyłączyliście automatycznego uzupełniania nawiasów to program automatycznie wstawił też prawy nawias klamrowy, oznaczający po prostu koniec bloku.
Następnie w środku naszego bloku wpisujemy takie o to magiczne zaklęcie:
let container = NSPersistentContainer(name: "Tyflocentrum")
Tutaj też jest kilka możliwych do wyróżnienia części, ale tym razem omówimy tylko te najważniejsze
- let: Piekielnie ważne słówko kluczowe języka Swift, oznaczające stałą. Stałaj może być ustawiona raz, a potem nie może być zmieniana, i dlatego jest stałą a nie zmienną. 😀
NSPersistentContainer
: To jest nazwa klasy importowanej przez CoreData. Tutaj przydałoby się trochę historii w celu wyjaśnienia nazwy. Apple, a raczej NextStep kombinowali już z frameworkami do baz danych od bardzo długiego czasu. NS w tej nazwie oznacza po prostu NextStep, czyli nazwę systemu operacyjnego na podwalinach którego powstał współczesny MacOS i w konsekwencji tego iOS. Core Data powstało wraz z iPhone OS 3 (to wtedy NIE był iOS!) To stąd ta archaiczna nazwa.- name: “Tyflocentrum”: Kolejny niezwykle ważny konstrukt Swifta. Są to tak zwane parametry nazwane (named parameters po angielsku). Jak ktoś miał do czynienia z programowaniem to jest przyzwyczajony raczej do czegoś takiego:
void pozdrow(const wchar_t *kogo)
. W Swifcie jest inaczej (o tym zaraz).
No i elegancko. Pewnie czujecie się jak na średnio ciekawej lekcji matematyki w szkole, gdzie nauczycielka swoje, wasze ręce swoje a mózg już zjada pizzę w jakiejś eleganckiej Włoskiej restauracji. Ta długa, strasznie brzmiąca linijka przygotowuje po prostu naszą bazę danych do użycia.
Następnym krokiem jest stworzenie własnego konstruktora (initializer po angielsku). Konstruktor to zestaw instrukcji jakie są wykonywane po “narodzinach” obiektu. Jak rodzi się dziecko to instrukcją, którą ma lekarz jest odcięciem pępowiny. Nasza instrukcja będzie mniej spektakularna, i po narodzinach kontrolera danych biblioteka będzie się wczytywała. Poniżej kod z notatkami, jak to ja mam w zwyczaju
init() { // Tworzymy konstruktor
container.loadPersistentStores { description, error in // Ładujemy nasze dane. Jako, że jesteśmy pesymistami to zakładamy, że coś pójdzie nie tak.
if let error = error { // Jeżeli jest błąd, to...
fatalError("Failed to load the data model!\n\(error.localizedDescription)") // Z takiego błędu nie można się wykaraskać. Jedyne co to możemy pokazać błąd.
}
}
}
}
W tym kodzie jest bardzo dużo rzeczy do omówienia, albowiem wjeżdżają między innymi funkcje anonimowe, lambdy, predykaty… zwał to jak zwał, w każdym razie o co chodzi z linijką container.LoadPersistentStores {description, error in
Zapis może brzmieć strasznie ale w gruncie rzeczy koncept jest bardzo prosty. Chodzi bowiem o to, że funkcja LoadPersistentStores
jako swój parametr przyjmuje coś, co Apple nazywa “Completion Handler”. Ten “Completion handler” to funkcja, która wykonuje się po wykonaniu swojej funkcji macierzystej, w tym wypadku nasze ukochane LoadPer`sistentStores
. Z kolei tamta funkcja przyjmuje dwa parametry, odpowiednio description
i error
. Nasz zapis jest po prostu skrótem. Nie będę już Wam mieszał ale ten completion handler może “żyć” w zupełnie innym miejscu kodu.
następna linijka może być równie czarnomagiczna, jak ja uczyłem się Swifta to długo zastanawiałem się po co to komu i na co, także jeżeli moje tłumaczenie do Was nie trafia, to zapraszam do kontaktu 😉
if let error = error {
Tę linijkę można wyjaśnić na conajmniej dwa sposoby. Pierwszy z nich to kilka zdań, a drugi. jakieś 30, 40 stron maszynopisu. Pozwólcie, że dla waszego i mojego zdrowia psychicznego ogranicze się do pierwszego sposobu
Zapis ten oznacza nic więcej, niż tylko “Jeżeli istnieje błąd to…” W Swifcie jest sobie coś co nazywa się wartościami opcjonalnymi (Optionals po angielsku). Wartość może istnieć, albo nie istnieć. Na przykład jeżeli mamy zmienną
hoursWorked: Int = 42
To jest akurat proste, oznacza to że wartość przepracowanych godzin jest równa 42, nawet zapis hoursWorked: Int = 0
ma sens, ale zapis hoursWorked: Int = nil
już taki oczywisty nie jest. Oznacza to tyle, że ktoś może w ogóle nie zamierza pracować, dlatego nie prowadzi indeksu przepracowanych godzin, dlatego wartość zwyczajnie nie istnieje. Tak samo jest w naszym przykładzie. Jeżeli wszystko poszło zgodnie z planem (baza danych została poprawnie wczytana), to błąd zwyczajnie NIE ISTNIEJE. W Swifcie ten mechanizm jest bardzo często stosowany, i nawet w tym projekcie spotkamy się z konstruktem if let blabla = blabla
jeszcze z 10 razy dlatego nie ma, że boli i trzeba przyswajać.
Co ciekawe istnieje konstrukt niejako odwrotny do if let blabla = blabla
, ale… o tym opowiem Wam już innym razem.
Zanim nasza baza danych będzie już tak na serio gotowa do działania musimy zrobić jeszcze jedną istotną rzecz, a mianowicie “wstrzyknąć” ją do środowiska. Chodzi o to, że program korzysta przeważnie tylko z jednej bazy danych, więc żeby nie trzebabyło nią “rząglować” pomiędzy konkretnymi oknami, możemy sprawić aby ta była dostępna globalnie dla całej aplikacji.
W tym celu otwieramy plik “TyflocentrumApp.Swift”.
Następnie udajemy się pod linijkę struct TyflocentrumApp: App {
i tóż pod nią wpisujemy: @StateObject private var dataController = DataController()
Znowu w tym kodzie jest kilka rzeczy do wyjaśnienia, więc czym prędzej spieszę:
- StateObject: To jest takie ustrojstwo, które pozwala nam utrzymywać bardziej skomplikowane obiekty przy życiu pomiędzy oknami. W tym wypadku jest to o tyle ważne, że nasza aplikacja będzie potrzebować dostępu do bazy danych z różnych miejsc.
- private: to słowo kluczowe oznacza, że nasza zmienna będzie prywatna dla klasy/struktury, w której została stworzona. Z polskiego na nasze nie będziemy mogli dostać się do niej z zewnątrz.
Obiecuję, to już ostatni krok jeżeli chodzi o ustawianie naszej bazy danych. Teraz należy ustawić się na końcu linijki contentView()
i dodać tę satanistyczną inwokację:
.environment(\.managedObjectContext, dataController.container.viewContext)
Bwer Company is a top supplier of weighbridge truck scales in Iraq, providing a complete range of solutions for accurate vehicle load measurement. Their services cover every aspect of truck scales, from truck scale installation and maintenance to calibration and repair. Bwer Company offers commercial truck scales, industrial truck scales, and axle weighbridge systems, tailored to meet the demands of heavy-duty applications. Bwer Company’s electronic truck scales and digital truck scales incorporate advanced technology, ensuring precise and reliable measurements. Their heavy-duty truck scales are engineered for rugged environments, making them suitable for industries such as logistics, agriculture, and construction. Whether you’re looking for truck scales for sale, rental, or lease, Bwer Company provides flexible options to match your needs, including truck scale parts, accessories, and software for enhanced performance. As trusted truck scale manufacturers, Bwer Company offers certified truck scale calibration services, ensuring compliance with industry standards. Their services include truck scale inspection, certification, and repair services, supporting the long-term reliability of your truck scale systems. With a team of experts, Bwer Company ensures seamless truck scale installation and maintenance, keeping your operations running smoothly. For more information on truck scale prices, installation costs, or to learn about their range of weighbridge truck scales and other products, visit Bwer Company’s website at bwerpipes.com.
أنابيب LDPE في العراق تقدم شركة إيليت بايب في العراق مجموعة شاملة من أنابيب الـ LDPE، التي تُقدّر لمرونتها وخفتها ومقاومتها لمجموعة متنوعة من المواد الكيميائية. تم تصميم أنابيب الـ LDPE لدينا لتلبية معايير الجودة العالية، مما يضمن أداءً موثوقًا عبر تطبيقات متنوعة. باعتبارها واحدة من أفضل وأكثر شركات تصنيع الأنابيب موثوقية في العراق، تلتزم شركة إيليت بايب بتقديم منتجات تجمع بين المتانة والأداء. لمزيد من المعلومات حول أنابيب الـ LDPE الخاصة بنا، تفضل بزيارة elitepipeiraq.com.
Wiem że nikt tego nie czyta ale trzecia część w drodze, a będzie się działo, oj będzie. Przepisywaliśmy obsługę sieci, bo pomyliłem parę rzeczy i działało powoli, a nawet pokaże Wam, jak dodać możliwośc puszczania sobie podcastów ze skrótów czy Siri
Czytam, czytam, więcej później…