Skip to content

Commit

Permalink
Add Moya analysis to network section
Browse files Browse the repository at this point in the history
  • Loading branch information
josefdolezal committed May 3, 2017
1 parent 07256e4 commit 49f1e9b
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 1 deletion.
6 changes: 6 additions & 0 deletions assets/code/bi-bap-sample-code.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
D22D70811EB9DE91002C4A42 /* urlsessionrequest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = urlsessionrequest.swift; sourceTree = SOURCE_ROOT; };
D22D70861EB9FCB4002C4A42 /* alamofire-router.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "alamofire-router.swift"; sourceTree = SOURCE_ROOT; };
D22D70881EBA005D002C4A42 /* alamofire-sessionmanager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "alamofire-sessionmanager.swift"; sourceTree = SOURCE_ROOT; };
D22D70AA1EBA1D0D002C4A42 /* moya-target.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "moya-target.swift"; sourceTree = SOURCE_ROOT; };
D22D70AC1EBA2463002C4A42 /* moya-provider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "moya-provider.swift"; sourceTree = SOURCE_ROOT; };
D22D70AE1EBA2D1B002C4A42 /* moya-reactive-extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "moya-reactive-extensions.swift"; sourceTree = SOURCE_ROOT; };
D2BA092E1EA4DF8B00C97E08 /* bi-bap-sample-code */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "bi-bap-sample-code"; sourceTree = BUILT_PRODUCTS_DIR; };
D2BA09381EA4E02200C97E08 /* create-dispatch-queue.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "create-dispatch-queue.swift"; sourceTree = SOURCE_ROOT; };
D2BA09391EA4E02200C97E08 /* operation-queue-demonstration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "operation-queue-demonstration.swift"; sourceTree = SOURCE_ROOT; };
Expand Down Expand Up @@ -76,6 +79,9 @@
D22D70811EB9DE91002C4A42 /* urlsessionrequest.swift */,
D22D70861EB9FCB4002C4A42 /* alamofire-router.swift */,
D22D70881EBA005D002C4A42 /* alamofire-sessionmanager.swift */,
D22D70AA1EBA1D0D002C4A42 /* moya-target.swift */,
D22D70AC1EBA2463002C4A42 /* moya-provider.swift */,
D22D70AE1EBA2D1B002C4A42 /* moya-reactive-extensions.swift */,
);
path = "bi-bap-sample-code";
sourceTree = "<group>";
Expand Down
9 changes: 9 additions & 0 deletions assets/code/moya-provider.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import Moya

let provider = ReactiveSwiftMoyaProvider<Printer>()

provider.request(.disconnectPrinter)
.filterSuccessfullStatusCodes()
.startWithResult { result in
/* zpracování odpovědi */
}
10 changes: 10 additions & 0 deletions assets/code/moya-reactive-extensions.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import Moya

provider.request(.authorize)
.flatMap(.latest) {
return provider.request(.movePrintHead(direction: .x))
}
.flatMap(.latest) {
return provider.request(.extrude)
}
.startWithResult { /* ... */}
14 changes: 14 additions & 0 deletions assets/code/moya-target.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import Moya

enum Printer: TargetType {
case printFile(URL)
case disconnectPrinter

var baseURL = /* ... */
var path = /* ... */
var method = /* ... */
var parameters = /* ... */
var parametersEncoding = /* ... */
var sampleData = /* ... */
var task = /* ... */
}
10 changes: 10 additions & 0 deletions bibliography.bib
Original file line number Diff line number Diff line change
Expand Up @@ -226,4 +226,14 @@ @ARTICLE {github-alamofire
year = "2017",
note = "[cit. 2017-5-3]",
url = "https://github.com/Alamofire/Alamofire"
}

@ARTICLE {github-moya,
title = "Moya: Network abstraction layer written in Swift.",
journal = "GitHub {[online]} {[online]}",
howpublished = "[online]",
month = "květen",
year = "2017",
note = "[cit. 2017-5-3]",
url = "https://github.com/Moya/Moya"
}
73 changes: 72 additions & 1 deletion chapters/analysis-networking.tex
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ \section{Síťování}\label{analyza-sitovani}
\item Jednotlivé požadavky musí jít snadno řetězit bez ztráty informací či ignorování chyb.
\end{enumerate}

Mým požadavkům se nejvíce přiblížili čtyři možná řešení, které následně podrobně popíši.
Mým požadavkům se nejvíce přiblížili tři možná řešení, které následně podrobně popíši.
Řešení jsem analyzoval od těch nejvíce \textit{low-level}, které pracují pouze se standardními knihovnami až po implementace za využití externích knihoven.

\subsection{URLSession}
Expand Down Expand Up @@ -95,3 +95,74 @@ \subsubsection{Shrnutí}

Pro zpracování je nicméně opět dostupný pouze \textit{completion blok}.
Řetězení požadavků zůstává prakticky stejné jako u \textit{URLSession}.

\subsection{Moya}

Jako poslední možné řešení síťových požadavků jsem zvážil open source knihovnu Moya \cite{github-moya}.

Moya je abstraktní vrstva na víše zmíněnou Alamofire.
Nabízí tedy stejné možnosti, klade si ale za cíl uživatele odstínit od správy URL adres a parametrů a dalšího nastavení.

Druhou výhodou je zapouzdřování endpointů do tkzv. \textit{Provider} objektů.
Na rozdíl od Router objektu zapouzdřuje Provider pouze endpointy se stejnými vlastnostmi (např. stejná úroveň řízení přístupu).
Během kompilace tak lze ověřit, že požadavky, které vyžadují oprávnění jsou vytváří stejný Provider.

\medskip

Velmi užitečný je i zcela jiný přístup k vytváření požadavků.
Moya vytváří požadavek ve třech fázích.
Nejprve nechá uživatele vytvořit \textit{Target}, ten se následně mapuje na \textit{Endpoint} z kterého teprve Provider vytvoří samotný požadavek.

\subsubsection{Target}

Prvním krokem vytváření požadavku je Target.
Target reprezentuje akci, která se má vykonat na vybraném vzdáleném API.
Typicky implementovaný jako enum a poskytuje vysokoúrovňové API pro využití ve zbytku aplikace.
Implementace targetu je vidět v ukázce \ref{code:moya-target}.

\swiftcode{code:moya-target}{Moya - Implementace Target objektu}{assets/code/moya-target.swift}

\subsubsection{Endpoint}

Endpoint je interní struktura reprezentující koncový bod, která je využita k sestavení požadavku.
Hlavním cílem této struktury je možnost modifikovat způsob, jakým budou požadavky vytvořeny.
Pomocí Endpoint objektu lze např. přidávat autorizační token či některé požadavky rušit, opozdit atp.

\subsubsection{Provider}

Při použití Moyi se veškeré požadavky odesílají skrz Provider.
Provider je generický objekt, který operuje na objektem Target.
Tím se v době kompilace dosáhne kontroly kompatibility Provider s Target objektem.

Provider nabízí rozhraní pro modifikaci vytvoření Endpointu i pro modifikaci požadavku.
Vytvoření požadavku je vidět v ukázce \ref{code:moya-provider}.

\swiftcode{code:moya-provider}{Moya - vytvoření požadavku}{assets/code/moya-provider.swift}

\subsubsection{Reaktivní rozšíření}

Moya v základu nabízí rozšíření pro použití s reaktivními knihovnami.
Díky tomu lze velmi dobře integrovat s architekturou MVVM, konkrétně do vrstvy View Model.
Usnadňuje tím také možnost řetězení požadavků pomocí flatMap operátoru jak je vidět v ukázce \ref{code:moya-reactive-extensions}.

\swiftcode{code:moya-reactive-extensions}{Moya - Řetězení požadavků}{assets/code/moya-reactive-extensions.swift}

\subsubsection{Testování}

Jednou z největších výhod Moyi je možnost testování.
V Target objektu je možné definovat, jaká data má požadavek vrátit v době kdy se aplikace testuje.
Tím Moya zaručí, že testy nebudou selhávat v případě kdy nebude dostupná síť.

Pro případ testování chování aplikace v momentě kdy je síť nedostupná nebo kdy požadavky selžou je možné opět využít úpravy Endpoint objektu.

\subsubsection{Shrnutí}

Moya je knihovna pro vytvoření abstrakce nad síťovou vrstvou.
Tato nová vrstva se stává jediným spojením aplikace s internetem.

Obsahuje totožné funkce jako knihovna Alamofire, kterou ve své implementaci využívá.
Oproti Alamofire navíc nabízí striktní oddělení Endpoint a Terget objektů.

Tím umožňuje požadavky automaticky mockovat při testování.

Díky reaktivním rozšířením lze navíc velmi dobře integrovat s architekturou MVVM.

0 comments on commit 49f1e9b

Please sign in to comment.