134 lines
4.8 KiB
Markdown
134 lines
4.8 KiB
Markdown
|
## News Feature
|
||
|
|
||
|
Das News Feature zeigt eine Liste von Nachrichten
|
||
|
der Tagesschau (siehe Abbildung \ref{newsList}). Die Nachrichten können in einer
|
||
|
Liste oder in einem Raster angezeigt werden (siehe Abbildung \ref{newsGrid}),
|
||
|
mithilfe eines Stateful Widgets kann zwischen den beiden Ansichten gewechselt werden.
|
||
|
|
||
|
Die Nachrichten werden von der Tagesschau-API abgerufen,
|
||
|
welche als OpenAPI unter der Adresse https://tagesschau.api.bund.dev/
|
||
|
verfügbar ist. Die Nutzung der API ist für den privaten nicht-kommerziellen
|
||
|
Gebrauch gestattet, die Veröffentlichung hingegen nicht - mit Ausnahme von
|
||
|
Angeboten, welche explizit unter der CC-Lizenz stehen.
|
||
|
Außerdem soll man mit nicht mehr als 60 Abrufen pro Stunde tätigen,
|
||
|
was für die Testzwecke in dieser Arbeit ausreichend ist [@TagesschauAPIOpenAPIa].
|
||
|
|
||
|
\Begin{multicols}{2}
|
||
|
|
||
|
\begin{figure}[H]
|
||
|
\caption{News Liste}
|
||
|
\label{newsList}
|
||
|
\centering
|
||
|
{\shadowimage[width=7cm]{./assets/screenshots/newsList.png}}
|
||
|
\end{figure}
|
||
|
|
||
|
\begin{figure}[H]
|
||
|
\caption{News Raster}
|
||
|
\label{newsGrid}
|
||
|
\centering
|
||
|
{\shadowimage[width=7cm]{./assets/screenshots/newsGrid.png}}
|
||
|
\end{figure}
|
||
|
|
||
|
\End{multicols}
|
||
|
|
||
|
In der Implementierung des News-Features wurden in der Datenzugriffsschicht passende
|
||
|
Modelle für die zum Test benötigten Daten erstellt, welche von der API abgerufen
|
||
|
werden. Die Modelle wurden mit Hilfe des Freezed-Pakets generiert und werden
|
||
|
in dem UML Klassen-Diagramm in Abbildung \ref{umlNews} dargestellt. Zum besseren
|
||
|
Verständnis werden in dem Diagramm die Typen der Attribute in den Typen aus der
|
||
|
Dart Programmiersprache angegeben. Viele der Attribute sind explizit als optional
|
||
|
deklariert, da die API nicht immer alle Attribute liefert, zudem wurden nur die
|
||
|
wenigsten Attribute modelliert, die für die Anzeige der Nachrichten benötigt werden.
|
||
|
Alle anderen Attribute werden aus der JSON Antwort der API nicht verwendet und
|
||
|
ignoriert.
|
||
|
|
||
|
In der Geschäftsschicht wurde ein Controller mit dem Namen _NewsController_
|
||
|
erstellt. Dieser nutzt den Riverpod Generator als Klasse. In der notwendigen
|
||
|
_build_ Methode wird als Future ein _RegionNews_ Objekt zurückgegeben, welches
|
||
|
die neuesten Nachrichten der Tagesschau enthält. Des weiteren wurde im Controller
|
||
|
eine _appendPage_ Methode implementiert, welche die nächste Seite der Nachrichten
|
||
|
abruft und an die bereits vorhandenen Nachrichten anhängt. Der von Riverpod
|
||
|
generierte Provider _newsControllerProvider_ wird in der Präsentationsschicht
|
||
|
verwendet, um die Nachrichten anzuzeigen und sobald man am Ende der Liste oder
|
||
|
des Rasters angekommen ist, wird die nächste Seite der Nachrichten
|
||
|
mit der _appendPage_ Methode abgerufen und an die bereits vorhandenen Nachrichten
|
||
|
angehängt. Der Nutzer kann so unendlich tief in die Nachrichtenliste scrollen. \
|
||
|
|
||
|
```{=latex}
|
||
|
\begin{figure}[H]
|
||
|
\centering
|
||
|
\caption{UML Klassen-Diagram für das News Feature}
|
||
|
\label{umlNews}
|
||
|
```
|
||
|
|
||
|
```{.mermaid loc=assets/mermaid caption="News UML Diagram"}
|
||
|
classDiagram
|
||
|
RegionNews *-- "0..n" News
|
||
|
News *-- "0..1" TeaserImage
|
||
|
class RegionNews{
|
||
|
+news: List~News~
|
||
|
+nextPage: String?
|
||
|
+fromJSON(Map~String, dynamic~ json) RegionNews
|
||
|
+toJSON() Map~String, dynamic~
|
||
|
}
|
||
|
class News{
|
||
|
+title: String?
|
||
|
+teaserImage: TeaserImage?
|
||
|
+brandingImage: TeaserImage?
|
||
|
+date: String?
|
||
|
+type: String?
|
||
|
+fromJSON(Map~String, dynamic~ json) News
|
||
|
+toJSON() Map~String, dynamic~
|
||
|
}
|
||
|
class TeaserImage{
|
||
|
+imageVariants: Map~String, String~?
|
||
|
+fromJSON(Map~String, dynamic~ json) TeaserImage
|
||
|
+toJSON() Map~String, dynamic~
|
||
|
}
|
||
|
```
|
||
|
|
||
|
```{=latex}
|
||
|
\end{figure}
|
||
|
```
|
||
|
|
||
|
<!-- Daraus ergab sich die folgende Ordnerstruktur:
|
||
|
|
||
|
\begin{figure}[H]
|
||
|
\caption{Example caption}
|
||
|
\centering
|
||
|
\begin{minipage}{7cm}
|
||
|
\dirtree{%
|
||
|
.1 news\char`\_api/.
|
||
|
.2 business/.
|
||
|
.3 news\char`\_controller.dart.
|
||
|
.3 scroll\char`\_state\char`\_controller.dart.
|
||
|
.2 data/.
|
||
|
.3 models/.
|
||
|
.4 news.dart.
|
||
|
.4 region\char`\_news.dart.
|
||
|
.4 teaser\char`\_image\char`\_url.dart.
|
||
|
.4 teaser\char`\_image.dart.
|
||
|
.3 repository/.
|
||
|
.4 news\char`\_repository.dart.
|
||
|
.2 presentation/.
|
||
|
.3 widgets/.
|
||
|
.4 news\char`\_grid\char`\_item.dart.
|
||
|
.4 news\char`\_grid.dart.
|
||
|
.4 news\char`\_list\char`\_item.dart.
|
||
|
.4 news\char`\_list.dart.
|
||
|
.3 news\char`\_screen.dart.
|
||
|
}
|
||
|
\end{minipage}
|
||
|
\end{figure} -->
|
||
|
|
||
|
<!-- wurde verwendet, um die Modelle zu generieren.
|
||
|
|
||
|
\lstinputlisting[language=Java, caption=Implementierung der News Klasse, linerange={0-20}, captionpos=t]
|
||
|
{code/flutter_elinux/lib/features/news_api/data/models/news.dart}
|
||
|
|
||
|
\lstinputlisting[language=Java, caption=Implementierung des News Controllers, captionpos=t]
|
||
|
{code/flutter_elinux/lib/features/news_api/data/repository/news_repository.dart}
|
||
|
|
||
|
\lstinputlisting[language=Java, caption=Implementierung des News Controllers, captionpos=t]
|
||
|
{code/flutter_elinux/lib/features/news_api/business/news_controller.dart} -->
|