モヤ-ネットワークの部分について心配するのをやめて、生活を始める方法

こんにちは! プロジェクトを次のRESTful APIと統合する必要があるときの悲観を知っていますか? これは、ある種のAPIManagerを作成し、Alamofireクエリで埋めてからデータマッピングモデルに関連付ける必要がある場合です。 個人的には、すべての作業を可能な限り最適化するようにしています。そのため、繰り返しコードを大量に書いてルーチンを削除しないように、さまざまなライブラリを定期的に研究しています。 これらの訪問の1つで、素晴らしいMoyaライブラリに出会いました。

最初の知り合い


実際、私はこのライブラリに何度か出くわし、ブラウザのタブにほこりが散らばっていましたが、勉強を延期しましたが、後で何度も後悔しました。 このライブラリの作成者は、「前」と「後」の雄弁な写真をリポジトリに投稿しました。
画像
印象的でしょ? ライブラリの本質は、ネットワーク全体を最小限の動きで迅速に統合できることです。すべての低レベルの作業はMoyaによって行われます。

統合を開始


シングルビューアプリケーションを作成してライブラリをプロジェクトに接続しましょう(マッピングには、 ObjectMapperライブラリを使用し、サードパーティの依存関係を接続するには-CocoaPodsを使用します

ポッドファイル
platform :ios, '9.0'

def app_pods
pod 'ObjectMapper', '~> 2.2'
pod 'Moya'
pod 'Moya-ObjectMapper'
end

target 'MoyaExample' do
use_frameworks!
app_pods

# Pods for MoyaExample

target 'MoyaExampleTests' do
inherit! :search_paths
app_pods
end

end


次に、リクエストを含むファイルを作成する必要があります。これは次のように行われます。

 import Moya enum MoyaExampleService { case getRestaurants(page: Int?, perPage: Int?) } extension MoyaExampleService: TargetType { var baseURL: URL { return URL(string: "http://moya-example.svyatoslav-reshetnikov.ru")! } var path: String { switch self { case .getRestaurants: return "/restaurants.json" } var method: Moya.Method { return .get } var parameters: [String: Any]? { return nil } var parameterEncoding: ParameterEncoding { return URLEncoding.default } var sampleData: Data { return Data() } var task: Task { return .request } } 

このファイルでは、リクエストが設定されています。 最初に列挙型が表示されます-これはすべてのリクエストを処理する将来のサービスです。 すべての要求を1つのサービスに詰め込むことができますが、大規模なプロジェクトでは、 SOLIDからの手紙Iに固執し、ファイルを混乱させないことをお勧めします。 すべてのリクエストを列挙にリストした後、 TargetTypeプロトコルでクラスを拡張する必要があります。 このプロトコルの内容を詳しく見てみましょう。

1. var baseURLは、RESTful APIが存在するサーバーのアドレスです。
2. var pathこれらは要求ルートです。
3. var methodは、送信するメソッドです。 モヤは何も発明せず、アラモファイアのすべての方法を取り入れています。
4. var parametersはクエリパラメーターです。 この段階では、ライブラリはこれらのパラメータがリクエスト本文(POST)にあるかURL(GET)にあるかを気にしません。これらのニュアンスは後で決定されます。 とりあえず、リクエストで渡したいパラメーターを書くだけです。
5. var parameterEncodingは、同じくAlamofireから取得したパラメーターエンコーディングです。 それらをjson、url、プロパティリストとして作成できます。
6. var sampleDataこれらは、テストに使用されるいわゆるスタブです。 サーバーから標準応答を取得し、JSON形式でプロジェクトに保存して、単体テストで使用できます。
7. var taskは、実行するタスクです。 リクエスト、ダウンロード、アップロードの3つのみです。

私たちはプロジェクトに応募します


Moyaの使用を開始するには、プロバイダーを作成する必要があります-これは、リクエストへのアクセスを提供するライブラリーの抽象化です:

 let provider = MoyaProvider<MoyaExampleService>() 

その後、プロバイダーを使用してリクエストを行うことと結婚できます。

 provider.request(.getRestaurants()) { result in switch result { case .success(let response): let restaurantsResponse = try? response.mapObject(RestaurantsResponse.self) // Do something with restaurantsResponse case .failure(let error): print(error.errorDescription ?? "Unknown error") } } 

反応性を追加


MoyaはReactiveSwiftとRxSwiftをサポートしています。 個人的に、私は最新のライブラリを好むので、私の例は彼女のためです。 まず、必要な依存関係を追加しましょう。

ポッドファイル
プラットフォーム:ios、「9.0」

def app_pods
ポッド「ObjectMapper」、「〜> 2.2」
ポッド「モヤ」
ポッド「Moya-ObjectMapper」
ポッド「Moya / RxSwift」
ポッド「Moya-ObjectMapper / RxSwift」
終わり

ターゲット 'MoyaExample' do
use_frameworks!
app_pods

#MoyaExampleのポッド

ターゲット 'MoyaExampleTests' do
継承! :search_paths
app_pods
終わり

終わり

また、コードは次のように変換されます。

 let provider = RxMoyaProvider<MoyaExampleService>() provider.request(.getRestaurants()) .mapObject(RestaurantsResponse.self) .catchError { error in // Do something with error return Observable.error(error) } .subscribe( onNext: { response in self.restaurants = response.data } ) .addDisposableTo(disposeBag) 

モヤとのトリックのペア


Moyaのすべての機能について話すのは長いので、この記事を読んだ後、 ドキュメントをご覧になることをお勧めします。 そして今、私はあなたに役立つかもしれないいくつかのことを紹介します:

1.要求ヘッダーに何かを追加します(たとえば、基本認証)
まず、requestClosureを作成しましょう-これは、送信されたリクエストを変更できるクロージャーです。

 let requestClosure = { (endpoint: Endpoint<MoyaExampleService>, done: MoyaProvider.RequestResultClosure) in var request = endpoint.urlRequest request?.setValue("set_your_token", forHTTPHeaderField: "XAuthToken") done(.success(request!)) } 

このrequestClosureをプロバイダーに追加する必要があります。

 let provider = RxMoyaProvider<MoyaExampleService>(requestClosure: requestClosure) 

2.リクエストを転送する

Moyaにはクールなものがあります-プラグイン、詳細を調べることをお勧めします。 たとえば、プラグインの1つは、すべてのリクエストをコンソールに自動的に表示します。

 let provider = RxMoyaProvider<MoyaExampleService>(plugins: [NetworkLoggerPlugin(verbose: true)]) 

単体テスト


私はBDDスタイルのテストを好むので、ユニットテストにはQuickおよびNimbleライブラリを使用します。 それらをPodfileに追加します。

ポッドファイル
プラットフォーム:ios、「9.0」

def app_pods
ポッド「ObjectMapper」、「〜> 2.2」
ポッド「モヤ」
ポッド「Moya-ObjectMapper」
ポッド「Moya / RxSwift」
ポッド「Moya-ObjectMapper / RxSwift」
終わり

def test_pods
ポッド「クイック」
ポッド「ニンブル」
終わり

ターゲット 'MoyaExample' do
use_frameworks!
app_pods

#MoyaExampleのポッド

ターゲット 'MoyaExampleTests' do
継承! :search_paths
app_pods
test_pods
終わり

終わり

次に、小さなテストを作成します。

 import Quick import Nimble import RxSwift import Moya @testable import MoyaExample class NetworkTests: QuickSpec { override func spec() { var testProvider: RxMoyaProvider<MoyaExampleService>! let disposeBag = DisposeBag() beforeSuite { testProvider = RxMoyaProvider<MoyaExampleService>(stubClosure: MoyaProvider.immediatelyStub) } describe("testProvider") { it("should be not nil") { expect(testProvider).toNot(beNil()) } } describe("getRestaurants") { it("should return not nil RestaurantsResponse object") { testProvider.request(.getRestaurants()) .mapObject(RestaurantsResponse.self) .subscribe( onNext: { response in expect(response).toNot(beNil()) } ) .addDisposableTo(disposeBag) } } } } 

テストを実行し、合格したことを確認してから、ネットワーク部分がテストで100%カバーされていることを確認します(xcodeでコードカバレッジを有効にする方法については、 こちらをお読みください )。

おわりに


この記事では、強力なMoyaネットワークライブラリの基本的なアイデアを読者に提供し、意図的にニュアンスを下げて、独立して探索し、iOS開発でネットワークレイヤーを構築するときに幅広いタスクを解決できる開発ツールを楽しむことができるようにしました。 Githubでソースコードが待っています。

Source: https://habr.com/ru/post/J332570/


All Articles